pixel pixel - 3 months ago 12
C++ Question

How do I include a custom icon in the client area of a dialog box?

This question is different than Using an icon on a dialog box window C++ Win32 API, I'm trying to include a custom icon into the client area of a dialog box. When I run the code, I get a default Windows icon instead of the custom one I want. If I change the value of

IDI_ICON1
to any number between 80 and 120, I'll get different Windows icons; I've tried higher numbers but then nothing will appear. I saw someone at cplusplus.com run into the same error and I did the same thing, but it didn't make a difference.

Microsoft's reference about icons.

When I run the code:

Unmatched Dialog Box

Visual Studio says it'll look like this:
Visual Studio's Dialog Editor

Source.cpp

#pragma comment(lib,"ole32.lib")
#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

_TCHAR szClassName[] = "StackOverflow";
HWND hwnd;

LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK DialogProc(HWND handle, UINT message, WPARAM wparam, LPARAM lparam);

int _stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR CmdLine, int nShowCmd)
{
MSG messages;
WNDCLASSEX wincl;
HWND about;

wincl.cbSize = sizeof(WNDCLASSEX);
wincl.style = CS_DBLCLKS;
wincl.lpfnWndProc = WindowProcedure;
wincl.cbClsExtra = 0;
wincl.cbWndExtra = 0;
wincl.hInstance = hInstance;
wincl.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON1));
wincl.hCursor = LoadCursor(NULL, IDC_ARROW);
wincl.hbrBackground = (HBRUSH)COLOR_WINDOW;//COLOR_BACKGROUND;
wincl.lpszMenuName = NULL;
wincl.lpszClassName = szClassName;
wincl.hIconSm = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON1));

if(!RegisterClassEx(&wincl))
return 0;

hwnd = CreateWindowEx(WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_WINDOWEDGE, //dwExStyle
szClassName, //ClassName
"StackOverflow", //WindowName
WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION | WS_EX_PALETTEWINDOW, //Window Style
CW_USEDEFAULT, //Horizontal Pos
CW_USEDEFAULT, //Verticals Pos
100, //Width
100, //Height
HWND_DESKTOP, //Parent
NULL, //Menu
hInstance, //Module Assoc
NULL); //CreateStruct

about = CreateDialog( NULL,
MAKEINTRESOURCE(IDD_DIALOG),
hwnd,
DialogProc);

while (GetMessage(&messages, NULL, 0, 0))
{
TranslateMessage(&messages);
DispatchMessage(&messages);
}

return messages.wParam;
}

INT_PTR CALLBACK DialogProc(HWND handle, UINT message, WPARAM wparam, LPARAM lparam)
{
switch (message)
{
case WM_INITDIALOG:
//This changes the Icon in the TitleBar
SendMessage(handle, WM_SETICON, ICON_SMALL,
(LPARAM)LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON1)));
return TRUE;
case WM_CLOSE:
DestroyWindow(handle);
return TRUE;
case WM_DESTROY:
PostQuitMessage(0);
return TRUE;
case WM_COMMAND:
switch (LOWORD(wparam))
{
case IDCOK:
//TODO
case IDCANCEL:
//EndDialog(handle,wparam);
DestroyWindow(handle);
return TRUE;
default:
return FALSE;
}
default:
return FALSE;
}
return FALSE;
}

LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
return DefWindowProc(hwnd, message, wParam, lParam);
}


StackOverflow.rc

#include "resource.h"

IDD_DIALOG DIALOGEX 0, 0, 245, 57
STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "About Dialog"
FONT 10, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,166,7,50,14
PUSHBUTTON "Cancel",2,166,30,50,14
LTEXT "The Icon here needs to match the one in the Titlebar",IDC_STATIC,50,15,107,28
ICON IDI_ICON1,103,19,16,20,20, SS_ICON
END

// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_ICON1 ICON "C:\\Users\\pixel\\Desktop\\MEIN.ico"


resource.h

//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by StackOverflow.rc
//
#define IDD_DIALOG 101
#define IDI_ICON1 103
#define IDCOK 105
#define IDCANCEL 106

Answer

The problem is your call to CreateDialog is not providing a module handle, which is stopping the icon control from being able to locate the specified icon in your program's resources.

Obviously in this instance it defaults to looking in the system image list, which is why you see system icons appear (and change when you change the ID).

Change your call to:

about = CreateDialog(hInstance,
                        MAKEINTRESOURCE(IDD_DIALOG),
                        hwnd,
                        DialogProc);
Comments