update for HEAD-2003091401
[reactos.git] / apps / tests / combo / combotst.c
1 /* ComboBox Control Test for ReactOS.
2
3 * This is a test program. Not made to be fast, small
4 * easy to mantain, or portable.
5
6 * I'm not erasing text because I don't want to use other functions from the API
7 * or make this more complex. Also Fonts are not heavily used.
8
9 * This source code is in the PUBLIC DOMAIN and has NO WARRANTY.
10 * by Waldo Alvarez CaƱizares <wac at ghost.matcom.uh.cu>, started July 11, 2003. */
11
12 //#define WIN32_LEAN_AND_MEAN
13 #include <windows.h>
14 #include "utils.h"
15
16 #define CONTROLCLASS  "COMBOBOX"  /* the class name */
17 #define CONTROLCLASSW L"COMBOBOX" /* the class name in unicode*/
18
19 #define WINDOWWIDTH 560
20 #define WINDOWHEIGHT 350
21
22 /* --- Command IDs of some buttons --- */
23 #define CREATEWINDOW_ID 106
24 #define CREATEWINDOWEX_ID 107
25 #define CREATEWINDOWW_ID 108
26 #define INITPAGE_ID 400
27 #define SECONDPAGE_ID 401
28 #define BACKFIRSTPAGE_ID 402
29
30 /* --- Position where the result text goes --- */
31 #define ResultX 0
32 #define ResultY 305
33
34 /* --- Position where the notify text goes --- */
35 #define NOTIFYX 390
36 #define NOTIFYY 285
37
38 /* --- The width of most buttons --- */
39 #define CHECKBUTWIDTH 190
40 #define SCROLLAMOUNT -15
41
42 /* Size of buffer to hold resulting strings from conversion
43 and returned by messages */
44 #define BUFFERLEN 80
45 char TextBuffer[BUFFERLEN]={'R','e','s','u','l','t',':',' '};
46
47 HWND g_hwnd = NULL;
48 HINSTANCE g_hInst = NULL;
49
50 int pos = 10;
51 int n = 0;
52 int yButPos = 10;
53 int xButPos = 0;
54
55 DWORD ComboStyle = 0;
56
57 /* --- Control coordinates --- */
58 #define CONTROLPOSX 390
59 #define CONTROLPOSY 10
60 DWORD ControlWidth = 160;
61 DWORD ControlHeight = 150;
62
63 static RECT  srect = {CONTROLPOSX,CONTROLPOSY,WINDOWWIDTH,WINDOWHEIGHT};
64
65 HWND hwndEdit = NULL;
66
67 RECT  rect;
68 DWORD StartP,EndP;
69 HWND hwnd; /* main window handle */
70
71 char AddString[] = "string added";
72
73 typedef void FunctionHandler(HWND,DWORD,WPARAM,LPARAM);
74 typedef FunctionHandler* LPFUNCTIONHANDLER;
75
76 PrintTextXY(char* Text,int x,int y,int len, RECT rect)
77     {
78     HDC hdc;
79     hdc = GetDC (g_hwnd);
80     SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT));
81
82     TextOut (hdc, x,y,Text,len);
83     ReleaseDC (g_hwnd, hdc);
84
85     ValidateRect (g_hwnd, &rect);
86     }
87
88 static
89 VOID
90 HandlePrintReturnHex(HWND handle,DWORD Msg,WPARAM wParam,LPARAM lParam)
91     {
92     LRESULT ret;
93     RECT rect;
94     ret = SendMessage(handle,Msg,wParam,lParam);
95     htoa((unsigned int)ret,&TextBuffer[8]);
96     GetWindowRect(g_hwnd,&rect);
97     PrintTextXY(TextBuffer,ResultX,ResultY,16,rect);
98     }
99
100
101 static
102 VOID
103 HandlePrintReturnStr(HWND handle,DWORD Msg,WPARAM wParam,LPARAM lParam)
104     {
105     LRESULT ret;
106     RECT rect;
107
108     TextBuffer[8] = (char)(BUFFERLEN - 8); /* Setting the max size to put chars in first byte */
109     ret = SendMessage(handle,Msg,wParam,lParam);
110     GetWindowRect(g_hwnd,&rect);
111     PrintTextXY(TextBuffer,ResultX,ResultY,8+(int)ret,rect);
112     }
113
114 static
115 VOID
116 HandlePrintRect(HWND handle,DWORD Msg,WPARAM wParam,LPARAM lParam)
117     {
118     RECT rect;
119     TextBuffer[8] = (char)(BUFFERLEN - 8); /* Setting the max size to put chars in first byte */
120     SendMessage(handle,Msg,wParam,lParam);
121
122     htoa(rect.top,&TextBuffer[8]);
123     TextBuffer[8+8] = ' ';
124     htoa(rect.bottom,&TextBuffer[8+8+1]);
125     TextBuffer[8+8+8+1] = ' ';
126     htoa(rect.left,&TextBuffer[8+8+8+1+1]);
127     TextBuffer[8+8+8+8+1+1] = ' ';
128     htoa(rect.right,&TextBuffer[8+8+8+8+1+1+1]);
129
130     GetWindowRect(g_hwnd,&rect);
131     PrintTextXY(TextBuffer,ResultX,ResultY,8+4*9-1,rect);
132     }
133
134 struct
135     {
136     char* Text;                 /* Text for the button */
137     DWORD MsgCode;              /* Message Code */
138     WPARAM wParam;              /* Well hope you can understand this */
139     LPARAM lParam;              /* ditto */
140     LPFUNCTIONHANDLER Handler;  /* Funtion called to handle the result of each message */
141     }
142 Msg[] =
143     {
144     "CB_ADDSTRING",CB_ADDSTRING,0,(LPARAM)&AddString,&HandlePrintReturnHex,
145         "CB_ADDSTRING - long",CB_ADDSTRING,0,(LPARAM)"very loooooooooong striiinnnnnnnnnggg",&HandlePrintReturnHex,
146         "CB_DELETESTRING",CB_DELETESTRING,2,0,&HandlePrintReturnHex,   /* remember to catch WM_DELETEITEM*/
147
148         /* What a message, why M$ decided to implement his thing ? */
149         "CB_DIR - drives",CB_DIR,DDL_DRIVES,
150         /* Hoping that most machines have this */
151         (LPARAM)"C:\\",
152         &HandlePrintReturnHex,
153
154         "CB_DIR - dirs",CB_DIR,DDL_DIRECTORY,(LPARAM)"C:\\*",&HandlePrintReturnHex,
155
156         "CB_DIR - files",CB_DIR,
157         DDL_ARCHIVE | DDL_EXCLUSIVE | DDL_HIDDEN | DDL_READONLY | DDL_READWRITE | DDL_SYSTEM,
158         (LPARAM)"C:\\*",&HandlePrintReturnHex,
159
160         /* Do not forget WM_COMPAREITEM */
161
162         "CB_FINDSTRING",CB_FINDSTRING,1,(LPARAM)"str",&HandlePrintReturnHex,
163         "CB_FINDSTRINGEXACT(-1)",CB_FINDSTRINGEXACT,-1,(LPARAM)&AddString,&HandlePrintReturnHex,
164         "CB_FINDSTRINGEXACT(2)",CB_FINDSTRINGEXACT,2,(LPARAM)&AddString,&HandlePrintReturnHex,
165
166         /* "CB_GETCOMBOBOXINFO",CB_GETCOMBOBOXINFO,0,0,&HandlePrintReturnHex, winXP & .net server remember to handle the struct  */
167
168         "CB_GETCOUNT",CB_GETCOUNT,0,0,&HandlePrintReturnHex,
169
170         "CB_GETCURSEL",CB_GETCURSEL,0,0,&HandlePrintReturnHex,
171
172         /* To implement "CB_GETEDITSEL - vars",CB_GETEDITSEL,,,&HandlePrintReturnHex, */
173
174         "CB_GETEXTENDEDUI",CB_GETEXTENDEDUI,0,0,&HandlePrintReturnHex,
175         "CB_GETHORIZONTALEXTENT",CB_GETHORIZONTALEXTENT,0,0,&HandlePrintReturnHex,
176
177
178
179         "CB_GETLBTEXT",CB_GETLBTEXT,1,(LPARAM)&TextBuffer[8],&HandlePrintReturnStr,
180         "CB_GETLBTEXTLEN",CB_GETLBTEXTLEN,1,0,&HandlePrintReturnHex,
181         "CB_GETLOCALE",CB_GETLOCALE,0,0,&HandlePrintReturnHex,
182
183         /* "CB_GETMINVISIBLE",CB_GETMINVISIBLE,0,0,&HandlePrintReturnHex, Included in Windows XP and Windows .NET Server. */
184
185         "CB_GETTOPINDEX",CB_GETTOPINDEX,0,0,&HandlePrintReturnHex,
186
187         "CB_INITSTORAGE",CB_INITSTORAGE,10,200,&HandlePrintReturnHex,
188         "CB_INSERTSTRING",CB_INSERTSTRING,2,(LPARAM)"inserted string",&HandlePrintReturnHex,
189
190         "CB_LIMITTEXT",CB_LIMITTEXT,10,0,&HandlePrintReturnHex,
191         "CB_RESETCONTENT",CB_RESETCONTENT ,0,0,&HandlePrintReturnHex,
192         "CB_SELECTSTRING",CB_SELECTSTRING,2,(LPARAM)"str",&HandlePrintReturnHex,
193         "CB_SETCURSEL",CB_SETCURSEL,1,0,&HandlePrintReturnHex,
194
195         "CB_SETDROPPEDWIDTH",CB_SETDROPPEDWIDTH,250,0,&HandlePrintReturnHex,
196
197         "CB_SETEXTENDEDUI - set",CB_SETEXTENDEDUI,TRUE,0,&HandlePrintReturnHex,
198         "CB_SETEXTENDEDUI - clear",CB_SETEXTENDEDUI,FALSE,0,&HandlePrintReturnHex,
199
200         /*
201         * win2k have a small bug with this ^ , if you press F4 while it is cleared,
202         * the combobox is using style cbs_dropdown
203         * and the pointer is over the edit box then the mouse pointer is not changed
204         * to an arrow
205         */
206
207         "CB_SETHORIZONTALEXTENT",CB_SETHORIZONTALEXTENT,500,0,&HandlePrintReturnHex,
208
209         "CB_GETITEMDATA",CB_GETITEMDATA,1,0,&HandlePrintReturnHex,
210         "CB_SETITEMDATA",CB_SETITEMDATA,1,0x791031,&HandlePrintReturnHex,
211
212         "CB_SETITEMHEIGHT",CB_SETITEMHEIGHT,-1,30,&HandlePrintReturnHex,
213         "CB_GETITEMHEIGHT",CB_GETITEMHEIGHT,2,0,&HandlePrintReturnHex,
214
215         /* "CB_SETMINVISIBLE",CB_SETMINVISIBLE,4,0,&HandlePrintReturnHex, Included in Windows XP and Windows .NET Server */
216
217         "CB_GETEDITSEL",CB_GETEDITSEL,(WPARAM)NULL,(LPARAM)NULL,&HandlePrintReturnHex,
218         "CB_SETEDITSEL",CB_SETEDITSEL,0,0x00020005,&HandlePrintReturnHex,
219         "CB_SETEDITSEL - clear",CB_SETEDITSEL,0,0xFFFFFFFF,&HandlePrintReturnHex,
220
221         "CB_SETTOPINDEX",CB_SETTOPINDEX,3,0,&HandlePrintReturnHex,
222
223         "CB_SHOWDROPDOWN - true",CB_SHOWDROPDOWN,TRUE,0,&HandlePrintReturnHex,
224         "CB_SHOWDROPDOWN - false",CB_SHOWDROPDOWN,FALSE,0,&HandlePrintReturnHex,
225
226         "CB_GETDROPPEDCONTROLRECT",CB_GETDROPPEDCONTROLRECT,0,(LPARAM)&rect,&HandlePrintRect,
227         "CB_GETDROPPEDSTATE",CB_GETDROPPEDSTATE,0,0,&HandlePrintReturnHex,
228         "CB_GETDROPPEDWIDTH",CB_GETDROPPEDWIDTH,0,0,&HandlePrintReturnHex,
229
230         "WM_PASTE",WM_PASTE,0,0,&HandlePrintReturnHex,
231     };
232
233 #define MAXMESSAGEBUTTONS 40
234
235 struct
236     {
237     char* Name;                 /* Text for the button */
238     DWORD Code;                 /* Style Code */
239     }
240 Styles[] = {
241     "WS_DISABLED",WS_DISABLED,
242         "CBS_AUTOHSCROLL",CBS_AUTOHSCROLL,
243         "CBS_DISABLENOSCROLL",CBS_DISABLENOSCROLL,
244         "CBS_DROPDOWN",CBS_DROPDOWN,
245         "CBS_DROPDOWNLIST",CBS_DROPDOWNLIST,
246         "CBS_HASSTRINGS",CBS_HASSTRINGS,
247         "CBS_LOWERCASE",CBS_LOWERCASE,
248         "CBS_NOINTEGRALHEIGHT",CBS_NOINTEGRALHEIGHT,
249         "CBS_OEMCONVERT",CBS_OEMCONVERT,
250         "CBS_OWNERDRAWFIXED",CBS_OWNERDRAWFIXED,
251         "CBS_OWNERDRAWVARIABLE",CBS_OWNERDRAWVARIABLE,
252         "CBS_SIMPLE",CBS_SIMPLE,
253         "CBS_SORT",CBS_SORT,
254         "CBS_UPPERCASE",CBS_UPPERCASE,
255         "CBS_DISABLENOSCROLL",CBS_DISABLENOSCROLL,
256         "WS_HSCROLL",WS_HSCROLL,
257         "WS_VSCROLL",WS_VSCROLL
258     };
259
260 /* The number of check buttons we have. 
261 * Maybe some calculations at compile time would be better
262 */
263
264 #define NUMBERCHECKS 17
265
266 #define NUMBERBUTTONS  NUMBERCHECKS + 7
267 HWND Buttons[NUMBERBUTTONS];
268 HWND MessageButtons[MAXMESSAGEBUTTONS];
269 HWND Back1But,Back2But;
270 HWND NextBut;
271
272 HWND
273 CreateCheckButton(const char* lpWindowName, DWORD xSize, DWORD id)
274     {
275     HWND h;
276     h  = CreateWindowEx(0,
277         "BUTTON",
278         lpWindowName,
279         WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
280         xButPos, /*  x  */
281         yButPos, /*  y  */
282         xSize,   /* nWidth  */
283         20,      /* nHeight */
284         g_hwnd,
285         (HMENU) id,
286         g_hInst,
287         NULL    
288         );
289     yButPos += 21;
290     return h;
291     }
292
293 HWND
294 CreatePushButton(const char* lpWindowName, DWORD xSize, DWORD id,DWORD Style)
295     {
296
297     HWND h = CreateWindow("BUTTON",
298         lpWindowName,
299         WS_CHILD | BS_PUSHBUTTON | Style,
300         xButPos, /* x */
301         yButPos, /* y */
302         xSize,   /* nWidth */
303         20,      /* nHeight */
304         g_hwnd,
305         (HMENU) id,
306         g_hInst,
307         NULL
308         );
309
310     yButPos += 21;
311     return h;
312     }
313
314 VOID
315 ReadNHide()
316     {
317     int i;
318     ComboStyle = 0;
319     for (i=0 ; i< NUMBERCHECKS ; i++)
320         {
321         if(BST_CHECKED == SendMessage(Buttons[i],BM_GETCHECK,0,0))
322             ComboStyle |= Styles[i].Code;
323         ShowWindow(Buttons[i],SW_HIDE);
324         }
325
326     for (; i< NUMBERBUTTONS ; i++)ShowWindow(Buttons[i],SW_HIDE);
327     for (i=0 ; i< 26 ; i++) ShowWindow(MessageButtons[i],SW_SHOW);
328
329     ShowWindow(Back1But,SW_SHOW);
330     ShowWindow(NextBut,SW_SHOW);
331     }
332
333 VOID
334 ForwardToSecondPage()
335     {
336     int i;
337     for (i=0;i<26;i++)ShowWindow(MessageButtons[i],SW_HIDE);
338     for(;i<MAXMESSAGEBUTTONS;i++)ShowWindow(MessageButtons[i],SW_SHOW);
339     ShowWindow(Back2But,SW_SHOW);
340
341     ShowWindow(Back1But,SW_HIDE);
342     ShowWindow(NextBut,SW_HIDE);
343     }
344
345 VOID
346 BackToFirstPage()
347     {
348     int i;
349     for (i=0;i<26;i++)ShowWindow(MessageButtons[i],SW_SHOW);
350     for(;i<MAXMESSAGEBUTTONS;i++)ShowWindow(MessageButtons[i],SW_HIDE);
351     ShowWindow(Back2But,SW_HIDE);
352     ShowWindow(Back1But,SW_SHOW);
353     ShowWindow(NextBut,SW_SHOW);
354     }
355
356 VOID
357 BackToInitialPage()
358     {
359     int i;
360     DestroyWindow(hwndEdit);
361     for (i=0 ; i< NUMBERBUTTONS ; i++) {ShowWindow(Buttons[i],SW_SHOW);}
362 for (i=0;i<26;i++)ShowWindow(MessageButtons[i],SW_HIDE);
363 ShowWindow(Back1But,SW_HIDE);
364 ShowWindow(NextBut,SW_HIDE);
365     }
366
367 LRESULT
368 CALLBACK
369 WndProc ( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
370     {   
371     int i;
372     switch ( msg )
373         {
374         case WM_CREATE:
375             g_hwnd = hwnd;
376
377             /* ---- Initial page ---- */
378
379             for (i = 0 ; i < 14 ; i++)
380                 Buttons[i] = CreateCheckButton(Styles[i].Name,CHECKBUTWIDTH,500+i);
381
382             xButPos += CHECKBUTWIDTH + 10;
383             yButPos = 10;
384
385             for (; i < NUMBERCHECKS ; i++)
386                 Buttons[i] = CreateCheckButton(Styles[i].Name,CHECKBUTWIDTH,500+i);
387
388             Buttons[i++] = CreatePushButton("Width +",70,100,WS_VISIBLE);
389             Buttons[i++] = CreatePushButton("Width -",70,101,WS_VISIBLE);
390
391             Buttons[i++] = CreatePushButton("Heigth +",70,102,WS_VISIBLE);
392             Buttons[i++] = CreatePushButton("Heigth -",70,103,WS_VISIBLE);
393
394             Buttons[i++] = CreatePushButton("CreateWindowA",CHECKBUTWIDTH,CREATEWINDOW_ID,WS_VISIBLE);
395             Buttons[i++] = CreatePushButton("CreateWindowExA",CHECKBUTWIDTH,CREATEWINDOWEX_ID,WS_VISIBLE);
396             Buttons[i++] = CreatePushButton("CreateWindowExW",CHECKBUTWIDTH,CREATEWINDOWW_ID,WS_VISIBLE);
397
398
399             /* ---- The 1st page of buttons ---- */
400
401             xButPos = 0;
402             yButPos = 10;
403
404             for (i = 0 ; i < 14 ; i++)
405                 MessageButtons[i] = CreatePushButton(Msg[i].Text,CHECKBUTWIDTH,600+i,0);
406
407             xButPos += CHECKBUTWIDTH + 10;
408             yButPos = 10;
409
410             for (; i < 26 ; i++)
411                 MessageButtons[i] = CreatePushButton(Msg[i].Text,CHECKBUTWIDTH,600+i,0);
412
413             Back1But = CreatePushButton("Back - destroys ComboBox",CHECKBUTWIDTH,INITPAGE_ID,0);
414             NextBut = CreatePushButton("Next",CHECKBUTWIDTH,SECONDPAGE_ID,0);
415
416             /* ---- The 2nd page of buttons ------*/
417
418             xButPos = 0;
419             yButPos = 10;
420
421             for (; i<40; i++)
422                 MessageButtons[i] = CreatePushButton(Msg[i].Text,CHECKBUTWIDTH,600+i,0);
423
424             xButPos += CHECKBUTWIDTH + 10;
425             yButPos = 10;
426
427             for (; i < MAXMESSAGEBUTTONS ; i++)
428                 MessageButtons[i] = CreatePushButton(Msg[i].Text,CHECKBUTWIDTH,600+i,0);
429
430             Back2But = CreatePushButton("Back",CHECKBUTWIDTH,BACKFIRSTPAGE_ID,0);
431
432             break;
433
434         case WM_COMMAND:
435             if (LOWORD(wParam) >= 600)
436                 {
437                 Msg[LOWORD(wParam)-600].Handler(hwndEdit,
438                     Msg[LOWORD(wParam)-600].MsgCode,
439                     Msg[LOWORD(wParam)-600].wParam,
440                     Msg[LOWORD(wParam)-600].lParam);
441                 break;
442                 }
443
444             switch(LOWORD(wParam)){
445
446         case 100:
447             ControlWidth += 10;
448             break;
449
450         case 101:
451             ControlWidth -= 10;
452             break;
453
454         case 102:
455             ControlHeight += 10;
456             break;
457
458         case 103:
459             ControlHeight -= 10;
460             break;
461
462         case INITPAGE_ID:
463             BackToInitialPage();
464             break;
465
466         case SECONDPAGE_ID:
467             ForwardToSecondPage();
468             break;
469
470         case BACKFIRSTPAGE_ID:
471             BackToFirstPage();
472             break;
473
474         case CREATEWINDOW_ID:
475             ReadNHide();
476             srect.top = CONTROLPOSY + ControlHeight;
477             hwndEdit = CreateWindow(CONTROLCLASS,
478                 NULL,
479                 ComboStyle | WS_CHILD | WS_VISIBLE,
480                 CONTROLPOSX,
481                 CONTROLPOSY,
482                 ControlWidth,
483                 ControlHeight,
484                 g_hwnd,
485                 NULL,
486                 g_hInst,
487                 NULL);
488             break;
489
490         case CREATEWINDOWEX_ID:
491             ReadNHide();
492             srect.top = CONTROLPOSY + ControlHeight;
493             hwndEdit = CreateWindowEx(WS_EX_CLIENTEDGE,
494                 CONTROLCLASS,
495                 NULL,
496                 ComboStyle | WS_CHILD | WS_VISIBLE ,
497                 CONTROLPOSX,
498                 CONTROLPOSY,
499                 ControlWidth,
500                 ControlHeight,
501                 g_hwnd,
502                 NULL,
503                 g_hInst,
504                 NULL);
505             break;
506
507         case CREATEWINDOWW_ID:
508             ReadNHide();
509             srect.top = CONTROLPOSY + ControlHeight;
510             hwndEdit = CreateWindowExW(WS_EX_CLIENTEDGE,
511                 CONTROLCLASSW,
512                 NULL,
513                 ComboStyle | WS_CHILD | WS_VISIBLE ,
514                 CONTROLPOSX,
515                 CONTROLPOSY,
516                 ControlWidth,
517                 ControlHeight,
518                 g_hwnd,
519                 NULL,
520                 g_hInst,
521                 NULL);
522             break;
523                 }
524
525         if (lParam == (LPARAM)hwndEdit)
526             switch(HIWORD(wParam))
527             {
528                 case CBN_DROPDOWN:
529                     ScrollWindow (hwnd, 0, SCROLLAMOUNT, &srect, &srect);
530                     PrintTextXY("CBN_DROPDOWN notification",NOTIFYX,NOTIFYY,25,srect);
531                     break;
532
533                 case CBN_CLOSEUP:
534                     ScrollWindow (hwnd, 0, SCROLLAMOUNT, &srect, &srect);
535                     PrintTextXY("CBN_CLOSEUP notification",NOTIFYX,NOTIFYY,24,srect);
536                     break;
537
538                 case CBN_DBLCLK:
539                     ScrollWindow (hwnd, 0, SCROLLAMOUNT, &srect, &srect);
540                     PrintTextXY("CBN_DBLCLK notification",NOTIFYX,NOTIFYY,23,srect);
541                     break;
542
543                 case CBN_EDITCHANGE:
544                     ScrollWindow (hwnd, 0, SCROLLAMOUNT, &srect, &srect);
545                     PrintTextXY("CBN_EDITCHANGE notification",NOTIFYX,NOTIFYY,27,srect);
546                     break;
547
548                 case CBN_ERRSPACE:
549                     ScrollWindow (hwnd, 0, SCROLLAMOUNT, &srect, &srect);
550                     PrintTextXY("CBN_ERRSPACE notification",NOTIFYX,NOTIFYY,25,srect);
551                     break;
552
553                 case CBN_KILLFOCUS:
554                     ScrollWindow (hwnd, 0, SCROLLAMOUNT, &srect, &srect);
555                     PrintTextXY("CBN_KILLFOCUS notification",NOTIFYX,NOTIFYY,26,srect);
556                     break;
557
558                 case CBN_EDITUPDATE:
559                     ScrollWindow (hwnd, 0, SCROLLAMOUNT, &srect, &srect);
560                     PrintTextXY("CBN_EDITUPDATE notification",NOTIFYX,NOTIFYY,27,srect);
561                     break;
562
563                 case CBN_SELCHANGE:
564                     ScrollWindow (hwnd, 0, SCROLLAMOUNT, &srect, &srect);
565                     PrintTextXY("CBN_SELCHANGE notification",NOTIFYX,NOTIFYY,26,srect);
566                     break;
567
568                 case CBN_SELENDCANCEL:
569                     ScrollWindow (hwnd, 0, SCROLLAMOUNT, &srect, &srect);
570                     PrintTextXY("CBN_SELENDCANCEL notification",NOTIFYX,NOTIFYY,29,srect);
571                     break;
572
573                 case CBN_SETFOCUS:
574                     ScrollWindow (hwnd, 0, SCROLLAMOUNT, &srect, &srect);
575                     PrintTextXY("CBN_SETFOCUS notification",NOTIFYX,NOTIFYY,25,srect);
576                     break;
577
578                 case CBN_SELENDOK:
579                     ScrollWindow (hwnd, 0, SCROLLAMOUNT, &srect, &srect);
580                     PrintTextXY("CBN_SELENDOK notification",NOTIFYX,NOTIFYY,25,srect);
581                     break;
582             }
583
584         return DefWindowProc ( hwnd, msg, wParam, lParam );
585
586         case WM_MEASUREITEM:
587             ScrollWindow (hwnd, 0, SCROLLAMOUNT, &srect, &srect);
588             PrintTextXY("WM_MEASUREITEM called",NOTIFYX,NOTIFYY,21,srect);
589             break;
590
591         case WM_COMPAREITEM:
592             ScrollWindow (hwnd, 0, SCROLLAMOUNT, &srect, &srect);
593             PrintTextXY("WM_COMPAREITEM called",NOTIFYX,NOTIFYY,21,srect);
594             break;
595
596         case WM_DRAWITEM:
597             ScrollWindow (hwnd, 0, SCROLLAMOUNT, &srect, &srect);
598             PrintTextXY("WM_DRAWITEM called",NOTIFYX,NOTIFYY,18,srect);
599             break;
600
601         case WM_SIZE :
602             return 0;
603
604         case WM_CLOSE:
605             DestroyWindow (g_hwnd);
606             return 0;
607
608         case WM_QUERYENDSESSION:
609             return 0;
610
611         case WM_DESTROY:
612             PostQuitMessage(0);
613             return 0;
614         }
615     return DefWindowProc ( hwnd, msg, wParam, lParam );
616     }
617
618
619 HWND
620 RegisterAndCreateWindow (HINSTANCE hInst,
621                          const char* className,
622                          const char* title)
623     {
624     WNDCLASSEX wc;
625
626
627     g_hInst = hInst;
628
629     wc.cbSize = sizeof (WNDCLASSEX);
630
631     wc.lpfnWndProc = WndProc;   /* window procedure */
632     wc.hInstance = hInst;       /* owner of the class */
633
634     wc.lpszClassName = className;
635     wc.hCursor = LoadCursor ( 0, IDC_ARROW );
636     wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
637     wc.style = CS_HREDRAW | CS_VREDRAW;
638     wc.cbClsExtra = 0;
639     wc.cbWndExtra = 0;
640     wc.hIcon = 0;
641     wc.hIconSm = 0;
642     wc.lpszMenuName = 0;
643
644     if ( !RegisterClassEx ( &wc ) )
645         return NULL;
646
647     hwnd = CreateWindowEx (
648         0,          /* dwStyleEx */
649         className,  /* class name */
650         title,      /* window title */
651
652         WS_OVERLAPPEDWINDOW, /* dwStyle */
653
654         1,            /* x */
655         1,            /* y */
656         WINDOWWIDTH,  /* width */
657         WINDOWHEIGHT, /* height */
658         NULL,         /* hwndParent */
659         NULL,         /* hMenu */
660         hInst,
661         0
662         );
663
664     if (!hwnd) return NULL;
665
666     ShowWindow (hwnd, SW_SHOW);
667     UpdateWindow (hwnd);
668
669     return hwnd;
670     }
671
672 int
673 WINAPI
674 WinMain ( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR cmdParam, int cmdShow )
675     {
676     char className [] = "ComboBox Control Test";
677     MSG msg;
678
679     RegisterAndCreateWindow ( hInst, className, "ComboBox Control Test" );
680
681     while (GetMessage (&msg, NULL, 0, 0))
682         {
683         TranslateMessage (&msg);
684         DispatchMessage (&msg);
685         }
686     return (int)msg.wParam;
687     }