先给出一个纯净的Windows程序:
1
#include
<
windows.h
>
2
3
LRESULT CALLBACK MyWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
4
5
int
WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
int
nShowCmd)
6
{
7
WNDCLASS MyWndClass;
8
HWND hWnd;
9
MSG msg;
10
UINT width;
11
UINT height;
12
13
//
CS:Class styles
14
MyWndClass.style
=
CS_HREDRAW
|
CS_VREDRAW;
15
MyWndClass.lpfnWndProc
=
MyWndProc;
//
Pointer to the window procedure
16
MyWndClass.cbClsExtra
=
0
;
17
MyWndClass.cbWndExtra
=
0
;
18
MyWndClass.hInstance
=
hInstance;
19
MyWndClass.hIcon
=
LoadIcon(NULL, IDI_APPLICATION);
20
MyWndClass.hCursor
=
LoadCursor(NULL, IDC_ARROW);
21
MyWndClass.hbrBackground
=
(HBRUSH)GetStockObject(WHITE_BRUSH);
22
MyWndClass.lpszMenuName
=
NULL;
23
MyWndClass.lpszClassName
=
"
myWndClassName
"
;
24
25
RegisterClass(
&
MyWndClass);
26
27
width
=
::GetSystemMetrics(SM_CXSCREEN)
/
2
;
28
height
=
::GetSystemMetrics(SM_CYSCREEN)
/
2
;
29
30
hWnd
=
::CreateWindow(
"
myWndClassName
"
,
31
"
window title
"
,
32
WS_OVERLAPPEDWINDOW,
33
10
,
34
10
,
35
width,
36
height,
37
NULL,
38
NULL,
39
NULL,
//
also be hInstance,
40
/**/
/*
[in] Windows 95/98/Me: Handle to the instance of the module to be associated with the window.
41
Windows NT/2000/XP: This value is ignored.
42
*/
43
NULL);
44
::ShowWindow(hWnd, nShowCmd);
45
::UpdateWindow(hWnd);
46
47
while
( (bRet
=
GetMessage(
&
msg, NULL,
0
,
0
))
!=
0
)
//
The thread get message from thread message queque and remove it from queue
48
//
when encounters the WM_QUIT message, it returns FALSE and ends the loop.
49
{
50
if
(bRet
==
-
1
)
51
{
52
//
handle the error and possibly exit
53
}
54
else
55
{
56
TranslateMessage(
&
msg);
57
DispatchMessage(
&
msg);
//
Direct the system to send Mes to appropriate window procedure.and it
58
//
does not pass the time the message was posted or mouse cursor position.
59
}
60
}
61
62
return
msg.wParam;
63
64
LRESULT CALLBACK MyWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
65
{
66
HDC hDC;
67
PAINTSTRUCT paintStruct;
68
switch
(message)
69
{
70
case
WM_PAINT:
71
hDC
=
::BeginPaint(hWnd,
&
paintStruct);
72
::TextOut(hDC,
10
,
10
,mesH
+
mesM
+
mesW
+
mesL,
100
);
73
::EndPaint(hWnd,
&
paintStruct);
74
return
0
;
75
case
WM_LBUTTONDOWN:
76
MessageBox(hWnd,
"
你按下了鼠标左键
"
,
"
左键按下提示
"
,MB_ICONEXCLAMATION
|
MB_OK);
77
return
0
;
78
case
WM_DESTROY:
79
::PostQuitMessage(
0
);
80
return
0
;
81
}
82
return
::DefWindowProc(hWnd,message,wParam,lParam);
83
}
好多啊,我都不想分析了,头文件中都有的,我只讲讲我分析了哪些东西吧,然后把我修改后的代码(比较乱,不过,如果你也和我作了一样多的工作,你的代码肯定也很乱)贴上来。
我分析的东西:LRESULT、CALLBACK、HWND、UINT、WPARAM、LPARAM……各种我不认识的玩意儿,还有就是如何发送、接收消息如SendMessage……
1#include <windows.h>
2#include "atlstr.h"
3
4//决定消息如何处理
5/**//* Types use for passing & returning polymorphic values */
6/**//* typedef UINT_PTR WPARAM;
7 typedef _W64 unsigned int UINT_PTR, *PUINT_PTR;
8
9 typedef LONG_PTR LPARAM;
10
11 typedef LONG_PTR LRESULT;
12 typedef _W64 long LONG_PTR, *PLONG_PTR;
13 #define _W64 __w64
14
15 #define CALLBACK __stdcall
16
17 Element Implementation
18 Argument-passing order Pushes parameters on the stack,Right to left.
19 Argument-passing convention By value, unless a pointer or reference type is passed.
20 Stack-maintenance responsibility Called function pops its own arguments from the stack.
21 Name-decoration convention An underscore (_) is prefixed to the name. The name is followed
22 by the at sign (@) followed by the number of bytes (in decimal)
23 in the argument list. Therefore, the function declared as
24 int func( int a, double b ) is decorated as follows: _func@12
25
26 DECLARE_HANDLE (HWND);
27 #define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
28 The two combined is
29 struct HWND__
30 {
31 int unused;
32 }*HWND;
33 */
34LRESULT CALLBACK MyWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
35struct MSGMAP_ENTRY{
36 UNIT nMessage;
37 LRESULT CALLBACK()
38}
39
40/**//*
41 #define WINAPI __stdcall
42
43 DECLARE_HANDLE(HINSTANCE);
44 #define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
45 The two combined is
46 struct HINSTANCE__
47 {
48 int unused;
49 }*HINSTANCE;
50
51 typedef __nullterminated CHAR *NPSTR, *LPSTR, *PSTR;
52*/
53CString myWndClassName = "any";
54//typedef LPCSTR PCTSTR, LPCTSTR, PCUTSTR, LPCUTSTR;
55//typedef __nullterminated CONST CHAR *LPCSTR, *PCSTR;
56LPCTSTR myMes = "my message.";
57UINT myMesID = 0;
58int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
59{
60 /**//*
61 typedef WNDCLASSA WNDCLASS;
62 typedef struct tagWNDCLASSA {
63 UINT style;
64 WNDPROC lpfnWndProc;//typedef LRESULT (CALLBACK* WNDPROC)(HWND, UINT, WPARAM, LPARAM);
65 int cbClsExtra;
66 int cbWndExtra;
67 HINSTANCE hInstance;
68 HICON hIcon;
69 HCURSOR hCursor;
70 HBRUSH hbrBackground;
71 LPCSTR lpszMenuName;
72 LPCSTR lpszClassName;
73 } WNDCLASSA, *PWNDCLASSA, NEAR *NPWNDCLASSA, FAR *LPWNDCLASSA;
74 */
75 WNDCLASS MyWndClass;//每个Windows应用程序都必须创建MyWndClass结构的一个实例
76 //并利用Windows对其注册
77 HWND hWnd;
78
79 /**//*
80 * Message structure
81 typedef struct tagMSG {
82 HWND hwnd;
83 UINT message;
84 WPARAM wParam;
85 LPARAM lParam;
86 DWORD time;
87 POINT pt;
88 #ifdef _MAC
89 DWORD lPrivate;
90 #endif
91 } MSG, *PMSG, NEAR *NPMSG, FAR *LPMSG;
92 */
93 MSG msg;
94 //typedef unsigned int UINT;
95 UINT width;
96 UINT height;
97
98 //CS:Class styles
99 MyWndClass.style = CS_HREDRAW | CS_VREDRAW;
100 MyWndClass.lpfnWndProc = MyWndProc;//Pointer to the window procedure
101 MyWndClass.cbClsExtra = 0;
102 MyWndClass.cbWndExtra = 0;
103 MyWndClass.hInstance = hInstance;
104 MyWndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
105 MyWndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
106 MyWndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
107 MyWndClass.lpszMenuName = NULL;
108 MyWndClass.lpszClassName = myWndClassName;
109
110 /**//*
111 #define RegisterClass RegisterClassA
112 WINUSERAPI
113 ATOM
114 WINAPI
115 RegisterClassA(
116 __in CONST MyWndClassA *lpMyWndClass);
117 typedef WORD ATOM;
118 typedef unsigned short WORD;
119 */
120 ATOM classAtom = RegisterClass(&MyWndClass);
121 if(classAtom == 0)
122 {
123 return 0;
124 }
125
126 width = ::GetSystemMetrics(SM_CXSCREEN)/2;
127 height = ::GetSystemMetrics(SM_CYSCREEN)/2;
128
129 CString title;
130 switch(nShowCmd)
131 {
132 case SW_HIDE:
133 title = "Hides the window and activates another window.";
134 break;
135 case SW_MAXIMIZE:
136 title = "Hides the window and activates another window.";
137 break;
138 case SW_MINIMIZE:
139 title = "Minimizes the specified window and activates the next top-level window in the Z order.";
140 break;
141 case SW_RESTORE:
142 title = "Activates and displays the window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when restoring a minimized window.";
143 break;
144 case SW_SHOW:
145 title = "Activates the window and displays it in its current size and position.";
146 break;
147 /**//*case SW_SHOWMAXIMIZED:
148 title = "Activates the window and displays it as a maximized window.";
149 break;*/
150 case SW_SHOWMINNOACTIVE:
151 title = "Displays the window as a minimized window. This value is similar to SW_SHOWMINIMIZED, except the window is not activated.";
152 break;
153 case SW_SHOWNA:
154 title = "Displays the window in its current size and position. This value is similar to SW_SHOW, except the window is not activated..";
155 break;
156 case SW_SHOWNOACTIVATE:
157 title = "Displays a window in its most recent size and position. This value is similar to SW_SHOWNORMAL, except the window is not actived.";
158 break;
159 case SW_SHOWNORMAL:
160 title = "Activates and displays a window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when displaying the window for the first time.";
161 break;
162 }
163 CString temp, temp1;
164 temp.Format("hInstance:%d", hInstance->unused);
165 if(hPrevInstance != NULL)
166 {
167 temp1.Format(" hPrevInstance:%d", hPrevInstance->unused);
168 }
169 else
170 {
171 temp1 = " hPrevInstance:NULL";
172 }
173 title = temp + temp1 + " nShowCmd: "+title;
174 hWnd = ::CreateWindow(myWndClassName,
175 title,
176 WS_OVERLAPPEDWINDOW,
177 10,
178 10,
179 width,
180 height,
181 NULL,
182 NULL,
183 NULL,//also be hInstance,
184 /**//*[in] Windows 95/98/Me: Handle to the instance of the module to be associated with the window.
185 Windows NT/2000/XP: This value is ignored.
186 */
187 NULL);
188 ::ShowWindow(hWnd, nShowCmd);
189 ::UpdateWindow(hWnd);
190
191 myMesID = RegisterWindowMessage(myMes);
192
193 BOOL bRet;
194 /**//*
195 * Message structure
196 typedef struct tagMSG {
197 HWND hwnd;
198 UINT message;
199 WPARAM wParam;
200 LPARAM lParam;
201 DWORD time;
202 POINT pt;
203 #ifdef _MAC
204 DWORD lPrivate;
205 #endif
206 } MSG, *PMSG, NEAR *NPMSG, FAR *LPMSG;
207 */
208
209 //while(true); // ending the message loop is often the first step in closing the application.
210 while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0) //The thread get message from thread message queque and remove it from queue
211 //when encounters the WM_QUIT message, it returns FALSE and ends the loop.
212 {
213 if (bRet == -1)
214 {
215 // handle the error and possibly exit
216 }
217 else
218 {
219 TranslateMessage(&msg);
220 DispatchMessage(&msg); //Direct the system to send Mes to appropriate window procedure.and it
221 //does not pass the time the message was posted or mouse cursor position.
222 }
223 }
224 //while(::GetMessage(&msg,NULL,0,0))//GetMessage()从窗口消息队列中索取消息
225 // {
226 // ::TranslateMessage(&msg);
227 // //TranslateMessage()处理虚拟消息键(代表按键的消息),
228 // //将它们译为字符消息,送回到消息队列。
229 // ::DispatchMessage(&msg);
230 // //DispatchMessage()将消息发给应用程序的窗口过程WndProc()
231 // }
232 return msg.wParam;
233
234}
235
236LRESULT CALLBACK MyWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
237{
238 HDC hDC;
239 PAINTSTRUCT paintStruct;
240 HWND hWnd1;
241 CString mesH, mesM, mesW, mesL;
242 if((message == myMesID) && (myMesID != 0))
243 {
244 MessageBox(hWnd,"my message appear!","提示",MB_ICONEXCLAMATION | MB_OK);
245 return 1;
246 }
247 switch(message)
248 {
249 case WM_PAINT:
250 if(hWnd != NULL)
251 {
252 mesH.Format("HWND: !NULL");//, hWnd->unused);
253 }
254 if(message != NULL)
255 mesM.Format(" message: %d", message);
256 else
257 mesM.Format(" message: NULL");
258 if(wParam != NULL)
259 mesW.Format(" WPARAM: %d", wParam);
260 else
261 mesW.Format(" WPARAM: NULL");
262 if(lParam != NULL)
263 mesL.Format(" LPARAM: %l", lParam);
264 else
265 mesL.Format(" LPARAM: NULL");
266 hDC = ::BeginPaint(hWnd,&paintStruct);
267 ::TextOut(hDC,10,10,mesH+mesM+mesW+mesL,100);
268 //MessageBox(hWnd,mesH+mesM+mesW+mesL,"提示",MB_ICONEXCLAMATION | MB_OK);
269 //::TextOut(hDC,100,100,"小辉愿和大家一起进步!",20);
270 ::EndPaint(hWnd,&paintStruct);
271 return 0;
272 case WM_LBUTTONDOWN:
273 MessageBox(hWnd,"你按下了鼠标左键, 又一个窗口生成了! and Post a myself message","左键按下提示",MB_ICONEXCLAMATION | MB_OK);
274 /**//*hWnd1 = ::CreateWindow(myWndClassName,
275 "child",
276 WS_OVERLAPPEDWINDOW,
277 20,
278 20,
279 60,
280 60,
281 NULL,
282 NULL,
283 NULL,
284 NULL);
285 ::ShowWindow(hWnd1, SW_SHOW);
286 ::UpdateWindow(hWnd1);*/
287 if(myMesID != 0)
288 {
289 /**//*
290 1 If the application supplies a NULL window handle when calling PostMessage, the message is posted to
291 the queue associated with the current thread
292 2 HWND_TOPMOST:post message to all top-level windows in the system.
293 */
294 //PostMessage(HWND_TOPMOST, myMesID, 0, 0);
295
296 /**//*
297 The function waits until the window procedure completes processing and then returns the message result.
298 */
299 if(SendMessage(HWND_TOPMOST, myMesID, 0, 0) == 1)
300 {
301 MessageBox(hWnd,"get result after send message!","Congratulation",MB_ICONEXCLAMATION | MB_OK);
302 }
303 }
304 return 0;
305 case WM_GETMINMAXINFO:
306 if(hWnd != NULL)
307 {
308 mesH.Format("HWND: !NULL");
309 }
310 if(message != NULL)
311 mesM.Format(" message: %d", message);
312 else
313 mesM.Format(" message: NULL");
314 if(wParam != NULL)
315 mesW.Format(" WPARAM: %d", wParam);
316 else
317 mesW.Format(" WPARAM: NULL");
318 if(lParam != NULL)
319 mesL.Format(" LPARAM: !NULL");
320 else
321 mesL.Format(" LPARAM: NULL");
322 //MessageBox(hWnd,mesH+mesM+mesW+mesL,"提示",MB_ICONEXCLAMATION | MB_OK);
323 return 0;
324 case WM_DESTROY:
325 ::PostQuitMessage(0);
326 return 0;
327 }
328
329 return ::DefWindowProc(hWnd,message,wParam,lParam);// system for default processing
330}