blob: 53d9f0ddf98093aca819faafe984109de6d662cb [file] [log] [blame]
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001/*
2 * Menus functions
3 */
Alexandre Julliard401710d1993-09-04 10:09:32 +00004static char RCSId[] = "$Id$";
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00005static char Copyright[] = "Copyright Martin Ayotte, 1993";
Alexandre Julliard401710d1993-09-04 10:09:32 +00006
Alexandre Julliardcdd09231994-01-12 11:12:51 +00007/*
Alexandre Julliard5f721f81994-01-04 20:14:34 +00008#define DEBUG_MENU
Alexandre Julliarddba420a1994-02-02 06:48:31 +00009#define DEBUG_SYSMENU
Alexandre Julliardcdd09231994-01-12 11:12:51 +000010*/
Alexandre Julliard5f721f81994-01-04 20:14:34 +000011
Alexandre Julliard401710d1993-09-04 10:09:32 +000012#include "windows.h"
Alexandre Julliarddba420a1994-02-02 06:48:31 +000013#include "sysmetrics.h"
Alexandre Julliard401710d1993-09-04 10:09:32 +000014#include "menu.h"
15#include "heap.h"
16#include "win.h"
Alexandre Julliard401710d1993-09-04 10:09:32 +000017
Alexandre Julliarddba420a1994-02-02 06:48:31 +000018#define SC_ABOUTWINE SC_SCREENSAVE+1
19#define SC_SYSMENU SC_SCREENSAVE+2
20#define SC_ABOUTWINEDLG SC_SCREENSAVE+3
21
22extern HINSTANCE hSysRes;
23HMENU hSysMenu = 0;
Alexandre Julliardcdd09231994-01-12 11:12:51 +000024HBITMAP hStdCheck = 0;
25HBITMAP hStdMnArrow = 0;
26
Alexandre Julliard5f721f81994-01-04 20:14:34 +000027LPPOPUPMENU PopupMenuGetStorageHeader(HWND hwnd);
28LPPOPUPMENU PopupMenuGetWindowAndStorage(HWND hwnd, WND **wndPtr);
Alexandre Julliardfb9a9191994-03-01 19:48:04 +000029void StdDrawMenuBar(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop);
30void MenuButtonDown(HWND hWnd, LPPOPUPMENU lppop, int x, int y);
31void MenuButtonUp(HWND hWnd, LPPOPUPMENU lppop, int x, int y);
32void MenuMouseMove(HWND hWnd, LPPOPUPMENU lppop, WORD wParam, int x, int y);
Alexandre Julliard5f721f81994-01-04 20:14:34 +000033void StdDrawPopupMenu(HWND hwnd);
Alexandre Julliardfb9a9191994-03-01 19:48:04 +000034LPMENUITEM MenuFindItem(LPPOPUPMENU lppop, int x, int y, WORD *lpRet);
35LPMENUITEM MenuFindItemBySelKey(LPPOPUPMENU lppop, WORD key, WORD *lpRet);
Alexandre Julliardcdd09231994-01-12 11:12:51 +000036void PopupMenuCalcSize(HWND hwnd);
Alexandre Julliardfb9a9191994-03-01 19:48:04 +000037void MenuBarCalcSize(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop);
Alexandre Julliard5f721f81994-01-04 20:14:34 +000038LPMENUITEM GetMenuItemPtr(LPPOPUPMENU menu, WORD nPos);
Alexandre Julliardcdd09231994-01-12 11:12:51 +000039WORD GetSelectionKey(LPSTR str);
40LPSTR GetShortCutString(LPSTR str);
41WORD GetShortCutPos(LPSTR str);
42BOOL HideAllSubPopupMenu(LPPOPUPMENU menu);
Alexandre Julliarddba420a1994-02-02 06:48:31 +000043HMENU CopySysMenu();
Alexandre Julliardcdd09231994-01-12 11:12:51 +000044WORD * ParseMenuResource(WORD *first_item, int level, HMENU hMenu);
45void SetMenuLogicalParent(HMENU hMenu, HWND hWnd);
Alexandre Julliard5f721f81994-01-04 20:14:34 +000046
Alexandre Julliarddba420a1994-02-02 06:48:31 +000047BOOL FAR PASCAL AboutWine_Proc(HWND hDlg, WORD msg, WORD wParam, LONG lParam);
48
Alexandre Julliard5f721f81994-01-04 20:14:34 +000049/***********************************************************************
50 * PopupMenuWndProc
51 */
52LONG PopupMenuWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam )
53{
54 CREATESTRUCT *createStruct;
55 WORD wRet;
56 short x, y;
57 WND *wndPtr;
Alexandre Julliardcdd09231994-01-12 11:12:51 +000058 LPPOPUPMENU lppop, lppop2;
Alexandre Julliard5f721f81994-01-04 20:14:34 +000059 LPMENUITEM lpitem, lpitem2;
60 HMENU hSubMenu;
61 RECT rect;
62 HDC hDC;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +000063 PAINTSTRUCT ps;
Alexandre Julliard5f721f81994-01-04 20:14:34 +000064 switch(message)
65 {
66 case WM_CREATE:
67#ifdef DEBUG_MENU
68 printf("PopupMenu WM_CREATE lParam=%08X !\n", lParam);
69#endif
70 createStruct = (CREATESTRUCT *)lParam;
71 lppop = (LPPOPUPMENU)createStruct->lpCreateParams;
Alexandre Julliardcdd09231994-01-12 11:12:51 +000072 if (lppop == NULL) break;
Alexandre Julliard5f721f81994-01-04 20:14:34 +000073 wndPtr = WIN_FindWndPtr(hwnd);
74 *((LPPOPUPMENU *)&wndPtr->wExtra[1]) = lppop;
75#ifdef DEBUG_MENU
76 printf("PopupMenu WM_CREATE lppop=%08X !\n", lppop);
77#endif
Alexandre Julliardcdd09231994-01-12 11:12:51 +000078 if (hStdCheck == (HBITMAP)NULL)
79 hStdCheck = LoadBitmap((HANDLE)NULL, (LPSTR)OBM_CHECK);
80 if (hStdMnArrow == (HBITMAP)NULL)
81 hStdMnArrow = LoadBitmap((HANDLE)NULL, (LPSTR)OBM_MNARROW);
Alexandre Julliard5f721f81994-01-04 20:14:34 +000082 return 0;
83 case WM_DESTROY:
84 lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
85#ifdef DEBUG_MENU
86 printf("PopupMenu WM_DESTROY %lX !\n", lppop);
87#endif
88 return 0;
Alexandre Julliardcdd09231994-01-12 11:12:51 +000089 case WM_COMMAND:
90 lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
Alexandre Julliarddba420a1994-02-02 06:48:31 +000091 if (lppop->hWndParent != (HWND)NULL) {
Alexandre Julliardcdd09231994-01-12 11:12:51 +000092 SendMessage(lppop->hWndParent, WM_COMMAND, wParam, lParam);
Alexandre Julliarddba420a1994-02-02 06:48:31 +000093#ifdef DEBUG_MENU
94 printf("PopupMenu // push to lower parent WM_COMMAND !\n");
95#endif
96 }
97 else {
98 if (lppop->SysFlag == 0) {
99 SendMessage(lppop->ownerWnd, WM_COMMAND, wParam, lParam);
100#ifdef DEBUG_MENU
101 printf("PopupMenu // push to Owner WM_COMMAND !\n");
102#endif
103 }
104 else {
105#ifdef DEBUG_SYSMENU
106 printf("PopupMenu // push to Owner WM_SYSCOMMAND !\n");
107#endif
108 SendMessage(lppop->ownerWnd, WM_SYSCOMMAND, wParam, lParam);
109 }
110 }
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000111 if (lppop->BarFlags == 0) ShowWindow(hwnd, SW_HIDE);
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000112 break;
113 case WM_SHOWWINDOW:
114 lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000115 if (wParam == 0 && lParam == 0L) {
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000116 HideAllSubPopupMenu(lppop);
117#ifdef DEBUG_MENU
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000118 printf("PopupMenu WM_SHOWWINDOW -> HIDE!\n");
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000119#endif
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000120/*
121 UpdateWindow(lppop->ownerWnd);
122*/
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000123 break;
124 }
125 lppop->FocusedItem = (WORD)-1;
126 if (lppop->BarFlags == 0) {
127 PopupMenuCalcSize(hwnd);
128#ifdef DEBUG_MENU
129 printf("PopupMenu WM_SHOWWINDOW Width=%d Height=%d !\n",
130 lppop->Width, lppop->Height);
131#endif
132 SetWindowPos(hwnd, 0, 0, 0, lppop->Width + 2, lppop->Height,
133 SWP_NOZORDER | SWP_NOMOVE);
134 }
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000135 break;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000136 case WM_LBUTTONDOWN:
137 lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
138 SetCapture(hwnd);
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000139 MenuButtonDown(hwnd, lppop, LOWORD(lParam), HIWORD(lParam));
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000140 break;
141 case WM_LBUTTONUP:
142 lppop = PopupMenuGetStorageHeader(hwnd);
143 ReleaseCapture();
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000144 MenuButtonUp(hwnd, lppop, LOWORD(lParam), HIWORD(lParam));
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000145 break;
146 case WM_MOUSEMOVE:
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000147 lppop = PopupMenuGetStorageHeader(hwnd);
148 MenuMouseMove(hwnd, lppop, wParam, LOWORD(lParam), HIWORD(lParam));
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000149 break;
150
151 case WM_KEYDOWN:
152 case WM_KEYUP:
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000153 if (lParam < 0L) break;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000154 lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000155 if (lppop->FocusedItem == (WORD)-1) {
156 if (wParam == VK_UP || wParam == VK_DOWN ||
157 wParam == VK_LEFT || wParam == VK_RIGHT) {
158 hDC = GetDC(hwnd);
159 lppop->FocusedItem = 0;
160 lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem);
161 if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) ||
162 ((lpitem->item_flags & MF_STRING) == MF_STRING)) {
163 InvertRect(hDC, &lpitem->rect);
164 }
165 ReleaseDC(hwnd, hDC);
166 }
167 break;
168 }
169 switch(wParam) {
170 case VK_UP:
171 if (lppop->BarFlags != 0) break;
172 if (lppop->FocusedItem < 1) break;
173 lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem);
174 if ((lpitem->item_flags & MF_POPUP) == MF_POPUP)
175 HideAllSubPopupMenu(lppop);
176 hDC = GetDC(hwnd);
177 if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) ||
178 ((lpitem->item_flags & MF_STRING) == MF_STRING)) {
179 InvertRect(hDC, &lpitem->rect);
180 }
181 lppop->FocusedItem--;
182 lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem);
183 if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) ||
184 ((lpitem->item_flags & MF_STRING) == MF_STRING)) {
185 InvertRect(hDC, &lpitem->rect);
186 }
187 ReleaseDC(hwnd, hDC);
188 break;
189 case VK_DOWN:
190 if (lppop->BarFlags != 0) goto ProceedSPACE;
191 if (lppop->FocusedItem >= lppop->nItems - 1) break;
192 lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem);
193 if ((lpitem->item_flags & MF_POPUP) == MF_POPUP)
194 HideAllSubPopupMenu(lppop);
195 hDC = GetDC(hwnd);
196 if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) ||
197 ((lpitem->item_flags & MF_STRING) == MF_STRING)) {
198 InvertRect(hDC, &lpitem->rect);
199 }
200 lppop->FocusedItem++;
201 lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem);
202 if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) ||
203 ((lpitem->item_flags & MF_STRING) == MF_STRING)) {
204 InvertRect(hDC, &lpitem->rect);
205 }
206 ReleaseDC(hwnd, hDC);
207 break;
208 case VK_LEFT:
209 if (lppop->BarFlags == 0) {
210 if (lppop->hWndParent != 0)
211 SendMessage(lppop->hWndParent, WM_KEYDOWN, wParam, lParam);
212 break;
213 }
214 if (lppop->FocusedItem < 1) break;
215 lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem);
216 if ((lpitem->item_flags & MF_POPUP) == MF_POPUP)
217 HideAllSubPopupMenu(lppop);
218 hDC = GetDC(hwnd);
219 if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) ||
220 ((lpitem->item_flags & MF_STRING) == MF_STRING)) {
221 InvertRect(hDC, &lpitem->rect);
222 }
223 lppop->FocusedItem--;
224 lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem);
225 if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) ||
226 ((lpitem->item_flags & MF_STRING) == MF_STRING)) {
227 InvertRect(hDC, &lpitem->rect);
228 }
229 ReleaseDC(hwnd, hDC);
230 break;
231 case VK_RIGHT:
232 if (lppop->BarFlags == 0) {
233 if (lppop->hWndParent != 0)
234 SendMessage(lppop->hWndParent, WM_KEYDOWN, wParam, lParam);
235 break;
236 }
237 if (lppop->FocusedItem >= lppop->nItems - 1) break;
238 lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem);
239 if ((lpitem->item_flags & MF_POPUP) == MF_POPUP)
240 HideAllSubPopupMenu(lppop);
241 hDC = GetDC(hwnd);
242 if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) ||
243 ((lpitem->item_flags & MF_STRING) == MF_STRING)) {
244 InvertRect(hDC, &lpitem->rect);
245 }
246 lppop->FocusedItem++;
247 lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem);
248 if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) ||
249 ((lpitem->item_flags & MF_STRING) == MF_STRING)) {
250 InvertRect(hDC, &lpitem->rect);
251 }
252 ReleaseDC(hwnd, hDC);
253 break;
254 case VK_RETURN:
255 case VK_SPACE:
256ProceedSPACE:
257 printf("PopupMenu VK_SPACE !\n");
258 lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem);
259 if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
260 hSubMenu = (HMENU)lpitem->item_id;
261 lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu);
262 if (lppop2 == NULL) break;
263 lppop2->hWndParent = hwnd;
264 GetClientRect(hwnd, &rect);
265 if (lppop->BarFlags != 0) {
266 y = rect.bottom - rect.top;
267 TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON,
268 lpitem->rect.left, 0,
269 0, lppop->ownerWnd, (LPRECT)NULL);
270 }
271 else {
272 x = rect.right;
273 GetWindowRect(hwnd, &rect);
274 x += rect.left;
275 TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON,
276 x, lpitem->rect.top,
277 0, lppop->ownerWnd, (LPRECT)NULL);
278 }
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000279 GlobalUnlock(hSubMenu);
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000280 break;
281 }
282 if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
283 ((lpitem->item_flags & MF_POPUP) != MF_POPUP)) {
284 ShowWindow(lppop->hWnd, SW_HIDE);
285 if (lppop->hWndParent != (HWND)NULL)
286 SendMessage(lppop->hWndParent, WM_COMMAND,
287 lpitem->item_id, 0L);
288 else
289 SendMessage(lppop->ownerWnd, WM_COMMAND,
290 lpitem->item_id, 0L);
291#ifdef DEBUG_MENU
292 printf("PopupMenu // SendMessage WM_COMMAND wParam=%d !\n",
293 lpitem->item_id);
294#endif
295 }
296 break;
297 }
298 break;
299 case WM_CHAR:
300 if (lParam < 0L) break;
301 lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
302 if (wParam == VK_ESCAPE) {
303 if (lppop->hWndParent != 0) {
304 lppop2 = PopupMenuGetWindowAndStorage(
305 lppop->hWndParent, &wndPtr);
306 HideAllSubPopupMenu(lppop2);
307 break;
308 }
309 if (lppop->FocusedItem != (WORD)-1) {
310 lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem);
311 hDC = GetDC(hwnd);
312 if (((lpitem2->item_flags & MF_POPUP) == MF_POPUP) ||
313 ((lpitem2->item_flags & MF_STRING) == MF_STRING)) {
314 InvertRect(hDC, &lpitem2->rect);
315 }
316 ReleaseDC(hwnd, hDC);
317 lppop->FocusedItem = (WORD)-1;
318 }
319 }
320 if (wParam >= 'a' && wParam <= 'z') wParam -= 'a' - 'A';
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000321 lpitem = MenuFindItemBySelKey(lppop, wParam, &wRet);
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000322 if (lpitem != NULL) {
323 printf("Found wRet=%d !\n", wRet);
324 if (lppop->FocusedItem != (WORD)-1) {
325 lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem);
326 if ((lpitem2->item_flags & MF_POPUP) == MF_POPUP)
327 HideAllSubPopupMenu(lppop);
328 hDC = GetDC(hwnd);
329 if (((lpitem2->item_flags & MF_POPUP) == MF_POPUP) ||
330 ((lpitem2->item_flags & MF_STRING) == MF_STRING)) {
331 InvertRect(hDC, &lpitem2->rect);
332 }
333 ReleaseDC(hwnd, hDC);
334 }
335 lppop->FocusedItem = wRet;
336 goto ProceedSPACE;
337 }
338 break;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000339 case WM_PAINT:
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000340 lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000341 if (lppop->BarFlags == 0) {
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000342 PopupMenuCalcSize(hwnd);
343 StdDrawPopupMenu(hwnd);
344 }
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000345 break;
346 default:
347 return DefWindowProc( hwnd, message, wParam, lParam );
348 }
349return(0);
350}
351
352
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000353void MenuButtonDown(HWND hWnd, LPPOPUPMENU lppop, int x, int y)
354{
355 HDC hDC;
356 LPMENUITEM lpitem, lpitem2;
357 RECT rect;
358 HMENU hSubMenu;
359 WORD wRet;
360 LPPOPUPMENU lppop2;
361 lpitem = MenuFindItem(lppop, x, y, &wRet);
362#ifdef DEBUG_MENU
363 printf("MenuButtonDown // x=%d y=%d // wRet=%d lpitem=%08X !\n",
364 x, y, wRet, lpitem);
365#endif
366 if (lpitem != NULL) {
367 if (lppop->FocusedItem != (WORD)-1) {
368 HideAllSubPopupMenu(lppop);
369 lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem);
370 if (((lpitem2->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
371 ((lpitem2->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) {
372 hDC = GetWindowDC(hWnd);
373 InvertRect(hDC, &lpitem2->rect);
374 ReleaseDC(hWnd, hDC);
375 }
376 }
377 lppop->FocusedItem = wRet;
378 if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
379 ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) {
380 hDC = GetWindowDC(hWnd);
381 InvertRect(hDC, &lpitem->rect);
382 ReleaseDC(hWnd, hDC);
383 }
384 if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
385 hSubMenu = (HMENU)lpitem->item_id;
386 lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu);
387 if (lppop2 == NULL) return;
388 lppop2->hWndParent = hWnd;
389 if (lppop->BarFlags != 0) {
390 GetWindowRect(hWnd, &rect);
391/* y = rect.top + lppop->Height; */
392 y = rect.top + lppop->rect.bottom;
393 TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON,
394 rect.left + lpitem->rect.left,
395 y, 0, lppop->ownerWnd, (LPRECT)NULL);
396 }
397 else {
398 x = lppop->rect.right;
399 GetWindowRect(hWnd, &rect);
400 x += rect.left;
401 TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON,
402 x, rect.top + lpitem->rect.top,
403 0, lppop->ownerWnd, (LPRECT)NULL);
404 }
405 GlobalUnlock(hSubMenu);
406 }
407 }
408}
409
410
411
412void MenuButtonUp(HWND hWnd, LPPOPUPMENU lppop, int x, int y)
413{
414 HDC hDC;
415 LPMENUITEM lpitem, lpitem2;
416 RECT rect;
417 HMENU hSubMenu;
418 WORD wRet;
419 LPPOPUPMENU lppop2;
420 lpitem = MenuFindItem(lppop, x, y, &wRet);
421#ifdef DEBUG_MENU
422 printf("MenuButtonUp // x=%d y=%d // wRet=%d lpitem=%08X !\n",
423 x, y, wRet, lpitem);
424#endif
425 if (lpitem != NULL) {
426 if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
427 return;
428 }
429 if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
430 ((lpitem->item_flags & MF_POPUP) != MF_POPUP)) {
431 ShowWindow(lppop->hWnd, SW_HIDE);
432 if (lppop->hWndParent != (HWND)NULL) {
433 SendMessage(lppop->hWndParent, WM_COMMAND,
434 lpitem->item_id, 0L);
435#ifdef DEBUG_MENU
436 printf("MenuButtonUp // WM_COMMAND to ParentMenu wParam=%d !\n",
437 lpitem->item_id);
438#endif
439 }
440 else {
441 if (lppop->SysFlag == 0) {
442#ifdef DEBUG_MENU
443 printf("PopupMenu // WM_COMMAND wParam=%d !\n",
444 lpitem->item_id);
445#endif
446 SendMessage(lppop->ownerWnd, WM_COMMAND,
447 lpitem->item_id, 0L);
448 }
449 else {
450 if (lpitem->item_id == SC_ABOUTWINE) {
451 printf("SysMenu // Show 'About Wine ...' !\n");
452/* DialogBox(hSysRes, MAKEINTRESOURCE(SC_ABOUTWINEDLG), */
453 DialogBox(hSysRes, MAKEINTRESOURCE(2),
454 GetParent(hWnd), (FARPROC)AboutWine_Proc);
455 }
456 else {
457 SendMessage(lppop->ownerWnd, WM_SYSCOMMAND,
458 lpitem->item_id, 0L);
459#ifdef DEBUG_SYSMENU
460 printf("MenuButtonUp // WM_SYSCOMMAND wParam=%04X !\n",
461 lpitem->item_id);
462#endif
463 }
464 }
465 }
466#ifdef DEBUG_MENU
467 printf("MenuButtonUp // SendMessage WM_COMMAND wParam=%d !\n",
468 lpitem->item_id);
469#endif
470 return;
471 }
472 }
473 if (lppop->FocusedItem != (WORD)-1) {
474 HideAllSubPopupMenu(lppop);
475 lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem);
476 if (((lpitem2->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
477 ((lpitem2->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) {
478 hDC = GetWindowDC(hWnd);
479 InvertRect(hDC, &lpitem2->rect);
480 ReleaseDC(hWnd, hDC);
481 }
482 }
483}
484
485
486
487void MenuMouseMove(HWND hWnd, LPPOPUPMENU lppop, WORD wParam, int x, int y)
488{
489 HDC hDC;
490 LPMENUITEM lpitem, lpitem2;
491 RECT rect;
492 HMENU hSubMenu;
493 WORD wRet;
494 LPPOPUPMENU lppop2;
495 if ((wParam & MK_LBUTTON) != 0) {
496 lpitem = MenuFindItem(lppop, x, y, &wRet);
497#ifdef DEBUG_MENU
498 printf("MenuMouseMove // x=%d y=%d // wRet=%d lpitem=%08X !\n",
499 x, y, wRet, lpitem);
500#endif
501 if ((lpitem != NULL) && (lppop->FocusedItem != wRet)) {
502 lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem);
503 hDC = GetWindowDC(hWnd);
504 if (((lpitem2->item_flags & MF_POPUP) == MF_POPUP) ||
505 ((lpitem2->item_flags & MF_STRING) == MF_STRING)) {
506 InvertRect(hDC, &lpitem2->rect);
507 }
508 if ((lpitem2->item_flags & MF_POPUP) == MF_POPUP) {
509 HideAllSubPopupMenu(lppop);
510 }
511 lppop->FocusedItem = wRet;
512 if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) ||
513 ((lpitem->item_flags & MF_STRING) == MF_STRING)) {
514 InvertRect(hDC, &lpitem->rect);
515 }
516 if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
517 hSubMenu = (HMENU)lpitem->item_id;
518 lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu);
519 if (lppop2 == NULL) {
520 ReleaseDC(hWnd, hDC);
521 return;
522 }
523 if (lppop->BarFlags != 0) {
524 lppop2->hWndParent = hWnd;
525 GetWindowRect(hWnd, &rect);
526 rect.top += lppop->rect.bottom;
527 TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON,
528 rect.left + lpitem->rect.left, rect.top,
529 0, lppop->ownerWnd, (LPRECT)NULL);
530 }
531 GlobalUnlock(hSubMenu);
532 }
533 ReleaseDC(hWnd, hDC);
534 }
535 }
536}
537
538
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000539
540LPPOPUPMENU PopupMenuGetWindowAndStorage(HWND hwnd, WND **wndPtr)
541{
542 WND *Ptr;
543 LPPOPUPMENU lppop;
544 *(wndPtr) = Ptr = WIN_FindWndPtr(hwnd);
545 if (Ptr == 0) {
546 printf("Bad Window handle on PopupMenu !\n");
547 return 0;
548 }
549 lppop = *((LPPOPUPMENU *)&Ptr->wExtra[1]);
550 return lppop;
551}
552
553
554LPPOPUPMENU PopupMenuGetStorageHeader(HWND hwnd)
555{
556 WND *Ptr;
557 LPPOPUPMENU lppop;
558 Ptr = WIN_FindWndPtr(hwnd);
559 if (Ptr == 0) {
560 printf("Bad Window handle on PopupMenu !\n");
561 return 0;
562 }
563 lppop = *((LPPOPUPMENU *)&Ptr->wExtra[1]);
564 return lppop;
565}
566
567
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000568void SetMenuLogicalParent(HMENU hMenu, HWND hWnd)
569{
570 LPPOPUPMENU lppop;
571 lppop = (LPPOPUPMENU)GlobalLock(hMenu);
572 lppop->hWndParent = hWnd;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000573 GlobalUnlock(hMenu);
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000574}
575
576
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000577void StdDrawPopupMenu(HWND hwnd)
578{
579 WND *wndPtr;
580 LPPOPUPMENU lppop;
581 LPMENUITEM lpitem;
582 PAINTSTRUCT ps;
583 HBRUSH hBrush;
584 HPEN hOldPen;
585 HWND hWndParent;
586 HDC hDC, hMemDC;
587 RECT rect, rect2, rect3;
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000588 DWORD OldTextColor;
589 HFONT hOldFont;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000590 HBITMAP hBitMap;
591 BITMAP bm;
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000592 UINT i, x;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000593 hDC = BeginPaint( hwnd, &ps );
594 if (!IsWindowVisible(hwnd)) {
595 EndPaint( hwnd, &ps );
596 return;
597 }
598 lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
599 if (lppop == NULL) goto EndOfPaint;
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000600 hBrush = GetStockObject(WHITE_BRUSH);
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000601 GetClientRect(hwnd, &rect);
602 GetClientRect(hwnd, &rect2);
603 FillRect(hDC, &rect, hBrush);
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000604 FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH));
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000605 if (lppop->nItems == 0) goto EndOfPaint;
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000606 lpitem = lppop->firstItem;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000607 if (lpitem == NULL) goto EndOfPaint;
608 for(i = 0; i < lppop->nItems; i++) {
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000609 CopyRect(&rect2, &lpitem->rect);
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000610 if ((lpitem->item_flags & MF_SEPARATOR) == MF_SEPARATOR) {
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000611 hOldPen = SelectObject(hDC, GetStockObject(BLACK_PEN));
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000612 MoveTo(hDC, rect2.left, rect2.top + 1);
613 LineTo(hDC, rect2.right, rect2.top + 1);
614 SelectObject(hDC, hOldPen);
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000615 }
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000616 if ((lpitem->item_flags & MF_CHECKED) == MF_CHECKED) {
617 hMemDC = CreateCompatibleDC(hDC);
618 if (lpitem->hCheckBit == 0) {
619 SelectObject(hMemDC, hStdCheck);
620 GetObject(hStdCheck, sizeof(BITMAP), (LPSTR)&bm);
621 }
622 else {
623 SelectObject(hMemDC, lpitem->hCheckBit);
624 GetObject(lpitem->hCheckBit, sizeof(BITMAP), (LPSTR)&bm);
625 }
626 BitBlt(hDC, rect2.left, rect2.top + 1,
627 bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
628 DeleteDC(hMemDC);
629 }
630 else {
631 if (lpitem->hUnCheckBit != 0) {
632 hMemDC = CreateCompatibleDC(hDC);
633 SelectObject(hMemDC, lpitem->hUnCheckBit);
634 GetObject(lpitem->hUnCheckBit, sizeof(BITMAP), (LPSTR)&bm);
635 BitBlt(hDC, rect2.left, rect2.top + 1,
636 bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
637 DeleteDC(hMemDC);
638 }
639 }
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000640 if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) {
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000641 hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text);
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000642 rect2.left += lppop->CheckWidth;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000643 hMemDC = CreateCompatibleDC(hDC);
644 SelectObject(hMemDC, hBitMap);
645 GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm);
646 BitBlt(hDC, rect2.left, rect2.top,
647 bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
648 DeleteDC(hMemDC);
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000649 }
650 if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) &&
651 ((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
652 ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) {
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000653 hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT));
654 if ((lpitem->item_flags & MF_DISABLED) == MF_DISABLED)
655 OldTextColor = SetTextColor(hDC, 0x00C0C0C0L);
656 else
657 OldTextColor = SetTextColor(hDC, 0x00000000L);
658 CopyRect(&rect3, &lpitem->rect);
659 InflateRect(&rect3, 0, -2);
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000660 rect3.left += lppop->CheckWidth;
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000661 if ((x = GetShortCutPos(lpitem->item_text)) != (WORD)-1) {
662 DrawText(hDC, lpitem->item_text, x, &rect3,
663 DT_LEFT | DT_VCENTER | DT_SINGLELINE);
664 DrawText(hDC, &lpitem->item_text[x], -1, &rect3,
665 DT_RIGHT | DT_VCENTER | DT_SINGLELINE);
666 }
667 else
668 DrawText(hDC, lpitem->item_text, -1, &rect3,
669 DT_LEFT | DT_VCENTER | DT_SINGLELINE);
670 SetTextColor(hDC, OldTextColor);
671 SelectObject(hDC, hOldFont);
672 CopyRect(&rect2, &lpitem->rect);
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000673 }
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000674 if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000675 CopyRect(&rect3, &lpitem->rect);
676 rect3.left = rect3.right - lppop->PopWidth;
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000677 hMemDC = CreateCompatibleDC(hDC);
678 SelectObject(hMemDC, hStdMnArrow);
679 GetObject(hStdMnArrow, sizeof(BITMAP), (LPSTR)&bm);
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000680 BitBlt(hDC, rect3.left, rect3.top + 1,
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000681 bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
682 DeleteDC(hMemDC);
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000683 }
684 if (lpitem->next == NULL) goto EndOfPaint;
685 lpitem = (LPMENUITEM)lpitem->next;
686 }
687EndOfPaint:
688 EndPaint( hwnd, &ps );
689}
690
691
692
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000693void StdDrawMenuBar(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop)
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000694{
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000695 LPMENUITEM lpitem;
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000696 HBRUSH hBrush;
697 HPEN hOldPen;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000698 HDC hMemDC;
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000699 RECT rect, rect2, rect3;
700 HFONT hOldFont;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000701 DWORD OldTextColor;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000702 HBITMAP hBitMap;
703 BITMAP bm;
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000704 UINT i, textwidth;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000705 if (lppop == NULL || lprect == NULL) return;
706#ifdef DEBUG_MENU
707 printf("StdDrawMenuBar(%04X, %08X, %08X); !\n", hDC, lprect, lppop);
708#endif
709 MenuBarCalcSize(hDC, lprect, lppop);
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000710 hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT));
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000711 hBrush = GetStockObject(WHITE_BRUSH);
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000712 CopyRect(&rect, lprect);
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000713 FillRect(hDC, &rect, hBrush);
714 FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH));
715 if (lppop->nItems == 0) goto EndOfPaint;
716 lpitem = lppop->firstItem;
717 if (lpitem == NULL) goto EndOfPaint;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000718 for(i = 0; i < lppop->nItems; i++) {
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000719 CopyRect(&rect2, &lpitem->rect);
720 if ((lpitem->item_flags & MF_CHECKED) == MF_CHECKED) {
721 hMemDC = CreateCompatibleDC(hDC);
722 if (lpitem->hCheckBit == 0) {
723 SelectObject(hMemDC, hStdCheck);
724 GetObject(hStdCheck, sizeof(BITMAP), (LPSTR)&bm);
725 }
726 else {
727 SelectObject(hMemDC, lpitem->hCheckBit);
728 GetObject(lpitem->hCheckBit, sizeof(BITMAP), (LPSTR)&bm);
729 }
730 BitBlt(hDC, rect2.left, rect2.top + 1,
731 bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
732 DeleteDC(hMemDC);
733 }
734 else {
735 if (lpitem->hUnCheckBit != 0) {
736 hMemDC = CreateCompatibleDC(hDC);
737 SelectObject(hMemDC, lpitem->hUnCheckBit);
738 GetObject(lpitem->hUnCheckBit, sizeof(BITMAP), (LPSTR)&bm);
739 BitBlt(hDC, rect2.left, rect2.top + 1,
740 bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
741 DeleteDC(hMemDC);
742 }
743 }
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000744 if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) {
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000745 hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text);
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000746 hMemDC = CreateCompatibleDC(hDC);
747 SelectObject(hMemDC, hBitMap);
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000748 GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm);
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000749 BitBlt(hDC, rect2.left, rect2.top,
750 bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
751 DeleteDC(hMemDC);
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000752 }
753 if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) &&
754 ((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
755 ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) {
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000756 hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT));
757 if ((lpitem->item_flags & MF_DISABLED) == MF_DISABLED)
758 OldTextColor = SetTextColor(hDC, 0x00C0C0C0L);
759 else
760 OldTextColor = SetTextColor(hDC, 0x00000000L);
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000761 DrawText(hDC, lpitem->item_text, -1, &rect2,
762 DT_LEFT | DT_VCENTER | DT_SINGLELINE);
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000763 SetTextColor(hDC, OldTextColor);
764 SelectObject(hDC, hOldFont);
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000765 }
766 if (lpitem->next == NULL) goto EndOfPaint;
767 lpitem = (LPMENUITEM)lpitem->next;
768 }
769EndOfPaint:
770 SelectObject(hDC, hOldFont);
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000771}
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000772
773
774
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000775LPMENUITEM MenuFindItem(LPPOPUPMENU lppop, int x, int y, WORD *lpRet)
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000776{
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000777 LPMENUITEM lpitem;
778 UINT i;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000779 if (lpRet != NULL) *lpRet = 0;
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000780 if (lppop == NULL) return NULL;
781 if (lppop->nItems == 0) return NULL;
782 lpitem = lppop->firstItem;
783 for(i = 0; i < lppop->nItems; i++) {
784 if (lpitem == NULL) return NULL;
785#ifdef DEBUG_MENUFINDITEM
786 printf("FindItem // left=%d top=%d right=%d bottom=%d\n",
787 lpitem->rect.left, lpitem->rect.top,
788 lpitem->rect.right, lpitem->rect.bottom);
789#endif
790 if (x > lpitem->rect.left && x < lpitem->rect.right &&
791 y > lpitem->rect.top && y < lpitem->rect.bottom) {
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000792 if (lpRet != NULL) *lpRet = i;
793 return lpitem;
794 }
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000795 lpitem = (LPMENUITEM)lpitem->next;
796 }
797 return NULL;
798}
799
800
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000801LPMENUITEM MenuFindItemBySelKey(LPPOPUPMENU lppop, WORD key, WORD *lpRet)
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000802{
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000803 LPMENUITEM lpitem;
804 UINT i;
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000805 if (lppop == NULL) return NULL;
806 if (lppop->nItems == 0) return NULL;
807 lpitem = lppop->firstItem;
808 for(i = 0; i < lppop->nItems; i++) {
809 if (lpitem == NULL) return NULL;
810#ifdef DEBUG_MENUFINDITEM
811 printf("FindItemBySelKey // key=%d lpitem->sel_key=%d\n",
812 key, lpitem->sel_key);
813#endif
814 if (key == lpitem->sel_key) {
815 if (lpRet != NULL) *lpRet = i;
816 return lpitem;
817 }
818 lpitem = (LPMENUITEM)lpitem->next;
819 }
820 return NULL;
821}
822
823
824void PopupMenuCalcSize(HWND hwnd)
825{
826 WND *wndPtr;
827 LPPOPUPMENU lppop;
828 LPMENUITEM lpitem;
829 HDC hDC;
830 RECT rect;
831 HBITMAP hBitMap;
832 BITMAP bm;
833 HFONT hOldFont;
834 UINT i, OldWidth, TempWidth;
835 DWORD dwRet;
Alexandre Julliarddba420a1994-02-02 06:48:31 +0000836#ifdef DEBUG_MENUCALC
837 printf("PopupMenuCalcSize hWnd=%04X !\n", hWnd);
838#endif
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000839 lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
840 if (lppop == NULL) return;
841 if (lppop->nItems == 0) return;
842 hDC = GetDC(hwnd);
843 lppop->Width = 20;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000844 lppop->CheckWidth = lppop->PopWidth = 0;
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000845 hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT));
846CalcAGAIN:
847 OldWidth = lppop->Width;
848 SetRect(&rect, 1, 1, OldWidth, 0);
849 lpitem = lppop->firstItem;
850 for(i = 0; i < lppop->nItems; i++) {
851 if (lpitem == NULL) break;
Alexandre Julliarddba420a1994-02-02 06:48:31 +0000852#ifdef DEBUG_MENUCALC
853 printf("PopupMenuCalcSize item #%d !\n", i);
854#endif
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000855 rect.right = rect.left + lppop->Width;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000856 if ((lpitem->item_flags & MF_CHECKED) == MF_CHECKED) {
857 if (lpitem->hCheckBit != 0)
858 GetObject(lpitem->hCheckBit, sizeof(BITMAP), (LPSTR)&bm);
859 else
860 GetObject(hStdCheck, sizeof(BITMAP), (LPSTR)&bm);
861 lppop->CheckWidth = max(lppop->CheckWidth, bm.bmWidth);
862 }
863 else {
864 if (lpitem->hUnCheckBit != 0) {
865 GetObject(lpitem->hUnCheckBit, sizeof(BITMAP), (LPSTR)&bm);
866 lppop->CheckWidth = max(lppop->CheckWidth, bm.bmWidth);
867 }
868 }
869 if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
870 GetObject(hStdMnArrow, sizeof(BITMAP), (LPSTR)&bm);
871 lppop->PopWidth = max(lppop->PopWidth, bm.bmWidth);
872 }
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000873 if ((lpitem->item_flags & MF_SEPARATOR) == MF_SEPARATOR) {
874 rect.bottom = rect.top + 3;
875 }
876 if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) {
877 hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text);
878 GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm);
879 rect.bottom = rect.top + bm.bmHeight;
880 lppop->Width = max(lppop->Width, bm.bmWidth);
881 }
882 if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) &&
883 ((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
884 ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) {
885 dwRet = GetTextExtent(hDC, (char *)lpitem->item_text,
886 strlen((char *)lpitem->item_text));
887 rect.bottom = rect.top + HIWORD(dwRet);
888 InflateRect(&rect, 0, 2);
889 TempWidth = LOWORD(dwRet);
890 if (GetShortCutPos(lpitem->item_text) != (WORD)-1)
891 TempWidth += 15;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000892 TempWidth += lppop->CheckWidth;
893 TempWidth += lppop->PopWidth;
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000894 lppop->Width = max(lppop->Width, TempWidth);
895 }
896 CopyRect(&lpitem->rect, &rect);
897 rect.top = rect.bottom;
898 lpitem = (LPMENUITEM)lpitem->next;
899 }
900 if (OldWidth < lppop->Width) goto CalcAGAIN;
901 lppop->Height = rect.bottom;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000902 SetRect(&lppop->rect, 1, 1, lppop->Width, lppop->Height);
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000903#ifdef DEBUG_MENUCALC
Alexandre Julliarddba420a1994-02-02 06:48:31 +0000904 printf("PopupMenuCalcSize w=%d h=%d !\n", lppop->Width, lppop->Height);
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000905#endif
906 SelectObject(hDC, hOldFont);
Alexandre Julliarddba420a1994-02-02 06:48:31 +0000907 ReleaseDC(hwnd, hDC);
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000908}
909
910
911
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000912void MenuBarCalcSize(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop)
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000913{
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000914 LPMENUITEM lpitem;
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000915 RECT rect;
916 HBITMAP hBitMap;
917 BITMAP bm;
918 HFONT hOldFont;
919 UINT i, OldHeight;
920 DWORD dwRet;
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000921 if (lppop == NULL) return;
922 if (lppop->nItems == 0) return;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000923#ifdef DEBUG_MENUCALC
924 printf("MenuBarCalcSize left=%d top=%d right=%d bottom=%d !\n",
925 lprect->left, lprect->top, lprect->right, lprect->bottom);
926#endif
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000927 hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT));
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000928 lppop->Height = lprect->bottom - lprect->top;
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000929CalcAGAIN:
930 OldHeight = lppop->Height;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000931 SetRect(&rect, lprect->left, lprect->top, 0, lprect->top + OldHeight);
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000932 lpitem = lppop->firstItem;
933 for(i = 0; i < lppop->nItems; i++) {
934 if (lpitem == NULL) break;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000935 rect.bottom = lprect->top + lppop->Height;
936 if (rect.right > lprect->right)
937 SetRect(&rect, lprect->left, rect.bottom,
938 0, rect.bottom + SYSMETRICS_CYMENU);
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000939 if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) {
940 hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text);
941 GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm);
942 rect.right = rect.left + bm.bmWidth;
943 lppop->Height = max(lppop->Height, bm.bmHeight);
944 }
945 if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) &&
946 ((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
947 ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) {
948 dwRet = GetTextExtent(hDC, (char *)lpitem->item_text,
949 strlen((char *)lpitem->item_text));
950 rect.right = rect.left + LOWORD(dwRet) + 10;
951 lppop->Height = max(lppop->Height, HIWORD(dwRet) + 10);
952 }
953 CopyRect(&lpitem->rect, &rect);
954 rect.left = rect.right;
955 lpitem = (LPMENUITEM)lpitem->next;
956 }
957 if (OldHeight < lppop->Height) goto CalcAGAIN;
958 lppop->Width = rect.right;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000959 lprect->bottom = lprect->top + lppop->Height;
960 CopyRect(&lppop->rect, lprect);
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000961#ifdef DEBUG_MENUCALC
962 printf("MenuBarCalcSize w=%d h=%d !\n",
963 lppop->Width, lppop->Height);
964#endif
965 SelectObject(hDC, hOldFont);
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000966}
967
968
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000969
970LPMENUITEM GetMenuItemPtr(LPPOPUPMENU menu, WORD nPos)
971{
972 LPMENUITEM lpitem;
973 int i;
974 if (menu == NULL) return NULL;
975 lpitem = menu->firstItem;
976 for (i = 0; i < menu->nItems; i++) {
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000977 if (lpitem == NULL) return NULL;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000978 if (i == nPos) return(lpitem);
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000979 lpitem = (LPMENUITEM)lpitem->next;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000980 }
981 return NULL;
982}
983
984
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000985WORD GetSelectionKey(LPSTR str)
986{
987 int i;
988 WORD sel_key;
989 for (i = 0; i < strlen(str); i++) {
990 if (str[i] == '&' && str[i + 1] != '&')
991 {
992 sel_key = str[i + 1];
993 if (sel_key >= 'a' && sel_key <= 'z') sel_key -= 'a' - 'A';
994#ifdef DEBUG_MENU
995 printf("GetSelectionKey // %04X\n", sel_key);
996#endif
997 return sel_key;
998 }
999 }
1000#ifdef DEBUG_MENU
1001 printf("GetSelectionKey NULL \n");
1002#endif
1003 return 0;
1004}
1005
1006
1007
1008LPSTR GetShortCutString(LPSTR str)
1009{
1010 int i;
1011 LPSTR str2;
1012 for (i = 0; i < strlen(str); i++) {
1013 if (str[i] == '\t' && str[i + 1] != '\t')
1014 {
1015 str2 = &str[i + 1];
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001016#ifdef DEBUG_MENUSHORTCUT
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001017 printf("GetShortCutString // '%s' \n", str2);
1018#endif
1019 return str2;
1020 }
1021 }
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001022#ifdef DEBUG_MENUSHORTCUT
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001023 printf("GetShortCutString NULL \n");
1024#endif
1025 return NULL;
1026}
1027
1028
1029
1030WORD GetShortCutPos(LPSTR str)
1031{
1032 int i;
1033 for (i = 0; i < strlen(str); i++) {
1034 if (str[i] == '\t' && str[i + 1] != '\t')
1035 {
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001036#ifdef DEBUG_MENUSHORTCUT
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001037 printf("GetShortCutPos = %d \n", i);
1038#endif
1039 return i;
1040 }
1041 }
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001042#ifdef DEBUG_MENUSHORTCUT
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001043 printf("GetShortCutString NULL \n");
1044#endif
1045 return -1;
1046}
1047
1048
1049
1050BOOL HideAllSubPopupMenu(LPPOPUPMENU menu)
1051{
1052 LPPOPUPMENU submenu;
1053 LPMENUITEM lpitem;
1054 BOOL someClosed = FALSE;
1055 int i;
1056 if (menu == NULL) return;
1057 lpitem = menu->firstItem;
1058 for (i = 0; i < menu->nItems; i++) {
1059 if (lpitem == NULL) return;
1060 if (lpitem->item_flags & MF_POPUP) {
1061 submenu = (LPPOPUPMENU) GlobalLock((HMENU)lpitem->item_id);
1062 if (submenu != NULL) {
1063 if (IsWindowVisible(submenu->hWnd)) {
1064 ShowWindow(submenu->hWnd, SW_HIDE);
1065 someClosed = TRUE;
1066 }
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001067 GlobalUnlock((HMENU)lpitem->item_id);
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001068 }
1069 }
1070 lpitem = (LPMENUITEM)lpitem->next;
1071 }
1072 return someClosed;
1073}
1074
1075
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001076
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001077
Alexandre Julliard401710d1993-09-04 10:09:32 +00001078/**********************************************************************
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001079 * ChangeMenu [USER.153]
Alexandre Julliard401710d1993-09-04 10:09:32 +00001080 */
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001081BOOL ChangeMenu(HMENU hMenu, WORD nPos, LPSTR lpNewItem,
1082 WORD wItemID, WORD wFlags)
Alexandre Julliard401710d1993-09-04 10:09:32 +00001083{
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001084 if (wFlags & MF_APPEND) {
1085 return AppendMenu(hMenu, wFlags, wItemID, lpNewItem);
Alexandre Julliard401710d1993-09-04 10:09:32 +00001086 }
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001087 if (wFlags & MF_DELETE) {
1088 return DeleteMenu(hMenu, wItemID, wFlags);
Alexandre Julliard401710d1993-09-04 10:09:32 +00001089 }
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001090 if (wFlags & MF_INSERT) {
1091 return InsertMenu(hMenu, nPos, wFlags, wItemID, lpNewItem);
Alexandre Julliard401710d1993-09-04 10:09:32 +00001092 }
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001093 if (wFlags & MF_CHANGE) {
1094 return ModifyMenu(hMenu, nPos, wFlags, wItemID, lpNewItem);
Alexandre Julliard401710d1993-09-04 10:09:32 +00001095 }
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001096 if (wFlags & MF_REMOVE) {
1097 return RemoveMenu(hMenu, wItemID, wFlags);
Alexandre Julliard401710d1993-09-04 10:09:32 +00001098 }
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001099 return FALSE;
Alexandre Julliard401710d1993-09-04 10:09:32 +00001100}
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001101
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001102
1103/**********************************************************************
1104 * CheckMenuItem [USER.154]
1105 */
1106BOOL CheckMenuItem(HMENU hMenu, WORD wItemID, WORD wFlags)
1107{
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001108 WND *wndPtr;
1109 LPPOPUPMENU menu;
1110 LPMENUITEM lpitem;
1111 int i;
1112#ifdef DEBUG_MENU
1113 printf("CheckMenuItem (%04X, %04X, %04X) !\n", hMenu, wItemID, wFlags);
1114#endif
1115 menu = (LPPOPUPMENU) GlobalLock(hMenu);
1116 if (menu == NULL) return FALSE;
1117 lpitem = menu->firstItem;
1118 for (i = 0; i < menu->nItems; i++) {
1119 if (lpitem == NULL) break;
1120 if (i == wItemID) {
1121 if (wFlags && MF_CHECKED)
1122 lpitem->item_flags |= MF_CHECKED;
1123 else
1124 lpitem->item_flags &= ((WORD)-1 ^ MF_CHECKED);
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001125 GlobalUnlock(hMenu);
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001126 return(TRUE);
1127 }
1128 lpitem = (LPMENUITEM)lpitem->next;
1129 }
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001130 GlobalUnlock(hMenu);
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001131 return FALSE;
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001132}
1133
1134
1135/**********************************************************************
1136 * EnableMenuItem [USER.155]
1137 */
1138BOOL EnableMenuItem(HMENU hMenu, WORD wItemID, WORD wFlags)
1139{
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001140 WND *wndPtr;
1141 LPPOPUPMENU menu;
1142 LPMENUITEM lpitem;
1143 int i;
1144#ifdef DEBUG_MENU
1145 printf("EnableMenuItem (%04X, %04X, %04X) !\n", hMenu, wItemID, wFlags);
1146#endif
1147 menu = (LPPOPUPMENU) GlobalLock(hMenu);
1148 if (menu == NULL) return FALSE;
1149 lpitem = menu->firstItem;
1150 for (i = 0; i < menu->nItems; i++) {
1151 if (lpitem == NULL) break;
1152 if (i == wItemID) {
1153 if (wFlags && MF_DISABLED)
1154 lpitem->item_flags |= MF_DISABLED;
1155 else
1156 lpitem->item_flags &= ((WORD)-1 ^ MF_DISABLED);
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001157 GlobalUnlock(hMenu);
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001158 return(TRUE);
1159 }
1160 lpitem = (LPMENUITEM)lpitem->next;
1161 }
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001162 GlobalUnlock(hMenu);
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001163 return FALSE;
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001164}
1165
1166
1167/**********************************************************************
1168 * InsertMenu [USER.410]
1169 */
1170BOOL InsertMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewItem)
1171{
1172 WND *wndPtr;
1173 LPPOPUPMENU menu;
1174 HANDLE hNewItem;
1175 LPMENUITEM lpitem, lpitem2;
1176 int i;
1177#ifdef DEBUG_MENU
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001178 if (wFlags & MF_STRING)
1179 printf("InsertMenu (%04X, %04X, %04X, '%s') !\n",
1180 hMenu, wFlags, wItemID, lpNewItem);
1181 else
1182 printf("InsertMenu (%04X, %04X, %04X, %04X, %08X) !\n",
1183 hMenu, nPos, wFlags, wItemID, lpNewItem);
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001184#endif
1185 menu = (LPPOPUPMENU) GlobalLock(hMenu);
1186 if (menu == NULL) return FALSE;
1187 lpitem = menu->firstItem;
1188 for (i = 0; i < menu->nItems; i++) {
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001189 if (lpitem == NULL) break;
1190 if (i == nPos) break;
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001191 lpitem = (LPMENUITEM)lpitem->next;
1192 printf("InsertMenu // during loop items !\n");
1193 }
1194 printf("InsertMenu // after loop items !\n");
1195 hNewItem = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM));
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001196 if (hNewItem == 0) {
1197 GlobalUnlock(hMenu);
1198 return FALSE;
1199 }
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001200 lpitem2 = (LPMENUITEM)GlobalLock(hNewItem);
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001201 if (lpitem2 == NULL) {
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001202 GlobalFree(hNewItem);
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001203 GlobalUnlock(hMenu);
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001204 return FALSE;
1205 }
1206 lpitem2->item_flags = wFlags;
1207 lpitem2->item_id = wItemID;
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001208 if (((wFlags & MF_BITMAP) != MF_BITMAP) &&
1209 ((wFlags & MF_MENUBREAK) != MF_MENUBREAK) &&
1210 ((wFlags & MF_STRING) != MF_SEPARATOR)) {
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001211 lpitem2->item_text = lpNewItem;
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001212 lpitem2->sel_key = GetSelectionKey(lpitem2->item_text);
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001213 }
1214 else
1215 lpitem2->item_text = lpNewItem;
1216 lpitem2->prev = lpitem;
1217 if (lpitem->next != NULL)
1218 lpitem2->next = lpitem->next;
1219 else
1220 lpitem2->next = NULL;
1221 lpitem->next = lpitem2;
1222 lpitem2->child = NULL;
1223 lpitem2->parent = NULL;
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001224 menu->nItems++;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001225 GlobalUnlock(hMenu);
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001226 return TRUE;
1227}
1228
1229
1230/**********************************************************************
1231 * AppendMenu [USER.411]
1232 */
1233BOOL AppendMenu(HMENU hMenu, WORD wFlags, WORD wItemID, LPSTR lpNewItem)
1234{
1235 WND *wndPtr;
1236 LPPOPUPMENU menu;
1237 HANDLE hNewItem;
1238 LPMENUITEM lpitem, lpitem2;
1239#ifdef DEBUG_MENU
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001240 if ((wFlags & (MF_BITMAP | MF_SEPARATOR | MF_MENUBREAK | MF_OWNERDRAW)) == 0)
1241 printf("AppendMenu (%04X, %04X, %04X, '%s') !\n",
1242 hMenu, wFlags, wItemID, lpNewItem);
1243 else
1244 printf("AppendMenu (%04X, %04X, %04X, %08X) !\n",
1245 hMenu, wFlags, wItemID, lpNewItem);
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001246#endif
1247 menu = (LPPOPUPMENU) GlobalLock(hMenu);
1248 if (menu == NULL) return FALSE;
1249 lpitem = menu->firstItem;
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001250 if (lpitem != NULL) {
1251 while (lpitem->next != NULL) {
1252 lpitem = (LPMENUITEM)lpitem->next;
1253 }
1254 }
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001255 hNewItem = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM));
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001256 if (hNewItem == 0) {
1257 GlobalUnlock(hMenu);
1258 return FALSE;
1259 }
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001260 lpitem2 = (LPMENUITEM)GlobalLock(hNewItem);
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001261 if (lpitem2 == NULL) {
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001262 GlobalFree(hNewItem);
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001263 GlobalUnlock(hMenu);
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001264 return FALSE;
1265 }
1266 lpitem2->item_flags = wFlags;
1267 lpitem2->item_id = wItemID;
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001268 if (((wFlags & MF_BITMAP) != MF_BITMAP) &&
1269 ((wFlags & MF_MENUBREAK) != MF_MENUBREAK) &&
1270 ((wFlags & MF_STRING) != MF_SEPARATOR)) {
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001271 lpitem2->item_text = lpNewItem;
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001272 lpitem2->sel_key = GetSelectionKey(lpitem2->item_text);
1273 lpitem2->shortcut = GetShortCutString(lpitem2->item_text);
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001274 }
1275 else
1276 lpitem2->item_text = lpNewItem;
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001277 if (lpitem == NULL)
1278 menu->firstItem = lpitem2;
1279 else
1280 lpitem->next = lpitem2;
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001281 lpitem2->prev = lpitem;
1282 lpitem2->next = NULL;
1283 lpitem2->child = NULL;
1284 lpitem2->parent = NULL;
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001285 lpitem2->hCheckBit = (HBITMAP)NULL;
1286 lpitem2->hUnCheckBit = (HBITMAP)NULL;
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001287 menu->nItems++;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001288 GlobalUnlock(hMenu);
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001289 return TRUE;
1290}
1291
1292
1293/**********************************************************************
1294 * RemoveMenu [USER.412]
1295 */
1296BOOL RemoveMenu(HMENU hMenu, WORD nPos, WORD wFlags)
1297{
1298 WND *wndPtr;
1299 LPPOPUPMENU menu;
1300 LPMENUITEM lpitem;
1301 int i;
1302#ifdef DEBUG_MENU
1303 printf("RemoveMenu (%04X, %04X, %04X) !\n", hMenu, nPos, wFlags);
1304#endif
1305 menu = (LPPOPUPMENU) GlobalLock(hMenu);
1306 if (menu == NULL) return FALSE;
1307 lpitem = menu->firstItem;
1308 for (i = 0; i < menu->nItems; i++) {
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001309 if (lpitem == NULL) break;
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001310 if (i == nPos) {
1311 lpitem->prev->next = lpitem->next;
1312 lpitem->next->prev = lpitem->prev;
1313 GlobalFree(HIWORD(lpitem));
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001314 GlobalUnlock(hMenu);
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001315 return(TRUE);
1316 }
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001317 lpitem = (LPMENUITEM)lpitem->next;
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001318 printf("RemoveMenu // during loop items !\n");
1319 }
1320 printf("RemoveMenu // after loop items !\n");
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001321 GlobalUnlock(hMenu);
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001322 return FALSE;
1323}
1324
1325
1326/**********************************************************************
1327 * DeleteMenu [USER.413]
1328 */
1329BOOL DeleteMenu(HMENU hMenu, WORD nPos, WORD wFlags)
1330{
1331#ifdef DEBUG_MENU
1332 printf("DeleteMenu (%04X, %04X, %04X) !\n", hMenu, nPos, wFlags);
1333#endif
1334 return TRUE;
1335}
1336
1337
1338/**********************************************************************
1339 * ModifyMenu [USER.414]
1340 */
1341BOOL ModifyMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewItem)
1342{
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001343 WND *wndPtr;
1344 LPPOPUPMENU menu;
1345 LPMENUITEM lpitem;
1346 int i;
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001347#ifdef DEBUG_MENU
1348 printf("ModifyMenu (%04X, %04X, %04X, %04X, %08X) !\n",
1349 hMenu, nPos, wFlags, wItemID, lpNewItem);
1350#endif
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001351 menu = (LPPOPUPMENU) GlobalLock(hMenu);
1352 if (menu == NULL) return FALSE;
1353 lpitem = menu->firstItem;
1354 for (i = 0; i < menu->nItems; i++) {
1355 if (lpitem == NULL) break;
1356 if (i == nPos) {
1357 lpitem->item_flags = wFlags;
1358 lpitem->item_id = wItemID;
1359 lpitem->item_text = lpNewItem;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001360 GlobalUnlock(hMenu);
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001361 return(TRUE);
1362 }
1363 lpitem = (LPMENUITEM)lpitem->next;
1364 }
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001365 GlobalUnlock(hMenu);
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001366 return FALSE;
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001367}
1368
1369
1370/**********************************************************************
1371 * CreatePopupMenu [USER.415]
1372 */
1373HMENU CreatePopupMenu()
1374{
1375 HANDLE hItem;
1376 HMENU hMenu;
1377 LPPOPUPMENU menu;
1378#ifdef DEBUG_MENU
1379 printf("CreatePopupMenu !\n");
1380#endif
1381 hMenu = GlobalAlloc(GMEM_MOVEABLE, sizeof(POPUPMENU));
1382 menu = (LPPOPUPMENU) GlobalLock(hMenu);
1383 if (menu == NULL) {
1384 GlobalFree(hMenu);
1385 return 0;
1386 }
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001387 menu->nItems = 0;
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001388 menu->firstItem = NULL;
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001389 menu->ownerWnd = 0;
1390 menu->hWnd = 0;
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001391 menu->hWndParent = 0;
1392 menu->MouseFlags = 0;
1393 menu->BarFlags = 0;
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001394 menu->SysFlag = FALSE;
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001395 menu->Width = 100;
1396 menu->Height = 0;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001397 GlobalUnlock(hMenu);
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001398 return hMenu;
1399}
1400
1401
1402/**********************************************************************
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001403 * TrackPopupMenu [USER.416]
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001404 */
1405BOOL TrackPopupMenu(HMENU hMenu, WORD wFlags, short x, short y,
1406 short nReserved, HWND hWnd, LPRECT lpRect)
1407{
1408 WND *wndPtr;
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001409 LPPOPUPMENU lppop;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001410 RECT rect;
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001411#ifdef DEBUG_MENU
1412 printf("TrackPopupMenu (%04X, %04X, %d, %d, %04X, %04X, %08X) !\n",
1413 hMenu, wFlags, x, y, nReserved, hWnd, lpRect);
1414#endif
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001415 lppop = (LPPOPUPMENU) GlobalLock(hMenu);
1416 if (lppop == NULL) return FALSE;
1417 wndPtr = WIN_FindWndPtr(hWnd);
1418 lppop->ownerWnd = hWnd;
1419 if (lppop->hWnd == (HWND)NULL) {
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001420 lppop->hWnd = CreateWindow("POPUPMENU", "", WS_POPUP | WS_VISIBLE,
1421 x, y, lppop->Width, lppop->Height, (HWND)NULL, 0,
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001422 wndPtr->hInstance, (LPSTR)lppop);
1423 }
1424 else {
1425 ShowWindow(lppop->hWnd, SW_SHOW);
1426 }
1427 if (lppop->BarFlags == 0) {
1428 PopupMenuCalcSize(lppop->hWnd);
1429#ifdef DEBUG_MENU
1430 printf("TrackPopupMenu // x=%d y=%d Width=%d Height=%d\n",
1431 x, y, lppop->Width, lppop->Height);
1432#endif
1433 SetWindowPos(lppop->hWnd, 0, x, y, lppop->Width + 2, lppop->Height,
1434 SWP_NOZORDER);
1435 }
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001436 GlobalUnlock(hMenu);
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001437 return TRUE;
1438}
1439
1440
1441/**********************************************************************
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001442 * NC_TrackSysMenu [Internal]
1443 */
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001444void NC_TrackSysMenu(HWND hWnd)
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001445{
1446 RECT rect;
1447 LPPOPUPMENU lpsys;
1448 WND *wndPtr = WIN_FindWndPtr(hWnd);
1449#ifdef DEBUG_MENU
1450 printf("NC_TrackSysMenu hWnd=%04X !\n", hWnd);
1451#endif
1452 if (!wndPtr) return;
1453 lpsys = (LPPOPUPMENU)GlobalLock(wndPtr->hSysMenu);
1454#ifdef DEBUG_MENU
1455 printf("NC_TrackSysMenu wndPtr->hSysMenu=%04X !\n", wndPtr->hSysMenu);
1456#endif
1457 if (lpsys == NULL) return;
1458#ifdef DEBUG_MENU
1459 printf("NC_TrackSysMenu wndPtr->hSysMenu=%04X !\n", wndPtr->hSysMenu);
1460#endif
1461 lpsys->BarFlags = FALSE;
1462 lpsys->SysFlag = TRUE;
1463 if (!IsWindowVisible(lpsys->hWnd)) {
1464 GetWindowRect(hWnd, &rect);
1465#ifdef DEBUG_MENU
1466 printf("NC_TrackSysMenu lpsys->hWnd=%04X !\n", lpsys->hWnd);
1467#endif
1468 TrackPopupMenu(wndPtr->hSysMenu, TPM_LEFTBUTTON,
1469 rect.left, rect.top + SYSMETRICS_CYSIZE,
1470 0, hWnd, (LPRECT)NULL);
1471 }
1472 else {
1473 ShowWindow(lpsys->hWnd, SW_HIDE);
1474 }
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001475 GlobalUnlock(wndPtr->hSysMenu);
1476}
1477
1478
1479/**********************************************************************
1480 * GetMenuCheckMarkDimensions [USER.417]
1481 */
1482DWORD GetMenuCheckMarkDimensions()
1483{
1484 BITMAP bm;
1485 if (hStdCheck == (HBITMAP)NULL)
1486 hStdCheck = LoadBitmap((HANDLE)NULL, (LPSTR)OBM_CHECK);
1487 GetObject(hStdCheck, sizeof(BITMAP), (LPSTR)&bm);
1488 return MAKELONG(bm.bmWidth, bm.bmHeight);
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001489}
1490
1491
1492/**********************************************************************
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001493 * SetMenuItemBitmaps [USER.418]
1494 */
1495BOOL SetMenuItemBitmaps(HMENU hMenu, WORD nPos, WORD wFlags,
1496 HBITMAP hNewCheck, HBITMAP hNewUnCheck)
1497{
1498 WND *wndPtr;
1499 LPPOPUPMENU menu;
1500 LPMENUITEM lpitem;
1501 int i;
1502#ifdef DEBUG_MENU
1503 printf("SetMenuItemBitmaps (%04X, %04X, %04X, %04X, %08X) !\n",
1504 hMenu, nPos, wFlags, hNewCheck, hNewUnCheck);
1505#endif
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001506 menu = (LPPOPUPMENU) GlobalLock(hMenu);
1507 if (menu == NULL) return FALSE;
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001508 lpitem = menu->firstItem;
1509 for (i = 0; i < menu->nItems; i++) {
1510 if (lpitem == NULL) break;
1511 if (i == nPos) {
1512 lpitem->hCheckBit = hNewCheck;
1513 lpitem->hUnCheckBit = hNewUnCheck;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001514 GlobalUnlock(hMenu);
1515 return TRUE;
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001516 }
1517 lpitem = (LPMENUITEM)lpitem->next;
1518 }
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001519 GlobalUnlock(hMenu);
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001520 return FALSE;
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001521}
1522
1523
1524/**********************************************************************
1525 * CreateMenu [USER.151]
1526 */
1527HMENU CreateMenu()
1528{
1529 HANDLE hItem;
1530 HMENU hMenu;
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001531 LPPOPUPMENU menu;
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001532#ifdef DEBUG_MENU
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001533 printf("CreatePopupMenu !\n");
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001534#endif
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001535 hMenu = GlobalAlloc(GMEM_MOVEABLE, sizeof(POPUPMENU));
1536 menu = (LPPOPUPMENU) GlobalLock(hMenu);
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001537 if (menu == NULL) {
1538 GlobalFree(hMenu);
1539 return 0;
1540 }
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001541 menu->nItems = 0;
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001542 menu->firstItem = NULL;
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001543 menu->ownerWnd = 0;
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001544 menu->hWnd = 0;
1545 menu->hWndParent = 0;
1546 menu->MouseFlags = 0;
1547 menu->BarFlags = TRUE;
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001548 menu->SysFlag = FALSE;
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001549 menu->Width = 100;
1550 menu->Height = 0;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001551 GlobalUnlock(hMenu);
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001552 return hMenu;
1553}
1554
1555
1556/**********************************************************************
1557 * DestroyMenu [USER.152]
1558 */
1559BOOL DestroyMenu(HMENU hMenu)
1560{
1561 LPPOPUPMENU lppop;
1562 LPMENUITEM lpitem, lpitem2;
1563#ifdef DEBUG_MENU
1564 printf("DestroyMenu (%04X) !\n", hMenu);
1565#endif
1566 if (hMenu == 0) return FALSE;
1567 lppop = (LPPOPUPMENU) GlobalLock(hMenu);
1568 if (lppop == NULL) return FALSE;
1569 if (lppop->hWnd) DestroyWindow (lppop->hWnd);
1570 lpitem = lppop->firstItem;
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001571 while (lpitem != NULL) {
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001572#ifdef DEBUG_MENU
1573 printf("DestroyMenu (%04X) // during loop items !\n", hMenu);
1574#endif
1575 if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
1576 DestroyMenu((HMENU)lpitem->item_id);
1577 }
1578 lpitem = (LPMENUITEM)lpitem->next;
1579 }
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001580 GlobalUnlock(hMenu);
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001581 GlobalFree(hMenu);
1582#ifdef DEBUG_MENU
1583 printf("DestroyMenu (%04X) // End !\n", hMenu);
1584#endif
1585 return TRUE;
1586}
1587
1588
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001589/**********************************************************************
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001590 * LoadMenu [USER.150]
1591 */
1592HMENU LoadMenu(HINSTANCE instance, char *menu_name)
1593{
1594 HMENU hMenu;
1595 HANDLE hMenu_desc;
1596 MENU_HEADER *menu_desc;
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001597#ifdef DEBUG_MENU
1598 if ((LONG)menu_name & 0xFFFF0000L)
1599 printf("LoadMenu: instance %02x, menu '%s'\n", instance, menu_name);
1600 else
1601 printf("LoadMenu: instance %02x, menu '%04X'\n", instance, menu_name);
1602#endif
1603 if (instance == (HANDLE)NULL) instance = hSysRes;
1604 if (menu_name == NULL ||
1605 (hMenu_desc = RSC_LoadMenu(instance, menu_name)) == 0 ||
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001606 (menu_desc = (MENU_HEADER *) GlobalLock(hMenu_desc)) == NULL) {
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001607 return 0;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001608 }
1609 hMenu = LoadMenuIndirect((LPSTR)menu_desc);
1610/*
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001611 hMenu = CreateMenu();
1612 ParseMenuResource((WORD *) (menu_desc + 1), 0, hMenu);
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001613 GlobalUnlock(hMenu_desc);
1614 GlobalFree(hMenu_desc);
1615*/
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001616 return hMenu;
1617}
1618
1619
1620/**********************************************************************
1621 * GetSystemMenu [USER.156]
1622 */
1623HMENU GetSystemMenu(HWND hWnd, BOOL bRevert)
1624{
1625 WND *wndPtr;
1626 wndPtr = WIN_FindWndPtr(hWnd);
1627 if (!bRevert) {
1628 return wndPtr->hSysMenu;
1629 }
1630 else {
1631 DestroyMenu(wndPtr->hSysMenu);
1632 wndPtr->hSysMenu = CopySysMenu();
1633 }
1634 return wndPtr->hSysMenu;
1635}
1636
1637
1638/**********************************************************************
1639 * GetMenu [USER.157]
1640 */
1641HMENU GetMenu(HWND hWnd)
1642{
1643 WND * wndPtr = WIN_FindWndPtr(hWnd);
1644 if (wndPtr == NULL) return 0;
1645 return wndPtr->wIDmenu;
1646}
1647
1648/**********************************************************************
1649 * SetMenu [USER.158]
1650 */
1651BOOL SetMenu(HWND hWnd, HMENU hMenu)
1652{
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001653 LPPOPUPMENU lppop;
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001654 WND * wndPtr = WIN_FindWndPtr(hWnd);
1655 if (wndPtr == NULL) return FALSE;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001656#ifdef DEBUG_MENU
1657 printf("SetMenu(%04X, %04X);\n", hWnd, hMenu);
1658#endif
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001659 wndPtr->wIDmenu = hMenu;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001660 if (hMenu == 0) return TRUE;
1661 lppop = (LPPOPUPMENU) GlobalLock(hMenu);
1662 if (lppop == NULL) return FALSE;
1663 lppop->ownerWnd = hWnd;
1664 GlobalUnlock(hMenu);
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001665 return TRUE;
1666}
1667
1668
1669/**********************************************************************
1670 * GetSubMenu [USER.159]
1671 */
1672HMENU GetSubMenu(HMENU hMenu, short nPos)
1673{
1674 HMENU hSubMenu;
1675 LPPOPUPMENU lppop;
1676 LPMENUITEM lpitem;
1677 int i;
1678#ifdef DEBUG_MENU
1679 printf("GetSubMenu (%04X, %04X) !\n", hMenu, nPos);
1680#endif
1681 if (hMenu == 0) return 0;
1682 lppop = (LPPOPUPMENU) GlobalLock(hMenu);
1683 if (lppop == NULL) return 0;
1684 lpitem = lppop->firstItem;
1685 for (i = 0; i < lppop->nItems; i++) {
1686 if (lpitem == NULL) break;
1687 if (i == nPos) {
1688 if (lpitem->item_flags & MF_POPUP)
1689 return hSubMenu;
1690 else
1691 return 0;
1692 }
1693 lpitem = (LPMENUITEM)lpitem->next;
1694 }
1695 return 0;
1696}
1697
1698
1699/**********************************************************************
1700 * DrawMenuBar [USER.160]
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001701 */
1702void DrawMenuBar(HWND hWnd)
1703{
1704 WND *wndPtr;
1705#ifdef DEBUG_MENU
1706 printf("DrawMenuBar (%04X)\n", hWnd);
1707#endif
1708 wndPtr = WIN_FindWndPtr(hWnd);
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001709 if (wndPtr != NULL && wndPtr->wIDmenu != 0) {
1710#ifdef DEBUG_MENU
1711 printf("DrawMenuBar wIDmenu=%04X \n", wndPtr->wIDmenu);
1712#endif
1713 SendMessage(hWnd, WM_NCPAINT, 1, 0L);
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001714 }
1715}
1716
1717
1718/**********************************************************************
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001719 * LoadMenuIndirect [USER.220]
1720 */
1721HMENU LoadMenuIndirect(LPSTR menu_template)
1722{
1723 HMENU hMenu;
1724 MENU_HEADER *menu_desc;
1725#ifdef DEBUG_MENU
1726 printf("LoadMenuIndirect: menu_template '%08X'\n", menu_template);
1727#endif
1728 hMenu = CreateMenu();
1729 menu_desc = (MENU_HEADER *)menu_template;
1730 ParseMenuResource((WORD *)(menu_desc + 1), 0, hMenu);
1731 return hMenu;
1732}
1733
1734
1735/**********************************************************************
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001736 * CopySysMenu (Internal)
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001737 */
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001738HMENU CopySysMenu()
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001739{
1740 HMENU hMenu;
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001741 LPPOPUPMENU menu;
1742 LPPOPUPMENU sysmenu;
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001743#ifdef DEBUG_MENU
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001744 printf("CopySysMenu entry !\n");
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001745#endif
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001746 if (hSysMenu == 0) {
1747 hSysMenu = LoadMenu((HINSTANCE)NULL, MAKEINTRESOURCE(1));
1748/* hSysMenu = LoadMenu((HINSTANCE)NULL, MAKEINTRESOURCE(SC_SYSMENU));*/
1749/* hSysMenu = LoadMenu((HINSTANCE)NULL, "SYSMENU"); */
1750 if (hSysMenu == 0) {
1751 printf("SysMenu not found in system resources !\n");
1752 return (HMENU)NULL;
1753 }
1754#ifdef DEBUG_MENU
1755 else
1756 printf("SysMenu loaded from system resources %04X !\n", hSysMenu);
1757#endif
1758 }
1759 hMenu = GlobalAlloc(GMEM_MOVEABLE, sizeof(POPUPMENU));
1760 menu = (LPPOPUPMENU) GlobalLock(hMenu);
1761 sysmenu = (LPPOPUPMENU) GlobalLock(hSysMenu);
1762 if (menu != NULL && sysmenu != NULL) {
1763 sysmenu->BarFlags = FALSE;
1764 memcpy(menu, sysmenu, sizeof(POPUPMENU));
1765 }
1766 else {
1767 printf("CopySysMenu // Bad SysMenu pointers !\n");
1768 if (menu != NULL) {
1769 GlobalUnlock(hMenu);
1770 GlobalFree(hMenu);
1771 }
1772 return (HMENU)NULL;
1773 }
1774 GlobalUnlock(hMenu);
1775 GlobalUnlock(hSysMenu);
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001776#ifdef DEBUG_MENU
1777 printf("CopySysMenu hMenu=%04X !\n", hMenu);
1778#endif
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001779 return hMenu;
1780}
1781
1782
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001783/**********************************************************************
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001784 * ParseMenuResource (from Resource or Template)
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001785 */
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001786WORD * ParseMenuResource(WORD *first_item, int level, HMENU hMenu)
1787{
1788 WORD *item;
1789 WORD *next_item;
1790 HMENU hSubMenu;
1791 int i;
1792
1793 level++;
1794 next_item = first_item;
1795 i = 0;
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001796 do {
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001797 i++;
1798 item = next_item;
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001799 if (*item & MF_POPUP) {
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001800 MENU_POPUPITEM *popup_item = (MENU_POPUPITEM *) item;
1801 next_item = (WORD *) (popup_item->item_text +
1802 strlen(popup_item->item_text) + 1);
1803 hSubMenu = CreatePopupMenu();
1804 next_item = ParseMenuResource(next_item, level, hSubMenu);
1805 AppendMenu(hMenu, popup_item->item_flags,
1806 hSubMenu, popup_item->item_text);
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001807 }
1808 else {
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001809 MENUITEMTEMPLATE *normal_item = (MENUITEMTEMPLATE *) item;
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001810 next_item = (WORD *) (normal_item->item_text +
1811 strlen(normal_item->item_text) + 1);
1812 AppendMenu(hMenu, normal_item->item_flags,
1813 normal_item->item_id, normal_item->item_text);
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001814 }
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001815 }
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001816 while (!(*item & MF_END));
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001817 return next_item;
1818}
1819
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001820