Icons in Win32 Property Pages are ugly - 4 bit icons [duplicate] - c++

This question already has answers here:
Why are icons in property sheets rendered with so few colors?
(2 answers)
Closed 6 years ago.
I'm using Win32 API C++ Property Sheets in my application, and icons used in page headers have low quality compared to main header for example or other icons in application.
http://i.imgur.com/goiF7Je.png
On attached image both house icons are from same resource.
Is there a way to change it to 32bit color icons?
const int Sheets = 2;
PROPSHEETPAGE psp[Sheets];
for (int i=0; i<Sheets; ++i)
{
psp[i].dwSize = sizeof(PROPSHEETPAGE);
psp[i].dwFlags = PSP_USEICONID | PSP_USETITLE;
psp[i].lParam = 0;
psp[i].pfnCallback = NULL;
psp[i].hInstance = m_hInst;
}
psp[0].pszTemplate = MAKEINTRESOURCE(IDDNEW_IS0);
psp[0].pszIcon = MAKEINTRESOURCE(IDI_GENERAL_TAB);
psp[0].pfnDlgProc = IntegrationServer::tabGeneral;
psp[0].pszTitle = "General";
psp[1].pszTemplate = MAKEINTRESOURCE(IDDNEW_IS1);
psp[1].pszIcon = MAKEINTRESOURCE(IDI_GENERAL_REQUESTS);
psp[1].pfnDlgProc = IntegrationServer::tabRequests;
psp[1].pszTitle = "Requests";
PROPSHEETHEADER psh;
psh.dwSize = sizeof(PROPSHEETHEADER);
psh.dwFlags = PSH_USEICONID | PSH_PROPSHEETPAGE | PSH_NOCONTEXTHELP | PSH_NOAPPLYNOW;
psh.hInstance = m_hInst;
psh.pszIcon = MAKEINTRESOURCE(IDI_GENERAL_TAB);
psh.pszCaption = (LPSTR) "Integration Server configuration";
psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
psh.nStartPage = 0;
psh.ppsp = (LPCPROPSHEETPAGE) &psp;
psh.hwndParent = m_hWnd;
PropertySheet(&psh);

Finally, I have found a solution for above problem. Instead of Property Sheets, I have used Tab Control to create similar window.
Benefits of use Tab Control:
easier to maintain the content of each tab (just show/hide HWND),
icons are 32 bits,
it is a standard control like button, static text etc., so it works in same way.
Defects:
need to write more code.
Here is an example window:
http://i.imgur.com/4AcXvSz.png
And source code:
/*
Need this:
#include <commctrl.h >
#pragma comment(lib, "Comctl32.lib")
#pragma comment(linker,"/manifestdependency:\"type='win32' "
"name='Microsoft.Windows.Common-Controls' version='6.0.0.0' "
"processorArchitecture='*' publicKeyToken='6595b64144ccf1df' "
"language='*'\"")
*/
// get HWND of Tab Control
HWND tab = GetDlgItem(hDlg, IDC_TAB1);
// get current instance
HINSTANCE hInst = (HINSTANCE) GetModuleHandle(NULL);
// insert 7 tabs in our Tab Control
TCITEM tie;
tie.mask = TCIF_TEXT | TCIF_IMAGE;
LPSTR item[] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" };
for (int i = 0; i < 7; i++)
{
tie.pszText = item[i];
tie.iImage = i;
if (TabCtrl_InsertItem(tab, i, &tie) == -1)
break;
}
// insert 7 icons for each Tab
HIMAGELIST hi = ImageList_Create(16, 16, ILC_COLOR32, 0, 7);
if (hi != NULL)
{
int icons[] = {IDI_ACTIONADD, IDI_ACTIONDELETE, IDI_ACTIONEDIT,
IDI_ACTIONIMPORT, IDI_ACTIONVIEW, IDI_CONFIGURATION,
IDI_CONF_CLEANUP};
for (int i =0; i<7; ++i)
{
HICON icon = (HICON) LoadImage(hInst, MAKEINTRESOURCE(icons[i]), IMAGE_ICON, 16, 16, 0);
ICONINFO iconinfo;
GetIconInfo(icon, &iconinfo);
HBITMAP bitmap = iconinfo.hbmColor;
ImageList_Add(hi, bitmap, NULL);
DestroyIcon(icon);
}
}
TabCtrl_SetImageList(tab, hi);
// Set position and size of child window to
// put it on the entire surface of tab display window
RECT rect;
GetClientRect(tab, &rect);
// This will collect entire Tab window and will return rectangle, which will
// fulfill display space
TabCtrl_AdjustRect(tab, FALSE, &rect);
// Create child window, which will be inserted into Tab display space
HWND child = CreateDialog(hInst, MAKEINTRESOURCE(IDD_IS_COMMON_CLEANUP),
tab, IntegrationServer::empty);
// Set child window position and size to fulfill Tab Control
// those "-2", "-1" etc. are just for me - I don't like white space :)
SetWindowPos(child, NULL,
rect.left-2, rect.top-1, rect.right-rect.left+2, rect.bottom-rect.top+2,
SWP_NOZORDER);
// Show child window
ShowWindow(child, SW_SHOW);
After that you have to look for Tab Control notifications, when user is going to change currently displayed tab, and load new HWND into Tab Control's display space.
Notifications for Tab Control can be found here:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb760548(v=vs.85).aspx

Related

Can not assign different Icons in Win32 ImageList only one Icon is being shown

I am working on a project that uses Win32 listview to arrange and visualize some data and files. And I would like to add different kind of icons to the list items along with their names. I have seen screenshots of many applications that has different kind of icons assigned to it and mine one , with no icons , looks very much odd and old styled.
I tried the example code from Microsoft's official page which was supposed to add different icons into imagelists.I then tried to assign the imagelist to my listbox but unfortunately , only one of the icons is being assigned to all the other items and other icons are being completely ignored.
As you can see in the screenshot, the parent window has the IDI_NETWORK icon which means our resource files has successfully been configured by my application. But the problem is...
Even after adding this code from Microsoft's official site in my application to insert icons, the function InitListViewImageLists assigns the same icon to all the items in the listview.
BOOL InitListViewImageLists(HWND hWndListView)
{
int index=0;
HICON hIconItem; // Icon for list-view items.
HIMAGELIST hLarge; // Image list for icon view.
HIMAGELIST hSmall; // Image list for other views.
// Create the full-sized icon image lists.
hLarge = ImageList_Create(32,
32,
ILC_COLOR32, 1, 1);
hSmall = ImageList_Create(32,
32,
ILC_COLOR32, 1, 1);
// Add an icon to each image list.
/*hiconItem = LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_ITEM));
ImageList_AddIcon(hLarge, hiconItem);
ImageList_AddIcon(hSmall, hiconItem);
DestroyIcon(hiconItem);*/
// When you are dealing with multiple icons, you can use the previous four lines of
// code inside a loop. The following code shows such a loop. The
// icons are defined in the application's header file as resources, which
// are numbered consecutively starting with IDS_FIRSTICON. The number of
// icons is defined in the header file as C_ICONS.
for(index = 0; index < 5; index++)
{
hIconItem = LoadIcon (GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MALE+index));
ImageList_AddIcon(hSmall, hIconItem);
ImageList_AddIcon(hLarge, hIconItem);
DestroyIcon(hIconItem);
}
// Assign the image lists to the list-view control.
ListView_SetImageList(hWndListView, hLarge, LVSIL_NORMAL);
ListView_SetImageList(hWndListView, hSmall, LVSIL_SMALL);
return TRUE;
}
you can see in the screenshot that the listview items only have IDI_FEMALE icon assigned ignoring rest of the icons.
for(index = 0; index < 5; index++)
{
hIconItem = LoadIcon (GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MALE+index));
ImageList_AddIcon(hSmall, hIconItem);
ImageList_AddIcon(hLarge, hIconItem);
DestroyIcon(hIconItem);
}
This code in function InitListViewImageLists was supposed to add add all the icons but unfortunately this is only assgning only one icon that is IDI_FEMALE
I am leaving my codes below
Contents of resource.rc
#include "resource.h"
IDI_MALE ICON "male.ico"
IDI_FEMALE ICON "female.ico"
IDI_NETWORK ICON "net.ico"
IDI_WIFI ICON "wifi.ico"
IDI_TRANS ICON "trans.ico"
Contents of resource.h
#define IDI_MALE 1
#define IDI_FEMALE 2
#define IDI_TRANS 3
#define IDI_WIFI 4
#define IDI_NETWORK 5
Compiled into resource.rs and is being used in my application
My Application code
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <windows.h>
#include <commctrl.h>
#include "resource.h"
HWND Wmain , ListView;
char col[][255] = {"Filename","Size"};
// InitListViewImageLists: Creates image lists for a list-view control.
// This function only creates image lists. It does not insert the items into
// the control, which is necessary for the control to be visible.
//
// Returns TRUE if successful, or FALSE otherwise.
//
// hWndListView: Handle to the list-view control.
// global variable g_hInst: The handle to the module of either a
// dynamic-link library (DLL) or executable (.exe) that contains
// the image to be loaded. If loading a standard or system
// icon, set g_hInst to NULL.
//
BOOL InitListViewImageLists(HWND hWndListView)
{
int index=0;
HICON hIconItem; // Icon for list-view items.
HIMAGELIST hLarge; // Image list for icon view.
HIMAGELIST hSmall; // Image list for other views.
// Create the full-sized icon image lists.
hLarge = ImageList_Create(32,
32,
ILC_COLOR32, 1, 1);
hSmall = ImageList_Create(32,
32,
ILC_COLOR32, 1, 1);
// Add an icon to each image list.
/*hiconItem = LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_ITEM));
ImageList_AddIcon(hLarge, hiconItem);
ImageList_AddIcon(hSmall, hiconItem);
DestroyIcon(hiconItem);*/
// When you are dealing with multiple icons, you can use the previous four lines of
// code inside a loop. The following code shows such a loop. The
// icons are defined in the application's header file as resources, which
// are numbered consecutively starting with IDS_FIRSTICON. The number of
// icons is defined in the header file as C_ICONS.
for(index = 0; index < 5; index++)
{
hIconItem = LoadIcon (GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MALE+index));
ImageList_AddIcon(hSmall, hIconItem);
ImageList_AddIcon(hLarge, hIconItem);
DestroyIcon(hIconItem);
}
// Assign the image lists to the list-view control.
ListView_SetImageList(hWndListView, hLarge, LVSIL_NORMAL);
ListView_SetImageList(hWndListView, hSmall, LVSIL_SMALL);
return TRUE;
}
void LV_addColumns(HWND hwnd , char name[] , char size[]){
LVCOLUMN lvc;
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
int counter=0;
lvc.iSubItem = counter++;
lvc.pszText = (LPSTR)name;
lvc.cx = 200;
lvc.fmt = LVCFMT_LEFT;
ListView_InsertColumn(hwnd, counter, &lvc);
lvc.iSubItem = counter;
lvc.pszText = (LPSTR)size;
lvc.cx = 200;
lvc.fmt = LVCFMT_LEFT;
ListView_InsertColumn(hwnd, counter, &lvc);
}
void AddLVItem(HWND hwnd , int index,char Name[] , char Size[]){
LVITEM lvi;
int x=0;
lvi.mask= LVIF_TEXT | LVIF_IMAGE;
lvi.iItem=index; //cRecord is raised 1 before every function call
lvi.iImage = 1;
lvi.iSubItem=0;
lvi.pszText=(LPSTR)"1";
SendMessage(hwnd, LVM_INSERTITEM, 0, (LPARAM) &lvi);
//Add Subitems from a structur
lvi.iSubItem=0;
lvi.pszText=(LPSTR)Name;
lvi.mask = LVIF_TEXT | LVIF_STATE ;
SendMessage(hwnd, LVM_SETITEM, 0,(LPARAM) &lvi);
lvi.iSubItem=1;
lvi.pszText=(LPSTR)Size;
lvi.mask = LVIF_TEXT | LVIF_STATE ;
SendMessage(hwnd, LVM_SETITEM, 0,(LPARAM) &lvi);
}
LRESULT CALLBACK WndProc(HWND hwnd , UINT Msg , WPARAM wParam , LPARAM lParam){
switch(Msg){
case WM_DESTROY: {
PostQuitMessage(0);
break;
}
case WM_CREATE: {
ListView= CreateWindowEx(WS_EX_CLIENTEDGE, WC_LISTVIEW, NULL, LVS_REPORT | WS_VISIBLE|WS_CHILD | LVS_ICON , 0, 0, 400, 500, hwnd, NULL, NULL, NULL);
LV_addColumns(ListView,(char*)"FileName",(char*)"Size");
AddLVItem(ListView,0,(char*)"AudioFile",(char*)"3GB");
AddLVItem(ListView,1,(char*)"ImageFile",(char*)"10MB");
AddLVItem(ListView,2,(char*)"VideoFile",(char*)"100MB");
AddLVItem(ListView,3,(char*)"TextFile",(char*)"300B");
InitListViewImageLists(ListView);
break;
}
case WM_COMMAND: {
break;
}
default:
return DefWindowProc(hwnd,Msg,wParam,lParam);
}
return 0;
}
/* Below are the codes for parent Window (WinMain) that have not been provided here to keep the code short and more readable */
After more googling ...
I further tried codes from CodeProject and StackOverflow but I dont seem to have luck.
Now how can I achieve something like this ? This is what I want.
I have been trying to figure it out since the day before yesterday but I think I am in need of some advices from the experienced community. The compilers I am using are gcc and g++ (MinGW on Windows 10).Please provide a working source code along with a good explanation . A working source code will make it easier for me to understand my errors.
Thank You So Much!

When using DialogBoxIndirect, how do I get text the user entered when the dialog closes?

I'm using DialogBoxIndirect() to create a modal dialog in memory. One of the controls that I'm adding to the dialog has the EDIT class, so users can type in information in the dialog. When the dialog is closed, how do I figure out what the user typed into the EDIT field? I don't have an HWND for the EDIT field or the dialog itself, all I have is the id. The only way I know of is GetWindowText(), but that requires an HWND.
Code snippet:
//-----------------------
// Define Edit Input
//-----------------------
lpw = lpwAlign(lpw); // Align DLGITEMTEMPLATE on DWORD boundary
lpdit = (LPDLGITEMTEMPLATE)lpw;
lpdit->x = 10; lpdit->y = 10;
lpdit->cx = 150; lpdit->cy = 25;
lpdit->id = ID_TEXT2; // Text input
lpdit->dwExtendedStyle = WS_EX_CLIENTEDGE;
lpdit->style = WS_CHILD | WS_VISIBLE;
lpw = (LPWORD)(lpdit + 1);
*lpw++ = 0xFFFF;
*lpw++ = 0x0081; // Edit class
lpwsz = (LPWSTR)lpw;
nchar = MultiByteToWideChar(CP_ACP, 0, lpszMessage, -1, lpwsz, 50);
lpw += nchar;
*lpw++ = 0; // No creation data
//-----------------------
// Define an OK button.
//-----------------------
lpw = lpwAlign(lpw); // Align DLGITEMTEMPLATE on DWORD boundary
lpdit = (LPDLGITEMTEMPLATE)lpw;
lpdit->x = 10; lpdit->y = 40;
lpdit->cx = 35; lpdit->cy = 13;
lpdit->id = IDOK; // OK button identifier
lpdit->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;
lpw = (LPWORD)(lpdit + 1);
*lpw++ = 0xFFFF;
*lpw++ = 0x0080; // Button class
lpwsz = (LPWSTR)lpw;
nchar = MultiByteToWideChar(CP_ACP, 0, "OK", -1, lpwsz, 50);
lpw += nchar;
*lpw++ = 0; // No creation data
GlobalUnlock(hgbl);
ret = DialogBoxIndirect(hinst, (LPDLGTEMPLATE)hgbl, GetFocus(), (DLGPROC)GenericDlgProc);
// How do I get the text here, that the user entered into control id ID_TEXT2?
You can use GetDlgItemText() to get text from an edit control using its ID; basically what this does is a GetDlgItem() followed by a GetWindowText() all in one useful function call.
However by the time your DialogBoxIndirect() call has returned it's too late to do this - the dialog is gone, and the controls along with it. You can't read a control's value once it's been destroyed.
The usual way to deal with this is to handle WM_DESTROY in your DialogProc, and save the control values there (alternatively, if you have an OK and a Cancel button, you might do this in the WM_COMMAND handler for IDOK instead).

MFC Icons are displayed as black squares on remote desktops

I'm encountering the following problem. I wolud very much appreciate your help.
Description of the problem
MFC Desktop Application
VisualStudio 2010
Icons are supposed to be displayed in a CListCtrl as a CImageList.
It usually works fine except when using RemoteDesktop with the OS Windows 2008 / 2003.
In these particular cases the icons are just displayed as a black square.
Connecting with VMware vSphere (alternative to RemoteDesktop) -> Icons are shown appropriately
Remotdesktop on Windows XP / 7 / 8 -> Icons are shown appropriately
Code:
OnInitDialog()
{
// Setting the symbol for this dialog-field. This is done automatically
// if the mainwindow of the application is no dialog-field.
SetIcon(m_hIcon, TRUE); // using big symbol
SetIcon(m_hIcon, FALSE); // using small symbol
// TODO: appending additional initialization
InitList(); //
m_list.SetImageList(imageList, LVSIL_NORMAL);
//captions
CString buf = _T("testitem");
m_list.InsertItem(0, buf, 0);
m_list.SetItemData(0, (DWORD) 0);
m_list.SetItemText(0, 0, _T("0"));
m_list.SetItemState(0, 2, LVIS_SELECTED);
m_list.EnsureVisible(0, FALSE);
}
void CDispomarkierungTestDlg::InitList()
{
imageList = new CImageList();
int err = imageList->Create(16, 16, ILC_COLOR32 | ILC_MASK, 1, 1); //ILC_COLOR16 , ILC_COLOR8 , ... getested
int id = 40;
int requiredLength = 3154;
LPCSTR picInCharsFromDB = GetBitmapAsText();
int width = 24;
int heigth = 24;
int pixel = 32;
int planes = 1;
BYTE *picInBytes = new BYTE[requiredLength];
int lengthVariable = requiredLength;
int* lengthPointer;
lengthPointer = &lengthVariable;
Base64Decode(picInCharsFromDB, requiredLength, picInBytes, lengthPointer);
HANDLE hBitMap = CreateBitmap(width, heigth, planes, pixel, picInBytes);
BITMAP bitmap;
GetObject(hBitMap,sizeof(BITMAP),&bitmap);
CImage image;
image.Attach((HBITMAP)hBitMap);
CBitmap icon;
icon.Attach((HBITMAP)hBitMap);
CBitmap* bitmappointer;
bitmappointer = &icon;
BITMAP bmp;
icon.GetBitmap(&bmp);
CClientDC dcClient(this);
CDC memDC;
memDC.CreateCompatibleDC(&dcClient);
HBITMAP hbmMask = ::CreateCompatibleBitmap(memDC.GetSafeHdc(), width, heigth);
ICONINFO ii = {0};
ii.fIcon = TRUE;
ii.hbmColor = icon;
ii.hbmMask = hbmMask;
HICON hIcon = ::CreateIconIndirect(&ii);
::DeleteObject(hbmMask);
err = imageList->Add(hIcon);
}
In the real application, the source is a database which saves the Bitmap as a string. That’s the reason for the complicated code during the loading. Loading the images as a resource is possible, but in this case no option.
Drivers of server and client are updated to latest version.
I added the project here https://www.hidrive.strato.com/lnk/gRuMg38R. Thanks for helping out

how to attach scrollbar to a dialog

I have to find the correct way to attach a scrollbar to a set of images that are created dynamically by the application.
In my code I create the scrollbar but it is not working properly. The main window does not scroll to view all the images.
int currentLength = iImage * (WIDTH + SPACER);
picName.Format(_T("Image %d"),iImage);
CPoint topLeft(currentLength,0);
CPoint bottomRigth(currentLength + (WIDTH), HEIGHT);
CRect miniCRect(topLeft, bottomRigth);
Miniature[iImage] = new CStatic();
Miniature[iImage]->Create(picName, WS_CHILD|WS_VISIBLE|SS_BITMAP, miniCRect, this);
if((bottomRigth.x > 500) && (currentLength <= 500))
{
//creo la scrool bar
CPoint ptnrigin(0,210);
CPoint endptn(bottomRigth.x,230);
CRect workingArea(ptnrigin,endptn);
cs.Create(WS_VISIBLE,workingArea,this,0);
cs.EnableScrollBar(ESB_ENABLE_BOTH);
SCROLLINFO info;
info.cbSize = sizeof(SCROLLINFO);
info.fMask = SIF_ALL;
info.nMin = 1;
info.nMax = 10;
info.nPage = 2;
info.nPos = 5;
info.nTrackPos = 5;
cs.SetScrollInfo(&info);
}
HDC hDCScreen_mini = ::CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
HDC hDCMem_mini = ::CreateCompatibleDC(hDCScreen_mini);
// create a compatible bitmap and select it in the memory DC
HBITMAP hBitmap_mini = ::CreateCompatibleBitmap(hDCScreen_mini, miniCRect.Width(), miniCRect.Height());
HBITMAP hBmpOld_mini = (HBITMAP)::SelectObject(hDCMem_mini, hBitmap_mini);
BitBlt(hDCMem_mini, 0, 0, desktopRect.Width(), desktopRect.Height(), hDCScreen_mini, desktopRect.left, desktopRect.top, dwRop);
Miniature[iImage]->SetBitmap(hBitmap_mini);
Invalidate();
// restore the memory DC and perform cleanup
SelectObject(hDCMem_mini, hBmpOld_mini);
DeleteDC(hDCMem_mini);
DeleteDC(hDCScreen_mini);
//end capture
Can someone help me?
A scrollbar does not scroll your window or its contents. It only provides input from the user to code that you must write to reposition the images. Such code typically uses ScrollWindow to move the visible portion, followed by adding the newly-visible portion in WM_PAINT.
A different approach (that does do the scrolling for you) would be to put the images in an owner-drawn list box.

am trying to create class to encapsulate toolbar but the background turns black. c++ win32api

I created a simple class to hide the details of creating a toolbar in win32 API but I don't like the toolbars it is producing. (See image for clarification. I don't have reputation points so I have just posted a link)
http://i35.tinypic.com/1zmfeip.jpg
I have no idea now the black background is coming into my application.
Here is the class declaration in file CToolBar.h
#ifndef _CTOOLBAR_H
#define _CTOOLBAR_H
#include<windows.h>
#include<commctrl.h>
class CToolBar
{
public:
CToolBar();//constructor
~CToolBar();//destructor
void AddButton(int iconID, int command);//add Both a button, its icon and its command ID
void Show();//display the toolbar
void Initialise(HINSTANCE hInst, HWND hParent);
protected:
HINSTANCE m_hInst;
HWND m_hParent;
HWND m_hToolBar;
HIMAGELIST m_hImageList;
TBBUTTON m_Tbb[4]; //toolbar buttons
int m_numberButtons;
};
#endif
here is the implementation in file CToolBar.cpp
//CToolBar.cpp
#include "CToolBar.h"
#include<windows.h>
#include<commctrl.h>
CToolBar::CToolBar()//the constructor
{
m_hImageList=ImageList_Create(32, 32, ILC_COLOR32, 0, 15);//returns NULL if the function fails
//finish other initialisations
InitCommonControls();//initialise commctrl.dll whatever.. or else your toolbar wont appear
}
void CToolBar::Initialise(HINSTANCE hInst, HWND hParent)
{
m_hInst=hInst;
m_hParent=hParent;
m_hToolBar=CreateWindowEx(
WS_EX_PALETTEWINDOW ,
TOOLBARCLASSNAME,
"",
WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS |WS_VISIBLE|TBSTYLE_BUTTON | TBSTYLE_TOOLTIPS | CCS_ADJUSTABLE | CCS_TOP ,
0, 0,
0, 0,
m_hParent,
NULL,
m_hInst,
0);
}
CToolBar::~CToolBar()//destructor
{
ImageList_Destroy(m_hImageList);
}
void CToolBar::AddButton(int iconID, int command)
{
HICON hIcon = LoadIcon(m_hInst, MAKEINTRESOURCE(iconID));
ImageList_AddIcon(m_hImageList, hIcon);
DeleteObject(hIcon);
if(iconID!= -1)//-1 means the separator. The rest are mere buttons
{
m_Tbb[m_numberButtons].iBitmap =m_numberButtons;
m_Tbb[m_numberButtons].idCommand = command;
m_Tbb[m_numberButtons].fsState = TBSTATE_ENABLED;
m_Tbb[m_numberButtons].fsStyle = TBSTYLE_BUTTON;
m_Tbb[m_numberButtons].dwData = 0;
m_Tbb[m_numberButtons].iString = 0;
}
else//ie if (iconID== -1) ; then display the separator. the command value is ignored
{
m_Tbb[m_numberButtons].iBitmap =-1;
m_Tbb[m_numberButtons].idCommand = 0;
m_Tbb[m_numberButtons].fsState = TBSTATE_ENABLED;
m_Tbb[m_numberButtons].fsStyle = TBSTYLE_SEP;
m_Tbb[m_numberButtons].dwData = 0;
m_Tbb[m_numberButtons].iString = 0;
}
m_numberButtons++;
}
void CToolBar::Show()
{
SendMessage(m_hToolBar, TB_SETIMAGELIST , (WPARAM)0, (LPARAM)m_hImageList);
SendMessage(m_hToolBar, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);//message for backward
//compatibility
SendMessage(m_hToolBar, TB_ADDBUTTONS, m_numberButtons, (LPARAM)m_Tbb);
SendMessage(m_hToolBar,WM_SIZE,0,0);
ShowWindow(m_hToolBar, SW_SHOW);
}
How i used the class
in main.cpp, i created a global instance of the class.
CToolBar myToolBar;
in the callback procedure, under WM_CREATE, I used some member functions.
case WM_CREATE:
myToolBar.Initialise(g_hInst,hwnd);
myToolBar.AddButton(IDI_OPEN, ID_OPEN);
myToolBar.AddButton(IDI_MAIN,ID_OPEN);//Separator button
myToolBar.AddButton(IDI_CLOSE, ID_CLOSE);
myToolBar.AddButton(IDI_CLOSEALL, ID_CLOSE);
myToolBar.Show();
break;
That's about it.
Try modifying the flags parameter of ImageList_Create to include ILC_MASK as well
Looks like you are using bitmap with transparency channel. GDI does not support alpha channel. It uses special color which will be transparent. If you want to support 32-bit bitmaps you could use GDI+ for drawing such bitmaps. Another option is to use CAplhaToolbar which already supports bitmaps with alpha transparency.