What's wrong with multiple messages ?

Jan 17, 2012 at 3:30pm
This is somehow funny for me, :

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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include <Windows.h>
#include <CommCtrl.h>
#include "resource.h"

LRESULT CALLBACK WinProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
LRESULT CALLBACK DlgProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);

INT WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hprevInstance,LPSTR lpCmdLine,int nShowCmd)
{
	MSG Msg;
	HWND hWnd;
	WNDCLASSEX WndClsEx;
	HINSTANCE hInst = hInstance;

	const int NUMBUTTONS = 4;

	LPCWSTR ClsName = TEXT("BasicApp");
	LPCWSTR WndName = TEXT("Kudy Window Programming with C++");

	WndClsEx.cbSize = sizeof(WNDCLASSEX);
	WndClsEx.style = CS_HREDRAW || CS_VREDRAW;
	WndClsEx.cbClsExtra = 0;
	WndClsEx.cbWndExtra = 0;
	WndClsEx.lpszClassName = ClsName;
	WndClsEx.lpszMenuName = MAKEINTRESOURCE(IDR_MAINFRAME);
	WndClsEx.lpfnWndProc = WinProc;
	WndClsEx.hCursor = LoadCursor(hInstance,MAKEINTRESOURCE(IDC_CURSOR1));
	WndClsEx.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1));
	WndClsEx.hIconSm = LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1));
	WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	WndClsEx.hInstance = hInstance;

	RegisterClassEx(&WndClsEx);

	hWnd = CreateWindowEx(0,ClsName,WndName,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);

	if(!hWnd)
		return 0;

	INITCOMMONCONTROLSEX InitCtrlEx;

	InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
	InitCtrlEx.dwICC = ICC_BAR_CLASSES;

	TBBUTTON tbrButtons[4];

	tbrButtons[0].iBitmap = 0;
	tbrButtons[0].idCommand = IDM_FILE_NEW;
	tbrButtons[0].fsState = TBSTATE_ENABLED;
	tbrButtons[0].fsStyle = TBSTYLE_BUTTON;
	tbrButtons[0].dwData = 0L;
	tbrButtons[0].iString = 0;

	tbrButtons[1].iBitmap = 0;
	tbrButtons[1].idCommand = 0;
	tbrButtons[1].fsState = TBSTATE_ENABLED;
	tbrButtons[1].fsStyle = TBSTYLE_SEP;
	tbrButtons[1].dwData = 0L;
	tbrButtons[1].iString = 0;

	tbrButtons[2].iBitmap = 1;
	tbrButtons[2].idCommand = IDM_FILE_DICT;
	tbrButtons[2].fsState = TBSTATE_ENABLED;
	tbrButtons[2].fsStyle = TBSTYLE_BUTTON;
	tbrButtons[2].dwData = 0L;
	tbrButtons[2].iString = 0;

	tbrButtons[3].iBitmap = 2;
	tbrButtons[3].idCommand = IDM_FILE_CALC;
	tbrButtons[3].fsState = TBSTATE_ENABLED;
	tbrButtons[3].fsStyle = TBSTYLE_BUTTON;
	tbrButtons[3].dwData = 0L;
	tbrButtons[3].iString = 0;

	HWND hWndToolbar = CreateToolbarEx(hWnd,WS_VISIBLE | WS_BORDER | WS_CHILD,IDB_STANDARD,NUMBUTTONS,hInst,IDB_STANDARD,tbrButtons,NUMBUTTONS,16,16,16,16,sizeof(TBBUTTON));

	ShowWindow(hWnd,SW_SHOWNORMAL);
	UpdateWindow(hWnd);

	//MessageBox(NULL,TEXT("Test succesful"),TEXT("Test"),MB_OKCANCEL | MB_ICONSTOP | MB_DEFBUTTON1);

	//DialogBox(hInstance, MAKEINTRESOURCE(IDD_DLGFIRST),hWnd, reinterpret_cast<DLGPROC>(DlgProc));

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

	return Msg.wParam;
}

LRESULT CALLBACK WinProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
	switch(uMsg)
	{
	/*case WM_CREATE:
		MessageBoxW(NULL,L"WM_CREATE",L"!!!",MB_OK);
		break;
	case WM_ACTIVATE:
		MessageBoxW(NULL,L"WM_ACTIVATE",L"!!!",MB_OK);
		break;
	case WM_SHOWWINDOW:
		MessageBoxW(NULL,L"WM_SHOWWINDOW",L"!!!",MB_OK);
		break;
	case WM_PAINT:
		MessageBoxW(NULL,L"WM_PAINT",L"!!!",MB_OK);
		break;
	case WM_SIZE:
		MessageBoxW(NULL,L"WM_SIZE",L"!!!",MB_OK);
		break;
	case WM_SIZING:
		MessageBoxW(NULL,L"WM_SIZING",L"!!!",MB_OK);
		break;
	case WM_MOVE:
		MessageBoxW(NULL,L"WM_MOVE",L"!!!",MB_OK);
		break;*/
	case WM_DESTROY:
		PostQuitMessage(WM_QUIT);
		break;
	default:
		return DefWindowProc(hWnd,uMsg,wParam,lParam);
	}

	return 0;
}

LRESULT CALLBACK DlgProc(HWND hWndDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
{
	switch(Msg)
	{
	case WM_INITDIALOG:
		return TRUE;
	case WM_COMMAND:
		switch(wParam)
		{
		case IDOK:
			EndDialog(hWndDlg, 0);
			return TRUE;
		}
		break;
	}

	return FALSE;
}


As you can see there's a large commented blocks in the winproc() that would be disaster if being uncommented.

The window can load but there's no toolbar,the clock is constantly running and when I close the program it keeps saying WM_ACTIVATE message box. xD

May I know something wrong with this,Thanks in advance.
Last edited on Jan 17, 2012 at 3:31pm
Jan 17, 2012 at 6:37pm
http://msdn.microsoft.com/en-us/library/windows/desktop/ms646274(v=vs.85).aspx
msdn wrote:
WM_ACTIVATE
Sent to both the window being activated and the window being deactivated


When your window is closed it sends the WM_ACTIVATE word. Then when the message box pops up, this sends another WM_ACTIVATE word activating another message box. When they are closed they activate more message boxes.

Edit: This is my guess anyways.
Last edited on Jan 17, 2012 at 6:38pm
Jan 17, 2012 at 9:00pm
#1 I can see you're declaring a INITCOMMONCONTROLSEX variable, but I don't see it being passed to InitCommonControlsEx(). Note it should be pretty much the first thing you do in WinMain.

#2 Child windows are normally created in the WM_CREATE handler.

#3 And note that CreateToolbarEx is deprecated. Nowadays you're supposed to create a toolbar using CreateWindowEx (see MSDN for details)
Jan 17, 2012 at 9:09pm
Never, never, never, never, never use Message Boxes for debugging or monitoring gui program activity. Its a very bad idea. Use an output log file. Did I mention not to use Message Boxes for monitoring windows messages? If not, don't ever do it.

You said yourself its a disaster to uncomment those lines. That's because you should never, never, never use message boxes to monitor gui program activity.
Last edited on Jan 17, 2012 at 9:11pm
Jan 18, 2012 at 1:54am
OK,this is just funny,and I know that.I'll choose label then,to know what messages being sent.
Jan 18, 2012 at 2:10am
I wrote you a program that shows how I code/debug Windows GUI programs. I called it Debug1. Its just two files, i.e., Main.cpp and Main.h. Compiles to 8 K wit GNU Mingw. Create a GUI project and run it. When it appears close the window and check your directory where you put it for "Output.txt". Its a file the program opens to log messages...

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
//Main.h
#ifndef Main_h
#define Main_h

#define dim(x) (sizeof(x) / sizeof(x[0]))               // Macro That Determines # Of Msgs

typedef struct WindowsEventArguments                    // Amalgamates Window Procedure
{                                                       // parameters Into A UDT (struct).
 HWND                         hWnd;                     // .NET Does This.  Its OK.
 WPARAM                       wParam;
 LPARAM                       lParam;
 HINSTANCE                    hIns;
}WndEventArgs, *lpWndEventArgs;

long fnWndProc_OnCreate       (lpWndEventArgs Wea);     // Foreward Procedure Declarations
long fnWndProc_OnSize         (lpWndEventArgs Wea);     // Of Event/Message Handlers
long fnWndProc_OnPaint        (lpWndEventArgs Wea);
long fnWndProc_OnClose        (lpWndEventArgs Wea);
long fnWndProc_OnDestroy      (lpWndEventArgs Wea);

struct EVENTHANDLER                                     // UDT (struct) That Associates
{                                                       // Windows Messages With The
 unsigned int                 iMsg;                     // Procedure Which Handles Them.
 long                         (*fnPtr)(lpWndEventArgs); // I Got This From Douglas Boling
};                                                      // Who Got It From Ray Duncan.

const EVENTHANDLER EventHandler[]=                      // Array Of Message/Event Handlers.
{                                                       // To Add A New Message Handler Just
 {WM_CREATE,                  fnWndProc_OnCreate},      // Declare It Above And Add It To
 {WM_SIZE,                    fnWndProc_OnSize},        // The Array Here.
 {WM_PAINT,                   fnWndProc_OnPaint},
 {WM_CLOSE,                   fnWndProc_OnClose},
 {WM_DESTROY,                 fnWndProc_OnDestroy}
};
#endif 

Jan 18, 2012 at 2:11am
Here's Main.cpp...

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 <windows.h>
#include <tchar.h>
#include <cstdio>
#include "Main.h"
FILE* fp=NULL;


long fnWndProc_OnCreate(lpWndEventArgs Wea)
{
 Wea->hIns=((LPCREATESTRUCT)Wea->lParam)->hInstance;
 fprintf(fp,"  Entering fnWndProc_OnCreate()\n");
 fprintf(fp,"    Wea->hWnd = %u\n",(unsigned)Wea->hWnd);
 fprintf(fp,"  Leaving fnWndProc_OnCreate()\n\n");

 return 0;
}


long fnWndProc_OnSize(lpWndEventArgs Wea)
{
 fprintf(fp,"  Entering fnWndProc_OnSize()\n");
 fprintf(fp,"    Width = %d\tHeight = %d\n",LOWORD(Wea->lParam),HIWORD(Wea->lParam));
 fprintf(fp,"  Leaving fnWndProc_OnSize()\n\n");

 return 0;
}


long fnWndProc_OnPaint(lpWndEventArgs Wea)
{
 PAINTSTRUCT ps;
 HDC hDC;

 fprintf(fp,"  Entering fnWndProc_OnPaint()\n");
 hDC=BeginPaint(Wea->hWnd,&ps);
 fprintf(fp,"    Painting Window!\n");
 fprintf(fp,"    ps.rcPaint.right  = %d\n",(int)ps.rcPaint.right);
 fprintf(fp,"    ps.rcPaint.bottom = %d\n",(int)ps.rcPaint.bottom);
 EndPaint(Wea->hWnd,&ps);
 fprintf(fp,"  Leaving fnWndProc_OnPaint()\n\n");

 return 0;
}


long fnWndProc_OnClose(lpWndEventArgs Wea)
{
 fprintf(fp,"  Entering fnWndProc_OnClose()\n");
 fprintf(fp,"    Wea->hWnd = %u\n",(unsigned)Wea->hWnd);
 DestroyWindow(Wea->hWnd);
 fprintf(fp,"  Leaving fnWndProc_OnClose()\n");

 return 0;
}


long fnWndProc_OnDestroy(lpWndEventArgs Wea)
{
 fprintf(fp,"    Entering fnWndProc_OnDestroy()\n");
 fprintf(fp,"      Wea->hWnd = %u\n",(unsigned)Wea->hWnd);
 PostQuitMessage(0);
 fprintf(fp,"    Leaving fnWndProc_OnDestroy()\n");

 return 0;
}


LRESULT CALLBACK fnWndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{
 WndEventArgs Wea;

 for(unsigned int i=0; i<dim(EventHandler); i++)
 {
     if(EventHandler[i].iMsg==msg)
     {
        Wea.hWnd=hwnd, Wea.lParam=lParam, Wea.wParam=wParam;
        return (*EventHandler[i].fnPtr)(&Wea);
     }
 }

 return (DefWindowProc(hwnd, msg, wParam, lParam));
}


int WINAPI WinMain(HINSTANCE hIns, HINSTANCE hPrevIns, LPSTR lpszArgument, int iShow)
{
 TCHAR szClassName[]=_T("Debugging Windows Programs");
 WNDCLASSEX wc;
 MSG messages;
 HWND hWnd;

 wc.lpszClassName=szClassName;                wc.lpfnWndProc=fnWndProc;
 wc.cbSize=sizeof (WNDCLASSEX);               wc.style=CS_DBLCLKS;
 wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);     wc.hInstance=hIns;
 wc.hIconSm=LoadIcon(NULL, IDI_APPLICATION);  wc.hCursor=LoadCursor(NULL,IDC_ARROW);
 wc.hbrBackground=(HBRUSH)COLOR_BTNSHADOW;    wc.cbWndExtra=0;
 wc.lpszMenuName=NULL;                        wc.cbClsExtra=0;
 RegisterClassEx(&wc);
 fp=fopen("Output.txt","w");
 fprintf(fp,"Output.txt Opened In WinMain()\n");
 hWnd=CreateWindowEx(0,szClassName,szClassName,WS_OVERLAPPEDWINDOW,75,75,320,305,HWND_DESKTOP,0,hIns,0);
 ShowWindow(hWnd,iShow);
 while(GetMessage(&messages,NULL,0,0))
 {
    TranslateMessage(&messages);
    DispatchMessage(&messages);
 }
 fprintf(fp,"Output.txt Closed In WinMain()\n");
 fclose(fp);

 return messages.wParam;
}


Here's the output from starting it then x'ing right out...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Output.txt Opened In WinMain()
  Entering fnWndProc_OnCreate()
    Wea->hWnd = 1508284
  Leaving fnWndProc_OnCreate()

  Entering fnWndProc_OnSize()
    Width = 304	Height = 267
  Leaving fnWndProc_OnSize()

  Entering fnWndProc_OnPaint()
    Painting Window!
    ps.rcPaint.right  = 304
    ps.rcPaint.bottom = 267
  Leaving fnWndProc_OnPaint()

  Entering fnWndProc_OnClose()
    Wea->hWnd = 1508284
    Entering fnWndProc_OnDestroy()
      Wea->hWnd = 1508284
    Leaving fnWndProc_OnDestroy()
  Leaving fnWndProc_OnClose()
Output.txt Closed In WinMain()
Jan 18, 2012 at 2:14am
If you are interested I can show you how to log those messages in a console window along side a GUI window. That can be very, very helpful.
Jan 18, 2012 at 5:51am
closed account (DSLq5Di1)
@freddie1
Have you considered using the HANDLE_MSG() macro defined in <windowsx.h>?
Jan 18, 2012 at 1:32pm
Hi sloppy,

No, I wasn't aware of it, and just did a real quick look at a CodeProject tutorial on it. I have to get ready for a funeral now, so I'll have to look at it again when I have time. Basically, the bottom line is, that as soon as you graduate from simple beginner programs and try to write your first SDK style Windows program that actually does something, you end up with these gargantuan WndProcs of several thousand lines that are unmaintainable. So in self defense you have to do something to deal with it. Whenever I post anything here in terms of demo programs I'm always torn between posting standard switch WndProc logic, or my message cracker setup which I much prefer. I fear it will be to much for beginners.

freddie
Jan 18, 2012 at 3:52pm
Hi freddie1, I'm actually reading your programming debugging tips at the moment,and I'll further reply if I understand your posts above.
Jan 18, 2012 at 8:45pm
Another useful idea in terms of logging debug output is that it can be done in terms of conditional defines, which turn debugging on/off depending on whether some define is present or not. Try this one...

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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include <windows.h>
#include <tchar.h>
#include <cstdio>
#include "Main.h"
#define  MYDEBUG
#if defined(MYDEBUG)
    FILE* fp=NULL;
#endif


long fnWndProc_OnCreate(lpWndEventArgs Wea)
{
 Wea->hIns=((LPCREATESTRUCT)Wea->lParam)->hInstance;
 #if defined(MYDEBUG)
 fprintf(fp,"  Entering fnWndProc_OnCreate()\n");
 fprintf(fp,"    Wea->hWnd = %u\n",(unsigned)Wea->hWnd);
 fprintf(fp,"  Leaving fnWndProc_OnCreate()\n\n");
 #endif

 return 0;
}


long fnWndProc_OnSize(lpWndEventArgs Wea)
{
 #if defined(MYDEBUG)
 fprintf(fp,"  Entering fnWndProc_OnSize()\n");
 fprintf(fp,"    Width = %d\tHeight = %d\n",LOWORD(Wea->lParam),HIWORD(Wea->lParam));
 fprintf(fp,"  Leaving fnWndProc_OnSize()\n\n");
 #endif

 return 0;
}


long fnWndProc_OnPaint(lpWndEventArgs Wea)
{
 PAINTSTRUCT ps;
 HDC hDC;

 #if defined(MYDEBUG)
 fprintf(fp,"  Entering fnWndProc_OnPaint()\n");
 #endif
 hDC=BeginPaint(Wea->hWnd,&ps);
 #if defined(MYDEBUG)
 fprintf(fp,"    Painting Window!\n");
 fprintf(fp,"    ps.rcPaint.right  = %d\n",(int)ps.rcPaint.right);
 fprintf(fp,"    ps.rcPaint.bottom = %d\n",(int)ps.rcPaint.bottom);
 #endif
 EndPaint(Wea->hWnd,&ps);
 #if defined(MYDEBUG)
 fprintf(fp,"  Leaving fnWndProc_OnPaint()\n\n");
 #endif

 return 0;
}


long fnWndProc_OnClose(lpWndEventArgs Wea)
{
 #if defined(MYDEBUG)
 fprintf(fp,"  Entering fnWndProc_OnClose()\n");
 fprintf(fp,"    Wea->hWnd = %u\n",(unsigned)Wea->hWnd);
 #endif
 DestroyWindow(Wea->hWnd);
 #if defined(MYDEBUG)
 fprintf(fp,"  Leaving fnWndProc_OnClose()\n");
 #endif

 return 0;
}


long fnWndProc_OnDestroy(lpWndEventArgs Wea)
{
 #if defined(MYDEBUG)
 fprintf(fp,"    Entering fnWndProc_OnDestroy()\n");
 fprintf(fp,"      Wea->hWnd = %u\n",(unsigned)Wea->hWnd);
 #endif
 PostQuitMessage(0);
 #if defined(MYDEBUG)
 fprintf(fp,"    Leaving fnWndProc_OnDestroy()\n");
 #endif

 return 0;
}


LRESULT CALLBACK fnWndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{
 WndEventArgs Wea;

 for(unsigned int i=0; i<dim(EventHandler); i++)
 {
     if(EventHandler[i].iMsg==msg)
     {
        Wea.hWnd=hwnd, Wea.lParam=lParam, Wea.wParam=wParam;
        return (*EventHandler[i].fnPtr)(&Wea);
     }
 }

 return (DefWindowProc(hwnd, msg, wParam, lParam));
}


int WINAPI WinMain(HINSTANCE hIns, HINSTANCE hPrevIns, LPSTR lpszArgument, int iShow)
{
 TCHAR szClassName[]=_T("Debugging Windows Programs");
 WNDCLASSEX wc;
 MSG messages;
 HWND hWnd;

 wc.lpszClassName=szClassName;                wc.lpfnWndProc=fnWndProc;
 wc.cbSize=sizeof (WNDCLASSEX);               wc.style=0;
 wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);     wc.hInstance=hIns;
 wc.hIconSm=LoadIcon(NULL, IDI_APPLICATION);  wc.hCursor=LoadCursor(NULL,IDC_ARROW);
 wc.hbrBackground=(HBRUSH)COLOR_BTNSHADOW;    wc.cbWndExtra=0;
 wc.lpszMenuName=NULL;                        wc.cbClsExtra=0;
 RegisterClassEx(&wc);
 #if defined(MYDEBUG)
 fp=fopen("Output.txt","w");
 fprintf(fp,"Output.txt Opened In WinMain()\n");
 fprintf(fp,"  About To Make CreateWindowEx() Call...\n\n");
 #endif
 hWnd=CreateWindowEx(0,szClassName,szClassName,WS_OVERLAPPEDWINDOW,75,75,320,305,HWND_DESKTOP,0,hIns,0);
 #if defined(MYDEBUG)
 fprintf(fp,"  hWnd = %u\n\n",(unsigned)hWnd);
 #endif
 ShowWindow(hWnd,iShow);
 while(GetMessage(&messages,NULL,0,0))
 {
    TranslateMessage(&messages);
    DispatchMessage(&messages);
 }
 #if defined(MYDEBUG)
 fprintf(fp,"Output.txt Closed In WinMain()\n");
 fclose(fp);
 #endif

 return messages.wParam;
}


The Main.h file would be the same. Also, this thread was about debugging, but if you are caught up in that message cracker thing I sprung on you, I have a tutorial on that here...

http://www.jose.it-berater.org/smfforum/index.php?topic=3391.0

I believe I'm going to take a look at sloppy9's HANDLE_MSG thing in windowssx.h now.
Last edited on Jan 18, 2012 at 8:47pm
Topic archived. No new replies allowed.