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

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

SetWindowRgn memory leak + InsertMenu bug fixed

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