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

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

* empty log message *

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