source: trunk/src/user32/winmenu.cpp@ 1453

Last change on this file since 1453 was 1453, checked in by sandervl, 26 years ago

Menu changes + fixes

File size: 40.6 KB
Line 
1/* $Id: winmenu.cpp,v 1.11 1999-10-26 11:14:52 sandervl Exp $ */
2
3/*
4 * Win32 menu API functions for OS/2
5 *
6 * Copyright 1998 Sander van Leeuwen
7 * Copyright 1998 Patrick Haller
8 *
9 * Parts ported from Wine:
10 * Copyright 1993 Martin Ayotte
11 * Copyright 1994 Alexandre Julliard
12 * Copyright 1997 Morten Welinder
13 *
14 *
15 * TODO: Set/GetMenu(Item)Info only partially implemented
16 * TODO: Memory leak when deleting submenus
17 * TODO: Check error nrs
18 *
19 * Project Odin Software License can be found in LICENSE.TXT
20 *
21 */
22#include <os2win.h>
23#include <odin.h>
24#include <odinwrap.h>
25#include <stdlib.h>
26#include <string.h>
27#include <win32wbase.h>
28#include "oslibmenu.h"
29#include "oslibwin.h"
30#include "winmenudef.h"
31
32ODINDEBUGCHANNEL(USER32)
33
34BOOL ODIN_INTERNAL ODIN_InsertMenuA(HMENU,UINT,UINT,UINT,LPCSTR);
35BOOL ODIN_INTERNAL ODIN_InsertMenuW(HMENU,UINT,UINT,UINT,LPCWSTR);
36BOOL ODIN_INTERNAL ODIN_InsertMenuItemA(HMENU,UINT,BOOL,const MENUITEMINFOA*);
37BOOL ODIN_INTERNAL ODIN_InsertMenuItemW(HMENU,UINT,BOOL,const MENUITEMINFOW*);
38BOOL ODIN_INTERNAL ODIN_AppendMenuA(HMENU,UINT,UINT,LPCSTR);
39BOOL ODIN_INTERNAL ODIN_AppendMenuW(HMENU,UINT,UINT,LPCWSTR);
40HMENU ODIN_INTERNAL ODIN_CreateMenu(void);
41HMENU ODIN_INTERNAL ODIN_CreatePopupMenu(void);
42BOOL ODIN_INTERNAL ODIN_DestroyMenu(HMENU);
43
44
45//@@@PH: experiment with WINE LoadMenuIndirect code
46#include <heapstring.h>
47#define MENU_ITEM_TYPE(flags) \
48 ((flags) & (MF_STRING | MF_BITMAP | MF_OWNERDRAW | MF_SEPARATOR))
49
50#define IS_STRING_ITEM(flags) (MENU_ITEM_TYPE ((flags)) == MF_STRING)
51#define IS_BITMAP_ITEM(flags) (MENU_ITEM_TYPE ((flags)) == MF_BITMAP)
52
53/**********************************************************************
54 * MENU_ParseResource
55 *
56 * Parse a standard menu resource and add items to the menu.
57 * Return a pointer to the end of the resource.
58 */
59static LPCSTR MENU_ParseResource( LPCSTR res, HMENU hMenu)
60{
61 WORD flags, id = 0;
62 LPCSTR str;
63
64 do
65 {
66 flags = GET_WORD(res);
67 res += sizeof(WORD);
68 if (!(flags & MF_POPUP))
69 {
70 id = GET_WORD(res);
71 res += sizeof(WORD);
72 }
73 if (!IS_STRING_ITEM(flags))
74 dprintf(("USER32: WinMenu: MENU_ParseResource: not a string item %04x\n", flags ));
75 str = res;
76
77 res += (lstrlenW((LPCWSTR)str) + 1) * sizeof(WCHAR);
78 if (flags & MF_POPUP)
79 {
80 HMENU hSubMenu = ODIN_CreatePopupMenu();
81 if (!hSubMenu) return NULL;
82 if (!(res = MENU_ParseResource( res, hSubMenu)))
83 return NULL;
84 ODIN_AppendMenuW( hMenu, flags, (UINT)hSubMenu, (LPCWSTR)str );
85 }
86 else /* Not a popup */
87 {
88 ODIN_AppendMenuW( hMenu, flags, id, *(LPCWSTR)str ? (LPCWSTR)str : NULL );
89 }
90 } while (!(flags & MF_END));
91 return res;
92}
93
94
95/**********************************************************************
96 * MENUEX_ParseResource
97 *
98 * Parse an extended menu resource and add items to the menu.
99 * Return a pointer to the end of the resource.
100 */
101static LPCSTR MENUEX_ParseResource( LPCSTR res, HMENU hMenu)
102{
103 WORD resinfo;
104
105 do {
106 MENUITEMINFOW mii;
107
108 mii.cbSize = sizeof(mii);
109 mii.fMask = MIIM_STATE | MIIM_ID | MIIM_TYPE;
110 mii.fType = GET_DWORD(res);
111 res += sizeof(DWORD);
112 mii.fState = GET_DWORD(res);
113 res += sizeof(DWORD);
114 mii.wID = GET_DWORD(res);
115 res += sizeof(DWORD);
116 resinfo = GET_WORD(res); /* FIXME: for 16-bit apps this is a byte. */
117 res += sizeof(WORD);
118
119 /* Align the text on a word boundary. */
120 res += (~((int)res - 1)) & 1;
121 mii.dwTypeData = (LPWSTR) res;
122 res += (1 + lstrlenW(mii.dwTypeData)) * sizeof(WCHAR);
123 /* Align the following fields on a dword boundary. */
124 res += (~((int)res - 1)) & 3;
125
126 /* FIXME: This is inefficient and cannot be optimised away by gcc. */
127 {
128 LPSTR newstr = HEAP_strdupWtoA(GetProcessHeap(), 0, mii.dwTypeData);
129
130 dprintf(("USER32:WinMenu:MENUEX_ParseResource Menu item: [%08x,%08x,%04x,%04x,%s]\n",
131 mii.fType, mii.fState, mii.wID, resinfo, newstr));
132 HeapFree( GetProcessHeap(), 0, newstr );
133 }
134
135 if (resinfo & 1) { /* Pop-up? */
136 /* DWORD helpid = GET_DWORD(res); FIXME: use this. */
137 res += sizeof(DWORD);
138 mii.hSubMenu = ODIN_CreatePopupMenu();
139 if (!mii.hSubMenu)
140 return NULL;
141 if (!(res = MENUEX_ParseResource(res, mii.hSubMenu))) {
142 DestroyMenu(mii.hSubMenu);
143 return NULL;
144 }
145 mii.fMask |= MIIM_SUBMENU;
146 mii.fType |= MF_POPUP;
147 }
148 ODIN_InsertMenuItemW(hMenu, -1, MF_BYPOSITION, &mii);
149 }
150 while (!(resinfo & MF_END));
151
152 return res;
153}
154/**********************************************************************
155 * myLoadMenuIndirect
156 */
157HMENU myLoadMenuIndirect(LPCVOID pMenuTemplate)
158{
159 HMENU hMenu;
160 WORD version,
161 offset;
162 LPCSTR p = (LPCSTR)pMenuTemplate;
163
164 version = GET_WORD(p);
165 p += sizeof(WORD);
166
167 switch (version)
168 {
169 case 0:
170 offset = GET_WORD(p);
171 p += sizeof(WORD) + offset;
172 if (!(hMenu = ODIN_CreateMenu()))
173 return 0;
174 if (!MENU_ParseResource( p, hMenu))
175 {
176 DestroyMenu( hMenu );
177 return 0;
178 }
179 return hMenu;
180
181 case 1:
182 offset = GET_WORD(p);
183 p += sizeof(WORD) + offset;
184 if (!(hMenu = ODIN_CreateMenu()))
185 return 0;
186 if (!MENUEX_ParseResource( p, hMenu))
187 {
188 ODIN_DestroyMenu( hMenu );
189 return 0;
190 }
191 return hMenu;
192
193 default:
194 dprintf(("USER32: LoadMenuIndirectA: version %d not supported.\n", version));
195 return 0;
196 }
197}
198//******************************************************************************
199//******************************************************************************
200void SetInternalMenuInfo(HMENU hMenu)
201{
202 LPPOPUPMENU lpMenuInfo;
203
204 lpMenuInfo = (LPPOPUPMENU)malloc(sizeof(*lpMenuInfo));
205 memset(lpMenuInfo, 0, sizeof(*lpMenuInfo));
206 OSLibWinSetWindowULong(hMenu, OSLIB_QWL_USER, (ULONG)lpMenuInfo);
207}
208//******************************************************************************
209//******************************************************************************
210LPPOPUPMENU GetInternalMenuInfo(HMENU hMenu)
211{
212 return (LPPOPUPMENU)OSLibWinGetWindowULong(hMenu, OSLIB_QWL_USER);
213}
214//******************************************************************************
215//******************************************************************************
216void DeleteInternalMenuInfo(HMENU hMenu)
217{
218 LPPOPUPMENU lpMenuInfo;
219
220 lpMenuInfo = (LPPOPUPMENU)OSLibWinGetWindowULong(hMenu, OSLIB_QWL_USER);
221 if(lpMenuInfo) {
222 free(lpMenuInfo);
223 OSLibWinSetWindowULong(hMenu, OSLIB_QWL_USER, 0);
224 }
225}
226//******************************************************************************
227//******************************************************************************
228ODINFUNCTION0(HMENU, CreateMenu)
229{
230 HMENU hMenu;
231
232 dprintf(("USER32: CreateMenu\n"));
233
234 hMenu = OSLibWinCreateEmptyMenu();
235 if(hMenu) {
236 SetInternalMenuInfo(hMenu);
237 }
238 else SetLastError(ERROR_INVALID_PARAMETER); //wrong error
239
240 return hMenu;
241}
242//******************************************************************************
243//******************************************************************************
244ODINFUNCTION0(HMENU, CreatePopupMenu)
245{
246 HMENU hMenu;
247
248 dprintf(("USER32: CreatePopupMenu\n"));
249
250 hMenu = OSLibWinCreateEmptyPopupMenu();
251 if(hMenu) {
252 SetInternalMenuInfo(hMenu);
253 }
254 else SetLastError(ERROR_INVALID_PARAMETER); //wrong error
255
256 return hMenu;
257}
258//******************************************************************************
259//******************************************************************************
260ODINFUNCTION2(HMENU, LoadMenuA,
261 HINSTANCE, hinst,
262 LPCSTR, lpszMenu)
263{
264 Win32Resource *winres;
265 HMENU hMenu;
266
267 winres = (Win32Resource *)FindResourceA(hinst, lpszMenu, RT_MENUA);
268 if(winres)
269 {
270 hMenu = myLoadMenuIndirect((MENUITEMTEMPLATEHEADER *)winres->lockResource());
271 if(hMenu) {
272 SetInternalMenuInfo(hMenu);
273 }
274 else SetLastError(ERROR_INVALID_PARAMETER);
275
276 delete winres;
277 return hMenu;
278 }
279 return 0;
280}
281//******************************************************************************
282//******************************************************************************
283ODINFUNCTION2(HMENU, LoadMenuW,
284 HINSTANCE, hinst,
285 LPCWSTR, lpszMenu)
286{
287 Win32Resource *winres;
288 HMENU hMenu;
289
290 winres = (Win32Resource *)FindResourceW(hinst, lpszMenu, RT_MENUW);
291 if(winres) {
292 hMenu = myLoadMenuIndirect((MENUITEMTEMPLATEHEADER *)winres->lockResource());
293 if(hMenu) {
294 SetInternalMenuInfo(hMenu);
295 }
296 else SetLastError(ERROR_INVALID_PARAMETER);
297
298 delete winres;
299 return hMenu;
300 }
301 return 0;
302}
303//******************************************************************************
304//NOTE: menutemplate strings are always in Unicode format
305//******************************************************************************
306ODINFUNCTION1(HMENU, LoadMenuIndirectW,
307 const MENUITEMTEMPLATEHEADER *, menuTemplate)
308{
309 HMENU hMenu;
310
311 hMenu = O32_LoadMenuIndirect(menuTemplate);
312 if(hMenu) {
313 SetInternalMenuInfo(hMenu);
314 }
315 else SetLastError(ERROR_INVALID_PARAMETER);
316
317 return (HMENU)hMenu;
318}
319//******************************************************************************
320//******************************************************************************
321ODINFUNCTION1(BOOL, DestroyMenu,
322 HMENU, hMenu)
323{
324 if(hMenu == 0)
325 {
326 SetLastError(ERROR_INVALID_PARAMETER);
327 return 0;
328 }
329 DeleteInternalMenuInfo(hMenu);
330 return O32_DestroyMenu(hMenu);
331}
332//******************************************************************************
333//******************************************************************************
334ODINFUNCTION1(HMENU, GetMenu,
335 HWND, hwnd)
336{
337 Win32BaseWindow *window;
338
339 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
340 if(!window)
341 {
342 dprintf(("GetMenu, window %x not found", hwnd));
343 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
344 return 0;
345 }
346
347 return window->GetMenu();
348}
349//******************************************************************************
350//******************************************************************************
351ODINFUNCTION2(BOOL, SetMenu,
352 HWND, hwnd,
353 HMENU, hMenu)
354{
355 Win32BaseWindow *window;
356
357 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
358 if(!window)
359 {
360 dprintf(("SetMenu, window %x not found", hwnd));
361 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
362 return 0;
363 }
364
365 window->SetMenu(hMenu);
366 return TRUE;
367}
368//******************************************************************************
369//******************************************************************************
370ODINFUNCTION0(DWORD, GetMenuCheckMarkDimensions)
371{
372 return O32_GetMenuCheckMarkDimensions();
373}
374//******************************************************************************
375//******************************************************************************
376ODINFUNCTION1(int, GetMenuItemCount,
377 HMENU, hMenu)
378{
379 if(hMenu == 0)
380 {
381 SetLastError(ERROR_INVALID_PARAMETER);
382 return 0;
383 }
384 return OSLibGetMenuItemCount(hMenu);
385}
386//******************************************************************************
387//******************************************************************************
388ODINFUNCTION2(UINT, GetMenuItemID,
389 HMENU, hMenu,
390 int, nPos)
391{
392 if(hMenu == 0)
393 {
394 SetLastError(ERROR_INVALID_PARAMETER);
395 return 0;
396 }
397 return O32_GetMenuItemID(hMenu, nPos);
398}
399//******************************************************************************
400//******************************************************************************
401ODINFUNCTION3(UINT, GetMenuState,
402 HMENU, hMenu,
403 UINT, arg2,
404 UINT, arg3)
405{
406 if(hMenu == 0)
407 {
408 SetLastError(ERROR_INVALID_PARAMETER);
409 return 0;
410 }
411
412 return O32_GetMenuState(hMenu, arg2, arg3);
413}
414//******************************************************************************
415//******************************************************************************
416ODINFUNCTION5(int, GetMenuStringA,
417 HMENU, hMenu,
418 UINT, arg2,
419 LPSTR, arg3,
420 int, arg4,
421 UINT, arg5)
422{
423 if(hMenu == 0)
424 {
425 SetLastError(ERROR_INVALID_PARAMETER);
426 return 0;
427 }
428
429 return O32_GetMenuString(hMenu, arg2, arg3, arg4, arg5);
430}
431//******************************************************************************
432//******************************************************************************
433ODINFUNCTION5(int, GetMenuStringW,
434 HMENU, hMenu,
435 UINT, idItem,
436 LPWSTR,lpsz,
437 int, cchMax,
438 UINT, fuFlags)
439{
440 char *astring = (char *)malloc(cchMax);
441 int rc;
442
443 rc = ODIN_GetMenuStringA(hMenu, idItem, astring, cchMax, fuFlags);
444 free(astring);
445 if(rc)
446 {
447 dprintf(("USER32: OS2GetMenuStringW %s\n", astring));
448 AsciiToUnicode(astring, lpsz);
449 }
450 else lpsz[0] = 0;
451
452 return(rc);
453}
454//******************************************************************************
455//******************************************************************************
456ODINFUNCTION5(BOOL, SetMenuItemBitmaps,
457 HMENU, hMenu,
458 UINT, arg2,
459 UINT, arg3,
460 HBITMAP, arg4,
461 HBITMAP, arg5)
462{
463 dprintf(("USER32: SetMenuItemBitmaps\n"));
464 if(hMenu == 0)
465 {
466 SetLastError(ERROR_INVALID_PARAMETER);
467 return 0;
468 }
469 return O32_SetMenuItemBitmaps(hMenu, arg2, arg3, arg4, arg5);
470}
471//******************************************************************************
472//******************************************************************************
473ODINFUNCTION2(HMENU, GetSubMenu,
474 HWND, hMenu,
475 int, arg2)
476{
477 if(hMenu == 0)
478 {
479 SetLastError(ERROR_INVALID_PARAMETER);
480 return 0;
481 }
482
483 return O32_GetSubMenu(hMenu, arg2);
484}
485//******************************************************************************
486//******************************************************************************
487ODINFUNCTION2(HMENU, GetSystemMenu,
488 HWND, hSystemWindow,
489 BOOL, bRevert)
490{
491 Win32BaseWindow *window;
492
493 window = Win32BaseWindow::GetWindowFromHandle(hSystemWindow);
494 if(!window)
495 {
496 dprintf(("GetSystemMenu, window %x not found", hSystemWindow));
497 return 0;
498 }
499
500 return O32_GetSystemMenu(window->getOS2FrameWindowHandle(), bRevert);
501}
502//******************************************************************************
503//******************************************************************************
504ODINFUNCTION1(BOOL, IsMenu,
505 HMENU, hMenu)
506{
507 dprintf(("USER32: IsMenu\n"));
508 return O32_IsMenu(hMenu);
509}
510//******************************************************************************
511//******************************************************************************
512ODINFUNCTION7(BOOL, TrackPopupMenu,
513 HMENU, hMenu,
514 UINT, arg2,
515 int, arg3,
516 int, arg4,
517 int, arg5,
518 HWND, arg6,
519 const RECT *, arg7)
520{
521 Win32BaseWindow *window;
522
523 window = Win32BaseWindow::GetWindowFromHandle(arg6);
524 if(!window)
525 {
526 dprintf(("TrackPopupMenu, window %x not found", arg6));
527 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
528 return 0;
529 }
530 dprintf(("USER32: TrackPopupMenu\n"));
531 if(hMenu == 0)
532 {
533 SetLastError(ERROR_INVALID_PARAMETER);
534 return 0;
535 }
536 return O32_TrackPopupMenu(hMenu, arg2, arg3, arg4, arg5, window->getOS2WindowHandle(),
537 arg7);
538}
539//******************************************************************************
540//******************************************************************************
541ODINFUNCTION6(BOOL, TrackPopupMenuEx,
542 HMENU, hMenu,
543 UINT, flags,
544 int, X,
545 int, Y,
546 HWND, hwnd,
547 LPTPMPARAMS, lpPM)
548{
549 RECT *rect = NULL;
550 Win32BaseWindow *window;
551
552 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
553 if(!window)
554 {
555 dprintf(("TrackPopupMenu, window %x not found", hwnd));
556 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
557 return 0;
558 }
559
560 dprintf(("USER32: TrackPopupMenuEx, not completely implemented\n"));
561 if(lpPM->cbSize != 0)
562 rect = &lpPM->rcExclude;
563
564 if(hMenu == 0)
565 {
566 SetLastError(ERROR_INVALID_PARAMETER);
567 return 0;
568 }
569 return O32_TrackPopupMenu(hMenu, flags, X, Y, 0, window->getOS2WindowHandle(), rect);
570}
571//******************************************************************************
572//******************************************************************************
573ODINFUNCTION4(BOOL, AppendMenuA,
574 HMENU, hMenu,
575 UINT, uFlags,
576 UINT, id,
577 LPCSTR, lpNewItem)
578{
579 return ODIN_InsertMenuA( hMenu, -1, uFlags | MF_BYPOSITION, id, lpNewItem );
580}
581//******************************************************************************
582//******************************************************************************
583ODINFUNCTION4(BOOL, AppendMenuW,
584 HMENU, hMenu,
585 UINT, uFlags,
586 UINT, id,
587 LPCWSTR, lpNewItem)
588{
589 return ODIN_InsertMenuW( hMenu, -1, uFlags | MF_BYPOSITION, id, lpNewItem );
590}
591//******************************************************************************
592//******************************************************************************
593ODINFUNCTION3(DWORD, CheckMenuItem,
594 HMENU, hMenu,
595 UINT, arg2,
596 UINT, arg3)
597{
598 dprintf(("USER32: OS2CheckMenuItem\n"));
599 if(hMenu == 0)
600 {
601 SetLastError(ERROR_INVALID_PARAMETER);
602 return 0;
603 }
604 return O32_CheckMenuItem(hMenu, arg2, arg3);
605}
606//******************************************************************************
607//******************************************************************************
608ODINFUNCTION3(BOOL,EnableMenuItem,HMENU,hMenu,
609 UINT, uIDEnableItem,
610 UINT, uEnable)
611{
612 if(hMenu == 0)
613 {
614 SetLastError(ERROR_INVALID_PARAMETER);
615 return 0;
616 }
617
618 return O32_EnableMenuItem(hMenu,
619 uIDEnableItem,
620 uEnable);
621}
622//******************************************************************************
623//******************************************************************************
624ODINFUNCTION5(BOOL, ModifyMenuA,
625 HMENU, hMenu,
626 UINT, arg2,
627 UINT, arg3,
628 UINT, arg4,
629 LPCSTR, arg5)
630{
631 dprintf(("USER32: OS2ModifyMenuA\n"));
632 if(hMenu == 0)
633 {
634 SetLastError(ERROR_INVALID_PARAMETER);
635 return 0;
636 }
637 return O32_ModifyMenu(hMenu, arg2, arg3, arg4, arg5);
638}
639//******************************************************************************
640//******************************************************************************
641ODINFUNCTION5(BOOL, ModifyMenuW,
642 HMENU, hMenu,
643 UINT, arg2,
644 UINT, arg3,
645 UINT, arg4,
646 LPCWSTR, arg5)
647{
648 BOOL rc;
649 char *astring = NULL;
650
651 if(hMenu == 0)
652 {
653 SetLastError(ERROR_INVALID_PARAMETER);
654 return 0;
655 }
656
657 if(HIWORD(arg5) != 0)
658 astring = UnicodeToAsciiString((LPWSTR)arg5);
659 else
660 astring = (char *) arg5;
661
662 rc = ODIN_ModifyMenuA(hMenu, arg2, arg3, arg4, astring);
663 if(HIWORD(arg5) != 0)
664 FreeAsciiString(astring);
665
666 return(rc);
667}
668//******************************************************************************
669//******************************************************************************
670ODINFUNCTION3(BOOL, RemoveMenu,
671 HMENU, hMenu,
672 UINT, arg2,
673 UINT, arg3)
674{
675 dprintf(("USER32: OS2RemoveMenu\n"));
676 if(hMenu == 0)
677 {
678 SetLastError(ERROR_INVALID_PARAMETER);
679 return 0;
680 }
681
682 return O32_RemoveMenu(hMenu, arg2, arg3);
683}
684//******************************************************************************
685//******************************************************************************
686ODINFUNCTION3(BOOL, DeleteMenu,
687 HMENU, hMenu,
688 UINT, arg2,
689 UINT, arg3)
690{
691 dprintf(("USER32: OS2DeleteMenu\n"));
692 if(hMenu == 0)
693 {
694 SetLastError(ERROR_INVALID_PARAMETER);
695 return 0;
696 }
697
698 return O32_DeleteMenu(hMenu, arg2, arg3);
699}
700//******************************************************************************
701//******************************************************************************
702ODINFUNCTION4(BOOL, HiliteMenuItem,
703 HWND, hMenu,
704 HMENU, arg2,
705 UINT, arg3,
706 UINT, arg4)
707{
708 dprintf(("USER32: OS2HiliteMenuItem\n"));
709 if(hMenu == 0)
710 {
711 SetLastError(ERROR_INVALID_PARAMETER);
712 return 0;
713 }
714
715 return O32_HiliteMenuItem(hMenu, arg2, arg3, arg4);
716}
717//******************************************************************************
718//******************************************************************************
719ODINFUNCTION5(BOOL, InsertMenuA,
720 HMENU, hMenu,
721 UINT, pos,
722 UINT, flags,
723 UINT, id,
724 LPCSTR, str)
725{
726 dprintf(("USER32: InsertMenuA %x %d %x %d %s", hMenu, pos, flags, id, str));
727 if(hMenu == 0)
728 {
729 SetLastError(ERROR_INVALID_PARAMETER);
730 return 0;
731 }
732
733 if(!str || *str == NULL) {
734 flags |= MF_SEPARATOR;
735 }
736 return O32_InsertMenu(hMenu, pos, flags, id, str);
737}
738//******************************************************************************
739//******************************************************************************
740ODINFUNCTION5(BOOL, InsertMenuW,
741 HMENU, hMenu,
742 UINT, arg2,
743 UINT, arg3,
744 UINT, arg4,
745 LPCWSTR, arg5)
746{
747 BOOL rc;
748 char *astring = NULL;
749
750 if(HIWORD(arg5) != 0)
751 astring = UnicodeToAsciiString((LPWSTR)arg5);
752 else
753 astring = (char *) arg5;
754
755 rc = ODIN_InsertMenuA(hMenu, arg2, arg3, arg4, astring);
756
757 if(HIWORD(arg5) != 0)
758 FreeAsciiString(astring);
759
760 return(rc);
761}
762//******************************************************************************
763//******************************************************************************
764ODINFUNCTION2(BOOL, SetMenuContextHelpId,
765 HMENU, hMenu,
766 DWORD, dwContextHelpId)
767{
768 POPUPMENU *menu;
769
770 menu = GetInternalMenuInfo(hMenu);
771 if(menu == NULL) {
772 dprintf(("USER32: SetMenuContextHelpId(%x) No POPUPMENU structure found!", hMenu));
773 SetLastError(ERROR_INVALID_PARAMETER);
774 return FALSE;
775 }
776 dprintf(("USER32: SetMenuContextHelpId %x %d", hMenu, dwContextHelpId));
777 menu->dwContextHelpID = dwContextHelpId;
778 return(TRUE);
779}
780//******************************************************************************
781//******************************************************************************
782ODINFUNCTION1(DWORD, GetMenuContextHelpId,
783 HMENU, hMenu)
784{
785 POPUPMENU *menu;
786
787 menu = GetInternalMenuInfo(hMenu);
788 if(menu == NULL) {
789 dprintf(("USER32: GetMenuContextHelpId(%x) No POPUPMENU structure found!", hMenu));
790 SetLastError(ERROR_INVALID_PARAMETER);
791 return 0;
792 }
793 dprintf(("USER32: GetMenuContextHelpId %x %d", hMenu, menu->dwContextHelpID));
794 return menu->dwContextHelpID;
795}
796//******************************************************************************
797//******************************************************************************
798ODINFUNCTION5(BOOL, CheckMenuRadioItem,
799 HMENU, hMenu,
800 UINT, idFirst,
801 UINT, idLast,
802 UINT, idCheck,
803 UINT, uFlags)
804{
805 dprintf(("USER32: OS2CheckMenuRadioItem, not implemented\n"));
806 return(TRUE);
807}
808//******************************************************************************
809//******************************************************************************
810ODINFUNCTION5(BOOL, ChangeMenuA,
811 HMENU, hMenu,
812 UINT, pos,
813 LPCSTR, data,
814 UINT, id,
815 UINT, flags)
816{
817 dprintf(("USER32: ChangeMenuA flags %X\n", flags));
818
819 if (flags & MF_APPEND) return ODIN_AppendMenuA(hMenu, flags & ~MF_APPEND,
820 id, data );
821 if (flags & MF_DELETE) return ODIN_DeleteMenu(hMenu, pos, flags & ~MF_DELETE);
822 if (flags & MF_CHANGE) return ODIN_ModifyMenuA(hMenu, pos, flags & ~MF_CHANGE,
823 id, data );
824 if (flags & MF_REMOVE) return ODIN_RemoveMenu(hMenu,
825 flags & MF_BYPOSITION ? pos : id,
826 flags & ~MF_REMOVE );
827 /* Default: MF_INSERT */
828 return InsertMenuA( hMenu, pos, flags, id, data );
829}
830//******************************************************************************
831//******************************************************************************
832ODINFUNCTION5(BOOL, ChangeMenuW,
833 HMENU, hMenu,
834 UINT, pos,
835 LPCWSTR, data,
836 UINT, id,
837 UINT, flags)
838{
839 dprintf(("USER32: ChangeMenuW flags %X\n", flags));
840
841 if (flags & MF_APPEND) return ODIN_AppendMenuW(hMenu, flags & ~MF_APPEND,
842 id, data );
843 if (flags & MF_DELETE) return ODIN_DeleteMenu(hMenu, pos, flags & ~MF_DELETE);
844 if (flags & MF_CHANGE) return ODIN_ModifyMenuW(hMenu, pos, flags & ~MF_CHANGE,
845 id, data );
846 if (flags & MF_REMOVE) return ODIN_RemoveMenu(hMenu,
847 flags & MF_BYPOSITION ? pos : id,
848 flags & ~MF_REMOVE );
849 /* Default: MF_INSERT */
850 return InsertMenuW(hMenu, pos, flags, id, data);
851}
852//******************************************************************************
853//******************************************************************************
854ODINFUNCTION4(BOOL, SetMenuItemInfoA,
855 HMENU, hMenu,
856 UINT, par1,
857 BOOL, par2,
858 const MENUITEMINFOA *, lpmii)
859{
860 dprintf(("USER32: SetMenuItemInfoA faked %x", hMenu));
861
862 if (!hMenu) {
863 SetLastError(ERROR_INVALID_PARAMETER);
864 return FALSE;
865 }
866 return TRUE;
867}
868/*****************************************************************************
869 * Function : SetMenuItemInfoW
870 * Purpose : The SetMenuItemInfo function changes information about a menu item.
871 * Parameters:
872 * Variables :
873 * Result : If the function succeeds, the return value is TRUE.
874 * If the function fails, the return value is FALSE. To get extended
875 * error information, use the GetLastError function.
876 * Remark :
877 * Status : UNTESTED STUB
878 *
879 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
880 *****************************************************************************/
881
882ODINFUNCTION4(BOOL, SetMenuItemInfoW,
883 HMENU, hMenu,
884 UINT, uItem,
885 BOOL, fByPosition,
886 const MENUITEMINFOW *, lpmmi)
887{
888 dprintf(("USER32:SetMenuItemInfoW (%08xh,%08xh,%08xh,%08x) not implemented.\n",
889 hMenu,
890 uItem,
891 fByPosition,
892 lpmmi));
893
894 return (SetMenuItemInfoA(hMenu,
895 uItem,
896 fByPosition,
897 (const MENUITEMINFOA *)lpmmi));
898}
899/*****************************************************************************
900 * Function : GetMenuDefaultItem
901 * Purpose : TheGetMenuDefaultItem function determines the default menu item
902 * on the specified menu.
903 * Parameters:
904 * Variables :
905 * Result : If the function succeeds, the return value is the identifier or
906 * position of the menu item.
907 * If the function fails, the return value is - 1.
908 * Remark :
909 * Status : UNTESTED STUB
910 *
911 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
912 *****************************************************************************/
913
914ODINFUNCTION3(UINT, GetMenuDefaultItem,
915 HMENU, hMenu,
916 UINT, fByPos,
917 UINT, gmdiFlags)
918{
919 dprintf(("USER32:GetMenuDefaultItem (%08xh,%u,%08x) not implemented.\n",
920 hMenu,
921 fByPos,
922 gmdiFlags));
923
924 return (-1);
925}
926//******************************************************************************
927//******************************************************************************
928ODINFUNCTION3(BOOL, SetMenuDefaultItem,
929 HMENU, hMenu,
930 UINT, uItem,
931 UINT, fByPos)
932{
933 dprintf(("USER32: SetMenuDefaultItem, faked\n"));
934 return(TRUE);
935}
936//******************************************************************************
937//******************************************************************************
938BOOL GetMenuItemInfoAW(HMENU hMenu, UINT uItem, BOOL byPos, MENUITEMINFOA *lpmii, BOOL unicode)
939{
940 if(byPos) {
941 uItem = GetMenuItemID(hMenu, uItem);
942 }
943 if(ODIN_GetMenuState(hMenu, uItem, MF_BYCOMMAND) == -1) {
944 //item doesn't exist
945 dprintf(("USER32: GetMenuItemInfoAW %x item %d doesn't exist", hMenu, uItem));
946 SetLastError(ERROR_INVALID_PARAMETER);
947 return FALSE;
948 }
949 if (lpmii->fMask & MIIM_TYPE)
950 {
951 lpmii->fType = ODIN_GetMenuState(hMenu, uItem, MF_BYCOMMAND); //not correct
952// lpmii->fType = menu->fType;
953 if (unicode) {
954 lpmii->cch = ODIN_GetMenuStringW(hMenu, uItem, (LPWSTR)lpmii->dwTypeData, lpmii->cch, MF_BYCOMMAND);
955 }
956 else {
957 lpmii->cch = ODIN_GetMenuStringA(hMenu, uItem, (LPSTR)lpmii->dwTypeData, lpmii->cch, MF_BYCOMMAND);
958 }
959//TODO:
960#if 0
961 switch (MENU_ITEM_TYPE(menu->fType)) {
962 case MF_STRING:
963 if (menu->text && lpmii->dwTypeData && lpmii->cch) {
964 if (unicode) {
965 lstrcpynAtoW((LPWSTR) lpmii->dwTypeData, menu->text, lpmii->cch);
966 lpmii->cch = lstrlenW((LPWSTR)menu->text);
967 }
968 else {
969 lstrcpynA(lpmii->dwTypeData, menu->text, lpmii->cch);
970 lpmii->cch = lstrlenA(menu->text);
971 }
972 }
973 break;
974 case MF_OWNERDRAW:
975 case MF_BITMAP:
976 lpmii->dwTypeData = menu->text;
977 /* fall through */
978 default:
979 lpmii->cch = 0;
980 }
981#endif
982 }
983
984 if (lpmii->fMask & MIIM_STRING) {
985 if (unicode) {
986 lpmii->cch = ODIN_GetMenuStringW(hMenu, uItem, (LPWSTR)lpmii->dwTypeData, lpmii->cch, MF_BYCOMMAND);
987 }
988 else {
989 lpmii->cch = ODIN_GetMenuStringA(hMenu, uItem, (LPSTR)lpmii->dwTypeData, lpmii->cch, MF_BYCOMMAND);
990 }
991 }
992
993//TODO:
994#if 0
995 if (lpmii->fMask & MIIM_FTYPE)
996 lpmii->fType = menu->fType;
997
998 if (lpmii->fMask & MIIM_BITMAP)
999 lpmii->hbmpItem = menu->hbmpItem;
1000#endif
1001
1002 if (lpmii->fMask & MIIM_STATE)
1003 lpmii->fState = ODIN_GetMenuState(hMenu, uItem, MF_BYCOMMAND);
1004
1005 if (lpmii->fMask & MIIM_ID)
1006 lpmii->wID = uItem;
1007
1008//TODO:
1009#if 1
1010 lpmii->hSubMenu = 0;
1011 lpmii->hbmpChecked = 0;
1012 lpmii->hbmpUnchecked = 0;
1013 lpmii->dwItemData = 0;
1014#else
1015 if (lpmii->fMask & MIIM_SUBMENU)
1016 lpmii->hSubMenu = ODIN_GetSubMenu(hMenu, uItem); //need index, not id
1017
1018 if (lpmii->fMask & MIIM_CHECKMARKS) {
1019 lpmii->hbmpChecked = menu->hCheckBit;
1020 lpmii->hbmpUnchecked = menu->hUnCheckBit;
1021 }
1022 if (lpmii->fMask & MIIM_DATA)
1023 lpmii->dwItemData = menu->dwItemData;
1024#endif
1025
1026 return(FALSE);
1027}
1028//******************************************************************************
1029//******************************************************************************
1030ODINFUNCTION4(BOOL, GetMenuItemInfoA,
1031 HMENU, hMenu,
1032 UINT, uItem,
1033 BOOL, byPos,
1034 MENUITEMINFOA *, lpMenuItemInfo)
1035{
1036 return GetMenuItemInfoAW(hMenu, uItem, byPos, lpMenuItemInfo, FALSE);
1037}
1038/*****************************************************************************
1039 * Function : GetMenuItemInfoW
1040 * Purpose : The GetMenuItemInfo function retrieves information about a menu item.
1041 * Parameters:
1042 * Variables :
1043 * Result : If the function succeeds, the return value is TRUE.
1044 * If the function fails, the return value is FALSE. To get extended
1045 * error information, use the GetLastError function.
1046 * Remark :
1047 * Status : UNTESTED STUB
1048 *
1049 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
1050 *****************************************************************************/
1051
1052ODINFUNCTION4(BOOL, GetMenuItemInfoW,
1053 HMENU, hMenu,
1054 UINT, uItem,
1055 BOOL, byPos,
1056 MENUITEMINFOW *, lpMenuItemInfo)
1057{
1058 return GetMenuItemInfoAW(hMenu, uItem, byPos, (MENUITEMINFOA*)lpMenuItemInfo, TRUE);
1059}
1060/*****************************************************************************
1061 * Function : GetMenuItemRect
1062 * Purpose : The GetMenuItemRect function retrieves the bounding rectangle
1063 * for the specified menu item.
1064 * Parameters:
1065 * Variables :
1066 * Result : If the function succeeds, the return value is TRUE.
1067 * If the function fails, the return value is FALSE. To get
1068 * extended error information, use the GetLastError function.
1069 * Remark :
1070 * Status : UNTESTED STUB
1071 *
1072 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
1073 *****************************************************************************/
1074
1075ODINFUNCTION4(BOOL, GetMenuItemRect,
1076 HWND, hWnd,
1077 HMENU, hMenu,
1078 UINT, uItem,
1079 LPRECT, lprcItem)
1080{
1081 dprintf(("USER32:GetMenuItemRect (%08xh,%08xh,%08xh,%08x) not implemented.\n",
1082 hWnd,
1083 hMenu,
1084 uItem,
1085 lprcItem));
1086
1087 return (FALSE);
1088}
1089/*****************************************************************************
1090 * Function : InsertMenuItemA
1091 * Purpose : The InsertMenuItem function inserts a new menu item at the specified
1092 * position in a menu bar or pop-up menu.
1093 * Parameters:
1094 * Variables :
1095 * Result : If the function succeeds, the return value is TRUE.
1096 * If the function fails, the return value is FALSE. To get extended
1097 * error information, use the GetLastError function.
1098 * Remark :
1099 * Status : UNTESTED STUB
1100 *
1101 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
1102 *****************************************************************************/
1103
1104ODINFUNCTION4(BOOL, InsertMenuItemA,
1105 HMENU, hMenu,
1106 UINT, uItem,
1107 BOOL, fByPosition,
1108 const MENUITEMINFOA*, lpmii)
1109{
1110 dprintf(("USER32:InsertMenuItemA (%08xh,%08xh,%u,%08x) not correctly implemented.\n",
1111 hMenu,
1112 uItem,
1113 fByPosition,
1114 lpmii));
1115
1116 if(fByPosition) {
1117 return ODIN_InsertMenuA(hMenu, uItem, lpmii->fType | MF_BYPOSITION, (lpmii->fType & MF_POPUP) ? lpmii->hSubMenu : lpmii->wID, lpmii->dwTypeData);
1118 }
1119 else return ODIN_InsertMenuA(hMenu, uItem, lpmii->fType | MF_BYCOMMAND, (lpmii->fType & MF_POPUP) ? lpmii->hSubMenu : lpmii->wID, lpmii->dwTypeData);
1120}
1121
1122
1123/*****************************************************************************
1124 * Function : InsertMenuItemW
1125 * Purpose : The InsertMenuItem function inserts a new menu item at the specified
1126 * position in a menu bar or pop-up menu.
1127 * Parameters:
1128 * Variables :
1129 * Result : If the function succeeds, the return value is TRUE.
1130 * If the function fails, the return value is FALSE. To get extended
1131 * error information, use the GetLastError function.
1132 * Remark :
1133 * Status : UNTESTED STUB
1134 *
1135 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
1136 *****************************************************************************/
1137
1138ODINFUNCTION4(BOOL, InsertMenuItemW,
1139 HMENU, hMenu,
1140 UINT, uItem,
1141 BOOL, fByPosition,
1142 const MENUITEMINFOW *, lpmii)
1143{
1144 dprintf(("USER32:InsertMenuItemW (%08xh,%08xh,%u,%08x) not correctly implemented.\n",
1145 hMenu,
1146 uItem,
1147 fByPosition,
1148 lpmii));
1149
1150 if(fByPosition) {
1151 return ODIN_InsertMenuW(hMenu, uItem, lpmii->fType | MF_BYPOSITION, (lpmii->fType & MF_POPUP) ? lpmii->hSubMenu : lpmii->wID, lpmii->dwTypeData);
1152 }
1153 else return ODIN_InsertMenuW(hMenu, uItem, lpmii->fType | MF_BYCOMMAND, (lpmii->fType & MF_POPUP) ? lpmii->hSubMenu : lpmii->wID, lpmii->dwTypeData);
1154}
1155/*****************************************************************************
1156 * Function : MenuItemFromPoint
1157 * Purpose : TheMenuItemFromPoint function determines which menu item, if
1158 * any, is at the specified location.
1159 * Parameters:
1160 * Variables :
1161 * Result : Returns the zero-based position of the menu item at the specified
1162 * location or -1 if no menu item is at the specified location.
1163 * Remark :
1164 * Status : UNTESTED STUB
1165 *
1166 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
1167 *****************************************************************************/
1168
1169ODINFUNCTION3(UINT, MenuItemFromPoint,
1170 HWND, hWnd,
1171 HMENU, hMenu,
1172 POINT, ptScreen)
1173{
1174 dprintf(("USER32:MenuItemFromPoint (%08xh,%08xh,%u) not implemented.\n",
1175 hWnd,
1176 hMenu,
1177 ptScreen));
1178
1179 return (-1);
1180}
1181
1182
1183/*****************************************************************************
1184 * Function : GetMenuInfo
1185 * Parameters:
1186 * Variables :
1187 * Result :
1188 * Remark :
1189 * Status : UNTESTED STUB win98/NT5.0
1190 *
1191 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
1192 *****************************************************************************/
1193
1194ODINFUNCTION2(BOOL, GetMenuInfo,
1195 HMENU, hMenu,
1196 LPMENUINFO, lpmi)
1197{
1198 POPUPMENU *menu;
1199
1200 menu = GetInternalMenuInfo(hMenu);
1201 if(menu == NULL) {
1202 dprintf(("USER32: GetMenuInfo(%08xh,%08xh) No POPUPMENU structure found!", hMenu, lpmi));
1203 SetLastError(ERROR_INVALID_PARAMETER);
1204 return FALSE;
1205 }
1206 dprintf(("USER32: GetMenuInfo(%08xh,%08xh)", hMenu, lpmi));
1207
1208 if (lpmi)
1209 {
1210 if (lpmi->fMask & MIM_BACKGROUND)
1211 lpmi->hbrBack = menu->hbrBack;
1212
1213 if (lpmi->fMask & MIM_HELPID)
1214 lpmi->dwContextHelpID = menu->dwContextHelpID;
1215
1216 if (lpmi->fMask & MIM_MAXHEIGHT)
1217 lpmi->cyMax = menu->cyMax;
1218
1219 if (lpmi->fMask & MIM_MENUDATA)
1220 lpmi->dwMenuData = menu->dwMenuData;
1221
1222 if (lpmi->fMask & MIM_STYLE)
1223 lpmi->dwStyle = menu->dwStyle;
1224
1225 return TRUE;
1226 }
1227 SetLastError(ERROR_INVALID_PARAMETER);
1228 return FALSE;
1229}
1230/*****************************************************************************
1231 * Function : SetMenuInfo
1232 * Purpose :
1233 * Parameters:
1234 * Variables :
1235 * Result :
1236 * Remark :
1237 * FIXME
1238 * MIM_APPLYTOSUBMENUS
1239 * actually use the items to draw the menu
1240 * Status : UNTESTED STUB win98/NT5.0
1241 *
1242 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
1243 *****************************************************************************/
1244
1245ODINFUNCTION2(BOOL, SetMenuInfo,
1246 HMENU, hMenu,
1247 LPCMENUINFO, lpmi)
1248{
1249 POPUPMENU *menu;
1250
1251 menu = GetInternalMenuInfo(hMenu);
1252 if(menu == NULL) {
1253 dprintf(("USER32: SetMenuInfo(%08xh,%08xh) No POPUPMENU structure found!", hMenu, lpmi));
1254 SetLastError(ERROR_INVALID_PARAMETER);
1255 return FALSE;
1256 }
1257
1258 dprintf(("USER32: SetMenuInfo(%08xh,%08xh)", hMenu, lpmi));
1259
1260 if (lpmi && (lpmi->cbSize==sizeof(MENUINFO)))
1261 {
1262 if (lpmi->fMask & MIM_BACKGROUND)
1263 menu->hbrBack = lpmi->hbrBack;
1264
1265 if (lpmi->fMask & MIM_HELPID)
1266 menu->dwContextHelpID = lpmi->dwContextHelpID;
1267
1268 if (lpmi->fMask & MIM_MAXHEIGHT)
1269 menu->cyMax = lpmi->cyMax;
1270
1271 if (lpmi->fMask & MIM_MENUDATA)
1272 menu->dwMenuData = lpmi->dwMenuData;
1273
1274 if (lpmi->fMask & MIM_STYLE)
1275 menu->dwStyle = lpmi->dwStyle;
1276
1277 return TRUE;
1278 }
1279 SetLastError(ERROR_INVALID_PARAMETER);
1280 return FALSE;
1281}
1282//******************************************************************************
1283//******************************************************************************
1284
Note: See TracBrowser for help on using the repository browser.