source: trunk/src/user32/new/winmenu.cpp@ 2350

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

GetMenuStringA bugfix

File size: 41.5 KB
Line 
1/* $Id: winmenu.cpp,v 1.10 2000-01-07 00:24:34 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, idItem,
418 LPSTR, lpsz,
419 int, cchMax,
420 UINT, fuFlags)
421{
422 int rc, nritems;
423
424 if(hMenu == 0)
425 {
426 SetLastError(ERROR_INVALID_PARAMETER);
427 return 0;
428 }
429 if(!lpsz || !cchMax) {//determine menu string length
430 char menustr[256];
431 rc = O32_GetMenuString(hMenu, idItem, menustr, sizeof(menustr), fuFlags);
432 //SvL: Open32 returns the wrong error
433 return (rc == -1) ? 0 : rc;
434 }
435 rc = O32_GetMenuString(hMenu, idItem, lpsz, cchMax, fuFlags);
436 //SvL: Open32 returns the wrong error
437 return (rc == -1) ? 0 : rc;
438}
439//******************************************************************************
440//******************************************************************************
441ODINFUNCTION5(int, GetMenuStringW,
442 HMENU, hMenu,
443 UINT, idItem,
444 LPWSTR,lpsz,
445 int, cchMax,
446 UINT, fuFlags)
447{
448 char *astring = (char *)malloc(cchMax);
449 int rc;
450
451 rc = ODIN_GetMenuStringA(hMenu, idItem, astring, cchMax, fuFlags);
452 if(rc)
453 {
454 dprintf(("USER32: GetMenuStringW %s\n", astring));
455 AsciiToUnicode(astring, lpsz);
456 }
457 else lpsz[0] = 0;
458 free(astring);
459
460 return(rc);
461}
462//******************************************************************************
463//******************************************************************************
464ODINFUNCTION5(BOOL, SetMenuItemBitmaps,
465 HMENU, hMenu,
466 UINT, arg2,
467 UINT, arg3,
468 HBITMAP, arg4,
469 HBITMAP, arg5)
470{
471 dprintf(("USER32: SetMenuItemBitmaps\n"));
472 if(hMenu == 0)
473 {
474 SetLastError(ERROR_INVALID_PARAMETER);
475 return 0;
476 }
477 return O32_SetMenuItemBitmaps(hMenu, arg2, arg3, arg4, arg5);
478}
479//******************************************************************************
480//******************************************************************************
481ODINFUNCTION2(HMENU, GetSubMenu,
482 HWND, hMenu,
483 int, arg2)
484{
485 if(hMenu == 0)
486 {
487 SetLastError(ERROR_INVALID_PARAMETER);
488 return 0;
489 }
490
491 return O32_GetSubMenu(hMenu, arg2);
492}
493//******************************************************************************
494//******************************************************************************
495ODINFUNCTION2(HMENU, GetSystemMenu,
496 HWND, hSystemWindow,
497 BOOL, bRevert)
498{
499 Win32BaseWindow *window;
500
501 window = Win32BaseWindow::GetWindowFromHandle(hSystemWindow);
502 if(!window)
503 {
504 dprintf(("GetSystemMenu, window %x not found", hSystemWindow));
505 return 0;
506 }
507
508 return O32_GetSystemMenu(window->getOS2FrameWindowHandle(), bRevert);
509}
510//******************************************************************************
511//******************************************************************************
512ODINFUNCTION1(BOOL, IsMenu,
513 HMENU, hMenu)
514{
515 dprintf(("USER32: IsMenu\n"));
516 return O32_IsMenu(hMenu);
517}
518//******************************************************************************
519//******************************************************************************
520ODINFUNCTION7(BOOL, TrackPopupMenu,
521 HMENU, hMenu,
522 UINT, arg2,
523 int, arg3,
524 int, arg4,
525 int, arg5,
526 HWND, arg6,
527 const RECT *, arg7)
528{
529 Win32BaseWindow *window;
530
531 window = Win32BaseWindow::GetWindowFromHandle(arg6);
532 if(!window)
533 {
534 dprintf(("TrackPopupMenu, window %x not found", arg6));
535 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
536 return 0;
537 }
538 dprintf(("USER32: TrackPopupMenu\n"));
539 if(hMenu == 0)
540 {
541 SetLastError(ERROR_INVALID_PARAMETER);
542 return 0;
543 }
544 return O32_TrackPopupMenu(hMenu, arg2, arg3, arg4, arg5, window->getOS2WindowHandle(),
545 arg7);
546}
547//******************************************************************************
548//******************************************************************************
549ODINFUNCTION6(BOOL, TrackPopupMenuEx,
550 HMENU, hMenu,
551 UINT, flags,
552 int, X,
553 int, Y,
554 HWND, hwnd,
555 LPTPMPARAMS, lpPM)
556{
557 RECT *rect = NULL;
558 Win32BaseWindow *window;
559
560 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
561 if(!window)
562 {
563 dprintf(("TrackPopupMenu, window %x not found", hwnd));
564 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
565 return 0;
566 }
567
568 dprintf(("USER32: TrackPopupMenuEx, not completely implemented\n"));
569
570 if (lpPM != NULL) // this parameter can be NULL
571 if(lpPM->cbSize != 0)
572 rect = &lpPM->rcExclude;
573
574 if(hMenu == 0)
575 {
576 SetLastError(ERROR_INVALID_PARAMETER);
577 return 0;
578 }
579 return O32_TrackPopupMenu(hMenu, flags, X, Y, 0, window->getOS2WindowHandle(), rect);
580}
581//******************************************************************************
582//******************************************************************************
583ODINFUNCTION4(BOOL, AppendMenuA,
584 HMENU, hMenu,
585 UINT, uFlags,
586 UINT, id,
587 LPCSTR, lpNewItem)
588{
589 return ODIN_InsertMenuA( hMenu, -1, uFlags | MF_BYPOSITION, id, lpNewItem );
590}
591//******************************************************************************
592//******************************************************************************
593ODINFUNCTION4(BOOL, AppendMenuW,
594 HMENU, hMenu,
595 UINT, uFlags,
596 UINT, id,
597 LPCWSTR, lpNewItem)
598{
599 return ODIN_InsertMenuW( hMenu, -1, uFlags | MF_BYPOSITION, id, lpNewItem );
600}
601//******************************************************************************
602//******************************************************************************
603ODINFUNCTION3(DWORD, CheckMenuItem,
604 HMENU, hMenu,
605 UINT, arg2,
606 UINT, arg3)
607{
608 if(hMenu == 0)
609 {
610 SetLastError(ERROR_INVALID_PARAMETER);
611 return 0;
612 }
613 return O32_CheckMenuItem(hMenu, arg2, arg3);
614}
615//******************************************************************************
616//******************************************************************************
617ODINFUNCTION3(BOOL,EnableMenuItem,HMENU,hMenu,
618 UINT, uIDEnableItem,
619 UINT, uEnable)
620{
621 if(hMenu == 0)
622 {
623 SetLastError(ERROR_INVALID_PARAMETER);
624 return 0;
625 }
626
627 return O32_EnableMenuItem(hMenu,
628 uIDEnableItem,
629 uEnable);
630}
631//******************************************************************************
632//******************************************************************************
633ODINFUNCTION5(BOOL, ModifyMenuA,
634 HMENU, hMenu,
635 UINT, arg2,
636 UINT, arg3,
637 UINT, arg4,
638 LPCSTR, arg5)
639{
640 dprintf(("USER32: OS2ModifyMenuA\n"));
641 if(hMenu == 0)
642 {
643 SetLastError(ERROR_INVALID_PARAMETER);
644 return 0;
645 }
646 return O32_ModifyMenu(hMenu, arg2, arg3, arg4, arg5);
647}
648//******************************************************************************
649//******************************************************************************
650ODINFUNCTION5(BOOL, ModifyMenuW,
651 HMENU, hMenu,
652 UINT, arg2,
653 UINT, arg3,
654 UINT, arg4,
655 LPCWSTR, arg5)
656{
657 BOOL rc;
658 char *astring = NULL;
659
660 if(hMenu == 0)
661 {
662 SetLastError(ERROR_INVALID_PARAMETER);
663 return 0;
664 }
665
666 if(IS_STRING_ITEM(arg3) && HIWORD(arg5) != 0)
667 astring = UnicodeToAsciiString((LPWSTR)arg5);
668 else
669 astring = (char *) arg5;
670
671 rc = ODIN_ModifyMenuA(hMenu, arg2, arg3, arg4, astring);
672 if(IS_STRING_ITEM(arg3) && HIWORD(arg5) != 0)
673 FreeAsciiString(astring);
674
675 return(rc);
676}
677//******************************************************************************
678//******************************************************************************
679ODINFUNCTION3(BOOL, RemoveMenu,
680 HMENU, hMenu,
681 UINT, arg2,
682 UINT, arg3)
683{
684 dprintf(("USER32: OS2RemoveMenu\n"));
685 if(hMenu == 0)
686 {
687 SetLastError(ERROR_INVALID_PARAMETER);
688 return 0;
689 }
690
691 return O32_RemoveMenu(hMenu, arg2, arg3);
692}
693//******************************************************************************
694//******************************************************************************
695ODINFUNCTION3(BOOL, DeleteMenu,
696 HMENU, hMenu,
697 UINT, arg2,
698 UINT, arg3)
699{
700 dprintf(("USER32: OS2DeleteMenu\n"));
701 if(hMenu == 0)
702 {
703 SetLastError(ERROR_INVALID_PARAMETER);
704 return 0;
705 }
706
707 return O32_DeleteMenu(hMenu, arg2, arg3);
708}
709//******************************************************************************
710//******************************************************************************
711ODINFUNCTION4(BOOL, HiliteMenuItem,
712 HWND, hMenu,
713 HMENU, arg2,
714 UINT, arg3,
715 UINT, arg4)
716{
717 dprintf(("USER32: OS2HiliteMenuItem\n"));
718 if(hMenu == 0)
719 {
720 SetLastError(ERROR_INVALID_PARAMETER);
721 return 0;
722 }
723
724 return O32_HiliteMenuItem(hMenu, arg2, arg3, arg4);
725}
726//******************************************************************************
727//******************************************************************************
728ODINFUNCTION5(BOOL, InsertMenuA,
729 HMENU, hMenu,
730 UINT, pos,
731 UINT, flags,
732 UINT, id,
733 LPCSTR, str)
734{
735 if(IS_STRING_ITEM(flags) && HIWORD(str)) {
736 dprintf(("USER32: InsertMenuA %x %d %x %d %s", hMenu, pos, flags, id, str));
737 }
738 else dprintf(("USER32: InsertMenuA %x %d %x %d %x", hMenu, pos, flags, id, str));
739
740 if(hMenu == 0)
741 {
742 SetLastError(ERROR_INVALID_PARAMETER);
743 return 0;
744 }
745
746 if(IS_STRING_ITEM(flags) && (!str || *str == NULL)) {
747 flags |= MF_SEPARATOR;
748 }
749 //SvL: RealPlayer calls InsertMenu with flag 0 & pos -1
750 if((flags & (MF_BYCOMMAND|MF_BYPOSITION)) == 0 && (pos == 0xffffffff))
751 flags |= MF_BYPOSITION;
752
753 return O32_InsertMenu(hMenu, pos, flags, id, str);
754}
755//******************************************************************************
756//******************************************************************************
757ODINFUNCTION5(BOOL, InsertMenuW,
758 HMENU, hMenu,
759 UINT, arg2,
760 UINT, arg3,
761 UINT, arg4,
762 LPCWSTR, arg5)
763{
764 BOOL rc;
765 char *astring = NULL;
766
767 if(IS_STRING_ITEM(arg3) && HIWORD(arg5) != 0)
768 astring = UnicodeToAsciiString((LPWSTR)arg5);
769 else
770 astring = (char *) arg5;
771
772 rc = ODIN_InsertMenuA(hMenu, arg2, arg3, arg4, astring);
773
774 if(IS_STRING_ITEM(arg3) && HIWORD(arg5) != 0)
775 FreeAsciiString(astring);
776
777 return(rc);
778}
779//******************************************************************************
780//******************************************************************************
781ODINFUNCTION2(BOOL, SetMenuContextHelpId,
782 HMENU, hMenu,
783 DWORD, dwContextHelpId)
784{
785 POPUPMENU *menu;
786
787 menu = GetInternalMenuInfo(hMenu);
788 if(menu == NULL) {
789 dprintf(("USER32: SetMenuContextHelpId(%x) No POPUPMENU structure found!", hMenu));
790 SetLastError(ERROR_INVALID_PARAMETER);
791 return FALSE;
792 }
793 dprintf(("USER32: SetMenuContextHelpId %x %d", hMenu, dwContextHelpId));
794 menu->dwContextHelpID = dwContextHelpId;
795 return(TRUE);
796}
797//******************************************************************************
798//******************************************************************************
799ODINFUNCTION1(DWORD, GetMenuContextHelpId,
800 HMENU, hMenu)
801{
802 POPUPMENU *menu;
803
804 menu = GetInternalMenuInfo(hMenu);
805 if(menu == NULL) {
806 dprintf(("USER32: GetMenuContextHelpId(%x) No POPUPMENU structure found!", hMenu));
807 SetLastError(ERROR_INVALID_PARAMETER);
808 return 0;
809 }
810 dprintf(("USER32: GetMenuContextHelpId %x %d", hMenu, menu->dwContextHelpID));
811 return menu->dwContextHelpID;
812}
813//******************************************************************************
814//******************************************************************************
815ODINFUNCTION5(BOOL, CheckMenuRadioItem,
816 HMENU, hMenu,
817 UINT, idFirst,
818 UINT, idLast,
819 UINT, idCheck,
820 UINT, uFlags)
821{
822 dprintf(("USER32: OS2CheckMenuRadioItem, not implemented\n"));
823 return(TRUE);
824}
825//******************************************************************************
826//******************************************************************************
827ODINFUNCTION5(BOOL, ChangeMenuA,
828 HMENU, hMenu,
829 UINT, pos,
830 LPCSTR, data,
831 UINT, id,
832 UINT, flags)
833{
834 dprintf(("USER32: ChangeMenuA flags %X\n", flags));
835
836 if (flags & MF_APPEND) return ODIN_AppendMenuA(hMenu, flags & ~MF_APPEND,
837 id, data );
838 if (flags & MF_DELETE) return ODIN_DeleteMenu(hMenu, pos, flags & ~MF_DELETE);
839 if (flags & MF_CHANGE) return ODIN_ModifyMenuA(hMenu, pos, flags & ~MF_CHANGE,
840 id, data );
841 if (flags & MF_REMOVE) return ODIN_RemoveMenu(hMenu,
842 flags & MF_BYPOSITION ? pos : id,
843 flags & ~MF_REMOVE );
844 /* Default: MF_INSERT */
845 return InsertMenuA( hMenu, pos, flags, id, data );
846}
847//******************************************************************************
848//******************************************************************************
849ODINFUNCTION5(BOOL, ChangeMenuW,
850 HMENU, hMenu,
851 UINT, pos,
852 LPCWSTR, data,
853 UINT, id,
854 UINT, flags)
855{
856 dprintf(("USER32: ChangeMenuW flags %X\n", flags));
857
858 if (flags & MF_APPEND) return ODIN_AppendMenuW(hMenu, flags & ~MF_APPEND,
859 id, data );
860 if (flags & MF_DELETE) return ODIN_DeleteMenu(hMenu, pos, flags & ~MF_DELETE);
861 if (flags & MF_CHANGE) return ODIN_ModifyMenuW(hMenu, pos, flags & ~MF_CHANGE,
862 id, data );
863 if (flags & MF_REMOVE) return ODIN_RemoveMenu(hMenu,
864 flags & MF_BYPOSITION ? pos : id,
865 flags & ~MF_REMOVE );
866 /* Default: MF_INSERT */
867 return InsertMenuW(hMenu, pos, flags, id, data);
868}
869//******************************************************************************
870//******************************************************************************
871ODINFUNCTION4(BOOL, SetMenuItemInfoA,
872 HMENU, hMenu,
873 UINT, par1,
874 BOOL, par2,
875 const MENUITEMINFOA *, lpmii)
876{
877 dprintf(("USER32: SetMenuItemInfoA faked %x", hMenu));
878
879 if (!hMenu) {
880 SetLastError(ERROR_INVALID_PARAMETER);
881 return FALSE;
882 }
883 return TRUE;
884}
885/*****************************************************************************
886 * Function : SetMenuItemInfoW
887 * Purpose : The SetMenuItemInfo function changes information about a menu item.
888 * Parameters:
889 * Variables :
890 * Result : If the function succeeds, the return value is TRUE.
891 * If the function fails, the return value is FALSE. To get extended
892 * error information, use the GetLastError function.
893 * Remark :
894 * Status : UNTESTED STUB
895 *
896 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
897 *****************************************************************************/
898
899ODINFUNCTION4(BOOL, SetMenuItemInfoW,
900 HMENU, hMenu,
901 UINT, uItem,
902 BOOL, fByPosition,
903 const MENUITEMINFOW *, lpmmi)
904{
905 dprintf(("USER32:SetMenuItemInfoW (%08xh,%08xh,%08xh,%08x) not implemented.\n",
906 hMenu,
907 uItem,
908 fByPosition,
909 lpmmi));
910
911 return (SetMenuItemInfoA(hMenu,
912 uItem,
913 fByPosition,
914 (const MENUITEMINFOA *)lpmmi));
915}
916/*****************************************************************************
917 * Function : GetMenuDefaultItem
918 * Purpose : TheGetMenuDefaultItem function determines the default menu item
919 * on the specified menu.
920 * Parameters:
921 * Variables :
922 * Result : If the function succeeds, the return value is the identifier or
923 * position of the menu item.
924 * If the function fails, the return value is - 1.
925 * Remark :
926 * Status : UNTESTED STUB
927 *
928 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
929 *****************************************************************************/
930
931ODINFUNCTION3(UINT, GetMenuDefaultItem,
932 HMENU, hMenu,
933 UINT, fByPos,
934 UINT, gmdiFlags)
935{
936 dprintf(("USER32:GetMenuDefaultItem (%08xh,%u,%08x) not implemented.\n",
937 hMenu,
938 fByPos,
939 gmdiFlags));
940
941 return (-1);
942}
943//******************************************************************************
944//******************************************************************************
945ODINFUNCTION3(BOOL, SetMenuDefaultItem,
946 HMENU, hMenu,
947 UINT, uItem,
948 UINT, fByPos)
949{
950 dprintf(("USER32: SetMenuDefaultItem, faked\n"));
951 return(TRUE);
952}
953//******************************************************************************
954//******************************************************************************
955BOOL GetMenuItemInfoAW(HMENU hMenu, UINT uItem, BOOL byPos, MENUITEMINFOA *lpmii, BOOL unicode)
956{
957 if(byPos) {
958 uItem = GetMenuItemID(hMenu, uItem);
959 }
960 if(ODIN_GetMenuState(hMenu, uItem, MF_BYCOMMAND) == -1) {
961 //item doesn't exist
962 dprintf(("USER32: GetMenuItemInfoAW %x item %d doesn't exist", hMenu, uItem));
963 SetLastError(ERROR_INVALID_PARAMETER);
964 return FALSE;
965 }
966 if (lpmii->fMask & MIIM_TYPE)
967 {
968 lpmii->fType = ODIN_GetMenuState(hMenu, uItem, MF_BYCOMMAND); //not correct
969// lpmii->fType = menu->fType;
970 if (unicode) {
971 lpmii->cch = ODIN_GetMenuStringW(hMenu, uItem, (LPWSTR)lpmii->dwTypeData, lpmii->cch, MF_BYCOMMAND);
972 }
973 else {
974 lpmii->cch = ODIN_GetMenuStringA(hMenu, uItem, (LPSTR)lpmii->dwTypeData, lpmii->cch, MF_BYCOMMAND);
975 }
976//TODO:
977#if 0
978 switch (MENU_ITEM_TYPE(menu->fType)) {
979 case MF_STRING:
980 if (menu->text && lpmii->dwTypeData && lpmii->cch) {
981 if (unicode) {
982 lstrcpynAtoW((LPWSTR) lpmii->dwTypeData, menu->text, lpmii->cch);
983 lpmii->cch = lstrlenW((LPWSTR)menu->text);
984 }
985 else {
986 lstrcpynA(lpmii->dwTypeData, menu->text, lpmii->cch);
987 lpmii->cch = lstrlenA(menu->text);
988 }
989 }
990 break;
991 case MF_OWNERDRAW:
992 case MF_BITMAP:
993 lpmii->dwTypeData = menu->text;
994 /* fall through */
995 default:
996 lpmii->cch = 0;
997 }
998#endif
999 }
1000
1001 if (lpmii->fMask & MIIM_STRING) {
1002 if (unicode) {
1003 lpmii->cch = ODIN_GetMenuStringW(hMenu, uItem, (LPWSTR)lpmii->dwTypeData, lpmii->cch, MF_BYCOMMAND);
1004 }
1005 else {
1006 lpmii->cch = ODIN_GetMenuStringA(hMenu, uItem, (LPSTR)lpmii->dwTypeData, lpmii->cch, MF_BYCOMMAND);
1007 }
1008 }
1009
1010//TODO:
1011#if 0
1012 if (lpmii->fMask & MIIM_FTYPE)
1013 lpmii->fType = menu->fType;
1014
1015 if (lpmii->fMask & MIIM_BITMAP)
1016 lpmii->hbmpItem = menu->hbmpItem;
1017#endif
1018
1019 if (lpmii->fMask & MIIM_STATE)
1020 lpmii->fState = ODIN_GetMenuState(hMenu, uItem, MF_BYCOMMAND);
1021
1022 if (lpmii->fMask & MIIM_ID)
1023 lpmii->wID = uItem;
1024
1025//TODO:
1026#if 1
1027 lpmii->hSubMenu = 0;
1028 lpmii->hbmpChecked = 0;
1029 lpmii->hbmpUnchecked = 0;
1030 lpmii->dwItemData = 0;
1031#else
1032 if (lpmii->fMask & MIIM_SUBMENU)
1033 lpmii->hSubMenu = ODIN_GetSubMenu(hMenu, uItem); //need index, not id
1034
1035 if (lpmii->fMask & MIIM_CHECKMARKS) {
1036 lpmii->hbmpChecked = menu->hCheckBit;
1037 lpmii->hbmpUnchecked = menu->hUnCheckBit;
1038 }
1039 if (lpmii->fMask & MIIM_DATA)
1040 lpmii->dwItemData = menu->dwItemData;
1041#endif
1042
1043 return(FALSE);
1044}
1045//******************************************************************************
1046//******************************************************************************
1047ODINFUNCTION4(BOOL, GetMenuItemInfoA,
1048 HMENU, hMenu,
1049 UINT, uItem,
1050 BOOL, byPos,
1051 MENUITEMINFOA *, lpMenuItemInfo)
1052{
1053 return GetMenuItemInfoAW(hMenu, uItem, byPos, lpMenuItemInfo, FALSE);
1054}
1055/*****************************************************************************
1056 * Function : GetMenuItemInfoW
1057 * Purpose : The GetMenuItemInfo function retrieves information about a menu item.
1058 * Parameters:
1059 * Variables :
1060 * Result : If the function succeeds, the return value is TRUE.
1061 * If the function fails, the return value is FALSE. To get extended
1062 * error information, use the GetLastError function.
1063 * Remark :
1064 * Status : UNTESTED STUB
1065 *
1066 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
1067 *****************************************************************************/
1068
1069ODINFUNCTION4(BOOL, GetMenuItemInfoW,
1070 HMENU, hMenu,
1071 UINT, uItem,
1072 BOOL, byPos,
1073 MENUITEMINFOW *, lpMenuItemInfo)
1074{
1075 return GetMenuItemInfoAW(hMenu, uItem, byPos, (MENUITEMINFOA*)lpMenuItemInfo, TRUE);
1076}
1077/*****************************************************************************
1078 * Function : GetMenuItemRect
1079 * Purpose : The GetMenuItemRect function retrieves the bounding rectangle
1080 * for the specified menu item.
1081 * Parameters:
1082 * Variables :
1083 * Result : If the function succeeds, the return value is TRUE.
1084 * If the function fails, the return value is FALSE. To get
1085 * extended error information, use the GetLastError function.
1086 * Remark :
1087 * Status :
1088 *
1089 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
1090 *****************************************************************************/
1091
1092BOOL GetMenuItemRect(HWND hwnd, HMENU hMenu, UINT uItem, LPRECT lprcItem)
1093{
1094 BOOL rc;
1095
1096 rc = OSLibGetMenuItemRect(hMenu, uItem, lprcItem);
1097 dprintf(("GetMenuItemRect %x %x %x (%d,%d)(%d,%d)", hwnd, hMenu, uItem, lprcItem->top, lprcItem->left, lprcItem->bottom, lprcItem->right));
1098 return rc;
1099}
1100/*****************************************************************************
1101 * Function : InsertMenuItemA
1102 * Purpose : The InsertMenuItem function inserts a new menu item at the specified
1103 * position in a menu bar or pop-up menu.
1104 * Parameters:
1105 * Variables :
1106 * Result : If the function succeeds, the return value is TRUE.
1107 * If the function fails, the return value is FALSE. To get extended
1108 * error information, use the GetLastError function.
1109 * Remark :
1110 * Status : UNTESTED STUB
1111 *
1112 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
1113 *****************************************************************************/
1114
1115ODINFUNCTION4(BOOL, InsertMenuItemA,
1116 HMENU, hMenu,
1117 UINT, uItem,
1118 BOOL, fByPosition,
1119 const MENUITEMINFOA*, lpmii)
1120{
1121 DWORD dwType;
1122 BOOL rc;
1123
1124 dprintf(("USER32:InsertMenuItemA (%08xh,%08xh,%u,%08x) not correctly implemented.\n",
1125 hMenu,
1126 uItem,
1127 fByPosition,
1128 lpmii));
1129
1130 if(fByPosition) {
1131 dwType = lpmii->fType | MF_BYPOSITION;
1132 }
1133 else dwType = lpmii->fType | MF_BYCOMMAND;
1134
1135 if(lpmii->fMask & MIIM_SUBMENU && lpmii->hSubMenu) {
1136 rc &= ODIN_InsertMenuA(hMenu, uItem, dwType | MF_POPUP, lpmii->hSubMenu, lpmii->dwTypeData);
1137 }
1138 else
1139 if(lpmii->fMask & MIIM_ID) {
1140 rc = ODIN_InsertMenuA(hMenu, uItem, dwType, lpmii->wID, lpmii->dwTypeData);
1141 }
1142 if(lpmii->fMask & MIIM_STATE) {
1143 //TODO
1144 }
1145 return rc;
1146}
1147
1148
1149/*****************************************************************************
1150 * Function : InsertMenuItemW
1151 * Purpose : The InsertMenuItem function inserts a new menu item at the specified
1152 * position in a menu bar or pop-up menu.
1153 * Parameters:
1154 * Variables :
1155 * Result : If the function succeeds, the return value is TRUE.
1156 * If the function fails, the return value is FALSE. To get extended
1157 * error information, use the GetLastError function.
1158 * Remark :
1159 * Status : UNTESTED STUB
1160 *
1161 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
1162 *****************************************************************************/
1163
1164ODINFUNCTION4(BOOL, InsertMenuItemW,
1165 HMENU, hMenu,
1166 UINT, uItem,
1167 BOOL, fByPosition,
1168 const MENUITEMINFOW *, lpmii)
1169{
1170 dprintf(("USER32:InsertMenuItemW (%08xh,%08xh,%u,%08x) not correctly implemented.\n",
1171 hMenu,
1172 uItem,
1173 fByPosition,
1174 lpmii));
1175
1176 if(fByPosition) {
1177 return ODIN_InsertMenuW(hMenu, uItem, lpmii->fType | MF_BYPOSITION, (lpmii->fType & MF_POPUP) ? lpmii->hSubMenu : lpmii->wID, lpmii->dwTypeData);
1178 }
1179 else return ODIN_InsertMenuW(hMenu, uItem, lpmii->fType | MF_BYCOMMAND, (lpmii->fType & MF_POPUP) ? lpmii->hSubMenu : lpmii->wID, lpmii->dwTypeData);
1180}
1181/*****************************************************************************
1182 * Function : MenuItemFromPoint
1183 * Purpose : TheMenuItemFromPoint function determines which menu item, if
1184 * any, is at the specified location.
1185 * Parameters:
1186 * Variables :
1187 * Result : Returns the zero-based position of the menu item at the specified
1188 * location or -1 if no menu item is at the specified location.
1189 * Remark :
1190 * Status : UNTESTED STUB
1191 *
1192 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
1193 *****************************************************************************/
1194
1195ODINFUNCTION3(UINT, MenuItemFromPoint,
1196 HWND, hWnd,
1197 HMENU, hMenu,
1198 POINT, ptScreen)
1199{
1200 dprintf(("USER32:MenuItemFromPoint (%08xh,%08xh,%u) not implemented.\n",
1201 hWnd,
1202 hMenu,
1203 ptScreen));
1204
1205 return (-1);
1206}
1207
1208
1209/*****************************************************************************
1210 * Function : GetMenuInfo
1211 * Parameters:
1212 * Variables :
1213 * Result :
1214 * Remark :
1215 * Status : UNTESTED STUB win98/NT5.0
1216 *
1217 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
1218 *****************************************************************************/
1219
1220ODINFUNCTION2(BOOL, GetMenuInfo,
1221 HMENU, hMenu,
1222 LPMENUINFO, lpmi)
1223{
1224 POPUPMENU *menu;
1225
1226 menu = GetInternalMenuInfo(hMenu);
1227 if(menu == NULL) {
1228 dprintf(("USER32: GetMenuInfo(%08xh,%08xh) No POPUPMENU structure found!", hMenu, lpmi));
1229 SetLastError(ERROR_INVALID_PARAMETER);
1230 return FALSE;
1231 }
1232 dprintf(("USER32: GetMenuInfo(%08xh,%08xh)", hMenu, lpmi));
1233
1234 if (lpmi)
1235 {
1236 if (lpmi->fMask & MIM_BACKGROUND)
1237 lpmi->hbrBack = menu->hbrBack;
1238
1239 if (lpmi->fMask & MIM_HELPID)
1240 lpmi->dwContextHelpID = menu->dwContextHelpID;
1241
1242 if (lpmi->fMask & MIM_MAXHEIGHT)
1243 lpmi->cyMax = menu->cyMax;
1244
1245 if (lpmi->fMask & MIM_MENUDATA)
1246 lpmi->dwMenuData = menu->dwMenuData;
1247
1248 if (lpmi->fMask & MIM_STYLE)
1249 lpmi->dwStyle = menu->dwStyle;
1250
1251 return TRUE;
1252 }
1253 SetLastError(ERROR_INVALID_PARAMETER);
1254 return FALSE;
1255}
1256/*****************************************************************************
1257 * Function : SetMenuInfo
1258 * Purpose :
1259 * Parameters:
1260 * Variables :
1261 * Result :
1262 * Remark :
1263 * FIXME
1264 * MIM_APPLYTOSUBMENUS
1265 * actually use the items to draw the menu
1266 * Status : UNTESTED STUB win98/NT5.0
1267 *
1268 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
1269 *****************************************************************************/
1270
1271ODINFUNCTION2(BOOL, SetMenuInfo,
1272 HMENU, hMenu,
1273 LPCMENUINFO, lpmi)
1274{
1275 POPUPMENU *menu;
1276
1277 menu = GetInternalMenuInfo(hMenu);
1278 if(menu == NULL) {
1279 dprintf(("USER32: SetMenuInfo(%08xh,%08xh) No POPUPMENU structure found!", hMenu, lpmi));
1280 SetLastError(ERROR_INVALID_PARAMETER);
1281 return FALSE;
1282 }
1283
1284 dprintf(("USER32: SetMenuInfo(%08xh,%08xh)", hMenu, lpmi));
1285
1286 if (lpmi && (lpmi->cbSize==sizeof(MENUINFO)))
1287 {
1288 if (lpmi->fMask & MIM_BACKGROUND)
1289 menu->hbrBack = lpmi->hbrBack;
1290
1291 if (lpmi->fMask & MIM_HELPID)
1292 menu->dwContextHelpID = lpmi->dwContextHelpID;
1293
1294 if (lpmi->fMask & MIM_MAXHEIGHT)
1295 menu->cyMax = lpmi->cyMax;
1296
1297 if (lpmi->fMask & MIM_MENUDATA)
1298 menu->dwMenuData = lpmi->dwMenuData;
1299
1300 if (lpmi->fMask & MIM_STYLE)
1301 menu->dwStyle = lpmi->dwStyle;
1302
1303 return TRUE;
1304 }
1305 SetLastError(ERROR_INVALID_PARAMETER);
1306 return FALSE;
1307}
1308//******************************************************************************
1309//******************************************************************************
1310
Note: See TracBrowser for help on using the repository browser.