Small enhancement.
[wine/hacks.git] / libtest / guitest.c
blob36a9ce77836a3f6f24e3b6bdeda8aa07c01e5856
1 /* Windows GUI Behaviour Tester */
2 /* by Ove Kåven */
4 #include <stdio.h>
5 #include <string.h>
6 #include <stdarg.h>
7 #include <windows.h>
9 #include "guitest.rh"
11 /* checks to include */
12 #define LOGGING /* can be undefined under Wine and use -debugmsg +message instead */
13 #define MAIN_STYLE WS_OVERLAPPEDWINDOW
14 #undef TEST_DESTROY_MAIN
15 #undef SHOW_SUB
16 #define TEST_DIALOG
17 #define RESIZE_DIALOG
18 #undef TEST_SUBDIALOG
19 #undef TEST_COMMCTL
21 /************************/
22 /*** GLOBAL VARIABLES ***/
23 /************************/
25 HINSTANCE hInst;
26 DWORD StartTime;
27 HWND hListBox,hMainWnd,hSubWnd;
28 HWND hButton[4]={0,0,0,0};
29 HWND hDialog=0,hGroup=0,hSubDlg=0;
30 WNDPROC wndButton[4],wndDialog,wndGroup,wndSubDlg;
31 BOOL Clicked=0,Ready=0;
32 int State=0,Rec=0;
33 #define STATE_CREATE 0
34 #define STATE_DESTROY 1
35 #define STATE_SHOW 2
36 #define STATE_UPDATE 3
37 #define STATE_DIALOG 4
38 #define STATE_TEST 5
39 #define STATE_DIRECT 6
40 #define STATE_DISPATCH 7
41 #define STATE_RECURS 8
42 char*StateName[]={
43 "Creat",
44 "Destr",
45 "Show ",
46 "Updat",
47 "Dialg",
48 "Test ",
49 "Call ",
50 "Disp ",
51 "RCall"
54 static char wclassname[] = "GUITestClass";
55 static char wcclassname[] = "GUITestChildClass";
56 static char winname[] = "GUITest";
58 /**************************/
59 /*** LOGGING FACILITIES ***/
60 /**************************/
62 struct MSGNAMES {
63 int msg;
64 char*name;
65 } MsgNames[]={
66 #define MSG(x) {x,#x},
67 #define MSG2(x,y) {y,#x},
68 #define ENDMSG {0}
70 /* we get these in CreateWindow */
71 MSG(WM_GETMINMAXINFO)
72 MSG(WM_NCCREATE)
73 MSG(WM_NCCALCSIZE)
74 MSG(WM_CREATE)
75 MSG(WM_PARENTNOTIFY)
77 /* we get these in ShowWindow */
78 MSG(WM_SHOWWINDOW)
79 MSG(WM_WINDOWPOSCHANGING)
80 MSG(WM_QUERYNEWPALETTE)
81 MSG(WM_ACTIVATEAPP)
82 MSG(WM_NCACTIVATE)
83 MSG(WM_GETTEXT)
84 MSG(WM_ACTIVATE)
85 MSG(WM_SETFOCUS)
86 MSG(WM_NCPAINT)
87 MSG(WM_ERASEBKGND)
88 MSG(WM_WINDOWPOSCHANGED)
89 MSG(WM_SIZE)
90 MSG(WM_MOVE)
92 /* we get these in DestroyWindow */
93 MSG(WM_KILLFOCUS)
94 MSG(WM_DESTROY)
95 MSG(WM_NCDESTROY)
97 /* we get these directly sent */
98 MSG(WM_NCHITTEST)
99 MSG(WM_SETCURSOR)
100 MSG(WM_MOUSEACTIVATE)
101 MSG(WM_CHILDACTIVATE)
102 MSG(WM_COMMAND)
103 MSG(WM_SYSCOMMAND)
105 /* posted events */
106 MSG(WM_MOUSEMOVE)
107 MSG(WM_NCMOUSEMOVE)
108 MSG(WM_PAINT)
109 MSG(WM_LBUTTONDOWN)
110 MSG(WM_LBUTTONUP)
111 MSG(WM_NCLBUTTONDOWN)
112 MSG(WM_NCLBUTTONUP)
114 MSG(WM_KEYDOWN)
115 MSG(WM_KEYUP)
116 MSG(WM_CHAR)
118 #ifdef WIN32
119 MSG(WM_CTLCOLORBTN)
120 MSG(WM_CTLCOLORDLG)
121 MSG(WM_CTLCOLORSTATIC)
122 #else
123 MSG(WM_CTLCOLOR)
124 #endif
126 /* moving and sizing */
127 MSG2(WM_ENTERSIZEMOVE,0x0231)
128 MSG2(WM_EXITSIZEMOVE,0x0232)
129 #ifdef WIN32
130 MSG(WM_SIZING)
131 #endif
133 /* menus/dialog boxes */
134 MSG(WM_CANCELMODE)
135 MSG(WM_ENABLE)
136 MSG(WM_SETFONT)
137 MSG(WM_INITDIALOG)
138 MSG(WM_GETDLGCODE)
139 MSG(WM_ENTERIDLE)
141 /* getting these from Wine but not from Windows */
142 MSG2(WM_SETVISIBLE,0x0009) /* unheard of in BC++ 4.52 */
143 #ifdef WIN32
144 MSG(WM_CAPTURECHANGED)
145 #endif
147 ENDMSG};
149 struct MSGNAMES ButMsgs[]={
150 MSG(BM_SETSTATE)
151 MSG(BM_SETSTYLE)
153 ENDMSG};
155 char*MsgName(UINT msg,HWND hWnd)
157 int i;
158 static char buffer[64],wclass[64];
159 GetClassName(hWnd,wclass,sizeof(wclass));
161 #define MSGSEARCH(msgs) { \
162 for (i=0; msgs[i].name&&msgs[i].msg!=msg; i++); \
163 if (msgs[i].name) return msgs[i].name; \
166 if (!stricmp(wclass,"Button")) MSGSEARCH(ButMsgs);
167 MSGSEARCH(MsgNames);
168 /* WM_USER */
169 if (msg>=WM_USER) {
170 sprintf(buffer,"WM_USER+%04x{%s}",msg-WM_USER,wclass);
171 return buffer;
173 /* message not found */
174 sprintf(buffer,"%04x{%s}",msg,wclass);
175 return buffer;
178 char*WndName(HWND hWnd,int state=State)
180 static char buffer[16];
181 if (!hWnd) return "0000";
182 if (hWnd==hMainWnd || (state==STATE_CREATE && !hMainWnd)) return "main";
183 if (hWnd==hSubWnd || (state==STATE_CREATE && !hSubWnd)) return "chld";
184 if (hWnd==hDialog || (state==STATE_DIALOG && !hDialog)) return "tdlg";
185 if (hWnd==hGroup) return "tgrp";
186 if (hWnd==hButton[0]) return "but1";
187 if (hWnd==hButton[1]) return "but2";
188 if (hWnd==hButton[2]) return "but3";
189 if (hWnd==hButton[3]) return "but4";
190 if (hWnd==hSubDlg || (state==STATE_CREATE && !hSubDlg)) return "sdlg";
191 if (hDialog) {
192 int id=GetDlgCtrlID(hWnd);
193 if (id) {
194 sprintf(buffer,"dlgitem(%d)",id);
195 return buffer;
198 sprintf(buffer,"%04x",hWnd);
199 return buffer;
202 void Log(const char*fmt)
204 #ifdef LOGGING
205 if (!Clicked) SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)fmt);
206 #endif
209 void Logf(const char*fmt,...)
211 va_list par;
212 static char buffer[256];
214 va_start(par,fmt);
215 vsprintf(buffer,fmt,par);
216 va_end(par);
217 Log(buffer);
220 void LogChildOrder(HWND hWnd)
222 HWND hWndChild = GetWindow(hWnd,GW_CHILD);
223 char*name;
224 static char buffer[256];
226 strcpy(buffer,"child list:");
227 while (hWndChild) {
228 strcat(strcat(buffer," "),WndName(hWndChild));
229 hWndChild=GetWindow(hWndChild,GW_HWNDNEXT);
231 Log(buffer);
234 void LogMessage(int state,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,char*name=NULL)
236 static char buffer[256];
237 DWORD tick=GetTickCount()-StartTime;
238 char*msgname=MsgName(msg,hWnd);
239 if (!name) name=WndName(hWnd,state);
240 switch (msg) {
241 case WM_SETFOCUS:
242 case WM_KILLFOCUS:
243 case WM_SETCURSOR:
244 Logf("%04d[%s(%d):%s]%s(%s,%08x)",tick,StateName[state],Rec,
245 name,msgname,WndName((HWND)wParam),lParam);
246 break;
247 #ifdef WIN32
248 case WM_ENTERIDLE:
249 case WM_CTLCOLORBTN:
250 case WM_CTLCOLORDLG:
251 Logf("%04d[%s(%d):%s]%s(%08x,%s)",tick,StateName[state],Rec,
252 name,msgname,wParam,WndName((HWND)lParam));
253 break;
254 #else
255 case WM_ENTERIDLE:
256 case WM_CTLCOLOR:
257 Logf("%04d[%s(%d):%s]%s(%08x,%04x:%s)",tick,StateName[state],Rec,
258 name,msgname,wParam,HIWORD(lParam),WndName((HWND)LOWORD(lParam)));
259 break;
260 #endif
261 case WM_WINDOWPOSCHANGING:
262 case WM_WINDOWPOSCHANGED:
264 WINDOWPOS*pos=(WINDOWPOS*)lParam;
265 #ifdef WIN32
266 Logf("%04d[%s(%d):%s]%s(%08x,%p)",tick,StateName[state],Rec,
267 name,msgname,wParam,pos);
268 #else
269 Logf("%04d[%s(%d):%s]%s(%04x,%p)",tick,StateName[state],Rec,
270 name,msgname,wParam,pos);
271 #endif
272 strcpy(buffer,"FLAGS:");
273 if (pos->flags&SWP_DRAWFRAME) strcat(buffer," DRAWFRAME");
274 if (pos->flags&SWP_HIDEWINDOW) strcat(buffer," HIDEWINDOW");
275 if (pos->flags&SWP_NOACTIVATE) strcat(buffer," NOACTIVATE");
276 if (pos->flags&SWP_NOCOPYBITS) strcat(buffer," NOCOPYBITS");
277 if (pos->flags&SWP_NOMOVE) strcat(buffer," NOMOVE");
278 if (pos->flags&SWP_NOOWNERZORDER) strcat(buffer," NOOWNERZORDER");
279 if (pos->flags&SWP_NOSIZE) strcat(buffer," NOSIZE");
280 if (pos->flags&SWP_NOREDRAW) strcat(buffer," NOREDRAW");
281 if (pos->flags&SWP_NOZORDER) strcat(buffer," NOZORDER");
282 if (pos->flags&SWP_SHOWWINDOW) strcat(buffer," SHOWWINDOW");
283 Log(buffer);
285 break;
286 default:
287 #ifdef WIN32
288 Logf("%04d[%s(%d):%s]%s(%08x,%08x)",tick,StateName[state],Rec,
289 name,msgname,wParam,lParam);
290 #else
291 Logf("%04d[%s(%d):%s]%s(%04x,%08x)",tick,StateName[state],Rec,
292 name,msgname,wParam,lParam);
293 #endif
297 /***************************/
298 /*** GRAPHICS FACILITIES ***/
299 /***************************/
301 void Paint(HWND hWnd)
303 HDC dc;
304 PAINTSTRUCT ps;
305 dc=BeginPaint(hWnd,&ps);
306 EndPaint(hWnd,&ps);
309 void FillPattern(HWND hWnd,HDC pdc=0)
311 HDC dc=pdc?pdc:GetDC(hWnd);
312 HBRUSH oldbrush;
313 RECT rect;
314 if (!dc) {
315 Logf("failed to acquire DC for window %s",WndName(hWnd));
316 return;
317 } else {
318 Logf("acquired DC for %s window %s, painting",
319 IsWindowVisible(hWnd)?"visible":"invisible",WndName(hWnd));
321 GetClientRect(hWnd,&rect);
322 oldbrush=SelectObject(dc,GetStockObject(LTGRAY_BRUSH));
323 PatBlt(dc,0,0,rect.right,rect.bottom,PATCOPY);
324 SelectObject(dc,oldbrush);
325 if (!pdc) ReleaseDC(hWnd,dc);
328 void PaintPattern(HWND hWnd)
330 HDC dc;
331 PAINTSTRUCT ps;
332 dc=BeginPaint(hWnd,&ps);
333 FillPattern(hWnd,dc);
334 EndPaint(hWnd,&ps);
337 /*************************/
338 /*** WINDOW PROCEDURES ***/
339 /*************************/
341 /* MAIN WINDOW */
342 LRESULT FAR CALLBACK _export MainWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
344 LRESULT lResult=0;
345 RECT rect;
346 int OldState=State;
348 State=STATE_RECURS; Rec++;
349 if (!Clicked) LogMessage(OldState,hWnd,msg,wParam,lParam);
350 switch (msg) {
351 case WM_NCHITTEST:
352 lResult=DefWindowProc(hWnd,msg,wParam,lParam);
353 break;
354 case WM_LBUTTONDOWN:
355 case WM_CHAR:
356 if (!Clicked) {
357 SetParent(hListBox,hWnd);
358 GetClientRect(hWnd,&rect);
359 MoveWindow(hListBox,0,0,rect.right,rect.bottom,TRUE);
360 ShowWindow(hListBox,SW_SHOW);
361 SetFocus(hListBox);
362 Clicked=TRUE;
364 break;
365 case WM_SIZE:
366 GetClientRect(hWnd,&rect);
367 if (Clicked) {
368 MoveWindow(hListBox,0,0,rect.right,rect.bottom,TRUE);
370 MoveWindow(hSubWnd,0,rect.bottom/2,rect.right,rect.bottom-(rect.bottom/2),TRUE);
371 break;
372 case WM_PAINT:
373 Paint(hWnd);
374 break;
375 case WM_DESTROY:
376 PostQuitMessage(0);
377 break;
378 default:
379 lResult=DefWindowProc(hWnd,msg,wParam,lParam);
381 State=OldState; Rec--;
382 return lResult;
385 /* CHILD WINDOW */
386 LRESULT FAR CALLBACK _export SubWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
388 LRESULT lResult=0;
389 RECT rect;
390 int OldState=State;
392 State=STATE_RECURS; Rec++;
393 if (!Clicked) LogMessage(OldState,hWnd,msg,wParam,lParam);
394 switch (msg) {
395 case WM_PAINT:
396 Paint(hWnd);
397 break;
398 default:
399 lResult=DefWindowProc(hWnd,msg,wParam,lParam);
401 State=OldState; Rec--;
402 return lResult;
405 BOOL FAR CALLBACK _export SubDialogProc(HWND hWndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
407 /* SUBCLASSED CONTROLS */
408 LRESULT FAR CALLBACK _export SubClassWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
410 LRESULT lResult=0;
411 RECT rect;
412 int OldState=State;
413 int But=-1;
415 if (hWnd==hButton[0]) But=0; else
416 if (hWnd==hButton[1]) But=1; else
417 if (hWnd==hButton[2]) But=2; else
418 if (hWnd==hButton[3]) But=3;
420 State=STATE_RECURS; Rec++;
421 if (!Clicked) {
422 LogMessage(OldState,hWnd,msg,wParam,lParam);
423 if (But!=-1) {
424 lResult=CallWindowProc((FARPROC)wndButton[But],hWnd,msg,wParam,lParam);
425 if (msg==WM_LBUTTONUP) {
426 LogChildOrder(GetParent(hWnd));
429 else if (hWnd==hDialog) {
430 lResult=CallWindowProc((FARPROC)wndDialog,hWnd,msg,wParam,lParam);
432 else if (hWnd==hSubDlg) {
433 lResult=CallWindowProc((FARPROC)wndSubDlg,hWnd,msg,wParam,lParam);
435 else if (hWnd==hGroup) {
436 lResult=CallWindowProc((FARPROC)wndGroup,hWnd,msg,wParam,lParam);
437 if (msg==WM_SETFOCUS) {
438 /* create subdialog */
439 if (hSubDlg) {
440 #if 0
441 SetRect(&rect,0,0,1,1);
442 InvalidateRect(hWnd,&rect,FALSE);
443 #endif
444 } else {
445 #ifdef TEST_SUBDIALOG
446 State=STATE_CREATE;
447 hSubDlg=CreateDialog(hInst,MAKEINTRESOURCE(2),hWnd,(FARPROC)SubDialogProc);
448 State=STATE_RECURS;
449 #else
450 #ifdef RESIZE_DIALOG
451 GetWindowRect(GetParent(hWnd),&rect);
452 rect.right++;
453 SetWindowPos(GetParent(hWnd),0,0,0,
454 rect.right-rect.left,rect.bottom-rect.top,
455 SWP_NOMOVE|SWP_NOZORDER);
456 #endif
457 #endif
462 State=OldState; Rec--;
463 return lResult;
466 /* MAIN DIALOG PROCEDURE */
467 BOOL FAR CALLBACK _export TestDialogProc(HWND hWndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
469 BOOL bResult=0;
470 RECT rect;
471 int OldState=State;
472 int But=-1;
474 State=STATE_RECURS; Rec++;
475 if (!Clicked) LogMessage(OldState,hWndDlg,msg,wParam,lParam,"dlgp");
476 switch (msg) {
477 case WM_INITDIALOG:
478 hDialog = hWndDlg;
479 /* subclass dialog window proc */
480 wndDialog = (WNDPROC)SetWindowLong(hDialog,GWL_WNDPROC,(LONG)SubClassWindowProc);
481 Logf("dialog visible=%s",IsWindowVisible(hWndDlg)?"TRUE":"FALSE");
482 /* subclass OK button */
483 hButton[3] = GetDlgItem(hWndDlg,IDOK);
484 wndButton[3] = (WNDPROC)SetWindowLong(hButton[3],GWL_WNDPROC,(LONG)SubClassWindowProc);
485 /* subclass group box */
486 hGroup = GetDlgItem(hWndDlg,IDC_GROUPBOX1);
487 wndGroup = (WNDPROC)SetWindowLong(hGroup,GWL_WNDPROC,(LONG)SubClassWindowProc);
489 #ifdef RESIZE_DIALOG
490 GetWindowRect(hWndDlg,&rect);
491 rect.right--;
492 SetWindowPos(hWndDlg,0,0,0,
493 rect.right-rect.left,rect.bottom-rect.top,
494 SWP_NOMOVE|SWP_NOZORDER);
495 // ShowWindow(GetDlgItem(hWndDlg,IDCANCEL),SW_HIDE);
496 #endif
498 bResult=TRUE; /* we don't do SetFocus */
499 break;
500 case WM_PAINT:
501 PaintPattern(hWndDlg);
502 bResult=TRUE;
503 break;
504 case WM_COMMAND:
505 EndDialog(hWndDlg,LOWORD(wParam));
506 bResult=TRUE;
507 break;
508 case WM_CLOSE:
509 EndDialog(hWndDlg,IDCANCEL);
510 bResult=TRUE;
511 break;
512 case WM_NCDESTROY:
513 hDialog = 0;
514 break;
516 State=OldState; Rec--;
517 return bResult;
520 /* SUBDIALOG PROCEDURE */
521 BOOL FAR CALLBACK _export SubDialogProc(HWND hWndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
523 BOOL bResult=0;
524 RECT rect;
525 int OldState=State;
526 int But=-1;
528 State=STATE_RECURS; Rec++;
529 if (!Clicked) LogMessage(OldState,hWndDlg,msg,wParam,lParam);
530 switch (msg) {
531 case WM_INITDIALOG:
532 hSubDlg = hWndDlg;
533 /* subclass dialog window proc */
534 wndSubDlg = (WNDPROC)SetWindowLong(hDialog,GWL_WNDPROC,(LONG)SubClassWindowProc);
536 bResult=TRUE; /* we don't do SetFocus */
537 break;
538 case WM_NCDESTROY:
539 hSubDlg = 0;
540 break;
542 State=OldState; Rec--;
543 return bResult;
546 /********************/
547 /*** MAIN PROGRAM ***/
548 /********************/
550 BOOL AppInit(void)
552 WNDCLASS wclass;
554 wclass.style = CS_HREDRAW|CS_VREDRAW;
555 wclass.lpfnWndProc = MainWindowProc;
556 wclass.cbClsExtra = 0;
557 wclass.cbWndExtra = 0;
558 wclass.hInstance = hInst;
559 wclass.hIcon = LoadIcon(hInst,MAKEINTRESOURCE(1));
560 wclass.hCursor = LoadCursor(0,IDC_ARROW);
561 wclass.hbrBackground = GetStockObject(WHITE_BRUSH);
562 wclass.lpszMenuName = NULL;
563 wclass.lpszClassName = wclassname;
564 if (!RegisterClass(&wclass)) return FALSE;
565 wclass.lpfnWndProc = SubWindowProc;
566 wclass.lpszClassName = wcclassname;
567 if (!RegisterClass(&wclass)) return FALSE;
568 return TRUE;
571 int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
572 LPSTR lpszCmdLine, int nCmdShow)
574 MSG msg;
575 RECT rect;
577 hInst = hInstance;
578 if (!hPrevInstance)
579 if (!AppInit())
580 return 0;
582 StartTime=GetTickCount();
583 hListBox = CreateWindow("LISTBOX","Messages",WS_BORDER|WS_VSCROLL|WS_CHILD|
584 LBS_HASSTRINGS|LBS_NOTIFY|LBS_WANTKEYBOARDINPUT,
585 0,0,0,0,GetDesktopWindow(),0,hInst,0);
586 if (!hListBox) {
587 MessageBox(0,"Could not create list box","Error",MB_OK);
590 State=STATE_CREATE;
591 hMainWnd = CreateWindow(wclassname,winname,MAIN_STYLE,
592 CW_USEDEFAULT,0,400,300,0,0,hInst,0);
593 if (!hMainWnd) return 0;
594 State=STATE_SHOW;
595 ShowWindow(hMainWnd,nCmdShow);
596 #ifdef TEST_DESTROY_MAIN
597 State=STATE_DESTROY;
598 DestroyWindow(hMainWnd);
599 State=STATE_DIRECT;
600 while (GetMessage(&msg,0,0,0)) {
601 TranslateMessage(&msg);
602 State=STATE_DISPATCH;
603 DispatchMessage(&msg);
604 State=STATE_DIRECT;
606 State=STATE_CREATE;
607 hMainWnd = CreateWindow(wclassname,winname,MAIN_STYLE,
608 CW_USEDEFAULT,0,400,300,0,0,hInst,0);
609 if (!hMainWnd) return 0;
610 State=STATE_SHOW;
611 ShowWindow(hMainWnd,nCmdShow);
612 #endif
613 /* update, so no WM_PAINTs are pending */
614 State=STATE_UPDATE;
615 // UpdateWindow(hMainWnd);
616 Ready=TRUE;
617 /* fill client area with a pattern */
618 FillPattern(hMainWnd);
619 /* create subwindow */
620 State=STATE_CREATE;
621 GetClientRect(hMainWnd,&rect);
622 hSubWnd = CreateWindow(wcclassname,winname,WS_CHILD|WS_BORDER|WS_CLIPSIBLINGS,
623 0,rect.bottom/2,rect.right,rect.bottom-(rect.bottom/2),hMainWnd,0,hInst,0);
624 if (!hSubWnd) return 0;
625 /* create buttons */
626 hButton[0] = CreateWindow("BUTTON","1",WS_CHILD|WS_CLIPSIBLINGS|WS_VISIBLE,
627 8,8,48,20,hMainWnd,0,hInst,0);
628 hButton[1] = CreateWindow("BUTTON","2",WS_CHILD|WS_CLIPSIBLINGS|WS_VISIBLE,
629 32,12,48,20,hMainWnd,0,hInst,0);
630 hButton[2] = CreateWindow("BUTTON","3",WS_CHILD|WS_CLIPSIBLINGS|WS_VISIBLE,
631 56,16,48,20,hMainWnd,0,hInst,0);
632 /* subclass them */
633 wndButton[0] = (WNDPROC)SetWindowLong(hButton[0],GWL_WNDPROC,(LONG)SubClassWindowProc);
634 wndButton[1] = (WNDPROC)SetWindowLong(hButton[1],GWL_WNDPROC,(LONG)SubClassWindowProc);
635 wndButton[2] = (WNDPROC)SetWindowLong(hButton[2],GWL_WNDPROC,(LONG)SubClassWindowProc);
636 /* show them */
637 State=STATE_UPDATE;
638 UpdateWindow(hButton[0]);
639 LogChildOrder(hMainWnd);
640 Logf("but1 visible=%d",IsWindowVisible(hButton[0]));
642 /* now reparent the button to our (invisible) subwindow */
643 State=STATE_TEST;
644 /* in different order, seeing who gets topmost */
645 SetParent(hButton[0],hSubWnd);
646 SetParent(hButton[2],hSubWnd);
647 SetParent(hButton[1],hSubWnd);
648 LogChildOrder(hSubWnd);
649 /* the button should now be invisible */
650 Logf("but1 visible=%d",IsWindowVisible(hButton[0]));
651 /* see if we can draw on them */
652 FillPattern(hButton[0]);
654 #ifdef SHOW_SUB
655 State=STATE_SHOW;
656 ShowWindow(hSubWnd,SW_SHOWNORMAL);
657 State=STATE_UPDATE;
658 UpdateWindow(hSubWnd);
659 FillPattern(hSubWnd);
660 // InvalidateRect(hMainWnd,NULL,TRUE);
661 Logf("but1 visible=%d",IsWindowVisible(hButton[0]));
662 #endif
664 #ifdef TEST_DIALOG
665 State=STATE_DIALOG;
666 DialogBox(hInst,MAKEINTRESOURCE(1),hMainWnd,(FARPROC)TestDialogProc);
667 #endif
668 #ifdef TEST_COMMCTL
670 DWORD arr[16];
671 CHOOSECOLOR cc={sizeof(cc),0,hInst,0,arr,0};
672 ChooseColor(&cc);
674 #endif
676 State=STATE_DIRECT;
677 while (GetMessage(&msg,0,0,0)) {
678 TranslateMessage(&msg);
679 State=STATE_DISPATCH;
680 DispatchMessage(&msg);
681 State=STATE_DIRECT;
683 return 0;