Release 940614
[wine] / controls / menu.c
1 /*
2  *        Menus functions
3  */
4 static char RCSId[] = "$Id$";
5 static char Copyright[] = "Copyright  Martin Ayotte, 1993";
6
7 /*
8 #define DEBUG_MENU
9 */
10
11 #include <stdlib.h>
12 #include <stdio.h>
13 #include "windows.h"
14 #include "sysmetrics.h"
15 #include "prototypes.h"
16 #include "menu.h"
17 #include "user.h"
18 #include "heap.h"
19 #include "win.h"
20
21 #define SC_ABOUTWINE            SC_SCREENSAVE+1
22 #define SC_SYSMENU                      SC_SCREENSAVE+2
23 #define SC_ABOUTWINEDLG         SC_SCREENSAVE+3
24
25 extern HINSTANCE hSysRes;
26 HMENU   hSysMenu = 0;
27 HBITMAP hStdCheck = 0;
28 HBITMAP hStdMnArrow = 0;
29 static BOOL     MenuHasFocus = FALSE;
30
31 LPPOPUPMENU PopupMenuGetStorageHeader(HWND hwnd);
32 LPPOPUPMENU PopupMenuGetWindowAndStorage(HWND hwnd, WND **wndPtr);
33 void StdDrawMenuBar(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop, 
34                     BOOL suppress_draw);
35 BOOL MenuButtonDown(HWND hWnd, LPPOPUPMENU lppop, int x, int y);
36 void MenuButtonUp(HWND hWnd, LPPOPUPMENU lppop, int x, int y);
37 void MenuMouseMove(HWND hWnd, LPPOPUPMENU lppop, WORD wParam, int x, int y);
38 void StdDrawPopupMenu(HWND hwnd);
39 void ResetHiliteFlags(LPPOPUPMENU lppop);
40 BOOL ExecFocusedMenuItem(HWND hWnd, LPPOPUPMENU lppop);
41 void MenuItemSelect(HWND hWnd, LPPOPUPMENU lppop, WORD wIndex);
42 LPMENUITEM MenuFindItem(LPPOPUPMENU lppop, int x, int y, WORD *lpRet);
43 LPMENUITEM MenuFindItemBySelKey(LPPOPUPMENU lppop, WORD key, WORD *lpRet);
44 BOOL ActivateMenuBarFocus(HWND hWnd);
45 BOOL MenuFocusLoop(HWND hWnd, LPPOPUPMENU lpmenu);
46 void PopupMenuCalcSize(HWND hwnd);
47 void MenuBarCalcSize(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop);
48 LPMENUITEM FindMenuItem(HMENU hMenu, WORD nPos, WORD wFlags);
49 LPMENUITEM GetMenuItemPtr(LPPOPUPMENU menu, WORD nPos);
50 WORD GetSelectionKey(LPSTR str);
51 LPSTR GetShortCutString(LPSTR str);
52 WORD GetShortCutPos(LPSTR str);
53 BOOL HideAllSubPopupMenu(LPPOPUPMENU menu);
54 void InitStdBitmaps();
55 HMENU CopySysMenu();
56 WORD * ParseMenuResource(WORD *first_item, int level, HMENU hMenu);
57 void SetMenuLogicalParent(HMENU hMenu, HWND hWnd);
58
59 BOOL FAR PASCAL AboutWine_Proc(HWND hDlg, WORD msg, WORD wParam, LONG lParam);
60
61 /***********************************************************************
62  *           PopupMenuWndProc
63  */
64 LONG PopupMenuWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam )
65 {    
66         CREATESTRUCT *createStruct;
67         WORD    wRet;
68         short   x, y;
69         WND     *wndPtr;
70         LPPOPUPMENU lppop, lppop2;
71         LPMENUITEM      lpitem, lpitem2;
72         HMENU   hSubMenu;
73         RECT    rect;
74         HDC             hDC;
75         PAINTSTRUCT ps;
76         switch(message) {
77         case WM_CREATE:
78 #ifdef DEBUG_MENU
79                 printf("PopupMenu WM_CREATE lParam=%08X !\n", lParam);
80 #endif
81                 createStruct = (CREATESTRUCT *)lParam;
82                 lppop = (LPPOPUPMENU)createStruct->lpCreateParams;
83                 if (lppop == NULL) break;
84                 wndPtr = WIN_FindWndPtr(hwnd);
85                 *((LPPOPUPMENU *)&wndPtr->wExtra[1]) = lppop;
86 #ifdef DEBUG_MENU
87                 printf("PopupMenu WM_CREATE lppop=%08X !\n", lppop);
88 #endif
89                 InitStdBitmaps();
90 #ifdef DEBUG_MENU
91                 printf("PopupMenu End of WM_CREATE !\n");
92 #endif
93                 return 0;
94         case WM_DESTROY:
95                 lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
96 #ifdef DEBUG_MENU
97                 printf("PopupMenu WM_DESTROY %lX !\n", lppop);
98 #endif
99                 return 0;
100         case WM_COMMAND:
101 #ifdef DEBUG_MENU
102                 printf("PopupMenuWndProc // WM_COMMAND received !\n");
103 #endif
104                 lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
105                 if (lppop == NULL) break;
106                 if (lppop->SysFlag) {
107                         MenuHasFocus = FALSE;
108                         if (wParam == SC_ABOUTWINE) {
109                                 printf("SysMenu // Show 'About Wine ...' !\n");
110 /*                              DialogBox(hSysRes, MAKEINTRESOURCE(SC_ABOUTWINEDLG), */
111                                 DialogBox(hSysRes, MAKEINTRESOURCE(2), 
112                                         GetParent(hwnd), (FARPROC)AboutWine_Proc);
113                                 }
114                         else {
115 #ifdef DEBUG_MENU
116                                 printf("PopupMenuWndProc // push to Owner WM_SYSCOMMAND !\n");
117 #endif
118                                 PostMessage(lppop->ownerWnd, WM_SYSCOMMAND, wParam, lParam);
119                                 }
120                         break;
121                         }
122 #ifdef DEBUG_MENU
123                 printf("PopupMenuWndProc // push to Owner WM_COMMAND !\n");
124 #endif
125                 MenuHasFocus = FALSE;
126                 PostMessage(lppop->hWndParent, WM_COMMAND, wParam, lParam);
127                 break;
128         case WM_SHOWWINDOW:
129 #ifdef DEBUG_MENU
130                 printf("PopupMenuWndProc // WM_SHOWWINDOW received !\n");
131 #endif
132                 lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
133                 if (lppop == NULL) break;
134                 if (wParam == 0 && lParam == 0L) {
135                         HideAllSubPopupMenu(lppop);
136 #ifdef DEBUG_MENU
137                         printf("PopupMenuWndProc hWnd=%04X WM_SHOWWINDOW -> HIDE!\n", hwnd);
138 #endif
139                         if (lppop->SysFlag) MenuHasFocus = FALSE;
140                         SetFocus(lppop->hWndPrev);
141                         if (GetCapture() != 0) ReleaseCapture(); 
142                         break;
143                         }
144                 lppop->FocusedItem = (WORD)-1;
145                 if (!lppop->BarFlag) {
146                         PopupMenuCalcSize(hwnd);
147                         ResetHiliteFlags(lppop);
148 #ifdef DEBUG_MENU
149                         printf("PopupMenuWndProc hWnd=%04X WM_SHOWWINDOW Width=%d Height=%d !\n", 
150                                                                         hwnd, lppop->Width, lppop->Height);
151 #endif
152                         SetWindowPos(hwnd, 0, 0, 0, lppop->Width + 2, lppop->Height, 
153                                                                         SWP_NOZORDER | SWP_NOMOVE);
154 #ifdef DEBUG_MENU
155                         printf("PopupMenuWndProc // End of WM_SHOWWINDOW !\n");
156 #endif
157                         }
158         break;
159         case WM_LBUTTONDOWN:
160                 lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
161                 if (lppop == NULL) break;
162                 SetCapture(hwnd); 
163                 MenuButtonDown(hwnd, lppop, LOWORD(lParam), HIWORD(lParam));
164                 break;
165         case WM_LBUTTONUP:
166                 lppop = PopupMenuGetStorageHeader(hwnd);
167                 if (lppop == NULL) break;
168                 ReleaseCapture(); 
169                 MenuButtonUp(hwnd, lppop, LOWORD(lParam), HIWORD(lParam));
170                 break;
171         case WM_MOUSEMOVE:
172                 lppop = PopupMenuGetStorageHeader(hwnd);
173                 if (lppop == NULL) break;
174                 MenuMouseMove(hwnd, lppop, wParam, LOWORD(lParam), HIWORD(lParam));
175                 break;
176
177         case WM_KEYUP:
178 #ifdef DEBUG_MENU
179                 printf("PopupMenuWndProc hWnd=%04X WM_KEYUP w=%04X l=%08X !\n", 
180                                                                                                 hwnd, wParam, lParam);
181 #endif
182                 break;
183         case WM_KEYDOWN:
184 #ifdef DEBUG_MENU
185                 printf("PopupMenuWndProc hWnd=%04X WM_KEYDOWN w=%04X l=%08X !\n", 
186                                                                                                 hwnd, wParam, lParam);
187 #endif
188                 if (lParam < 0L) break;
189                 lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
190                 if (lppop == NULL) break;
191                 switch(wParam) {
192                         case VK_HOME:
193                                 if (lppop->FocusedItem == 0) break;
194                                 MenuItemSelect(hwnd, lppop, 0);
195                                 break;
196                         case VK_UP:
197                                 if (lppop->BarFlag) break;
198                                 if (lppop->FocusedItem < 1) break;
199                                 MenuItemSelect(hwnd, lppop, lppop->FocusedItem - 1);
200                                 break;
201                         case VK_DOWN:
202                                 if (lppop->BarFlag) goto ProceedSPACE;
203                                 if (lppop->FocusedItem == (WORD)-1) {
204                                         MenuItemSelect(hwnd, lppop, lppop->FocusedItem + 1);
205                                         break;
206                                         }
207                                 if (lppop->FocusedItem >= lppop->nItems - 1) break;
208                                 MenuItemSelect(hwnd, lppop, lppop->FocusedItem + 1);
209                                 break;
210                         case VK_LEFT:
211                                 if (lppop->SysFlag != 0) {
212                                         ShowWindow(hwnd, SW_HIDE);
213                                         hwnd = lppop->hWndParent;
214                                         lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
215                                         printf("VK_LEFT // try to put focus on MenuBar %08X !\n", lppop);
216                                         if (lppop == NULL) break;
217                                         MenuItemSelect(hwnd, lppop, lppop->nItems - 1);
218                                     break;
219                                         }
220                                 if (lppop->BarFlag) {
221                                         if (lppop->FocusedItem < 1) {
222                                                 MenuItemSelect(hwnd, lppop, -1);
223                                                 NC_TrackSysMenu(hwnd);
224                                                 break;
225                                                 }
226                                         if (HideAllSubPopupMenu(lppop)) {
227                                                 MenuItemSelect(hwnd, lppop, lppop->FocusedItem - 1);
228                                                 goto ProceedSPACE;
229                                                 }
230                                         }
231                             if (lppop->hWndParent != 0) {
232                                         PostMessage(lppop->hWndParent, WM_KEYDOWN, wParam, lParam);
233                                     break;
234                                     }
235                                 MenuItemSelect(hwnd, lppop, lppop->FocusedItem - 1);
236                                 break;
237                         case VK_RIGHT:
238                                 if (lppop->SysFlag != 0) {
239                                         ShowWindow(hwnd, SW_HIDE);
240                                         hwnd = lppop->hWndParent;
241                                         lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
242                                         printf("VK_RIGHT // try to put focus on MenuBar %08X !\n", lppop);
243                                         if (lppop == NULL) break;
244                                         MenuItemSelect(hwnd, lppop, 0);
245                                     break;
246                                         }
247                                 if (lppop->BarFlag) {
248                                         if (lppop->FocusedItem >= lppop->nItems - 1) {
249                                                 MenuItemSelect(hwnd, lppop, -1);
250                                                 NC_TrackSysMenu(hwnd);
251                                                 break;
252                                                 }
253                                         if (HideAllSubPopupMenu(lppop)) {
254                                                 MenuItemSelect(hwnd, lppop, lppop->FocusedItem + 1);
255                                                 goto ProceedSPACE;
256                                                 }
257                                         }
258                             if (lppop->hWndParent != 0) {
259                                         PostMessage(lppop->hWndParent, WM_KEYDOWN, wParam, lParam);
260                                     break;
261                                     }
262                                 MenuItemSelect(hwnd, lppop, lppop->FocusedItem + 1);
263                                 break;
264                         default:
265                                 break;
266                         }
267                         break;
268         case WM_CHAR:
269 #ifdef DEBUG_MENU
270                 printf("PopupMenuWndProc hWnd=%04X WM_CHAR wParam=%04X !\n", hwnd, wParam);
271 #endif
272                 if (lParam < 0L) break;
273                 hwnd = GetFocus();
274                 lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
275                 if (lppop == NULL) break;
276                 switch(wParam) {
277                         case VK_RETURN:
278                         case VK_SPACE:
279 ProceedSPACE:   lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
280                                 ExecFocusedMenuItem(hwnd, lppop);
281                                 break;
282                         case VK_ESCAPE:
283                                 if (lppop->BarFlag) {
284 #ifdef DEBUG_MENU
285                                         printf("VK_ESCAPE // Unselect all MenuBar's Items !\n");
286 #endif
287                                         if (lppop->FocusedItem != (WORD)-1)
288                                                 MenuItemSelect(hwnd, lppop, -1);
289                                         }
290                                 if (lppop->SysFlag) {
291 #ifdef DEBUG_MENU
292                                         printf("VK_ESCAPE // SysMenu !\n");
293 #endif
294                                         ShowWindow(hwnd, SW_HIDE);
295                                         break;
296                                         }
297                                 if (lppop->hWndParent != 0) {
298 #ifdef DEBUG_MENU
299                                         printf("VK_ESCAPE // Hide only SubPopup !\n");
300 #endif
301                                         lppop2 = PopupMenuGetWindowAndStorage(lppop->hWndParent, &wndPtr);
302                                         if (lppop2 == NULL) break;
303                                         HideAllSubPopupMenu(lppop2);
304                                         break;
305                                         }
306                                 else {
307 #ifdef DEBUG_MENU
308                                         printf("VK_ESCAPE // Hide Root Popup !\n");
309 #endif
310                                         ShowWindow(hwnd, SW_HIDE);
311                                         MenuHasFocus = FALSE;
312                                         }
313                                 break;
314                         default:
315                                 if (wParam >= 'a' && wParam <= 'z') wParam -= 'a' - 'A';
316                                 lpitem = MenuFindItemBySelKey(lppop, wParam, &wRet);
317                                 if (lpitem != NULL) {
318                                     printf("ShortKey Found  wRet=%d !\n", wRet);
319                                         MenuItemSelect(hwnd, lppop, wRet);
320                                         lppop->FocusedItem = wRet;
321                                         goto ProceedSPACE;
322                                         }
323                             printf("ShortKey Not Found wParam=%04X wRet=%d lpitem=%08X !\n",
324                                         wParam, wRet, lpitem);
325                                 if (lppop->hWndParent != (HWND)NULL)
326                                         SendMessage(lppop->hWndParent, WM_MENUCHAR, wParam, 
327                                                 MAKELONG(0, 0));
328                                 else 
329                                         SendMessage(lppop->ownerWnd, WM_MENUCHAR, wParam, 
330                                                 MAKELONG(0, 0));
331                                 break;
332                         }
333                 break;
334         case WM_PAINT:
335 #ifdef DEBUG_MENU
336                 printf("PopupMenuWndProc // WM_PAINT received !\n");
337 #endif
338                 lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
339                 if (lppop == NULL) break;
340                 if (!lppop->BarFlag) {
341                         PopupMenuCalcSize(hwnd);
342                         StdDrawPopupMenu(hwnd);
343                         }
344                 break;
345         default:
346                 return DefWindowProc(hwnd, message, wParam, lParam);
347     }
348 return 0;
349 }
350
351
352 BOOL ExecFocusedMenuItem(HWND hWnd, LPPOPUPMENU lppop)
353 {
354         short   x, y;
355         LPPOPUPMENU lppop2;
356         LPMENUITEM      lpitem;
357         HMENU   hSubMenu;
358         RECT    rect;
359         lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem);
360         if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
361                 hSubMenu = (HMENU)lpitem->item_id;
362                 lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu);
363                 if (lppop2 == NULL) return FALSE;
364                 lppop2->hWndParent = hWnd;
365                 GetClientRect(hWnd, &rect);
366                 if (lppop->BarFlag) {
367                         GetWindowRect(hWnd, &rect);
368                         y = rect.top + lppop->rect.bottom;
369                         TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, 
370                                 rect.left + lpitem->rect.left, 
371                                 y, 0, lppop->ownerWnd, (LPRECT)NULL);
372                         }
373                 else {
374                         x = lppop->rect.right;
375                         GetWindowRect(hWnd, &rect);
376                         x += rect.left;
377                         TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, 
378                                 x, rect.top + lpitem->rect.top,
379                                 0, lppop->ownerWnd, (LPRECT)NULL);
380                         }
381                 GlobalUnlock(hSubMenu);
382                 return TRUE;
383                 }
384         if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
385                 ((lpitem->item_flags & MF_POPUP) != MF_POPUP)) {
386                 MenuHasFocus = FALSE;
387                 if (lppop->BarFlag) {
388                         PostMessage(lppop->ownerWnd, WM_COMMAND, lpitem->item_id, 0L);
389                         }
390                 else {
391                         ShowWindow(lppop->hWnd, SW_HIDE);
392                         SendMessage(lppop->hWnd, WM_COMMAND, lpitem->item_id, 0L);
393                         }
394                 }
395         return TRUE;
396 }
397
398
399
400 BOOL MenuButtonDown(HWND hWnd, LPPOPUPMENU lppop, int x, int y)
401 {
402         HDC             hDC;
403         LPMENUITEM      lpitem, lpitem2;
404         RECT    rect;
405         HMENU   hSubMenu;
406         WORD    wRet;
407         LPPOPUPMENU lppop2;
408         if (lppop == NULL) return;
409         lpitem = MenuFindItem(lppop, x, y, &wRet);
410 #ifdef DEBUG_MENU
411         printf("MenuButtonDown hWnd=%04X x=%d y=%d // wRet=%d lpitem=%08X !\n", 
412                                                                                         hWnd, x, y, wRet, lpitem);
413 #endif
414         if (lpitem != NULL) {
415                 if (lppop->FocusedItem != (WORD)-1 && wRet == lppop->FocusedItem) {
416                         lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem);
417                         if ((lpitem2->item_flags & MF_POPUP) == MF_POPUP) {
418                                 hSubMenu = (HMENU)lpitem2->item_id;
419                                 lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu);
420                                 if (lppop2 == NULL) return FALSE;
421                                 if (IsWindowVisible(lppop2->hWnd)) {
422                                         ShowWindow(lppop2->hWnd, SW_HIDE);
423                                         return TRUE;
424                                         }
425                                 }
426                         }
427                 MenuItemSelect(hWnd, lppop, wRet);
428                 if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
429                         hSubMenu = (HMENU)lpitem->item_id;
430                         lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu);
431                         if (lppop2 == NULL) return FALSE;
432                         lppop2->hWndParent = hWnd;
433                         if (lppop->BarFlag) {
434                                 GetWindowRect(hWnd, &rect);
435                                 y = rect.top + lppop->rect.bottom;
436                                 ReleaseCapture(); 
437                                 if (MenuHasFocus) {
438                                         TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, 
439                                                 rect.left + lpitem->rect.left, 
440                                                 y, 0, lppop->ownerWnd, (LPRECT)NULL);
441                                         }
442                                 else {
443                                         MenuHasFocus = TRUE;
444                                         TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, 
445                                                 rect.left + lpitem->rect.left, 
446                                                 y, 0, lppop->ownerWnd, (LPRECT)NULL);
447                                         MenuHasFocus = FALSE;
448                                         MenuFocusLoop(hWnd, lppop);
449                                         return TRUE;
450                                         }
451                                 }
452                         else {
453                                 x = lppop->rect.right;
454                                 GetWindowRect(hWnd, &rect);
455                                 x += rect.left;
456                                 TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON,
457                                         x, rect.top + lpitem->rect.top,
458                                         0, lppop->ownerWnd, (LPRECT)NULL);
459                                 }
460                         GlobalUnlock(hSubMenu);
461                         return TRUE;
462                         }
463                 if (lppop->BarFlag && !MenuHasFocus) {
464                         MenuFocusLoop(hWnd, lppop);
465                         }
466                 return TRUE;
467                 }
468         printf("MenuButtonDown // x=%d y=%d // Not Found !\n", x, y);
469         if (GetCapture() != 0) ReleaseCapture(); 
470         MenuHasFocus = FALSE;
471         ShowWindow(lppop->hWnd, SW_HIDE);
472         return FALSE;
473 }
474
475
476
477 void MenuButtonUp(HWND hWnd, LPPOPUPMENU lppop, int x, int y)
478 {
479         HDC             hDC;
480         LPMENUITEM      lpitem, lpitem2;
481         RECT    rect;
482         HMENU   hSubMenu;
483         WORD    wRet;
484         LPPOPUPMENU lppop2;
485         if (lppop == NULL) return;
486         lpitem = MenuFindItem(lppop, x, y, &wRet);
487 #ifdef DEBUG_MENU
488         printf("MenuButtonUp // x=%d y=%d // wRet=%d lpitem=%08X !\n", 
489                                                                                         x, y, wRet, lpitem);
490 #endif
491         if (lpitem != NULL) {
492                 if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
493                         return;
494                         }
495                 if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
496                         ((lpitem->item_flags & MF_POPUP) != MF_POPUP)) {
497                         MenuHasFocus = FALSE;
498                         if (lppop->BarFlag) {
499                                 PostMessage(lppop->ownerWnd, WM_COMMAND, lpitem->item_id, 0L);
500                                 }
501                         else {
502                                 ShowWindow(lppop->hWnd, SW_HIDE);
503                                 SendMessage(lppop->hWnd, WM_COMMAND, lpitem->item_id, 0L);
504                                 }
505                         return;
506                         }
507                 }
508         if (lppop->FocusedItem != (WORD)-1) {
509                 MenuItemSelect(hWnd, lppop, lppop->FocusedItem);
510                 }
511 }
512
513
514
515 void MenuMouseMove(HWND hWnd, LPPOPUPMENU lppop, WORD wParam, int x, int y)
516 {
517     HDC         hDC;
518     RECT        rect;
519     HMENU       hSubMenu;
520     LPMENUITEM  lpitem, lpitem2;
521     LPPOPUPMENU lppop2;
522     WORD        wRet;
523
524     if (GetKeyState(VK_LBUTTON) != 0) 
525     {
526         lpitem = MenuFindItem(lppop, x, y, &wRet);
527 #ifdef DEBUG_MENU
528         printf("MenuMouseMove // x=%d y=%d // wRet=%d lpitem=%08X !\n", 
529                x, y, wRet, lpitem);
530 #endif
531         if ((lpitem != NULL) && (lppop->FocusedItem != wRet)) 
532         {
533             lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem);
534             hDC = GetWindowDC(hWnd);
535             if ((lpitem2 != NULL ) &&
536                 (lpitem2->item_flags & MF_POPUP) == MF_POPUP) 
537             {
538                 HideAllSubPopupMenu(lppop);
539             }
540             MenuItemSelect(hWnd, lppop, wRet);
541             if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) 
542             {
543                 hSubMenu = (HMENU)lpitem->item_id;
544                 lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu);
545                 if (lppop2 == NULL) 
546                 {
547                     ReleaseDC(hWnd, hDC);
548                     return;
549                 }
550                 if (lppop->BarFlag) 
551                 {
552                     lppop2->hWndParent = hWnd;
553                     GetWindowRect(hWnd, &rect);
554                     rect.top += lppop->rect.bottom;
555                     TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, 
556                                    rect.left + lpitem->rect.left, rect.top, 
557                                    0, lppop->ownerWnd, (LPRECT)NULL);
558                 }
559                 GlobalUnlock(hSubMenu);
560             }
561             ReleaseDC(hWnd, hDC);
562         }
563     }
564 }
565
566
567 void ResetHiliteFlags(LPPOPUPMENU lppop)
568 {
569         LPMENUITEM lpitem;
570         int             i;
571 #ifdef DEBUG_MENU
572         printf("ResetHiliteFlags lppop=%08X\n", lppop);
573 #endif
574         if (lppop == NULL) return;
575         lpitem = lppop->firstItem;
576         for(i = 0; i < lppop->nItems; i++) {
577                 if (lpitem == NULL) return;
578                 lpitem->item_flags &= 0xFFFF ^ MF_HILITE;
579                 lpitem = (LPMENUITEM)lpitem->next;
580                 }
581 }
582
583
584 void MenuItemSelect0(HWND hWnd, LPPOPUPMENU lppop, 
585                                 LPMENUITEM lpitem, WORD wIndex)
586 {
587     LPMENUITEM lpprev;
588     
589     if (lppop == NULL) 
590         return;
591     if (lppop->FocusedItem != (WORD)-1) 
592     {
593         lpprev = GetMenuItemPtr(lppop, lppop->FocusedItem);
594         if (lpprev != NULL) 
595         {
596             lpprev->item_flags &= MF_HILITE ^ 0xFFFF;
597             if ((lpprev->item_flags & MF_POPUP) == MF_POPUP)
598                 HideAllSubPopupMenu(lppop);
599             if (lppop->BarFlag)
600                 DrawMenuBar(hWnd);
601             else 
602             {
603                 InvalidateRect(hWnd, &lpprev->rect, TRUE);
604                 UpdateWindow(hWnd);
605             }
606         }
607     }
608     lppop->FocusedItem = wIndex;
609     if (lpitem == NULL || wIndex == (WORD)-1) 
610     {
611         ResetHiliteFlags(lppop);
612         if (lppop->BarFlag) DrawMenuBar(hWnd);
613     }
614     else 
615     {
616         lpitem->item_flags |= MF_HILITE;
617         if (lppop->BarFlag)
618             DrawMenuBar(hWnd);
619         else 
620         {
621             InvalidateRect(hWnd, &lpitem->rect, TRUE);
622             UpdateWindow(hWnd);
623         }
624         SendMessage(hWnd, WM_MENUSELECT, lpitem->item_id, 
625                     MAKELONG(0, lpitem->item_flags));
626     }
627 }
628
629
630 void MenuItemSelect(HWND hWnd, LPPOPUPMENU lppop, WORD wIndex)
631 {
632         LPMENUITEM lpitem;
633     lpitem = GetMenuItemPtr(lppop, wIndex);
634         MenuItemSelect0(hWnd, lppop, lpitem, wIndex);
635 }
636
637
638 LPPOPUPMENU PopupMenuGetWindowAndStorage(HWND hwnd, WND **wndPtr)
639 {
640     WND  *Ptr;
641     LPPOPUPMENU lppop;
642     *(wndPtr) = Ptr = WIN_FindWndPtr(hwnd);
643     if (Ptr == 0) {
644         printf("PopupMenuGetWindowAndStorage // Bad Window handle !\n");
645         return NULL;
646         }
647     lppop = *((LPPOPUPMENU *)&Ptr->wExtra[1]);
648         if (lppop == NULL) {
649                 lppop = (LPPOPUPMENU) GlobalLock(Ptr->wIDmenu);
650                 if (lppop == NULL) {
651                         printf("PopupMenuGetWindowAndStorage // Bad Menu Handle !\n");
652                 return NULL;
653                         }
654                 }
655     return lppop;
656 }
657
658
659 LPPOPUPMENU PopupMenuGetStorageHeader(HWND hwnd)
660 {
661     WND  *Ptr;
662     LPPOPUPMENU lppop;
663     Ptr = WIN_FindWndPtr(hwnd);
664     if (Ptr == 0) {
665         printf("Bad Window handle on PopupMenu !\n");
666         return 0;
667         }
668     lppop = *((LPPOPUPMENU *)&Ptr->wExtra[1]);
669     return lppop;
670 }
671
672
673 void SetMenuLogicalParent(HMENU hMenu, HWND hWnd)
674 {
675     LPPOPUPMENU lppop;
676     lppop = (LPPOPUPMENU)GlobalLock(hMenu);
677     lppop->hWndParent = hWnd;
678     GlobalUnlock(hMenu);
679 }
680
681
682 void StdDrawPopupMenu(HWND hwnd)
683 {
684         WND     *wndPtr;
685         LPPOPUPMENU lppop;
686         LPMENUITEM      lpitem;
687         PAINTSTRUCT ps;
688         HBRUSH  hBrush;
689         HPEN    hOldPen;
690         HWND    hWndParent;
691         HDC     hDC, hMemDC;
692         RECT    rect, rect2, rect3;
693         DWORD   OldTextColor;
694         int             OldBkMode;
695         HFONT   hOldFont;
696         HBITMAP hBitMap;
697         BITMAP  bm;
698         UINT    i, x;
699         hDC = BeginPaint(hwnd, &ps);
700         if (!IsWindowVisible(hwnd)) {
701                 EndPaint(hwnd, &ps);
702                 return;
703                 }
704         InitStdBitmaps();
705         lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
706         if (lppop == NULL) goto EndOfPaint;
707         hBrush = GetStockObject(WHITE_BRUSH);
708         GetClientRect(hwnd, &rect);
709         GetClientRect(hwnd, &rect2);
710         FillRect(hDC, &rect, hBrush);
711         FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH));
712         if (lppop->nItems == 0) goto EndOfPaint;
713         lpitem = lppop->firstItem;
714         if (lpitem == NULL) goto EndOfPaint;
715         for(i = 0; i < lppop->nItems; i++) {
716         CopyRect(&rect2, &lpitem->rect);
717         if ((lpitem->item_flags & MF_SEPARATOR) == MF_SEPARATOR) {
718                 hOldPen = SelectObject(hDC, GetStockObject(BLACK_PEN));
719                 MoveTo(hDC, rect2.left, rect2.top + 1);
720                 LineTo(hDC, rect2.right, rect2.top + 1);
721                 SelectObject(hDC, hOldPen);
722                 }
723         if ((lpitem->item_flags & MF_CHECKED) == MF_CHECKED) {
724                 hMemDC = CreateCompatibleDC(hDC);
725                 if (lpitem->hCheckBit == 0) {
726                         SelectObject(hMemDC, hStdCheck);
727                         GetObject(hStdCheck, sizeof(BITMAP), (LPSTR)&bm);
728                         }
729                 else {
730                         SelectObject(hMemDC, lpitem->hCheckBit);
731                         GetObject(lpitem->hCheckBit, sizeof(BITMAP), (LPSTR)&bm);
732                         }
733                 BitBlt(hDC, rect2.left, rect2.top + 1,
734                 bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
735                 DeleteDC(hMemDC);
736                 }
737         else {
738                 if (lpitem->hUnCheckBit != 0) {
739                         hMemDC = CreateCompatibleDC(hDC);
740                         SelectObject(hMemDC, lpitem->hUnCheckBit);
741                         GetObject(lpitem->hUnCheckBit, sizeof(BITMAP), (LPSTR)&bm);
742                         BitBlt(hDC, rect2.left, rect2.top + 1,
743                         bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
744                         DeleteDC(hMemDC);
745                         }
746                 }
747         if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) {
748                 hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text);
749                 rect2.left += lppop->CheckWidth;
750                 hMemDC = CreateCompatibleDC(hDC);
751                 SelectObject(hMemDC, hBitMap);
752                 GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm);
753 #ifdef DEBUG_MENU
754                 printf("StdDrawPopupMenu // MF_BITMAP hBit=%04X w=%d h=%d\n",
755                                 hBitMap, bm.bmWidth, bm.bmHeight);
756 #endif
757                 BitBlt(hDC, rect2.left, rect2.top,
758                                 bm.bmWidth, bm.bmHeight, 
759                                 hMemDC, 0, 0, SRCCOPY);
760                 DeleteDC(hMemDC);
761                 if ((lpitem->item_flags & MF_HILITE) == MF_HILITE)
762                         InvertRect(hDC, &lpitem->rect);
763                 }
764         if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) &&
765                 ((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
766                 ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) {
767                 hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT));
768                 OldBkMode = SetBkMode(hDC, TRANSPARENT);
769                 if ((lpitem->item_flags & MF_DISABLED) == MF_DISABLED)
770                         OldTextColor = SetTextColor(hDC, 0x00C0C0C0L);
771                 else {
772                         if ((lpitem->item_flags & MF_HILITE) == MF_HILITE)
773                                 OldTextColor = SetTextColor(hDC, 0x00FFFFFFL);
774                         else
775                                 OldTextColor = SetTextColor(hDC, 0x00000000L);
776                         }
777                 CopyRect(&rect3, &lpitem->rect);
778                 if ((lpitem->item_flags & MF_HILITE) == MF_HILITE)
779                         FillRect(hDC, &rect3, GetStockObject(BLACK_BRUSH));
780                 InflateRect(&rect3, 0, -2);
781                 rect3.left += lppop->CheckWidth;
782                 hOldPen = SelectObject(hDC, GetStockObject(BLACK_PEN));
783                 if ((x = GetShortCutPos(lpitem->item_text)) != (WORD)-1) {
784                         DrawText(hDC, lpitem->item_text, x, &rect3, 
785                                 DT_LEFT | DT_VCENTER | DT_SINGLELINE);
786                         DrawText(hDC, &lpitem->item_text[x], -1, &rect3, 
787                                 DT_RIGHT | DT_VCENTER | DT_SINGLELINE);
788                         } 
789             else
790                         DrawText(hDC, lpitem->item_text, -1, &rect3, 
791                                 DT_LEFT | DT_VCENTER | DT_SINGLELINE);
792                 SelectObject(hDC, hOldPen);
793                 SetTextColor(hDC, OldTextColor);
794                 SetBkMode(hDC, OldBkMode);
795                 SelectObject(hDC, hOldFont);
796                 CopyRect(&rect2, &lpitem->rect);
797                 }
798         if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
799                 CopyRect(&rect3, &lpitem->rect);
800                 rect3.left = rect3.right - lppop->PopWidth;
801                 hMemDC = CreateCompatibleDC(hDC);
802                 SelectObject(hMemDC, hStdMnArrow);
803                 GetObject(hStdMnArrow, sizeof(BITMAP), (LPSTR)&bm);
804                 BitBlt(hDC, rect3.left, rect3.top + 1,
805                 bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
806                 DeleteDC(hMemDC);
807                 }
808         if (lpitem->next == NULL) goto EndOfPaint;
809         lpitem = (LPMENUITEM)lpitem->next;
810         }
811 EndOfPaint:
812         EndPaint( hwnd, &ps );
813 }
814
815
816
817 void StdDrawMenuBar(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop, 
818                     BOOL suppress_draw)
819 {
820         LPMENUITEM      lpitem;
821         HBRUSH  hBrush;
822         HPEN    hOldPen;
823         HDC     hMemDC;
824         RECT    rect, rect2, rect3;
825         HFONT   hOldFont;
826         DWORD   OldTextColor;
827         int             OldBkMode;
828         HBITMAP hBitMap;
829         BITMAP  bm;
830         UINT    i, textwidth;
831         if (lppop == NULL || lprect == NULL) return;
832 #ifdef DEBUG_MENU
833         printf("StdDrawMenuBar(%04X, %08X, %08X); !\n", hDC, lprect, lppop);
834 #endif
835         MenuBarCalcSize(hDC, lprect, lppop);
836         if (suppress_draw) return;
837         hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT));
838         hOldPen = SelectObject(hDC, GetStockObject(BLACK_PEN));
839         hBrush = GetStockObject(WHITE_BRUSH);
840         CopyRect(&rect, lprect);
841         FillRect(hDC, &rect, hBrush);
842         FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH));
843         if (lppop->nItems == 0) goto EndOfPaint;
844         lpitem = lppop->firstItem;
845         if (lpitem == NULL) goto EndOfPaint;
846         for(i = 0; i < lppop->nItems; i++) {
847                 CopyRect(&rect2, &lpitem->rect);
848 #ifdef DEBUG_MENU
849                 printf("StdDrawMenuBar // start left=%d\n", rect2.left);
850 #endif
851                 if ((lpitem->item_flags & MF_CHECKED) == MF_CHECKED) {
852                         hMemDC = CreateCompatibleDC(hDC);
853                         if (lpitem->hCheckBit == 0) {
854                                 SelectObject(hMemDC, hStdCheck);
855                                 GetObject(hStdCheck, sizeof(BITMAP), (LPSTR)&bm);
856                                 }
857                         else {
858                                 SelectObject(hMemDC, lpitem->hCheckBit);
859                                 GetObject(lpitem->hCheckBit, sizeof(BITMAP), (LPSTR)&bm);
860                                 }
861                         BitBlt(hDC, rect2.left, rect2.top + 1,
862                                 bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
863                         rect2.left += bm.bmWidth;
864 #ifdef DEBUG_MENU
865                         printf("StdDrawMenuBar // MF_CHECKED bm.bmWidth=%d\n", bm.bmWidth);
866 #endif
867                         DeleteDC(hMemDC);
868                         }
869                 else {
870                         if (lpitem->hUnCheckBit != 0) {
871                                 hMemDC = CreateCompatibleDC(hDC);
872                                 SelectObject(hMemDC, lpitem->hUnCheckBit);
873                                 GetObject(lpitem->hUnCheckBit, sizeof(BITMAP), (LPSTR)&bm);
874                                 BitBlt(hDC, rect2.left, rect2.top + 1,
875                                         bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
876                                 rect2.left += bm.bmWidth;
877 #ifdef DEBUG_MENU
878                                 printf("StdDrawMenuBar // MF_UNCHECKED bm.bmWidth=%d\n", bm.bmWidth);
879 #endif
880                                 DeleteDC(hMemDC);
881                                 }
882                         }
883                 if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) {
884                         hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text);
885                         hMemDC = CreateCompatibleDC(hDC);
886                         SelectObject(hMemDC, hBitMap);
887                         GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm);
888 #ifdef DEBUG_MENU
889                         printf("StdDrawMenuBar // MF_BITMAP hBit=%04X w=%d h=%d\n",
890                                         hBitMap, bm.bmWidth, bm.bmHeight);
891 #endif
892                         BitBlt(hDC, rect2.left, rect2.top,
893                                                 bm.bmWidth, bm.bmHeight, 
894                                                 hMemDC, 0, 0, SRCCOPY);
895                         DeleteDC(hMemDC);
896                         }
897                 if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) &&
898                         ((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
899                         ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) {
900                         hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT));
901                         OldBkMode = SetBkMode(hDC, TRANSPARENT);
902                         if ((lpitem->item_flags & MF_DISABLED) == MF_DISABLED)
903                                 OldTextColor = SetTextColor(hDC, 0x00C0C0C0L);
904                         else {
905                                 if ((lpitem->item_flags & MF_HILITE) == MF_HILITE)
906                                         OldTextColor = SetTextColor(hDC, 0x00FFFFFFL);
907                                 else
908                                         OldTextColor = SetTextColor(hDC, 0x00000000L);
909                                 }
910                         if ((lpitem->item_flags & MF_HILITE) == MF_HILITE)
911                                 FillRect(hDC, &rect2, GetStockObject(BLACK_BRUSH));
912 #ifdef DEBUG_MENU
913                         printf("StdDrawMenuBar // rect2.left=%d\n", rect2.left);
914 #endif
915                         DrawText(hDC, lpitem->item_text, -1, &rect2, 
916                                 DT_LEFT | DT_VCENTER | DT_SINGLELINE);
917                         SetTextColor(hDC, OldTextColor);
918                         SetBkMode(hDC, OldBkMode);
919                         SelectObject(hDC, hOldFont);
920                         }
921                 if (lpitem->next == NULL) goto EndOfPaint;
922                 lpitem = (LPMENUITEM)lpitem->next;
923                 }
924 EndOfPaint:
925         SelectObject(hDC, hOldPen);
926         SelectObject(hDC, hOldFont);
927
928
929
930
931 LPMENUITEM MenuFindItem(LPPOPUPMENU lppop, int x, int y, WORD *lpRet)
932 {
933         LPMENUITEM      lpitem;
934         UINT    i;
935         if (lpRet != NULL) *lpRet = 0;
936         if (lppop == NULL) return NULL;
937         if (lppop->nItems == 0) return NULL;
938         lpitem = lppop->firstItem;
939         for(i = 0; i < lppop->nItems; i++) {
940                 if (lpitem == NULL) return NULL;
941 #ifdef DEBUG_MENUFINDITEM
942                 printf("FindItem // left=%d top=%d right=%d bottom=%d\n",
943                 lpitem->rect.left, lpitem->rect.top, 
944                 lpitem->rect.right, lpitem->rect.bottom);
945 #endif
946                 if (x > lpitem->rect.left && x < lpitem->rect.right && 
947                         y > lpitem->rect.top && y < lpitem->rect.bottom) {
948                         if (lpRet != NULL) *lpRet = i;
949                         return lpitem;
950                         }
951                 lpitem = (LPMENUITEM)lpitem->next;
952                 }
953         return NULL;
954 }
955
956
957 LPMENUITEM MenuFindItemBySelKey(LPPOPUPMENU lppop, WORD key, WORD *lpRet)
958 {
959         LPMENUITEM      lpitem;
960         UINT    i;
961         if (lppop == NULL) return NULL;
962
963         if (lppop->nItems == 0) return NULL;
964         lpitem = lppop->firstItem;
965         for(i = 0; i < lppop->nItems; i++) {
966                 if (lpitem == NULL) return NULL;
967 #ifdef DEBUG_MENUFINDITEM
968                 printf("FindItemBySelKey // key=%04X lpitem->sel_key=%04X\n",
969                                                                                 key, lpitem->sel_key);
970 #endif
971                 if (key == lpitem->sel_key) {
972                         if (lpRet != NULL) *lpRet = i;
973                         return lpitem;
974                         }
975                 lpitem = (LPMENUITEM)lpitem->next;
976                 }
977         return NULL;
978 }
979
980
981 void PopupMenuCalcSize(HWND hwnd)
982 {
983         WND     *wndPtr;
984         LPPOPUPMENU lppop;
985         LPMENUITEM      lpitem;
986         HDC             hDC;
987         RECT    rect;
988         HBITMAP hBitMap;
989         BITMAP  bm;
990         HFONT   hOldFont;
991         UINT    i, OldWidth, TempWidth;
992         DWORD   dwRet;
993 #ifdef DEBUG_MENUCALC
994         printf("PopupMenuCalcSize hWnd=%04X !\n", hWnd);
995 #endif
996         InitStdBitmaps();
997         lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
998         if (lppop == NULL) return;
999         if (lppop->nItems == 0) return;
1000         hDC = GetDC(hwnd);
1001         lppop->Width = 20;
1002         lppop->CheckWidth = lppop->PopWidth = 0;
1003         hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT));
1004 CalcAGAIN:
1005         OldWidth = lppop->Width;
1006         SetRect(&rect, 1, 1, OldWidth, 0);
1007         lpitem = lppop->firstItem;
1008         for(i = 0; i < lppop->nItems; i++) {
1009                 if (lpitem == NULL) break;
1010 #ifdef DEBUG_MENUCALC
1011                 printf("PopupMenuCalcSize item #%d !\n", i);
1012 #endif
1013                 rect.right = rect.left + lppop->Width;
1014                 if ((lpitem->item_flags & MF_CHECKED) == MF_CHECKED) {
1015                         if (lpitem->hCheckBit != 0)
1016                                 GetObject(lpitem->hCheckBit, sizeof(BITMAP), (LPSTR)&bm);
1017                         else
1018                                 GetObject(hStdCheck, sizeof(BITMAP), (LPSTR)&bm);
1019                         lppop->CheckWidth = max(lppop->CheckWidth, bm.bmWidth);
1020                         }
1021                 else {
1022                         if (lpitem->hUnCheckBit != 0) {
1023                                 GetObject(lpitem->hUnCheckBit, sizeof(BITMAP), (LPSTR)&bm);
1024                                 lppop->CheckWidth = max(lppop->CheckWidth, bm.bmWidth);
1025                                 }
1026                         }
1027                 if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
1028                         GetObject(hStdMnArrow, sizeof(BITMAP), (LPSTR)&bm);
1029                         lppop->PopWidth = max(lppop->PopWidth, bm.bmWidth);
1030                         }
1031                 if ((lpitem->item_flags & MF_SEPARATOR) == MF_SEPARATOR) {
1032                         rect.bottom = rect.top + 3;
1033                         }
1034                 if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) {
1035                         hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text);
1036                         GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm);
1037                         rect.bottom = rect.top + bm.bmHeight;
1038                         lppop->Width = max(lppop->Width, bm.bmWidth);
1039                         }
1040                 if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) &&
1041                         ((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
1042                         ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) {
1043                         dwRet = GetTextExtent(hDC, (char *)lpitem->item_text, 
1044                         strlen((char *)lpitem->item_text));
1045                         rect.bottom = rect.top + HIWORD(dwRet);
1046                         InflateRect(&rect, 0, 2);
1047                         TempWidth = LOWORD(dwRet);
1048                         if (GetShortCutPos(lpitem->item_text) != (WORD)-1) 
1049                                 TempWidth += 15;
1050                         TempWidth += lppop->CheckWidth;
1051                         TempWidth += lppop->PopWidth;
1052                         lppop->Width = max(lppop->Width, TempWidth);
1053                         }
1054                 CopyRect(&lpitem->rect, &rect);
1055                 rect.top = rect.bottom;
1056                 lpitem = (LPMENUITEM)lpitem->next;
1057                 }
1058         if (OldWidth < lppop->Width) goto CalcAGAIN;
1059         lppop->Height = rect.bottom;
1060         SetRect(&lppop->rect, 1, 1, lppop->Width, lppop->Height);
1061 #ifdef DEBUG_MENUCALC
1062         printf("PopupMenuCalcSize w=%d h=%d !\n", lppop->Width, lppop->Height);
1063 #endif
1064         SelectObject(hDC, hOldFont);
1065         ReleaseDC(hwnd, hDC);
1066 }
1067
1068
1069
1070 void MenuBarCalcSize(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop)
1071 {
1072         LPMENUITEM      lpitem;
1073         LPMENUITEM      lpitem2;
1074         RECT    rect;
1075         HBITMAP hBitMap;
1076         BITMAP  bm;
1077         HFONT   hOldFont;
1078         UINT    i, j;
1079         UINT    OldHeight, LineHeight;
1080         DWORD   dwRet;
1081         if (lprect == NULL) return;
1082         if (lppop == NULL) return;
1083         if (lppop->nItems == 0) return;
1084         InitStdBitmaps();
1085 #ifdef DEBUG_MENUCALC
1086         printf("MenuBarCalcSize left=%d top=%d right=%d bottom=%d !\n", 
1087                 lprect->left, lprect->top, lprect->right, lprect->bottom);
1088 #endif
1089         hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT));
1090         lppop->CheckWidth = 0;
1091         LineHeight = OldHeight = SYSMETRICS_CYMENU + 2;
1092         SetRect(&rect, lprect->left, lprect->top, 0, lprect->top + LineHeight);
1093         lpitem2 = lppop->firstItem;
1094         while (lpitem != NULL) {
1095                 lpitem = lpitem2;
1096                 while(rect.right < lprect->right) {
1097                         if (lpitem == NULL) break;
1098                         rect.right = rect.left;
1099                         if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) {
1100                                 hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text);
1101                                 GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm);
1102                                 rect.right = rect.left + bm.bmWidth;
1103                                 LineHeight = max(LineHeight, bm.bmHeight);
1104                                 }
1105                         if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) &&
1106                                 ((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
1107                                 ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) {
1108                                 dwRet = GetTextExtent(hDC, (char *)lpitem->item_text, 
1109                                 strlen((char *)lpitem->item_text));
1110                                 rect.right = rect.left + LOWORD(dwRet) + 10;
1111                                 dwRet = max(SYSMETRICS_CYMENU, (HIWORD(dwRet) + 6));
1112                                 LineHeight = max(LineHeight, (WORD)dwRet);
1113                                 }
1114                         if ((lpitem->item_flags & MF_CHECKED) == MF_CHECKED) {
1115                                 if (lpitem->hCheckBit != 0)
1116                                         GetObject(lpitem->hCheckBit, sizeof(BITMAP), (LPSTR)&bm);
1117                                 else
1118                                         GetObject(hStdCheck, sizeof(BITMAP), (LPSTR)&bm);
1119                                 rect.right += bm.bmWidth;
1120                                 LineHeight = max(LineHeight, bm.bmHeight);
1121                                 }
1122                         else {
1123                                 if (lpitem->hUnCheckBit != 0) {
1124                                         GetObject(lpitem->hUnCheckBit, sizeof(BITMAP), (LPSTR)&bm);
1125                                         rect.right += bm.bmWidth;
1126                                         LineHeight = max(LineHeight, bm.bmHeight);
1127                                         }
1128                                 }
1129                         CopyRect(&lpitem->rect, &rect);
1130                         rect.left = rect.right;
1131                         lpitem = (LPMENUITEM)lpitem->next;
1132                         }
1133                 if (LineHeight == OldHeight) {
1134                         lpitem2 = lpitem;
1135                         LineHeight = OldHeight = SYSMETRICS_CYMENU + 1;
1136                         if (lpitem != NULL) 
1137                                 SetRect(&rect, lprect->left, rect.bottom, 
1138                                                 0, rect.bottom + LineHeight);
1139                         }
1140                 else {
1141                         OldHeight = LineHeight;
1142                         SetRect(&rect, lprect->left, rect.top, 0, rect.top + LineHeight);
1143                         }
1144                 }
1145         lppop->Width = lprect->right - lprect->left;
1146         lppop->Height = rect.bottom - lprect->top;
1147         lprect->bottom = lprect->top + lppop->Height;
1148         CopyRect(&lppop->rect, lprect);
1149 #ifdef DEBUG_MENUCALC
1150         printf("MenuBarCalcSize w=%d h=%d !\n", lppop->Width, lppop->Height);
1151 #endif
1152         SelectObject(hDC, hOldFont);
1153 }
1154
1155
1156
1157 /***********************************************************************
1158  *           FindMenuItem
1159  */
1160 LPMENUITEM FindMenuItem(HMENU hMenu, WORD nPos, WORD wFlags)
1161 {
1162         LPPOPUPMENU     menu;
1163         LPMENUITEM      lpitem;
1164         int             i;
1165         menu = (LPPOPUPMENU) GlobalLock(hMenu);
1166         if (menu == NULL) {
1167                 GlobalUnlock(hMenu);
1168                 return FALSE;
1169                 }
1170         lpitem = menu->firstItem;
1171         if (wFlags & MF_BYPOSITION) {
1172                 for (i = 0; i < nPos; i++, lpitem = lpitem->next) 
1173                         if (lpitem == NULL)     return NULL;
1174                 }
1175         else {
1176                 for (i = 0; i < menu->nItems && lpitem != NULL; i++) {
1177                         if (lpitem->item_id == nPos) return lpitem;
1178                         lpitem = lpitem->next;
1179                         }
1180                 return NULL;
1181                 }
1182     return lpitem;
1183 }
1184
1185
1186 LPMENUITEM GetMenuItemPtr(LPPOPUPMENU menu, WORD nPos)
1187 {
1188     LPMENUITEM  lpitem;
1189     int         i;
1190     if (menu == NULL) return NULL;
1191     lpitem = menu->firstItem;
1192     for (i = 0; i < menu->nItems; i++) {
1193         if (lpitem == NULL) return NULL;
1194         if (i == nPos) return(lpitem);
1195         lpitem = (LPMENUITEM)lpitem->next;
1196         }
1197     return NULL;
1198 }
1199
1200
1201 WORD GetSelectionKey(LPSTR str)
1202 {
1203         int             i;
1204         WORD    sel_key;
1205         for (i = 0; i < strlen(str); i++) {
1206                 if (str[i] == '&' && str[i + 1] != '&') {
1207                         sel_key = str[i + 1];
1208                         if (sel_key >= 'a' && sel_key <= 'z') sel_key -= 'a' - 'A';
1209 #ifdef DEBUG_MENU
1210                         printf("GetSelectionKey // %04X\n", sel_key);
1211 #endif
1212                         return sel_key;
1213                         }
1214                 }
1215 #ifdef DEBUG_MENU
1216         printf("GetSelectionKey NULL \n");
1217 #endif
1218         return 0;
1219 }
1220
1221
1222
1223 LPSTR GetShortCutString(LPSTR str)
1224 {
1225         int             i;
1226         LPSTR   str2;
1227         for (i = 0; i < strlen(str); i++) {
1228                 if (str[i] == '\t' && str[i + 1] != '\t') {
1229                         str2 = &str[i + 1];
1230 #ifdef DEBUG_MENUSHORTCUT
1231                         printf("GetShortCutString // '%s' \n", str2);
1232 #endif
1233                         return str2;
1234                         }
1235                 }
1236 #ifdef DEBUG_MENUSHORTCUT
1237         printf("GetShortCutString NULL \n");
1238 #endif
1239         return NULL;
1240 }
1241
1242
1243
1244 WORD GetShortCutPos(LPSTR str)
1245 {
1246         int             i;
1247         for (i = 0; i < strlen(str); i++) {
1248                 if (str[i] == '\t' && str[i + 1] != '\t') {
1249 #ifdef DEBUG_MENUSHORTCUT
1250                         printf("GetShortCutPos = %d \n", i);
1251 #endif
1252                         return i;
1253                         }
1254                 }
1255 #ifdef DEBUG_MENUSHORTCUT
1256         printf("GetShortCutString NULL \n");
1257 #endif
1258         return -1;
1259 }
1260
1261
1262
1263 BOOL HideAllSubPopupMenu(LPPOPUPMENU menu)
1264 {
1265         LPPOPUPMENU submenu;
1266         LPMENUITEM      lpitem;
1267         BOOL    someClosed = FALSE;
1268         int             i;
1269         if (menu == NULL) return;
1270         lpitem = menu->firstItem;
1271         for (i = 0; i < menu->nItems; i++) {
1272                 if (lpitem == NULL) return;
1273                 if (lpitem->item_flags & MF_POPUP) {
1274                         submenu = (LPPOPUPMENU) GlobalLock((HMENU)lpitem->item_id);
1275                         if (submenu != NULL) {
1276                                 if (IsWindowVisible(submenu->hWnd)) {
1277                                         ShowWindow(submenu->hWnd, SW_HIDE);
1278                                         someClosed = TRUE;
1279                                         }
1280                                 GlobalUnlock((HMENU)lpitem->item_id);
1281                         }
1282                     }
1283                 lpitem = (LPMENUITEM)lpitem->next;
1284                 }
1285         return someClosed;
1286 }
1287
1288
1289
1290
1291 /**********************************************************************
1292  *                      ChangeMenu              [USER.153]
1293  */
1294 BOOL ChangeMenu(HMENU hMenu, WORD nPos, LPSTR lpNewItem, 
1295                         WORD wItemID, WORD wFlags)
1296 {
1297         if (wFlags & MF_APPEND)
1298                 return AppendMenu(hMenu, wFlags, wItemID, lpNewItem);
1299         if (wFlags & MF_DELETE)
1300                 return DeleteMenu(hMenu, wItemID, wFlags);
1301         if (wFlags & MF_INSERT) 
1302                 return InsertMenu(hMenu, nPos, wFlags, wItemID, lpNewItem);
1303         if (wFlags & MF_CHANGE) 
1304                 return ModifyMenu(hMenu, nPos, wFlags, wItemID, lpNewItem);
1305         if (wFlags & MF_REMOVE) 
1306                 return RemoveMenu(hMenu, wItemID, wFlags);
1307         return FALSE;
1308 }
1309
1310
1311 /**********************************************************************
1312  *                      CheckMenuItem           [USER.154]
1313  */
1314 BOOL CheckMenuItem(HMENU hMenu, WORD wItemID, WORD wFlags)
1315 {
1316         LPMENUITEM      lpitem;
1317 #ifdef DEBUG_MENU
1318         printf("CheckMenuItem (%04X, %04X, %04X) !\n", hMenu, wItemID, wFlags);
1319 #endif
1320         lpitem = FindMenuItem(hMenu, wItemID, wFlags);
1321         if (lpitem != NULL) {
1322                 if ((wFlags & MF_CHECKED) == MF_CHECKED)
1323                         lpitem->item_flags |= MF_CHECKED;
1324                 else
1325                         lpitem->item_flags &= ((WORD)-1 ^ MF_CHECKED);
1326 #ifdef DEBUG_MENU
1327                 printf("CheckMenuItem // Found !\n");
1328 #endif
1329                 return(TRUE);
1330                 }
1331         return FALSE;
1332 }
1333
1334
1335 /**********************************************************************
1336  *                      EnableMenuItem          [USER.155]
1337  */
1338 BOOL EnableMenuItem(HMENU hMenu, WORD wItemID, WORD wFlags)
1339 {
1340         LPMENUITEM      lpitem;
1341 #ifdef DEBUG_MENU
1342         printf("EnableMenuItem (%04X, %04X, %04X) !\n", hMenu, wItemID, wFlags);
1343 #endif
1344         lpitem = FindMenuItem(hMenu, wItemID, wFlags);
1345         if (lpitem != NULL) {
1346                 if (wFlags && MF_DISABLED)
1347                         lpitem->item_flags |= MF_DISABLED;
1348                 else
1349                         lpitem->item_flags &= ((WORD)-1 ^ MF_DISABLED);
1350 #ifdef DEBUG_MENU
1351                 printf("EnableMenuItem // Found !\n");
1352 #endif
1353                 return(TRUE);
1354                 }
1355         return FALSE;
1356 }
1357
1358
1359 /**********************************************************************
1360  *                      GetMenuString           [USER.161]
1361  */
1362 int GetMenuString(HMENU hMenu, WORD wItemID, 
1363         LPSTR str, short nMaxSiz, WORD wFlags)
1364 {
1365         LPMENUITEM      lpitem;
1366         int             maxsiz;
1367 #ifdef DEBUG_MENU
1368         printf("GetMenuString(%04X, %04X, %08X, %d, %04X);\n",
1369                                         hMenu, wItemID, str, nMaxSiz, wFlags);
1370 #endif
1371         if (str == NULL) return FALSE;
1372         lpitem = FindMenuItem(hMenu, wItemID, wFlags);
1373         if (lpitem != NULL) {
1374                 if (lpitem->item_text != NULL) {
1375                         maxsiz = min(nMaxSiz - 1, strlen(lpitem->item_text));
1376                         strncpy(str, lpitem->item_text, maxsiz + 1);
1377                         }
1378                 else
1379                         maxsiz = 0;
1380 #ifdef DEBUG_MENU
1381                 printf("GetMenuString // Found !\n");
1382 #endif
1383                 return maxsiz;
1384                 }
1385         return 0;
1386 }
1387
1388
1389 /**********************************************************************
1390  *                      HiliteMenuItem          [USER.162]
1391  */
1392 BOOL HiliteMenuItem(HWND hWnd, HMENU hMenu, WORD wItemID, WORD wHilite)
1393 {
1394         LPPOPUPMENU     menu;
1395         LPMENUITEM      lpitem;
1396 #ifdef DEBUG_MENU
1397         printf("HiliteMenuItem(%04X, %04X, %04X, %04X);\n", 
1398                                                 hWnd, hMenu, wItemID, wHilite);
1399 #endif
1400         menu = (LPPOPUPMENU) GlobalLock(hMenu);
1401         if (menu == NULL) return FALSE;
1402         lpitem = FindMenuItem(hMenu, wItemID, wHilite);
1403         if (lpitem == NULL) return FALSE;
1404         return FALSE;
1405 }
1406
1407
1408 /**********************************************************************
1409  *                      GetMenuState            [USER.250]
1410  */
1411 WORD GetMenuState(HMENU hMenu, WORD wItemID, WORD wFlags)
1412 {
1413         LPPOPUPMENU     menu;
1414         LPMENUITEM      lpitem;
1415 #ifdef DEBUG_MENU
1416         printf("GetMenuState(%04X, %04X, %04X);\n", hMenu, wItemID, wFlags);
1417 #endif
1418         menu = (LPPOPUPMENU) GlobalLock(hMenu);
1419         if (menu == NULL) return -1;
1420         lpitem = FindMenuItem(hMenu, wItemID, wFlags);
1421         if (lpitem == NULL) return -1;
1422         return lpitem->item_flags;
1423 }
1424
1425
1426 /**********************************************************************
1427  *                      GetMenuItemCount                [USER.263]
1428  */
1429 WORD GetMenuItemCount(HMENU hMenu)
1430 {
1431         LPPOPUPMENU     menu;
1432 #ifdef DEBUG_MENU
1433         printf("GetMenuItemCount(%04X);\n", hMenu);
1434 #endif
1435         menu = (LPPOPUPMENU) GlobalLock(hMenu);
1436         if (menu == NULL) return (WORD)-1;
1437 #ifdef DEBUG_MENU
1438         printf("GetMenuItemCount(%04X) return %d \n", hMenu, menu->nItems);
1439 #endif
1440         return menu->nItems;
1441 }
1442
1443
1444 /**********************************************************************
1445  *                      GetMenuItemID                   [USER.264]
1446  */
1447 WORD GetMenuItemID(HMENU hMenu, int nPos)
1448 {
1449         WORD            i;
1450         LPPOPUPMENU     menu;
1451         LPMENUITEM      lpitem;
1452         printf("GetMenuItemID(%04X, %d);\n", hMenu, nPos);
1453         menu = (LPPOPUPMENU) GlobalLock(hMenu);
1454         if (menu == NULL) return -1;
1455         lpitem = menu->firstItem;
1456         for (i = 0; i < menu->nItems; i++) {
1457                 if (lpitem == NULL) break;
1458                 if (i == nPos) {
1459 #ifdef DEBUG_MENU
1460                         printf("GetMenuItemID // Found !\n");
1461 #endif
1462                         return lpitem->item_id;
1463                         }
1464                 lpitem = (LPMENUITEM)lpitem->next;
1465                 }
1466         return -1;
1467 }
1468
1469
1470 /**********************************************************************
1471  *                      InsertMenu              [USER.410]
1472  */
1473 BOOL InsertMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewItem)
1474 {
1475         LPPOPUPMENU     menu;
1476         HANDLE  hNewItem;
1477         LPMENUITEM      lpitem, lpitem2;
1478 #ifdef DEBUG_MENU
1479         if ((wFlags & (MF_BITMAP | MF_SEPARATOR | MF_MENUBREAK | MF_OWNERDRAW)) == 0)
1480                 printf("InsertMenu (%04X, %04X, %04X, '%s') !\n",
1481                                         hMenu, wFlags, wItemID, lpNewItem);
1482         else
1483                 printf("InsertMenu (%04X, %04X, %04X, %04X, %08X) !\n",
1484                                         hMenu, nPos, wFlags, wItemID, lpNewItem);
1485 #endif
1486         menu = (LPPOPUPMENU) GlobalLock(hMenu);
1487         if (menu == NULL) return FALSE;
1488         lpitem = FindMenuItem(hMenu, nPos, wFlags);
1489         if (lpitem == NULL) lpitem = menu->firstItem;
1490         hNewItem = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM));
1491         if (hNewItem == 0) {
1492                 GlobalUnlock(hMenu);
1493                 return FALSE;
1494                 }
1495         lpitem2 = (LPMENUITEM)GlobalLock(hNewItem);
1496         if (lpitem2 == NULL) {
1497                 GlobalFree(hNewItem);
1498                 GlobalUnlock(hMenu);
1499                 return FALSE;
1500                 }
1501         lpitem2->hItem = hNewItem;
1502         lpitem2->item_flags = wFlags;
1503         lpitem2->item_id = wItemID;
1504         if (!(wFlags & (MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK | 
1505                 MF_MENUBREAK | MF_SEPARATOR))) {
1506                 lpitem2->hText = GlobalAlloc(GMEM_MOVEABLE, strlen(lpNewItem) + 1);
1507                 lpitem2->item_text = GlobalLock(lpitem2->hText);
1508                 if (lpitem2->item_text != NULL)
1509                         strcpy(lpitem2->item_text, lpNewItem);
1510                 else {
1511                         printf("InsertMenu // Bad Alloc !\n");
1512                         return FALSE;
1513                         }
1514                 lpitem2->sel_key = GetSelectionKey(lpitem2->item_text);
1515                 }
1516         else {
1517                 lpitem2->item_text = lpNewItem;
1518                 }
1519         if (lpitem == NULL) {
1520                 menu->firstItem = lpitem2;
1521                 lpitem2->prev = NULL;
1522                 lpitem2->next = NULL;
1523                 }
1524         else {
1525                 lpitem2->prev = lpitem;
1526                 lpitem2->next = lpitem->next;
1527                 if (lpitem2->next != NULL) lpitem2->next->prev = lpitem2;
1528                 lpitem->next = lpitem2;
1529                 }
1530         menu->nItems++;
1531         GlobalUnlock(hMenu);
1532         return TRUE;
1533 }
1534
1535
1536 /**********************************************************************
1537  *                      AppendMenu              [USER.411]
1538  */
1539 BOOL AppendMenu(HMENU hMenu, WORD wFlags, WORD wItemID, LPSTR lpNewItem)
1540 {
1541         LPPOPUPMENU     menu;
1542         HANDLE  hNewItem;
1543         LPMENUITEM      lpitem, lpitem2;
1544 #ifdef DEBUG_MENU
1545         if ((wFlags & (MF_BITMAP | MF_SEPARATOR | MF_MENUBREAK | MF_OWNERDRAW)) == 0)
1546                 printf("AppendMenu (%04X, %04X, %04X, '%s') !\n",
1547                                         hMenu, wFlags, wItemID, lpNewItem);
1548         else
1549                 printf("AppendMenu (%04X, %04X, %04X, %08X) !\n",
1550                                         hMenu, wFlags, wItemID, lpNewItem);
1551 #endif
1552         menu = (LPPOPUPMENU) GlobalLock(hMenu);
1553         if (menu == NULL) return FALSE;
1554         lpitem = menu->firstItem;
1555         if (lpitem != NULL) {
1556                 while (lpitem->next != NULL) {
1557                         lpitem = (LPMENUITEM)lpitem->next;
1558                         }
1559                 }
1560         hNewItem = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM));
1561         if (hNewItem == 0) {
1562                 GlobalUnlock(hMenu);
1563                 return FALSE;
1564                 }
1565         lpitem2 = (LPMENUITEM)GlobalLock(hNewItem);
1566         lpitem2->hItem = hNewItem;
1567         if (lpitem2 == NULL) {
1568                 GlobalFree(hNewItem);
1569                 GlobalUnlock(hMenu);
1570                 return FALSE;
1571                 }
1572         lpitem2->item_flags = wFlags;
1573         lpitem2->item_id = wItemID;
1574         if (!(wFlags & (MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK | 
1575                 MF_MENUBREAK | MF_SEPARATOR))) {
1576                 lpitem2->hText = GlobalAlloc(GMEM_MOVEABLE, strlen(lpNewItem) + 1);
1577                 lpitem2->item_text = GlobalLock(lpitem2->hText);
1578                 if (lpitem2->item_text != NULL)
1579                         strcpy(lpitem2->item_text, lpNewItem);
1580                 else {
1581                         printf("AppendMenu // Bad Alloc !\n");
1582                         return FALSE;
1583                         }
1584                 lpitem2->sel_key = GetSelectionKey(lpitem2->item_text);
1585                 }
1586         else {
1587                 lpitem2->item_text = lpNewItem;
1588                 }
1589         if (lpitem == NULL)
1590                 menu->firstItem = lpitem2;
1591         else
1592                 lpitem->next = lpitem2;
1593         lpitem2->prev = lpitem;
1594         lpitem2->next = NULL;
1595         lpitem2->hCheckBit = (HBITMAP)NULL;
1596         lpitem2->hUnCheckBit = (HBITMAP)NULL;
1597         menu->nItems++;
1598         GlobalUnlock(hMenu);
1599         return TRUE;
1600 }
1601
1602
1603 /**********************************************************************
1604  *                      RemoveMenu              [USER.412]
1605  */
1606 BOOL RemoveMenu(HMENU hMenu, WORD nPos, WORD wFlags)
1607 {
1608         LPPOPUPMENU     menu;
1609         LPMENUITEM      lpitem;
1610         int             i;
1611 #ifdef DEBUG_MENU
1612         printf("RemoveMenu (%04X, %04X, %04X) !\n", hMenu, nPos, wFlags);
1613 #endif
1614         menu = (LPPOPUPMENU) GlobalLock(hMenu);
1615         if (menu == NULL) return FALSE;
1616         lpitem = menu->firstItem;
1617         for (i = 0; i < menu->nItems; i++) {
1618                 if (lpitem == NULL) break;
1619                 if (i == nPos) {
1620                         lpitem->prev->next = lpitem->next;
1621                         lpitem->next->prev = lpitem->prev;
1622                         if (!(lpitem->item_flags & 
1623                                 (MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK | 
1624                                 MF_MENUBREAK | MF_SEPARATOR))) {
1625                                 GlobalUnlock(lpitem->hText);
1626                                 GlobalFree(lpitem->hText);
1627                                 }
1628                         GlobalFree(lpitem->hItem);
1629                         GlobalUnlock(hMenu);
1630                         return TRUE;
1631                         }
1632                 lpitem = (LPMENUITEM)lpitem->next;
1633                 printf("RemoveMenu // during loop items !\n");
1634                 }
1635         printf("RemoveMenu // after loop items !\n");
1636         GlobalUnlock(hMenu);
1637         return FALSE;
1638 }
1639
1640
1641 /**********************************************************************
1642  *                      DeleteMenu              [USER.413]
1643  */
1644 BOOL DeleteMenu(HMENU hMenu, WORD nPos, WORD wFlags)
1645 {
1646         LPPOPUPMENU     menu;
1647         LPMENUITEM      lpitem;
1648         int             i;
1649 #ifdef DEBUG_MENU
1650         printf("DeleteMenu (%04X, %04X, %04X) !\n", hMenu, nPos, wFlags);
1651 #endif
1652         menu = (LPPOPUPMENU) GlobalLock(hMenu);
1653         if (menu == NULL) {
1654                 GlobalUnlock(hMenu);
1655                 return FALSE;
1656                 }
1657         lpitem = FindMenuItem(hMenu, nPos, wFlags);
1658         if (lpitem != NULL) {
1659                 if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) 
1660                         DestroyMenu((HMENU)lpitem->item_id);
1661                 if (!(lpitem->item_flags & 
1662                         (MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK | 
1663                         MF_MENUBREAK | MF_SEPARATOR))) {
1664                         GlobalUnlock(lpitem->hText);
1665                         GlobalFree(lpitem->hText);
1666                         }
1667                 if (lpitem->prev) lpitem->prev->next = lpitem->next;
1668                 if (lpitem->next) lpitem->next->prev = lpitem->prev;
1669                 GlobalFree(lpitem->hItem);
1670                 GlobalUnlock(hMenu);
1671                 return TRUE;
1672                 }
1673         GlobalUnlock(hMenu);
1674         return FALSE;
1675 }
1676
1677
1678 /**********************************************************************
1679  *                      ModifyMenu              [USER.414]
1680  */
1681 BOOL ModifyMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewItem)
1682 {
1683         LPPOPUPMENU     menu;
1684         LPMENUITEM      lpitem;
1685         int             i;
1686 #ifdef DEBUG_MENU
1687         if ((wFlags & (MF_BITMAP | MF_SEPARATOR | MF_MENUBREAK | MF_OWNERDRAW)) == 0)
1688                 printf("ModifyMenu (%04X, %04X, %04X, %04X, '%s') !\n",
1689                                         hMenu, nPos, wFlags, wItemID, lpNewItem);
1690         else
1691                 printf("ModifyMenu (%04X, %04X, %04X, %04X, %08X) !\n",
1692                                         hMenu, nPos, wFlags, wItemID, lpNewItem);
1693 #endif
1694         menu = (LPPOPUPMENU) GlobalLock(hMenu);
1695         if (menu == NULL) return FALSE;
1696         lpitem = menu->firstItem;
1697         for (i = 0; i < menu->nItems; i++) {
1698                 if (lpitem == NULL) break;
1699                 if (i == nPos) {
1700                         lpitem->item_flags = wFlags;
1701                         lpitem->item_id    = wItemID;
1702                         if (!(lpitem->item_flags & 
1703                                 (MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK | 
1704                                 MF_MENUBREAK | MF_SEPARATOR))) {
1705                                 GlobalUnlock(lpitem->hText);
1706                                 GlobalFree(lpitem->hText);
1707                                 lpitem->hText = GlobalAlloc(GMEM_MOVEABLE, strlen(lpNewItem) + 1);
1708                                 lpitem->item_text = GlobalLock(lpitem->hText);
1709                                 printf("ModifyMenu %08X %08X '%s') !\n",
1710                                         lpitem->item_text, lpNewItem, lpNewItem);
1711                                 if (lpitem->item_text != NULL)
1712                                         strcpy(lpitem->item_text, lpNewItem);
1713                                 else
1714                                         printf("ModifyMenu // Bad Alloc !\n");
1715                                 }
1716                         else
1717                                 lpitem->item_text = lpNewItem;
1718                                 GlobalUnlock(hMenu);
1719                                 return(TRUE);
1720                                 }
1721                 lpitem = (LPMENUITEM)lpitem->next;
1722                 }
1723     GlobalUnlock(hMenu);
1724     return FALSE;
1725 }
1726
1727
1728 /**********************************************************************
1729  *                      CreatePopupMenu         [USER.415]
1730  */
1731 HMENU CreatePopupMenu()
1732 {
1733         HANDLE  hItem;
1734         HMENU   hMenu;
1735         LPPOPUPMENU menu;
1736 #ifdef DEBUG_MENU
1737         printf("CreatePopupMenu !\n");
1738 #endif
1739         hMenu = GlobalAlloc(GMEM_MOVEABLE, sizeof(POPUPMENU));
1740         menu = (LPPOPUPMENU) GlobalLock(hMenu);
1741         if (menu == NULL) {
1742                 GlobalFree(hMenu);
1743                 return 0;
1744                 }
1745         menu->nItems            = 0;
1746         menu->firstItem         = NULL;
1747         menu->ownerWnd          = 0;
1748         menu->hWndPrev          = 0;
1749         menu->hWnd                      = 0;
1750         menu->hWndParent        = 0;
1751         menu->MouseFlags        = 0;
1752         menu->BarFlag           = FALSE;
1753         menu->SysFlag           = FALSE;
1754         menu->ChildFlag         = TRUE;
1755         menu->Width             = 100;
1756         menu->Height            = 0;
1757         GlobalUnlock(hMenu);
1758 #ifdef DEBUG_MENU
1759         printf("CreatePopupMenu // return %04X\n", hMenu);
1760 #endif
1761         return hMenu;
1762 }
1763
1764
1765 /**********************************************************************
1766  *                      TrackPopupMenu          [USER.416]
1767  */
1768 BOOL TrackPopupMenu(HMENU hMenu, WORD wFlags, short x, short y,
1769         short nReserved, HWND hWnd, LPRECT lpRect)
1770 {
1771         WND             *wndPtr;
1772         LPPOPUPMENU     lppop;
1773         RECT    rect;
1774 #ifdef DEBUG_MENU
1775         printf("TrackPopupMenu (%04X, %04X, %d, %d, %04X, %04X, %08X) !\n",
1776                 hMenu, wFlags, x, y, nReserved, hWnd, lpRect);
1777 #endif
1778         lppop = (LPPOPUPMENU) GlobalLock(hMenu);
1779         if (lppop == NULL) {
1780                 printf("TrackPopupMenu // Bad menu handle %04X !\n", hMenu);
1781                 return FALSE;
1782                 }
1783         wndPtr = WIN_FindWndPtr(hWnd);
1784         if (wndPtr == NULL) {
1785                 printf("TrackPopupMenu // Bad window handle %04X !\n", hWnd);
1786                 return FALSE;
1787                 }
1788         lppop->ownerWnd = hWnd;
1789         lppop->hWndPrev = GetFocus();
1790         if (lppop->hWnd == (HWND)NULL) {
1791                 lppop->hWnd = CreateWindow("POPUPMENU", "", WS_POPUP | WS_VISIBLE,
1792                         x, y, lppop->Width, lppop->Height, (HWND)NULL, 0, 
1793                         wndPtr->hInstance, (LPSTR)lppop);
1794                 if (lppop->hWnd == 0) {
1795                         printf("TrackPopupMenu // Can't create PopupMenu window !\n");
1796                         return FALSE;
1797                         }
1798                 }
1799         else {
1800                 ShowWindow(lppop->hWnd, SW_SHOW);
1801                 }
1802         if (!lppop->BarFlag) {
1803                 PopupMenuCalcSize(lppop->hWnd);
1804 #ifdef DEBUG_MENU
1805                 printf("TrackPopupMenu // x=%d y=%d Width=%d Height=%d\n", 
1806                         x, y, lppop->Width, lppop->Height); 
1807 #endif
1808                 SetWindowPos(lppop->hWnd, 0, x, y, lppop->Width + 2, lppop->Height, 
1809                         SWP_NOZORDER);
1810                 }
1811         SetFocus(lppop->hWnd);
1812         if (!MenuHasFocus) {
1813 #ifdef DEBUG_MENU
1814                 printf("TrackPopupMenu // before MenuFocusLoop !\n");
1815 #endif
1816                 MenuFocusLoop(hWnd, NULL);
1817 #ifdef DEBUG_MENU
1818                 printf("TrackPopupMenu // after MenuFocusLoop !\n");
1819 #endif
1820                 }
1821         GlobalUnlock(hMenu);
1822         return TRUE;
1823 }
1824
1825
1826 BOOL ActivateMenuBarFocus(HWND hWnd)
1827 {
1828         WND             *wndPtr;
1829         LPPOPUPMENU     lpmenu;
1830         BOOL    bRet;
1831         MSG             msg;
1832         if (MenuHasFocus) return FALSE;
1833         wndPtr = WIN_FindWndPtr(hWnd);
1834         if (wndPtr == NULL) return FALSE;
1835 #ifdef DEBUG_MENU
1836         printf("ActivateMenuBarFocus (%04X) !\n", hWnd);
1837 #endif
1838         while((wndPtr->dwStyle & WS_CHILD) == WS_CHILD) {
1839                 hWnd = GetParent(hWnd);
1840                 printf("ActivateMenuBarFocus // next Parent=%04X !\n", hWnd);
1841                 wndPtr = WIN_FindWndPtr(hWnd);
1842                 if (wndPtr == NULL) return FALSE;
1843                 }
1844         if ((wndPtr->dwStyle & WS_CHILD) == 0 && wndPtr->wIDmenu != 0) {
1845                 lpmenu = (LPPOPUPMENU) GlobalLock(wndPtr->wIDmenu);
1846                 if (lpmenu == NULL) return FALSE;
1847                 lpmenu->hWndPrev = GetFocus();
1848                 SetFocus(hWnd);
1849                 MenuItemSelect(hWnd, lpmenu, 0);
1850                 bRet = MenuFocusLoop(hWnd, lpmenu);
1851                 GlobalUnlock(wndPtr->wIDmenu);
1852                 return bRet;
1853                 }
1854         return FALSE;
1855 }
1856
1857
1858 BOOL MenuFocusLoop(HWND hWnd, LPPOPUPMENU lpmenu)
1859 {
1860         MSG             msg;
1861 #ifdef DEBUG_MENU
1862         printf("Enter in Menu Focus Loop !\n");
1863 #endif
1864         MenuHasFocus = TRUE;
1865         while(TRUE) {
1866                 if (!MenuHasFocus) break;
1867                 if (!GetMessage(&msg, (HWND)NULL, 0, 0)) break;
1868                 TranslateMessage(&msg);
1869                 if (hWnd == msg.hwnd && lpmenu != NULL) {
1870                         if ((msg.message == WM_SYSKEYDOWN && msg.wParam == VK_MENU) ||
1871                                 (msg.message == WM_CHAR && msg.wParam == VK_ESCAPE)) {
1872                                 HideAllSubPopupMenu(lpmenu);
1873                                 break;
1874                                 }
1875                         ScreenToClient(hWnd, &msg.pt);
1876                         msg.pt.y += lpmenu->rect.bottom;
1877                         switch(msg.message) {
1878                                 case WM_LBUTTONDOWN:
1879                                 case WM_NCLBUTTONDOWN:
1880                                     SetCapture(hWnd);
1881                                     MenuButtonDown(hWnd, lpmenu, msg.pt.x, msg.pt.y);
1882                                     break;
1883                                 case WM_LBUTTONUP:
1884                                 case WM_NCLBUTTONUP:
1885                                     MenuButtonUp(hWnd, lpmenu, msg.pt.x, msg.pt.y);
1886                                     ReleaseCapture();
1887                                     break;
1888                                 case WM_MOUSEMOVE:
1889                                 case WM_NCMOUSEMOVE:
1890                                     MenuMouseMove(hWnd, lpmenu, msg.wParam, msg.pt.x, msg.pt.y);
1891                                     break;
1892                                 case WM_KEYDOWN:
1893                                 case WM_KEYUP:
1894                                 case WM_CHAR:
1895                                         PopupMenuWndProc(hWnd, msg.message, msg.wParam, msg.lParam);
1896                                 default:
1897                                         DispatchMessage(&msg);
1898                                 }
1899                         }
1900                 else
1901                         DispatchMessage(&msg);
1902                 }
1903 EndOfFocus:
1904         MenuHasFocus = FALSE;
1905         if (lpmenu != NULL) MenuItemSelect(hWnd, lpmenu, -1);
1906 #ifdef DEBUG_MENU
1907         printf("End of Menu Focus Loop !\n");
1908 #endif
1909         return TRUE;
1910 }
1911
1912
1913 /**********************************************************************
1914  *                      NC_TrackSysMenu         [Internal]
1915  */
1916 void NC_TrackSysMenu(HWND hWnd)
1917 {
1918         RECT    rect;
1919         LPPOPUPMENU     lpsys;
1920         WND *wndPtr = WIN_FindWndPtr(hWnd);    
1921 #ifdef DEBUG_MENU
1922         printf("NC_TrackSysMenu hWnd=%04X !\n", hWnd);
1923 #endif
1924         if (!wndPtr) return;
1925         lpsys = (LPPOPUPMENU)GlobalLock(wndPtr->hSysMenu);
1926 #ifdef DEBUG_MENU
1927         printf("NC_TrackSysMenu wndPtr->hSysMenu=%04X !\n", wndPtr->hSysMenu);
1928 #endif
1929         if (lpsys == NULL) return;
1930 #ifdef DEBUG_MENU
1931         printf("NC_TrackSysMenu wndPtr->hSysMenu=%04X !\n", wndPtr->hSysMenu);
1932 #endif
1933         lpsys->BarFlag = FALSE;
1934         lpsys->SysFlag = TRUE;
1935         lpsys->ChildFlag = FALSE;
1936         lpsys->hWndParent = hWnd;
1937         if (!IsWindowVisible(lpsys->hWnd)) {
1938                 GetWindowRect(hWnd, &rect);
1939 #ifdef DEBUG_MENU
1940                 printf("NC_TrackSysMenu lpsys->hWnd=%04X !\n", lpsys->hWnd);
1941 #endif
1942                 if (MenuHasFocus) {
1943                         TrackPopupMenu(wndPtr->hSysMenu, TPM_LEFTBUTTON, 
1944                                 rect.left, rect.top + SYSMETRICS_CYSIZE, 
1945                                 0, hWnd, (LPRECT)NULL);
1946                         }
1947                 else {
1948                         MenuHasFocus = TRUE;
1949                         TrackPopupMenu(wndPtr->hSysMenu, TPM_LEFTBUTTON, 
1950                                 rect.left, rect.top + SYSMETRICS_CYSIZE, 
1951                                 0, hWnd, (LPRECT)NULL);
1952                         MenuHasFocus = FALSE;
1953 #ifdef DEBUG_MENU
1954                         printf("NC_TrackSysMenu // before MenuFocusLoop !\n");
1955 #endif
1956                         MenuFocusLoop(hWnd, NULL);
1957 #ifdef DEBUG_MENU
1958                         printf("NC_TrackSysMenu // after MenuFocusLoop !\n");
1959 #endif
1960                         }
1961                 }
1962         else {
1963                 ShowWindow(lpsys->hWnd, SW_HIDE);
1964                 }
1965         GlobalUnlock(wndPtr->hSysMenu);
1966 }
1967
1968
1969 /**********************************************************************
1970  *                      GetMenuCheckMarkDimensions      [USER.417]
1971  */
1972 DWORD GetMenuCheckMarkDimensions()
1973 {
1974     BITMAP      bm;
1975         InitStdBitmaps();
1976     GetObject(hStdCheck, sizeof(BITMAP), (LPSTR)&bm);
1977     return MAKELONG(bm.bmWidth, bm.bmHeight);
1978 }
1979
1980
1981 /**********************************************************************
1982  *                      SetMenuItemBitmaps      [USER.418]
1983  */
1984 BOOL SetMenuItemBitmaps(HMENU hMenu, WORD nPos, WORD wFlags,
1985                 HBITMAP hNewCheck, HBITMAP hNewUnCheck)
1986 {
1987         LPPOPUPMENU     menu;
1988         LPMENUITEM      lpitem;
1989         int             i;
1990 #ifdef DEBUG_MENU
1991         printf("SetMenuItemBitmaps (%04X, %04X, %04X, %04X, %08X) !\n",
1992                                         hMenu, nPos, wFlags, hNewCheck, hNewUnCheck);
1993 #endif
1994         menu = (LPPOPUPMENU) GlobalLock(hMenu);
1995         if (menu == NULL) return FALSE;
1996         lpitem = menu->firstItem;
1997         for (i = 0; i < menu->nItems; i++) {
1998                 if (lpitem == NULL) break;
1999                 if (i == nPos) {
2000                         lpitem->hCheckBit   = hNewCheck;
2001                         lpitem->hUnCheckBit = hNewUnCheck;
2002                         GlobalUnlock(hMenu);
2003                         return TRUE;
2004                         }
2005                 lpitem = (LPMENUITEM)lpitem->next;
2006                 }
2007         GlobalUnlock(hMenu);
2008         return FALSE;
2009 }
2010
2011
2012 /**********************************************************************
2013  *                      CreateMenu              [USER.151]
2014  */
2015 HMENU CreateMenu()
2016 {
2017         HANDLE  hItem;
2018         HMENU   hMenu;
2019         LPPOPUPMENU menu;
2020 #ifdef DEBUG_MENU
2021         printf("CreateMenu !\n");
2022 #endif
2023         hMenu = GlobalAlloc(GMEM_MOVEABLE, sizeof(POPUPMENU));
2024         menu = (LPPOPUPMENU) GlobalLock(hMenu);
2025         if (menu == NULL) {
2026                 GlobalFree(hMenu);
2027                 return 0;
2028                 }
2029         menu->nItems            = 0;
2030         menu->firstItem         = NULL;
2031         menu->hWndPrev          = 0;
2032         menu->ownerWnd          = 0;
2033         menu->hWnd                      = 0;
2034         menu->hWndParent        = 0;
2035         menu->MouseFlags        = 0;
2036         menu->BarFlag           = TRUE;
2037         menu->SysFlag           = FALSE;
2038         menu->ChildFlag         = TRUE;
2039         menu->Width             = 100;
2040         menu->Height            = 0;
2041         GlobalUnlock(hMenu);
2042 #ifdef DEBUG_MENU
2043         printf("CreateMenu // return %04X\n", hMenu);
2044 #endif
2045         return hMenu;
2046 }
2047
2048
2049 /**********************************************************************
2050  *                      DestroyMenu             [USER.152]
2051  */
2052 BOOL DestroyMenu(HMENU hMenu)
2053 {
2054         LPPOPUPMENU lppop;
2055         LPMENUITEM      lpitem, lpitem2;
2056 #ifdef DEBUG_MENU
2057         printf("DestroyMenu (%04X) !\n", hMenu);
2058 #endif
2059         if (hMenu == 0) return FALSE;
2060         lppop = (LPPOPUPMENU) GlobalLock(hMenu);
2061         if (lppop == NULL) return FALSE;
2062         if (lppop->hWnd) DestroyWindow (lppop->hWnd);
2063         lpitem = lppop->firstItem;
2064         while (lpitem != NULL) {
2065 #ifdef DEBUG_MENU
2066                 printf("DestroyMenu (%04X) // during loop items !\n", hMenu);
2067 #endif
2068                 if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
2069                         DestroyMenu((HMENU)lpitem->item_id);
2070                         }
2071                 lpitem = (LPMENUITEM)lpitem->next;
2072                 }
2073         GlobalUnlock(hMenu);
2074         GlobalFree(hMenu);
2075 #ifdef DEBUG_MENU
2076         printf("DestroyMenu (%04X) // End !\n", hMenu);
2077 #endif
2078         return TRUE;
2079 }
2080
2081
2082 /**********************************************************************
2083  *                      LoadMenu                [USER.150]
2084  */
2085 HMENU LoadMenu(HINSTANCE instance, char *menu_name)
2086 {
2087         HMENU                   hMenu;
2088         HANDLE          hMenu_desc;
2089         MENU_HEADER     *menu_desc;
2090 #ifdef DEBUG_MENU
2091         if ((LONG)menu_name & 0xFFFF0000L)
2092                 printf("LoadMenu: instance %02x, menu '%s'\n", instance, menu_name);
2093         else
2094                 printf("LoadMenu: instance %02x, menu '%04X'\n", instance, menu_name);
2095 #endif
2096         if (instance == (HANDLE)NULL)  instance = hSysRes;
2097         if (menu_name == NULL || 
2098                 (hMenu_desc = RSC_LoadMenu(instance, menu_name)) == 0 ||
2099                 (menu_desc = (MENU_HEADER *) GlobalLock(hMenu_desc)) == NULL) {
2100                 return 0;
2101                 }
2102         hMenu = LoadMenuIndirect((LPSTR)menu_desc);
2103         return hMenu;
2104 }
2105
2106
2107 /**********************************************************************
2108  *                      GetSystemMenu           [USER.156]
2109  */
2110 HMENU GetSystemMenu(HWND hWnd, BOOL bRevert)
2111 {
2112         WND             *wndPtr;
2113         wndPtr = WIN_FindWndPtr(hWnd);
2114         if (!bRevert) {
2115                 return wndPtr->hSysMenu;
2116                 }
2117         else {
2118                 DestroyMenu(wndPtr->hSysMenu);
2119                 wndPtr->hSysMenu = CopySysMenu();
2120                 }
2121         return wndPtr->hSysMenu;
2122 }
2123
2124 /**********************************************************************
2125  *                      SetSystemMenu           [USER.280]
2126  */
2127 BOOL SetSystemMenu(HWND hWnd, HMENU newHmenu)
2128 {
2129         WND     *wndPtr;
2130
2131         if ((wndPtr = WIN_FindWndPtr(hWnd)) != NULL)
2132                 wndPtr->hSysMenu = newHmenu;
2133 }
2134
2135
2136 /**********************************************************************
2137  *                      GetMenu         [USER.157]
2138  */
2139 HMENU GetMenu(HWND hWnd) 
2140
2141         WND * wndPtr = WIN_FindWndPtr(hWnd);
2142         if (wndPtr == NULL) return 0;
2143         return wndPtr->wIDmenu;
2144 }
2145
2146 /**********************************************************************
2147  *                      SetMenu         [USER.158]
2148  */
2149 BOOL SetMenu(HWND hWnd, HMENU hMenu)
2150 {
2151         RECT    rect;
2152         LPPOPUPMENU lpmenu;
2153         WORD    flags;
2154         WND * wndPtr = WIN_FindWndPtr(hWnd);
2155         if (wndPtr == NULL) {
2156                 printf("SetMenu(%04X, %04X) // Bad window handle !\n", hWnd, hMenu);
2157                 return FALSE;
2158                 }
2159 #ifdef DEBUG_MENU
2160         printf("SetMenu(%04X, %04X);\n", hWnd, hMenu);
2161 #endif
2162         if (GetCapture() == hWnd) ReleaseCapture();
2163         if (wndPtr->window != 0) {
2164                 flags = SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED;
2165                 if (!IsWindowVisible(hWnd)) flags |= SWP_NOREDRAW;
2166                 if (hMenu == 0) {
2167                         wndPtr->wIDmenu = hMenu;
2168                         printf("SetMenu(%04X, %04X) // Menu removed, need NC recalc!\n", hWnd, hMenu);
2169                         SetWindowPos(hWnd, 0, 0, 0, 0, 0, flags);
2170                         return TRUE;
2171                         }
2172                 wndPtr->wIDmenu = hMenu;
2173                 SetWindowPos(hWnd, 0, 0, 0, 0, 0, flags);
2174                 }
2175         lpmenu = (LPPOPUPMENU) GlobalLock(hMenu);
2176         if (lpmenu == NULL) {
2177                 printf("SetMenu(%04X, %04X) // Bad menu handle !\n", hWnd, hMenu);
2178                 return FALSE;
2179                 }
2180         lpmenu->ownerWnd = hWnd;
2181         ResetHiliteFlags(lpmenu);
2182         GlobalUnlock(hMenu);
2183         return TRUE;
2184 }
2185
2186
2187
2188 /**********************************************************************
2189  *                      GetSubMenu              [USER.159]
2190  */
2191 HMENU GetSubMenu(HMENU hMenu, short nPos)
2192 {
2193         HMENU   hSubMenu;
2194         LPPOPUPMENU lppop;
2195         LPMENUITEM      lpitem;
2196         int             i;
2197 #ifdef DEBUG_MENU
2198         printf("GetSubMenu (%04X, %04X) !\n", hMenu, nPos);
2199 #endif
2200         if (hMenu == 0) return 0;
2201         lppop = (LPPOPUPMENU) GlobalLock(hMenu);
2202         if (lppop == NULL) return 0;
2203         lpitem = lppop->firstItem;
2204         for (i = 0; i < lppop->nItems; i++) {
2205                 if (lpitem == NULL) break;
2206                 if (i == nPos) {
2207 #ifdef DEBUG_MENU
2208                         printf("    found %04x\n", lpitem->item_id);
2209 #endif      
2210                         if (lpitem->item_flags & MF_POPUP)
2211                                 return lpitem->item_id;
2212                         else
2213                                 return 0;
2214                         }
2215                 lpitem = (LPMENUITEM)lpitem->next;
2216                 }
2217         return 0;
2218 }
2219
2220
2221 /**********************************************************************
2222  *                      DrawMenuBar             [USER.160]
2223  */
2224 void DrawMenuBar(HWND hWnd)
2225 {
2226         WND             *wndPtr;
2227         LPPOPUPMENU lppop;
2228         HDC             hDC;
2229 #ifdef DEBUG_MENU
2230         printf("DrawMenuBar (%04X)\n", hWnd);
2231 #endif
2232         wndPtr = WIN_FindWndPtr(hWnd);
2233         if (wndPtr != NULL && (wndPtr->dwStyle & WS_CHILD) == 0 && 
2234                 wndPtr->wIDmenu != 0) {
2235 #ifdef DEBUG_MENU
2236                 printf("DrawMenuBar wIDmenu=%04X \n", wndPtr->wIDmenu);
2237 #endif
2238                 lppop = (LPPOPUPMENU) GlobalLock(wndPtr->wIDmenu);
2239                 if (lppop == NULL) return;
2240                 if (lppop->Height != 0) {
2241                         int oldHeight;
2242                         oldHeight = lppop->Height;
2243                         hDC = GetWindowDC(hWnd);
2244                         StdDrawMenuBar(hDC, &lppop->rect, lppop, FALSE);
2245                         ReleaseDC(hWnd, hDC);
2246                         if (oldHeight != lppop->Height) {
2247                                 printf("DrawMenuBar // menubar changed oldHeight=%d != lppop->Height=%d\n",
2248                                                                                         oldHeight, lppop->Height);
2249                                 /* Reduce ClientRect according to MenuBar height */
2250                                 wndPtr->rectClient.top -= oldHeight;
2251                                 wndPtr->rectClient.top += lppop->Height;
2252                                 SendMessage(hWnd, WM_NCPAINT, 1, 0L);
2253                                 }
2254                         }
2255                 else
2256                         SendMessage(hWnd, WM_NCPAINT, 1, 0L);
2257                 GlobalUnlock(wndPtr->wIDmenu);
2258                 }
2259 }
2260
2261
2262 /**********************************************************************
2263  *                      LoadMenuIndirect        [USER.220]
2264  */
2265 HMENU LoadMenuIndirect(LPSTR menu_template)
2266 {
2267         HMENU                   hMenu;
2268         MENU_HEADER     *menu_desc;
2269         LPPOPUPMENU lppop;
2270 #ifdef DEBUG_MENU
2271         printf("LoadMenuIndirect: menu_template '%08X'\n", menu_template);
2272 #endif
2273         hMenu = CreateMenu();
2274         menu_desc = (MENU_HEADER *)menu_template;
2275         ParseMenuResource((WORD *)(menu_desc + 1), 0, hMenu); 
2276         lppop = (LPPOPUPMENU) GlobalLock(hMenu);
2277         ResetHiliteFlags(lppop);
2278         GlobalUnlock(hMenu);
2279         return hMenu;
2280 }
2281
2282
2283 /**********************************************************************
2284  *                      InitStdBitmaps (Internal)
2285  */
2286 void InitStdBitmaps()
2287 {
2288         if (hStdCheck == (HBITMAP)NULL) 
2289                 hStdCheck = LoadBitmap((HANDLE)NULL, (LPSTR)OBM_CHECK);
2290         if (hStdMnArrow == (HBITMAP)NULL) 
2291                 hStdMnArrow = LoadBitmap((HANDLE)NULL, (LPSTR)OBM_MNARROW);
2292 }
2293
2294
2295 /**********************************************************************
2296  *                      CopySysMenu (Internal)
2297  */
2298 HMENU CopySysMenu()
2299 {
2300         HMENU                   hMenu;
2301         LPPOPUPMENU     menu;
2302         LPPOPUPMENU     sysmenu;
2303 #ifdef DEBUG_MENU
2304         printf("CopySysMenu entry !\n");
2305 #endif
2306         if (hSysMenu == 0) {
2307 /*              hSysMenu = LoadMenu((HINSTANCE)NULL, MAKEINTRESOURCE(1)); */
2308 /*              hSysMenu = LoadMenu((HINSTANCE)NULL, MAKEINTRESOURCE(SC_SYSMENU));*/
2309                 hSysMenu = LoadMenu((HINSTANCE)NULL, "SYSMENU"); 
2310                 if (hSysMenu == 0) {
2311                         printf("SysMenu not found in system resources !\n");
2312                         return (HMENU)NULL;
2313                         }
2314 #ifdef DEBUG_MENU
2315                 else
2316                         printf("SysMenu loaded from system resources %04X !\n", hSysMenu);
2317 #endif
2318                 }
2319         hMenu = GlobalAlloc(GMEM_MOVEABLE, sizeof(POPUPMENU));
2320         menu = (LPPOPUPMENU) GlobalLock(hMenu);
2321         sysmenu = (LPPOPUPMENU) GlobalLock(hSysMenu);
2322         if (menu != NULL && sysmenu != NULL) {
2323                 sysmenu->BarFlag = FALSE;
2324                 sysmenu->SysFlag = TRUE;
2325                 memcpy(menu, sysmenu, sizeof(POPUPMENU));
2326                 }
2327         else {
2328                 printf("CopySysMenu // Bad SysMenu pointers !\n");
2329                 if (menu != NULL) {
2330                         GlobalUnlock(hMenu);
2331                         GlobalFree(hMenu);
2332                         }
2333                 return (HMENU)NULL;
2334                 }
2335         GlobalUnlock(hMenu);
2336         GlobalUnlock(hSysMenu);
2337 #ifdef DEBUG_MENU
2338         printf("CopySysMenu hMenu=%04X !\n", hMenu);
2339 #endif
2340         return hMenu;
2341 }
2342
2343
2344 /**********************************************************************
2345  *                      ParseMenuResource (from Resource or Template)
2346  */
2347 WORD * ParseMenuResource(WORD *first_item, int level, HMENU hMenu)
2348 {
2349     WORD        *item;
2350     WORD        *next_item;
2351     HMENU       hSubMenu;
2352     int         i;
2353
2354     level++;
2355     next_item = first_item;
2356     i = 0;
2357     do {
2358         i++;
2359         item = next_item;
2360         if (*item & MF_POPUP) {
2361             MENU_POPUPITEM *popup_item = (MENU_POPUPITEM *) item;
2362             next_item = (WORD *) (popup_item->item_text + 
2363                                   strlen(popup_item->item_text) + 1);
2364             hSubMenu = CreatePopupMenu();
2365             next_item = ParseMenuResource(next_item, level, hSubMenu);
2366             AppendMenu(hMenu, popup_item->item_flags, 
2367                 hSubMenu, popup_item->item_text);
2368             }
2369         else {
2370                 MENUITEMTEMPLATE *normal_item = (MENUITEMTEMPLATE *) item;
2371                 next_item = (WORD *) (normal_item->item_text + 
2372                 strlen(normal_item->item_text) + 1);
2373                 if (strlen(normal_item->item_text) == 0 && normal_item->item_id == 0) 
2374                         normal_item->item_flags |= MF_SEPARATOR;
2375                 AppendMenu(hMenu, normal_item->item_flags, 
2376                         normal_item->item_id, normal_item->item_text);
2377             }
2378         }
2379     while (!(*item & MF_END));
2380     return next_item;
2381 }
2382
2383 /**********************************************************************
2384  *              IsMenu(USER.358)
2385  */
2386 BOOL IsMenu(HMENU hMenu)
2387 {
2388         LPPOPUPMENU     menu;
2389
2390         menu = (LPPOPUPMENU) GlobalLock(hMenu);
2391         if (menu == NULL) 
2392                 return FALSE;
2393
2394         GlobalUnlock(hMenu);
2395         return TRUE;
2396 }