Please help! I have tried loading image to image list via icon, hbitmap and cbitmap (i am using mfc dialog based application). But the images just wont show up. But I managed to view the image when i recreate it on an empty sdi mfc application.
m_TreeInspCtrl.DeleteAllItems();
CImageList imgl_Tree;
imgl_Tree.Create(16, 16, ILC_COLOR32, 1, 1);
/*
HBITMAP hBmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_TREE_PASS), IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS);
*/
imgl_Tree.Add(AfxGetApp()->LoadIcon(IDI_ICON_PASS));
/*
CBitmap m_TreePass;
//m_TreePass.Attach(hBmp);
m_TreePass.LoadBitmap(IDB_TREE_PASS);
imgl_Tree.Add(&m_TreePass, RGB(255,0,255));
*/
m_TreeInspCtrl.SetImageList (&imgl_Tree, TVSIL_NORMAL);
CString s_Root = "Inspection Sequence";
HTREEITEM h_Root = m_TreeInspCtrl.InsertItem(s_Root, 0, 0, TVI_ROOT);
m_TreeInspCtrl.SetItemColor(h_Root, RGB(0, 150, 0));
You have to create a CImageList that is valid throughout the existence of the dialog. The one that you created in your code is only temporary on the stack, it will be destroyed when the initialization function returns. I suggest that you create it as a member variable of the dialog class.
Related
This is hopefully simple: I have an application which uses CListCtr in report mode and I want to assign icons to the entries. The icons should be simple square uniformly coloured icons 16x16.
I know ( - I think I know - ) how to handle CListCtr and CImageList, but the challenge I have is the following:
The icon colour is created by the code and arbitrary COLORREF
The icons are not created as files in my resources but should be created by code also. If need be, there can be one 'template' icon in which a specific color is replaced by COLORREF from above.
Essentially, I want to 'abuse' the images as kind of status-light in my CListCtr but with arbitrary colour.
Can anybody give me a short example code snipped for:
Creating a HICON element which is a 16x16 uniformly filled bitmap of COLORREF specified colour?
Try something like this:
CDC dc;
dc.CreateCompatibleDC(NULL);
m_bitmap.CreateBitmap(16, 16, dc.GetDeviceCaps(PLANES), dc.GetDeviceCaps(BITSPIXEL), NULL);
m_imageList.Create(16, 16, ILC_COLORDDB, 0, 1);
HGDIOBJ hOld = dc.SelectObject(m_bitmap);
dc.FillSolidRect(0, 0, 16, 16, RGB(0xff, 0, 0));
dc.SelectObject(hOld);
m_imageList.Add(&m_bitmap, RGB(0, 0, 0));
m_listCtrl.SetImageList(&m_imageList, LVSIL_SMALL);
m_listCtrl.InsertItem(0, _T("hello"), 0);
Slight modification to the accepted answer from mockfrog above.
This also uses the trick I've learnt of here: Using CImageList to convert from HBITMAP to HICON.
Note that it's important to use ILC_COLOR32 to get the full range of colours and not some unwanted colour casting.
HICON CCMixTP_Dialog::CreateColorIcon2( COLORREF color )
{
CDC dc;
dc.CreateCompatibleDC(NULL);
CBitmap bitmap;
bitmap.CreateBitmap(16, 16, dc.GetDeviceCaps(PLANES), \
dc.GetDeviceCaps(BITSPIXEL), NULL);
CImageList convertBuffer;
convertBuffer.Create(16, 16, ILC_COLOR32, 1, 1);
HGDIOBJ hOld = dc.SelectObject(bitmap);
dc.FillSolidRect(0, 0, 16, 16, color);
dc.SelectObject(hOld);
convertBuffer.Add( &bitmap, RGB(0,0,0) ); // Mask black pixels as black.
return convertBuffer.ExtractIcon(0);
}
My advise is not to create icons in this way.
Just use NM_CUSTOMDRAW to draw the element by yourself. You find a great explanation here in this two articles. With this code it is simple to draw the specified area in the color you want!
Article1 Article2
Creating an icon is possible with CreateIconIndirect. You just need to create 2 bitmaps. The drawback here is you need to destroy all theicons you create.
h
I want to use a single CDC, inwhich to draw 3 bitmaps, positioned in the CDC, and then pass it into UpdateLayeredWindow. My problem is that I can't get the SIZE* psize parameter of the UpdateLayeredWindow function right! Can Anyone help? What do I do?
BLENDFUNCTION bBlendFnc = {
AC_SRC_OVER,
0,
255,
AC_SRC_ALPHA
};
CBitmap btCdcBuff;
CBitmap* cache;
BITMAP hbCdcBuff;
btCdcBuff.CreateCompatibleBitmap(pCdcMain, szWndSize.cx, szWndSize.cy); btCdcBuff.GetBitmap(&hbCdcBuff);
cache = pCdcMain->SelectObject(&btCdcBuff); // pCdcMain is a compatible CDC with the screen (pCdcScreen)
Blend(&btIcon); // This function just creates a compatible CDC from a CPaintDC, selects the passed in CBitmap via SelectObject and AlphaBlends it to the pCdcMain.
pCdcMain->SelectObject(cache);
UpdateLayeredWindow(pCdcScreen, NULL, new CSize(hbCdcBuff.bmWidth, hbCdcBuff.bmHeight), pCdcMain, new CPoint(0, 0), 0, &bBlendFnc, ULW_ALPHA) // This fails and returns false
When using CreateCompatibleBitmap with UpdateLayeredWindow, make sure you pass in the CDC for the screen (ie, pCdcScreen not pCdcMain), so that the Bitmap created is of the correct format. See this thread: http://social.msdn.microsoft.com/Forums/en/windowsuidevelopment/thread/1fbcf5e4-b9eb-4537-bf0b-d330aa333fea
I want to load a BitMap image in a pic box I created inside a window...picBoxDisp is created using following mechanism..
picBoxDisp = CreateWindow("STATIC", "image box",
WS_VISIBLE |WS_CHILD | SS_BITMAP |WS_TABSTOP | WS_BORDER,
50, 50, 250, 300, hwnd , (HMENU)10000, NULL, NULL);
Now Next I created a hBitmap object and loaded an image in to it...
hBitmap = (HBITMAP) LoadImage(NULL,szFileName,IMAGE_BITMAP,0,0,
LR_LOADFROMFILE| LR_DEFAULTSIZE);
SendMessage(picBoxDisp,STM_SETIMAGE,(WPARAM) IMAGE_BITMAP,(LPARAM) NULL);
//now assign the new image
//Create a compatible DC for the original size bitmap, for example originalMemDc.
HDC originalDC = GetDC((HWND)hBitmap);
HDC originalMemDC = CreateCompatibleDC(originalDC);
if(originalMemDC==NULL){
MessageBox(NULL,"Problem while creating DC.","Error",MB_OK);
}
//Select hBitmap into originalMemDc.
SelectObject(originalMemDC,hBitmap);
//Create a compatible DC for the resized bitmap, for example resizedMemDc.
HDC picBoxDC = GetDC(picBoxDisp);
HDC resizedMemDC = CreateCompatibleDC(picBoxDC);
//Create a compatible bitmap of the wanted size for the resized bitmap,
HBITMAP hResizedBitmap = CreateCompatibleBitmap(picBoxDC,250,300);
//Select hResizedBitmap into resizedMemDc.
SelectObject(resizedMemDC,hResizedBitmap);
//Stretch-blit from originalMemDc to resizedMemDc.
//BitBlt(resizedMemDC,0,0,250,300,originalMemDC,0,0,SRCCOPY);
BITMAP bmp_old,bmp_new;
GetObject(hBitmap,sizeof(bmp_old),&bmp_old);
GetObject(hResizedBitmap,sizeof(bmp_new),&bmp_new);
StretchBlt ( resizedMemDC,0,0,bmp_new.bmWidth,bmp_new.bmHeight,
originalMemDC,0,0,bmp_old.bmWidth,bmp_new.bmHeight,
SRCCOPY);
////De-select the bitmaps.
if((resizedMemDC==NULL)||(hResizedBitmap == NULL)) {
MessageBox(NULL,"Something is NULL","Error",MB_OK);
}
else
//Set hResizedBitmap as the label image with STM_SETIMAGE
SendMessage(picBoxDisp,STM_SETIMAGE, (WPARAM) IMAGE_BITMAP,(LPARAM) hResizedBitmap);
I just cant understand, why the above code is not working ?
Thanks in advance,
You misunderstood the STM_SETIMAGE usage. Do this:
hBitmap = (HBITMAP)::LoadImage(NULL, szFileName, IMAGE_BITMAP,
0, 0, LR_LOADFROMFILE| LR_DEFAULTSIZE);
if (hBitmap != NULL)
{
::SendMessage(picBoxDisp, STM_SETIMAGE,
(WPARAM)IMAGE_BITMAP, (LPARAM)hBitmap);
}
EDIT: If you want to resize the bitmap before setting it as the label image, then follow this scheme for the simplest possible way to do it (with sub-optimal quality in the resized image...):
Create a compatible DC for the original size bitmap, for example originalMemDc.
Select hBitmap into originalMemDc.
Create a compatible DC for the resized bitmap, for example resizedMemDc.
Create a compatible bitmap of the wanted size for the resized bitmap, for example hResizedBitmap.
Select hResizedBitmap into resizedMemDc.
Stretch-blit from originalMemDc to resizedMemDc.
De-select the bitmaps.
Set hResizedBitmap as the label image with STM_SETIMAGE
Should work!
The static control won't stretch the image to its size. You could use SS_CENTERIMAGE but it either clips or fills the empty space with the color of the top left pixel (see http://msdn.microsoft.com/en-US/library/b7w5x74z.aspx). You'd have to stretch the bitmap yourself before sending it to the static control.
You're trying to assign an image to a static control, so you don't need to draw the image but to set the image on it.
// set the image
HBITMAP hold = (HBITMAP)SendMessage(hpicBoxDc, STM_SETIMAGE, IMAGE_BITMAP, LPARAM(hBitmap));
// clear the old image
if(hold && hold != hBitmap)
DeleteObject(hold );
I'm trying to modify some old code (c++) that uses the CreateToolbarEx function, in an attempt to use a new bitmap and replace our 24x24 pixel toolbar buttons with flashier 36x36 ones. The function I'm using is as follows:
m_hToolbarWnd = CreateToolbarEx(m_hPagerWnd, ws, ID_TOOLBAR, NUMBERTOOLBARBITMAPS, hInst, IDB_TOOLBAR, tbInitButtons, m_ncButtons, 24, 24, 24, 24, sizeof(TBBUTTON));
I'm able to expand the size of the current toolbar buttons by changing the '24's to '36', but if I change IDB_TOOLBAR to the new toolbar bitmap and run the program I hit a memory access read violation pointing to the CreateToolbarEx function. Am I missing something on how the bitmap is getting its memory allocation or creating the individual buttons? The new toolbar is 1584x36 pixels (44 buttons).
This is old, but hopefully the solution I found will help someone. I had overlooked the fact that I was changing from a 16-bit color bitmap to 24-bit, which I was unable to get CreateToolbarEx to handle. Instead, I had to call CreateWindowEx and create and set the icon ImageList for it. Working code:
m_hToolbarWnd = CreateWindowEx(0L, TOOLBARCLASSNAME, "", ws, 36, 36, 36, 36, m_hPagerWnd, (HMENU) ID_TOOLBAR, hInst, NULL);
SendMessage(m_hToolbarWnd, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
HBITMAP hBmp = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_TOOLBAR));
HIMAGELIST hIcons = ImageList_Create(36, 36, ILC_COLOR24, 0, m_ncButtons);
ImageList_Add(hIcons, hBmp, NULL);
SendMessage(m_hToolbarWnd, TB_SETIMAGELIST, 0, (LPARAM) hIcons);
I have a Window (win32 API) Application in visual c++. I am not using MFC. I have to add a picutre box to my application and Change the image of this picture box periodically. Can any one help me out in achieving the above task? Thanks in advance.
This is quite a complex task to post full code here, but I will try to give a few guidelines on how to do it:
First method is to load the image and paint it
Load your image (unfortunately the plain Win32 API has support for quite a few image formats BMP, ICO ...).
HBITMAP hImage = (HBITMAP)LoadImage(NULL, (LPCSTR)file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_LOADTRANSPARENT);
Store the handle above somewhere in your application where you can access it from your WindowProcedure
In the WinProc on the WM_PAINT message you will need to paint the image. The code is something like:
HDC hdcMem = CreateCompatibleDC(hDC); // hDC is a DC structure supplied by Win32API
SelectObject(hdcMem, hImage);
StretchBlt(
hDC, // destination DC
left, // x upper left
top, // y upper left
width, // destination width
height, // destination height
hdcMem, // you just created this above
0,
0, // x and y upper left
w, // source bitmap width
h, // source bitmap height
SRCCOPY); // raster operation
Should work.
Now, the second way of doing it is to create a static control, with type being SS_BITMAP and set its image as:
hImage = LoadImage(NULL, file, IMAGE_BITMAP, w, h, LR_LOADFROMFILE);
SendMessage(hwnd, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hImage);
where hwnd is the handle of your static control.