- Minor API file update.
[wine.git] / libtest / guitest.c
blobfe76211fa011e98e952676ab5e23b02e8bae848d
1 /* Windows GUI Behaviour Tester
3 * Copyright 1999 Ove Kåven
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdarg.h>
23 #include <windows.h>
25 #include "guitest.rh"
27 /* checks to include */
28 #define LOGGING /* can be undefined under Wine and use -debugmsg +message instead */
29 #define MAIN_STYLE WS_OVERLAPPEDWINDOW|WS_HSCROLL
30 #define MAIN_EXSTYLE 0
31 #undef TEST_DESTROY_MAIN
32 #define SHOW_SUB
33 #undef TEST_DIALOG
34 #define RESIZE_DIALOG
35 #undef TEST_SUBDIALOG
36 #undef TEST_COMMCTL
38 /************************/
39 /*** GLOBAL VARIABLES ***/
40 /************************/
42 HINSTANCE hInst;
43 DWORD StartTime;
44 HWND hListBox,hMainWnd,hSubWnd;
45 HWND hButton[4]={0,0,0,0};
46 HWND hDialog=0,hGroup=0,hSubDlg=0;
47 WNDPROC wndButton[4],wndDialog,wndGroup,wndSubDlg;
48 BOOL Clicked=0,Ready=0;
49 int State=0,Rec=0;
50 #define STATE_CREATE 0
51 #define STATE_DESTROY 1
52 #define STATE_SHOW 2
53 #define STATE_UPDATE 3
54 #define STATE_DIALOG 4
55 #define STATE_TEST 5
56 #define STATE_DIRECT 6
57 #define STATE_DISPATCH 7
58 #define STATE_RECURS 8
59 char*StateName[]={
60 "Creat",
61 "Destr",
62 "Show ",
63 "Updat",
64 "Dialg",
65 "Test ",
66 "Call ",
67 "Disp ",
68 "RCall"
71 static char wclassname[] = "GUITestClass";
72 static char wcclassname[] = "GUITestChildClass";
73 static char winname[] = "GUITest";
75 /**************************/
76 /*** LOGGING FACILITIES ***/
77 /**************************/
79 struct MSGNAMES {
80 int msg;
81 char*name;
82 } MsgNames[]={
83 #define MSG(x) {x,#x},
84 #define MSG2(x,y) {y,#x},
85 #define ENDMSG {0}
87 /* we get these in CreateWindow */
88 MSG(WM_GETMINMAXINFO)
89 MSG(WM_NCCREATE)
90 MSG(WM_NCCALCSIZE)
91 MSG(WM_CREATE)
92 MSG(WM_PARENTNOTIFY)
94 /* we get these in ShowWindow */
95 MSG(WM_SHOWWINDOW)
96 MSG(WM_WINDOWPOSCHANGING)
97 MSG(WM_QUERYNEWPALETTE)
98 MSG(WM_ACTIVATEAPP)
99 MSG(WM_NCACTIVATE)
100 MSG(WM_GETTEXT)
101 MSG(WM_ACTIVATE)
102 MSG(WM_SETFOCUS)
103 MSG(WM_NCPAINT)
104 MSG(WM_ERASEBKGND)
105 MSG(WM_WINDOWPOSCHANGED)
106 MSG(WM_SIZE)
107 MSG(WM_MOVE)
109 /* we get these in DestroyWindow */
110 MSG(WM_KILLFOCUS)
111 MSG(WM_DESTROY)
112 MSG(WM_NCDESTROY)
114 /* we get these directly sent */
115 MSG(WM_NCHITTEST)
116 MSG(WM_SETCURSOR)
117 MSG(WM_MOUSEACTIVATE)
118 MSG(WM_CHILDACTIVATE)
119 MSG(WM_COMMAND)
120 MSG(WM_SYSCOMMAND)
122 /* posted events */
123 MSG(WM_MOUSEMOVE)
124 MSG(WM_NCMOUSEMOVE)
125 MSG(WM_PAINT)
126 MSG(WM_LBUTTONDOWN)
127 MSG(WM_LBUTTONUP)
128 MSG(WM_LBUTTONDBLCLK)
129 MSG(WM_NCLBUTTONDOWN)
130 MSG(WM_NCLBUTTONUP)
131 MSG(WM_NCLBUTTONDBLCLK)
133 MSG(WM_KEYDOWN)
134 MSG(WM_KEYUP)
135 MSG(WM_CHAR)
137 #ifdef WIN32
138 MSG(WM_CTLCOLORBTN)
139 MSG(WM_CTLCOLORDLG)
140 MSG(WM_CTLCOLORSTATIC)
141 #else
142 MSG(WM_CTLCOLOR)
143 #endif
145 /* moving and sizing */
146 MSG2(WM_ENTERSIZEMOVE,0x0231)
147 MSG2(WM_EXITSIZEMOVE,0x0232)
148 #ifdef WIN32
149 MSG(WM_SIZING)
150 #endif
152 /* menus/dialog boxes */
153 MSG(WM_CANCELMODE)
154 MSG(WM_ENABLE)
155 MSG(WM_SETFONT)
156 MSG(WM_INITDIALOG)
157 MSG(WM_GETDLGCODE)
158 MSG(WM_ENTERIDLE)
160 /* scroll bars */
161 MSG(WM_HSCROLL)
162 MSG(WM_VSCROLL)
164 /* getting these from Wine but not from Windows */
165 MSG2(WM_SETVISIBLE,0x0009) /* unheard of in BC++ 4.52 */
166 #ifdef WIN32
167 MSG(WM_CAPTURECHANGED)
168 #endif
170 ENDMSG};
172 struct MSGNAMES ButMsgs[]={
173 MSG(BM_SETSTATE)
174 MSG(BM_SETSTYLE)
176 ENDMSG};
178 char*MsgName(UINT msg,HWND hWnd)
180 int i;
181 static char buffer[64],wclass[64];
182 GetClassName(hWnd,wclass,sizeof(wclass));
184 #define MSGSEARCH(msgs) { \
185 for (i=0; msgs[i].name&&msgs[i].msg!=msg; i++); \
186 if (msgs[i].name) return msgs[i].name; \
189 if (!stricmp(wclass,"Button")) MSGSEARCH(ButMsgs);
190 MSGSEARCH(MsgNames);
191 /* WM_USER */
192 if (msg>=WM_USER) {
193 sprintf(buffer,"WM_USER+%04x{%s}",msg-WM_USER,wclass);
194 return buffer;
196 /* message not found */
197 sprintf(buffer,"%04x{%s}",msg,wclass);
198 return buffer;
201 char*WndName(HWND hWnd,int state)
203 static char buffer[16];
204 if (!hWnd) return "0000";
205 if (hWnd==hMainWnd || (state==STATE_CREATE && !hMainWnd)) return "main";
206 if (hWnd==hSubWnd || (state==STATE_CREATE && !hSubWnd)) return "chld";
207 if (hWnd==hDialog || (state==STATE_DIALOG && !hDialog)) return "tdlg";
208 if (hWnd==hGroup) return "tgrp";
209 if (hWnd==hButton[0]) return "but1";
210 if (hWnd==hButton[1]) return "but2";
211 if (hWnd==hButton[2]) return "but3";
212 if (hWnd==hButton[3]) return "but4";
213 if (hWnd==hSubDlg || (state==STATE_CREATE && !hSubDlg)) return "sdlg";
214 if (hDialog) {
215 int id=GetDlgCtrlID(hWnd);
216 if (id) {
217 sprintf(buffer,"dlgitem(%d)",id);
218 return buffer;
221 sprintf(buffer,"%04x",hWnd);
222 return buffer;
225 void Log(const char*fmt)
227 #ifdef LOGGING
228 if (!Clicked) SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)fmt);
229 #endif
232 void Logf(const char*fmt,...)
234 va_list par;
235 static char buffer[256];
237 va_start(par,fmt);
238 vsprintf(buffer,fmt,par);
239 va_end(par);
240 Log(buffer);
243 void LogChildOrder(HWND hWnd)
245 HWND hWndChild = GetWindow(hWnd,GW_CHILD);
246 static char buffer[256];
248 strcpy(buffer,"child list:");
249 while (hWndChild) {
250 strcat(strcat(buffer," "),WndName(hWndChild,State));
251 hWndChild=GetWindow(hWndChild,GW_HWNDNEXT);
253 Log(buffer);
256 void LogMessage(int state,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,char*name)
258 static char buffer[256];
259 DWORD tick=GetTickCount()-StartTime;
260 char*msgname=MsgName(msg,hWnd);
261 if (!name) name=WndName(hWnd,state);
262 switch (msg) {
263 case WM_SETFOCUS:
264 case WM_KILLFOCUS:
265 case WM_SETCURSOR:
266 Logf("%04d[%s(%d):%s]%s(%s,%08x)",tick,StateName[state],Rec,
267 name,msgname,WndName((HWND)wParam,State),lParam);
268 break;
269 #ifdef WIN32
270 case WM_ENTERIDLE:
271 case WM_CTLCOLORBTN:
272 case WM_CTLCOLORDLG:
273 Logf("%04d[%s(%d):%s]%s(%08x,%s)",tick,StateName[state],Rec,
274 name,msgname,wParam,WndName((HWND)lParam,State));
275 break;
276 #else
277 case WM_ENTERIDLE:
278 case WM_CTLCOLOR:
279 Logf("%04d[%s(%d):%s]%s(%08x,%04x:%s)",tick,StateName[state],Rec,
280 name,msgname,wParam,HIWORD(lParam),WndName((HWND)LOWORD(lParam),State));
281 break;
282 #endif
283 case WM_WINDOWPOSCHANGING:
284 case WM_WINDOWPOSCHANGED:
286 WINDOWPOS*pos=(WINDOWPOS*)lParam;
287 #ifdef WIN32
288 Logf("%04d[%s(%d):%s]%s(%08x,%p)",tick,StateName[state],Rec,
289 name,msgname,wParam,pos);
290 #else
291 Logf("%04d[%s(%d):%s]%s(%04x,%p)",tick,StateName[state],Rec,
292 name,msgname,wParam,pos);
293 #endif
294 strcpy(buffer,"FLAGS:");
295 if (pos->flags&SWP_DRAWFRAME) strcat(buffer," DRAWFRAME");
296 if (pos->flags&SWP_HIDEWINDOW) strcat(buffer," HIDEWINDOW");
297 if (pos->flags&SWP_NOACTIVATE) strcat(buffer," NOACTIVATE");
298 if (pos->flags&SWP_NOCOPYBITS) strcat(buffer," NOCOPYBITS");
299 if (pos->flags&SWP_NOMOVE) strcat(buffer," NOMOVE");
300 if (pos->flags&SWP_NOOWNERZORDER) strcat(buffer," NOOWNERZORDER");
301 if (pos->flags&SWP_NOSIZE) strcat(buffer," NOSIZE");
302 if (pos->flags&SWP_NOREDRAW) strcat(buffer," NOREDRAW");
303 if (pos->flags&SWP_NOZORDER) strcat(buffer," NOZORDER");
304 if (pos->flags&SWP_SHOWWINDOW) strcat(buffer," SHOWWINDOW");
305 Log(buffer);
307 break;
308 case WM_SYSCOMMAND:
310 char*cmd=NULL;
311 switch (wParam&0xFFF0) {
312 #define CASE(x) case SC_##x: cmd=#x; break;
313 CASE(CLOSE)
314 CASE(DEFAULT)
315 CASE(HOTKEY)
316 CASE(HSCROLL)
317 CASE(KEYMENU)
318 CASE(MAXIMIZE)
319 CASE(MINIMIZE)
320 CASE(MOUSEMENU)
321 CASE(MOVE)
322 CASE(NEXTWINDOW)
323 CASE(PREVWINDOW)
324 CASE(RESTORE)
325 CASE(SCREENSAVE)
326 CASE(SIZE)
327 CASE(TASKLIST)
328 CASE(VSCROLL)
329 #undef CASE
331 if (cmd) {
332 Logf("%04d[%s(%d):%s]%s(%s+%x,%08x)",tick,StateName[state],Rec,
333 name,msgname,cmd,wParam&0xF,lParam);
334 } else goto GENERIC_MSG;
336 break;
337 case WM_HSCROLL:
338 case WM_VSCROLL:
340 char*cmd=NULL;
341 switch (LOWORD(wParam)) {
342 #define CASE(x) case SB_##x: cmd=#x; break;
343 #define CASE2(h,v) case SB_##h: if (msg==WM_HSCROLL) cmd=#h; else cmd=#v; break;
344 CASE(BOTTOM)
345 CASE(ENDSCROLL)
346 CASE2(LINELEFT,LINEUP)
347 CASE2(LINERIGHT,LINEDOWN)
348 CASE2(PAGELEFT,PAGEUP)
349 CASE2(PAGERIGHT,PAGEDOWN)
350 CASE(THUMBPOSITION)
351 CASE(THUMBTRACK)
352 CASE(TOP)
353 #undef CASE
355 if (cmd) {
356 #ifdef WIN32
357 Logf("%04d[%s(%d):%s]%s(%s,%04x,%s)",tick,StateName[state],Rec,
358 name,msgname,cmd,HIWORD(wParam),WndName((HWND)lParam,State));
359 #else
360 Logf("%04d[%s(%d):%s]%s(%04x,%04x,%s)",tick,StateName[state],Rec,
361 name,msgname,cmd,LOWORD(lParam),WndName((HWND)HIWORD(lParam),State));
362 #endif
363 } else goto GENERIC_MSG;
365 break;
366 default:
367 GENERIC_MSG:
368 #ifdef WIN32
369 Logf("%04d[%s(%d):%s]%s(%08x,%08x)",tick,StateName[state],Rec,
370 name,msgname,wParam,lParam);
371 #else
372 Logf("%04d[%s(%d):%s]%s(%04x,%08x)",tick,StateName[state],Rec,
373 name,msgname,wParam,lParam);
374 #endif
378 /***************************/
379 /*** GRAPHICS FACILITIES ***/
380 /***************************/
382 void Paint(HWND hWnd)
384 HDC dc;
385 PAINTSTRUCT ps;
386 dc=BeginPaint(hWnd,&ps);
387 EndPaint(hWnd,&ps);
390 void FillPattern(HWND hWnd,HDC pdc)
392 HDC dc=pdc?pdc:GetDC(hWnd);
393 HBRUSH oldbrush;
394 RECT rect;
395 if (!dc) {
396 Logf("failed to acquire DC for window %s",WndName(hWnd,State));
397 return;
398 } else {
399 Logf("acquired DC for %s window %s, painting",
400 IsWindowVisible(hWnd)?"visible":"invisible",WndName(hWnd,State));
402 GetClientRect(hWnd,&rect);
403 oldbrush=SelectObject(dc,GetStockObject(LTGRAY_BRUSH));
404 PatBlt(dc,0,0,rect.right,rect.bottom,PATCOPY);
405 SelectObject(dc,oldbrush);
406 if (!pdc) ReleaseDC(hWnd,dc);
409 void PaintPattern(HWND hWnd)
411 HDC dc;
412 PAINTSTRUCT ps;
413 dc=BeginPaint(hWnd,&ps);
414 FillPattern(hWnd,dc);
415 EndPaint(hWnd,&ps);
418 /*************************/
419 /*** WINDOW PROCEDURES ***/
420 /*************************/
422 /* MAIN WINDOW */
423 LRESULT FAR CALLBACK _export MainWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
425 LRESULT lResult=0;
426 RECT rect;
427 int OldState=State;
429 State=STATE_RECURS; Rec++;
430 if (!Clicked) LogMessage(OldState,hWnd,msg,wParam,lParam,NULL);
431 switch (msg) {
432 case WM_NCHITTEST:
433 lResult=DefWindowProc(hWnd,msg,wParam,lParam);
434 break;
435 case WM_LBUTTONDOWN:
436 case WM_CHAR:
437 if (!Clicked) {
438 SetParent(hListBox,hWnd);
439 GetClientRect(hWnd,&rect);
440 MoveWindow(hListBox,0,0,rect.right,rect.bottom,TRUE);
441 ShowWindow(hListBox,SW_SHOW);
442 SetFocus(hListBox);
443 Clicked=TRUE;
445 break;
446 case WM_SIZE:
447 GetClientRect(hWnd,&rect);
448 if (Clicked) {
449 MoveWindow(hListBox,0,0,rect.right,rect.bottom,TRUE);
451 MoveWindow(hSubWnd,0,rect.bottom/2,rect.right,rect.bottom-(rect.bottom/2),TRUE);
452 break;
453 case WM_PAINT:
454 Paint(hWnd);
455 break;
456 case WM_DESTROY:
457 PostQuitMessage(0);
458 break;
459 default:
460 lResult=DefWindowProc(hWnd,msg,wParam,lParam);
462 State=OldState; Rec--;
463 return lResult;
466 /* CHILD WINDOW */
467 LRESULT FAR CALLBACK _export SubWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
469 LRESULT lResult=0;
470 RECT rect;
471 int OldState=State;
473 State=STATE_RECURS; Rec++;
474 if (!Clicked) LogMessage(OldState,hWnd,msg,wParam,lParam,NULL);
475 switch (msg) {
476 case WM_PAINT:
477 Paint(hWnd);
478 break;
479 default:
480 lResult=DefWindowProc(hWnd,msg,wParam,lParam);
482 State=OldState; Rec--;
483 return lResult;
486 BOOL FAR CALLBACK _export SubDialogProc(HWND hWndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
488 /* SUBCLASSED CONTROLS */
489 LRESULT FAR CALLBACK _export SubClassWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
491 LRESULT lResult=0;
492 RECT rect;
493 int OldState=State;
494 int But=-1;
496 if (hWnd==hButton[0]) But=0; else
497 if (hWnd==hButton[1]) But=1; else
498 if (hWnd==hButton[2]) But=2; else
499 if (hWnd==hButton[3]) But=3;
501 State=STATE_RECURS; Rec++;
502 if (!Clicked) {
503 LogMessage(OldState,hWnd,msg,wParam,lParam,NULL);
504 if (But!=-1) {
505 lResult=CallWindowProc((FARPROC)wndButton[But],hWnd,msg,wParam,lParam);
506 if (msg==WM_LBUTTONUP) {
507 LogChildOrder(GetParent(hWnd));
510 else if (hWnd==hDialog) {
511 lResult=CallWindowProc((FARPROC)wndDialog,hWnd,msg,wParam,lParam);
513 else if (hWnd==hSubDlg) {
514 lResult=CallWindowProc((FARPROC)wndSubDlg,hWnd,msg,wParam,lParam);
516 else if (hWnd==hGroup) {
517 lResult=CallWindowProc((FARPROC)wndGroup,hWnd,msg,wParam,lParam);
518 if (msg==WM_SETFOCUS) {
519 /* create subdialog */
520 if (hSubDlg) {
521 #if 0
522 SetRect(&rect,0,0,1,1);
523 InvalidateRect(hWnd,&rect,FALSE);
524 #endif
525 } else {
526 #ifdef TEST_SUBDIALOG
527 State=STATE_CREATE;
528 hSubDlg=CreateDialog(hInst,MAKEINTRESOURCE(2),hWnd,(FARPROC)SubDialogProc);
529 State=STATE_RECURS;
530 #else
531 #ifdef RESIZE_DIALOG
532 GetWindowRect(GetParent(hWnd),&rect);
533 rect.right++;
534 SetWindowPos(GetParent(hWnd),0,0,0,
535 rect.right-rect.left,rect.bottom-rect.top,
536 SWP_NOMOVE|SWP_NOZORDER);
537 #endif
538 #endif
543 State=OldState; Rec--;
544 return lResult;
547 /* MAIN DIALOG PROCEDURE */
548 BOOL FAR CALLBACK _export TestDialogProc(HWND hWndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
550 BOOL bResult=0;
551 RECT rect;
552 int OldState=State;
553 int But=-1;
555 State=STATE_RECURS; Rec++;
556 if (!Clicked) LogMessage(OldState,hWndDlg,msg,wParam,lParam,"dlgp");
557 switch (msg) {
558 case WM_INITDIALOG:
559 hDialog = hWndDlg;
560 /* subclass dialog window proc */
561 wndDialog = (WNDPROC)SetWindowLong(hDialog,GWL_WNDPROC,(LONG)SubClassWindowProc);
562 Logf("dialog visible=%s",IsWindowVisible(hWndDlg)?"TRUE":"FALSE");
563 /* subclass OK button */
564 hButton[3] = GetDlgItem(hWndDlg,IDOK);
565 wndButton[3] = (WNDPROC)SetWindowLong(hButton[3],GWL_WNDPROC,(LONG)SubClassWindowProc);
566 /* subclass group box */
567 hGroup = GetDlgItem(hWndDlg,IDC_GROUPBOX1);
568 wndGroup = (WNDPROC)SetWindowLong(hGroup,GWL_WNDPROC,(LONG)SubClassWindowProc);
570 #ifdef RESIZE_DIALOG
571 GetWindowRect(hWndDlg,&rect);
572 rect.right--;
573 SetWindowPos(hWndDlg,0,0,0,
574 rect.right-rect.left,rect.bottom-rect.top,
575 SWP_NOMOVE|SWP_NOZORDER);
576 // ShowWindow(GetDlgItem(hWndDlg,IDCANCEL),SW_HIDE);
577 #endif
579 bResult=TRUE; /* we don't do SetFocus */
580 break;
581 case WM_PAINT:
582 PaintPattern(hWndDlg);
583 bResult=TRUE;
584 break;
585 case WM_COMMAND:
586 EndDialog(hWndDlg,LOWORD(wParam));
587 bResult=TRUE;
588 break;
589 case WM_CLOSE:
590 EndDialog(hWndDlg,IDCANCEL);
591 bResult=TRUE;
592 break;
593 case WM_NCDESTROY:
594 hDialog = 0;
595 break;
597 State=OldState; Rec--;
598 return bResult;
601 /* SUBDIALOG PROCEDURE */
602 BOOL FAR CALLBACK _export SubDialogProc(HWND hWndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
604 BOOL bResult=0;
605 RECT rect;
606 int OldState=State;
607 int But=-1;
609 State=STATE_RECURS; Rec++;
610 if (!Clicked) LogMessage(OldState,hWndDlg,msg,wParam,lParam,NULL);
611 switch (msg) {
612 case WM_INITDIALOG:
613 hSubDlg = hWndDlg;
614 /* subclass dialog window proc */
615 wndSubDlg = (WNDPROC)SetWindowLong(hDialog,GWL_WNDPROC,(LONG)SubClassWindowProc);
617 bResult=TRUE; /* we don't do SetFocus */
618 break;
619 case WM_NCDESTROY:
620 hSubDlg = 0;
621 break;
623 State=OldState; Rec--;
624 return bResult;
627 /********************/
628 /*** MAIN PROGRAM ***/
629 /********************/
631 BOOL AppInit(void)
633 WNDCLASS wclass;
635 wclass.style = CS_HREDRAW|CS_VREDRAW;
636 wclass.lpfnWndProc = MainWindowProc;
637 wclass.cbClsExtra = 0;
638 wclass.cbWndExtra = 0;
639 wclass.hInstance = hInst;
640 wclass.hIcon = LoadIcon(hInst,MAKEINTRESOURCE(1));
641 wclass.hCursor = LoadCursor(0,IDC_ARROW);
642 wclass.hbrBackground = GetStockObject(WHITE_BRUSH);
643 wclass.lpszMenuName = NULL;
644 wclass.lpszClassName = wclassname;
645 if (!RegisterClass(&wclass)) return FALSE;
646 wclass.lpfnWndProc = SubWindowProc;
647 wclass.lpszClassName = wcclassname;
648 if (!RegisterClass(&wclass)) return FALSE;
649 return TRUE;
652 int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
653 LPSTR lpszCmdLine, int nCmdShow)
655 MSG msg;
656 RECT rect;
658 hInst = hInstance;
659 if (!hPrevInstance)
660 if (!AppInit())
661 return 0;
663 StartTime=GetTickCount();
664 hListBox = CreateWindow("LISTBOX","Messages",WS_BORDER|WS_VSCROLL|WS_CHILD|
665 LBS_HASSTRINGS|LBS_NOTIFY|LBS_WANTKEYBOARDINPUT,
666 0,0,0,0,GetDesktopWindow(),0,hInst,0);
667 if (!hListBox) {
668 MessageBox(0,"Could not create list box","Error",MB_OK);
671 State=STATE_CREATE;
672 hMainWnd = CreateWindowEx(MAIN_EXSTYLE,wclassname,winname,MAIN_STYLE,
673 CW_USEDEFAULT,0,400,300,0,0,hInst,0);
674 if (!hMainWnd) return 0;
675 State=STATE_SHOW;
676 ShowWindow(hMainWnd,nCmdShow);
677 #ifdef TEST_DESTROY_MAIN
678 State=STATE_DESTROY;
679 DestroyWindow(hMainWnd);
680 State=STATE_DIRECT;
681 while (GetMessage(&msg,0,0,0)) {
682 TranslateMessage(&msg);
683 State=STATE_DISPATCH;
684 DispatchMessage(&msg);
685 State=STATE_DIRECT;
687 State=STATE_CREATE;
688 hMainWnd = CreateWindowEx(MAIN_EXSTYLE,wclassname,winname,MAIN_STYLE,
689 CW_USEDEFAULT,0,400,300,0,0,hInst,0);
690 if (!hMainWnd) return 0;
691 State=STATE_SHOW;
692 ShowWindow(hMainWnd,nCmdShow);
693 #endif
694 /* update, so no WM_PAINTs are pending */
695 State=STATE_UPDATE;
696 // UpdateWindow(hMainWnd);
697 Ready=TRUE;
698 /* fill client area with a pattern */
699 FillPattern(hMainWnd,0);
700 /* create subwindow */
701 State=STATE_CREATE;
702 GetClientRect(hMainWnd,&rect);
703 hSubWnd = CreateWindow(wcclassname,winname,WS_CHILD|WS_BORDER|WS_CLIPSIBLINGS,
704 0,rect.bottom/2,rect.right,rect.bottom-(rect.bottom/2),hMainWnd,0,hInst,0);
705 if (!hSubWnd) return 0;
706 /* create buttons */
707 hButton[0] = CreateWindow("BUTTON","1",WS_CHILD|WS_CLIPSIBLINGS|WS_VISIBLE,
708 8,8,48,20,hMainWnd,0,hInst,0);
709 hButton[1] = CreateWindow("BUTTON","2",WS_CHILD|WS_CLIPSIBLINGS|WS_VISIBLE,
710 32,12,48,20,hMainWnd,0,hInst,0);
711 hButton[2] = CreateWindow("BUTTON","3",WS_CHILD|WS_CLIPSIBLINGS|WS_VISIBLE,
712 56,16,48,20,hMainWnd,0,hInst,0);
713 /* subclass them */
714 wndButton[0] = (WNDPROC)SetWindowLong(hButton[0],GWL_WNDPROC,(LONG)SubClassWindowProc);
715 wndButton[1] = (WNDPROC)SetWindowLong(hButton[1],GWL_WNDPROC,(LONG)SubClassWindowProc);
716 wndButton[2] = (WNDPROC)SetWindowLong(hButton[2],GWL_WNDPROC,(LONG)SubClassWindowProc);
717 /* show them */
718 State=STATE_UPDATE;
719 UpdateWindow(hButton[0]);
720 LogChildOrder(hMainWnd);
721 Logf("but1 visible=%d",IsWindowVisible(hButton[0]));
723 /* now reparent the button to our (invisible) subwindow */
724 State=STATE_TEST;
725 /* in different order, seeing who gets topmost */
726 SetParent(hButton[0],hSubWnd);
727 SetParent(hButton[2],hSubWnd);
728 SetParent(hButton[1],hSubWnd);
729 LogChildOrder(hSubWnd);
730 /* the button should now be invisible */
731 Logf("but1 visible=%d",IsWindowVisible(hButton[0]));
732 /* see if we can draw on them */
733 FillPattern(hButton[0],0);
735 #ifdef SHOW_SUB
736 State=STATE_SHOW;
737 ShowWindow(hSubWnd,SW_SHOWNORMAL);
738 State=STATE_UPDATE;
739 UpdateWindow(hSubWnd);
740 FillPattern(hSubWnd,0);
741 // InvalidateRect(hMainWnd,NULL,TRUE);
742 Logf("but1 visible=%d",IsWindowVisible(hButton[0]));
743 #endif
745 #ifdef TEST_DIALOG
746 State=STATE_DIALOG;
747 DialogBox(hInst,MAKEINTRESOURCE(1),hMainWnd,(FARPROC)TestDialogProc);
748 #endif
749 #ifdef TEST_COMMCTL
751 DWORD arr[16];
752 CHOOSECOLOR cc={sizeof(cc),0,hInst,0,arr,0};
753 ChooseColor(&cc);
755 #endif
757 State=STATE_DIRECT;
758 while (GetMessage(&msg,0,0,0)) {
759 TranslateMessage(&msg);
760 State=STATE_DISPATCH;
761 DispatchMessage(&msg);
762 State=STATE_DIRECT;
764 return 0;