Win32 - How to set up icon(s) properly?

This is my Window -class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#ifndef __LORE_WINDOW_HPP__
#define __LORE_WINDOW_HPP__
/* ------------------------- */
/* Programming language: C++ */
/* ------------------------- */
#if __cplusplus || defined __cplusplus
	#define __LORE_CPP__
#else
	#define __LORE_C__
#endif
/* --------------------------- */
/* Operating system: Mac OS X: */
/* --------------------------- */
#ifdef __APPLE__
	#define __LORE_MACOSX
/* -------------------------- */
/* Operating system: Windows: */
/* -------------------------- */
#elif (defined WIN32) || (defined _WIN32) || (defined __WIN32__)
	#define __LORE_WINDOWS
	#include <windows.h>
#endif
#ifdef __LORE_WINDOWS
	#define LORE_RES_ICO_MAIN		1001
	#define main() WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
#else
	#define main() main(int argc, char* argv[])
#endif
#include <string>
namespace LORE{
	typedef int LOREmode;
	struct Position{
		Position(void);
		bool mbInit;
		int miX, miY;
	};
	class Window{
		public:
			Window(void);
			void ConfirmSettings(void);
			Window& SetIcon(const std::string&);
			Window& SetMode(LOREmode);
			Window& SetPosition(int,int);
			Window& SetSize(int,int);
			Window& SetTitle(const std::string&);
			void Update(void);
			enum Mode{MODE_CENTERED, MODE_FULLSCREEN, MODE_WINDOWED};
		private:
			static void SetSizeMax(Window&);
			bool mbCentered, mbFullscreen, mbWindowed;
			Position moPosition, moSize;
			std::string moIcon;
			#ifndef __LORE_WINDOWS
			std::string moTitle;
			#else
			static LRESULT CALLBACK HandleCallback(HWND,UINT,WPARAM,LPARAM);
			void Init(void);
			HINSTANCE moHInstance;
			HWND moHWindow;
			LPCTSTR moTitle;
			MSG muMSG;
			WNDCLASSEX moClassExWindow;
			#endif
	};
}
#endif // __LORE_WINDOW_HPP__ 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include "window.hpp"

LORE::Position::Position(void) : mbInit(false), miX(0), miY(0){

}
LORE::Window::Window(void) : mbCentered(false), mbFullscreen(false), mbWindowed(true), moIcon("nil"), moTitle("nil"){
	this->Init();
}
void LORE::Window::ConfirmSettings(void){
	if(moPosition.mbInit && moSize.mbInit){
		#ifdef __LORE_WINDOWS
		RegisterClassEx(&moClassExWindow);
		moHWindow = CreateWindow("LORE",moTitle,
			WS_OVERLAPPEDWINDOW,
			moPosition.miX, moPosition.miY,
			moSize.miX, moSize.miY,
			0,0,moHInstance,0);
		#endif
	}
}
#ifdef __LORE_WINDOWS
LRESULT CALLBACK LORE::Window::HandleCallback(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){
    switch(msg){
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		default:
			return DefWindowProc(hWnd,msg,wParam,lParam);
			break;
    }
    return 0;
}
void LORE::Window::Init(void){
	moClassExWindow.cbSize        = sizeof(WNDCLASSEX);
	moClassExWindow.style         = CS_HREDRAW | CS_VREDRAW;
	moClassExWindow.lpfnWndProc   = Window::HandleCallback;
	moClassExWindow.cbClsExtra    = 0;
	moClassExWindow.cbWndExtra    = 0;
	moClassExWindow.hIcon         = LoadIcon(GetModuleHandle(0), MAKEINTRESOURCE(LORE_RES_ICO_MAIN));
	moClassExWindow.hCursor       = LoadCursor(0,IDC_ARROW);
	moClassExWindow.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
	moClassExWindow.lpszMenuName  = 0;
	moClassExWindow.lpszClassName = "LORE";
	moClassExWindow.hInstance     = moHInstance;
	moClassExWindow.hIconSm       = (HICON)LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(LORE_RES_ICO_MAIN), IMAGE_ICON, 32,32, 0);
}
#endif
LORE::Window& LORE::Window::SetMode(LORE::LOREmode mode){
	Window w;
	switch(mode){
		case MODE_CENTERED:
			if(!mbCentered && mbWindowed && moSize.mbInit){
				mbCentered = true;
				mbFullscreen = false;
				SetSizeMax(w);
				moPosition.miX = (w.moSize.miX - moSize.miX) * 0.5;
				moPosition.miY = (w.moSize.miY - moSize.miY) * 0.5;
			}
			break;
		case MODE_FULLSCREEN:
			if(!mbFullscreen){
				mbCentered = false;
				mbFullscreen = true;
				mbWindowed = false;
				SetSizeMax(*this);
			}
			break;
		case MODE_WINDOWED:
			if(!mbWindowed){
				mbFullscreen = false;
				mbWindowed = true;
			}
			break;
        default:
            break;
	}
	return *this;
}
LORE::Window& LORE::Window::SetPosition(int x, int y){
	moPosition.mbInit = true;
	moPosition.miX = x;
	moPosition.miY = y;
	return *this;
}
LORE::Window& LORE::Window::SetSize(int x, int y){
	moSize.mbInit = true;
	moSize.miX = x;
	moSize.miY = y;
	return *this;
}
void LORE::Window::SetSizeMax(LORE::Window& window){
	#if (defined __LORE_WINDOWS)
	window.moSize.miX = static_cast<int>(GetSystemMetrics(SM_CXSCREEN));
	window.moSize.miY = static_cast<int>(GetSystemMetrics(SM_CYSCREEN));
	#endif
}
LORE::Window& LORE::Window::SetTitle(const std::string& title){
	#if (defined __LORE_WINDOWS)
	moTitle = static_cast<LPCTSTR>(title.c_str());
	#else
	moTitle = title;
	#endif
	return *this;
}
void LORE::Window::Update(void){
	ShowWindow(moHWindow,SW_SHOWNORMAL);
	UpdateWindow(moHWindow);
	while(GetMessage(&muMSG,0,0,0)){
		TranslateMessage(&muMSG);
		DispatchMessage(&muMSG);
	}
}


And here's my main -function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "window.hpp"

int main(){
    using LORE::Window;

	Window window;
	window.SetPosition(0,0).SetSize(640,480);
	window.SetMode(LORE::Window::MODE_CENTERED).SetMode(LORE::Window::MODE_WINDOWED);
	window.SetTitle("Tim Firch - The Plans Of Dr. Deta");

	window.ConfirmSettings();
	window.Update();
	return 0;
}


And resource file:

LORE_RES_ICO_MAIN ICON "LORE.ico"

Pretty simple API. Works well, except I can't set up this LORE.ico -file to be visible in the place of the control icon (icon in Windows visible in the top left corner of the window). It works elsewhere, though. What do I wrong? Feel free to comment about my overall code.
Last edited on
Well, the only thing that looks a bit suspicious -- on first glance -- is telling Windows that 32 x 32 is the size you want for the small icon. For my PC, the small icon size is 16 x 16.

But rather that change 32 to 16, I'd change you code to use GetSystemMetrics(), with SM_CXSMICON and SM_CYSMICON, to get the size from the system.

By the way, this does assume that the icon file contains both the required images sizes.

Andy

P.S. For consistency, if nothing else, I'd used LoadImage for the normal size icon, too.
Last edited on
Thanks for the help, andywestken. I'll use your fixures in my code.

However, the control icon still won't change, it's the default Vista application icon. I'm running out of imagination, what should I do?
Well, that's all my code is doing and my icon is displaying fine (on Vista).

So the only other things I can ask are the obvious, starting with: Have you checked the hSmIcon and hIcon member are being init' correctly?

And why are you using GetModuleHandle(0) with LoadImage rather than moHInstance?
Last edited on
Topic archived. No new replies allowed.