I want to create a toolbar with custom image buttons, I have the images in .ico format how can I add them to the toolar in WTL? I'm trying to edit the images in the toolbar list, but there such poor quality, how can I add better quality images?
If you have a WTL Toolbar control that is already created you can attach images to it with the SetImageList() and SetHotImageList() methods of the CToolBarCtrl class. E.g.
CToolBarCtrl toolbar;
CImage image;
CBitmap bitmap;
// ... load the image into the bitmap ...
images.Create(32, 32, ILC_COLOR32 | ILC_MASK, 0, 1);
// repeat this for each image you want to use in the toolabr
images.Add(bitmap, RGB(255, 255, 255));
toolbar.SetImageList(images.Detach());
//... do the same for the hot (hover) images ...
The images can then be used by referencing the return value of the CImageList:Add() method.
Make sure you detach the image list from the CImageList class as I have done here otherwise the image list will be deleted when it goes out of scope.
Related
I have a Visual C++ MDI application. In this app, I have 3 toolbars of type CToolBar. To respond to runtime DPI changes (such as the user changing the display settings on the screen on which the app is displayed), I resize the height and sometimes the width of the toolbars. The toolbar resizing works fine, except for one issue. When I change the height of the toolbar, the toolbar button images do not vertically center. Instead, the toolbar button images maintain their position relative to the top edge of the toolbar. This doesn't look nice. Important to point out that I am loading the images from a file at runtime. If I close the app and restart it, the images are then correctly positioned within the toolbar.
My algorithm for this toolbar runtime sizing is as follows:
user changes DPI at runtime
based on new DPI, determine needed height for toolbar
detach existing bitmap from toolbar that is used for toolbar button images
delete each toolbar button
reset the size (height) of the toolbar based on the new DPI setting
attach the bitmap of images to the toolbar so the buttons will have images
Using the above alorithm, i would expect to see the newly loaded toolbar images vertically centered within the toolbar. However, the images are not vertically centered. Instead, they are closer to the top edge of the toolbar than the bottom edge of the toolbar. It is as if the images decided to keep their top left coordinate consistent despite the increase in toolbar height. This issue happens even if I intentionally load the same size images as were used prior to the runtime DPI change.
Here is the code for the algorithm detailed above:
//in my CMainFrame.h file (where CMainFrame is a CMDIFrameWnd)
CToolBar my_toolbar;
CBitmap m_bitmap_for_toolbar;
//in my CMainFrame.cpp file (where CMainFrame is a CMDIFrameWnd):
//detach the existing bitmap used for the toolbar images
(HBITMAP)m_bitmap_for_toolbar.Detach();
//remove the existing buttons prior to resizing the toolbar
int iButtonCount = my_toolbar.SendMessage(TB_BUTTONCOUNT, (WPARAM)0, (LPARAM)0);
for (int i = iButtonCount; i > 0; i--)
{
nButtonIndex = i - 1;
my_toolbar.SendMessage(TB_DELETEBUTTON, (WPARAM)nButtonIndex, (LPARAM)0);
}
//assign new size for the toolbar
my_toolbar.SetSizes(CSize(new_button_width, new_button_height), CSize(button_image_width, (button_image_height));
//create new buttons for the toolbar
TBBUTTON tbButtonsFile[3] =
{
{ 0, ID_FILE_NEW, TBSTATE_ENABLED, BTNS_AUTOSIZE, {0}, 0, (INT_PTR)NULL},
{ 1, ID_FILE_OPEN, TBSTATE_ENABLED, BTNS_AUTOSIZE, {0}, 0, (INT_PTR)NULL},
{ 2, ID_FILE_SAVE, TBSTATE_ENABLED, BTNS_AUTOSIZE, {0}, 0, (INT_PTR)NULL}
};
my_toolbar.SendMessage(TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
my_toolbar.SendMessage(TB_ADDBUTTONS, (WPARAM)3, (LPARAM)&tbButtonsFile);
my_toolbar.SendMessage(TB_AUTOSIZE, 0, 0);
my_toolbar.Invalidate();
//load images from a file for the toolbar buttons
HBITMAP hBitmap = (HBITMAP)LoadImage(NULL, str_bitmap_file_path, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
m_bitmap_for_toolbar.Attach(hBitmap); //attach bitmap that will be used for toolbar images
my_toolbar.SetBitmap(m_bmpToolBarFile);
my_toolbar.Invalidate();
//set the toolbar styles
my_toolbar.SetBarStyle(my_toolbar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
My application use a .bmp file for ImageList.
To do this, I use ImageList_LoadImage macro (https://msdn.microsoft.com/fr-fr/library/windows/desktop/bb761557(v=vs.85).aspx)
I would like to scale this ImageList programmatically.
For example, my .bmp file dimension is 72x24 (3 items of 24x24 icons).
And I would like scale it to 144x46 (3 items of 48x48 icons).
I didn't find any ImageList function to scale my HIMAGELIST handle loaded from .bmp file.
I tried using LoadImage function (https://msdn.microsoft.com/en-us/library/ms648045(v=vs.85).aspx)
But it must be used with bmp file, and here I have HIMAGELIST handle.
I tried to create a new image, copying scaled icons:
ImageList_Create (with icons 48)
Enumerate icons from image list 24 with ImageList_ExtractIcon
Scale icon with DrawIconEx
Add to new image list with ImageList_AddIcon
But it fails when addin icon to new image list.
I want to add an image control to the CView at runtime. Can anybody share some sample source code and format of the image that I am going to use is bitmap.
Basically you need to implement OnPaint of your CView-derived class:
void CImageView::OnPaint()
{
CPaintDC dc(this); // device context for painting
CRect rc;
GetClientRect(&rc);
CImage image;
image.LoadFromResource(::GetModuleHandle(NULL), IDB_BITMAP1);
image.Draw(dc.m_hDC, rc.left, rc.top, rc.Width(), rc.Height(), 0, 0,
image.GetWidth(), image.GetHeight());
}
In this example the image is loaded from BITMAP resource.
To load image from file use CImage::Load() method. It does support the following formats: BMP, GIF, JPEG, PNG and TIFF.
I have a CListCtrl in MFC where I am appending a set of 128x128 pixel images. Now I would like to append a 16x16 small status icon (OK/NOK style) to those images. How can I do this?
I think this may not solve your problem, but is near to be a solution.
CBitmap drawBitmap;
HICON hicon= m_pImageList->ExtractIcon(ix);
drawBitmap.Attach(hicon);
CDC dc;
dc.CreateCompatibleDC(NULL);
dc.SetBkMode(TRANSPARENT);
CPoint pt;
// do your calculations: pt will be define in what part of the image the icon will appear
DrawIcon(&dc.GetSafeHdc(), pt.x, pt.y, IDI_YOUR_ICON);
DeleteDC(dc);
m_pImageList->Replace(ix, &drawBitmap, (CBitmap*)NULL);
ix is the index of the one you want to replace.
Just after posting previous answer, I discovered that it exists CImageList::SetOverlayImage
I am Trying to add an image to an existing button..I have done that to an extent, the problem is I can add an ownerdrawn Image but am not able to add the extact image that I want.. for the example see the below code
CButton* pBtn= (CButton*)GetDlgItem(ID_WIZBACK);
pBtn->ModifyStyle( 0, BS_ICON );
HICON hIcn= (HICON)LoadImage(
AfxGetApp()->m_hInstance,
MAKEINTRESOURCE(IDI_ICON3),
IMAGE_ICON,
0,0, // use actual size
LR_DEFAULTCOLOR
);
pBtn->SetIcon( hIcn );
with the above code am converting the bitmap to an icon to add to my button...how can I add the exact Bitmap image directly to an existing button.Please help me frnds..
Steps for assigning bitmap to button in mfc :
Create object of bitmap
Load bitmap by using LoadBitmap()
Get Handle of button using id and GetDlgItem() method
Modify style so that we can assign bitmap to it
use SetBitmap() on button's handle to assign bitmap
Code :
CBitmap bmp;
bmp.LoadBitmap( IDB_BITMAP4 );
CButton* pButton = (CButton* )GetDlgItem(IDC_BUTTON1);
pButton->ModifyStyle(0,BS_BITMAP);
pButton->SetBitmap(bmp);
I actually fixed the problem..what I did is I replaced the HICON with HBITMAP and its working perfect...basically both would work fine but in my case when I loaded the icon into the button the background of the icon was not changing...I tried Bitmap then it work great. Now am working on positioning the Image and to add text...think I could go through
you don't know how much this helped out. Thanks for posting. Also have to change a few other things to bitmap as well ...
CButton* pBtn= (CButton*)GetDlgItem(ID_MYDIALOG);
pBtn->ModifyStyle( 0, BS_BITMAP );
HBITMAP hIcn= (HBITMAP)LoadImage(
AfxGetApp()->m_hInstance,
MAKEINTRESOURCE(IDB_MYPIC),
IMAGE_BITMAP,
0,0, // use actual size
LR_DEFAULTCOLOR
);
pBtn->SetBitmap( hIcn );
You could subclass existing button using CBitmapButton::SubclassWindow, then use LoadBitmaps.
Use the button classes from the Feature Pack. They have support for showing both text and images on buttons, your regular button can't do that. Look at the 'samples' directory in your VS installation directory.
I want to add some ideas to #Amruta Ghodke 's answer:
You can resize your button using the GetWindowRect and SetWindowPos functions. See an example below:
CRect rc;
pButton->GetWindowRect(rc);
pButton->SetWindowPos(NULL, rc.left, rc.top, myWidth, myHeight, SWP_NOSENDCHANGING | SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE);
If you want to display transparent images, use the software Pixelformer to convert your PNGs to Alpha-enabled BMPs. You will have to:
Go to Image->Properties and set RGB color with alpha channel
Export the file using format A8:R8:G8:B8 and disabled Premultiplied alpha and Top-down row order