2

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.

https://i.stack.imgur.com/SxxWc.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);
Ry-
  • 218,210
  • 55
  • 464
  • 476
krzynek91
  • 140
  • 10

1 Answers1

1

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: https://i.stack.imgur.com/0dxEv.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

krzynek91
  • 140
  • 10