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

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

win32 look update

File size: 41.8 KB
Line 
1/* $Id: winmenu.cpp,v 1.23 2000-01-09 15:56:06 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
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 return O32_ModifyMenu(hMenu, uItem, fuFlags, idNewItem, lpszNewItem);
656}
657//******************************************************************************
658//******************************************************************************
659ODINFUNCTION5(BOOL, ModifyMenuW,
660 HMENU, hMenu,
661 UINT, arg2,
662 UINT, arg3,
663 UINT, arg4,
664 LPCWSTR, arg5)
665{
666 BOOL rc;
667 char *astring = NULL;
668
669 if(hMenu == 0)
670 {
671 SetLastError(ERROR_INVALID_PARAMETER);
672 return 0;
673 }
674
675 if(IS_STRING_ITEM(arg3) && HIWORD(arg5) != 0)
676 astring = UnicodeToAsciiString((LPWSTR)arg5);
677 else
678 astring = (char *) arg5;
679
680 rc = ODIN_ModifyMenuA(hMenu, arg2, arg3, arg4, astring);
681 if(IS_STRING_ITEM(arg3) && HIWORD(arg5) != 0)
682 FreeAsciiString(astring);
683
684 return(rc);
685}
686//******************************************************************************
687//******************************************************************************
688ODINFUNCTION3(BOOL, RemoveMenu,
689 HMENU, hMenu,
690 UINT, arg2,
691 UINT, arg3)
692{
693 if(hMenu == 0)
694 {
695 SetLastError(ERROR_INVALID_PARAMETER);
696 return 0;
697 }
698
699 return O32_RemoveMenu(hMenu, arg2, arg3);
700}
701//******************************************************************************
702//******************************************************************************
703ODINFUNCTION3(BOOL, DeleteMenu,
704 HMENU, hMenu,
705 UINT, arg2,
706 UINT, arg3)
707{
708 if(hMenu == 0)
709 {
710 SetLastError(ERROR_INVALID_PARAMETER);
711 return 0;
712 }
713
714 return O32_DeleteMenu(hMenu, arg2, arg3);
715}
716//******************************************************************************
717//******************************************************************************
718ODINFUNCTION4(BOOL, HiliteMenuItem,
719 HWND, hMenu,
720 HMENU, arg2,
721 UINT, arg3,
722 UINT, arg4)
723{
724 dprintf(("USER32: OS2HiliteMenuItem\n"));
725 if(hMenu == 0)
726 {
727 SetLastError(ERROR_INVALID_PARAMETER);
728 return 0;
729 }
730
731 return O32_HiliteMenuItem(hMenu, arg2, arg3, arg4);
732}
733//******************************************************************************
734//******************************************************************************
735ODINFUNCTION5(BOOL, InsertMenuA,
736 HMENU, hMenu,
737 UINT, pos,
738 UINT, flags,
739 UINT, id,
740 LPCSTR, str)
741{
742 if(IS_STRING_ITEM(flags) && HIWORD(str)) {
743 dprintf(("USER32: InsertMenuA %x %d %x %d %s", hMenu, pos, flags, id, str));
744 }
745 else dprintf(("USER32: InsertMenuA %x %d %x %d %x", hMenu, pos, flags, id, str));
746
747 if(hMenu == 0)
748 {
749 SetLastError(ERROR_INVALID_PARAMETER);
750 return 0;
751 }
752
753 if(IS_STRING_ITEM(flags) && (!str || *str == NULL)) {
754 flags |= MF_SEPARATOR;
755 }
756 //SvL: RealPlayer calls InsertMenu with flag 0 & pos -1
757 if((flags & (MF_BYCOMMAND|MF_BYPOSITION)) == 0 && (pos == 0xffffffff))
758 flags |= MF_BYPOSITION;
759
760 return O32_InsertMenu(hMenu, pos, flags, id, str);
761}
762//******************************************************************************
763//******************************************************************************
764ODINFUNCTION5(BOOL, InsertMenuW,
765 HMENU, hMenu,
766 UINT, arg2,
767 UINT, arg3,
768 UINT, arg4,
769 LPCWSTR, arg5)
770{
771 BOOL rc;
772 char *astring = NULL;
773
774 if(IS_STRING_ITEM(arg3) && HIWORD(arg5) != 0)
775 astring = UnicodeToAsciiString((LPWSTR)arg5);
776 else
777 astring = (char *) arg5;
778
779 rc = ODIN_InsertMenuA(hMenu, arg2, arg3, arg4, astring);
780
781 if(IS_STRING_ITEM(arg3) && HIWORD(arg5) != 0)
782 FreeAsciiString(astring);
783
784 return(rc);
785}
786//******************************************************************************
787//******************************************************************************
788ODINFUNCTION2(BOOL, SetMenuContextHelpId,
789 HMENU, hMenu,
790 DWORD, dwContextHelpId)
791{
792 POPUPMENU *menu;
793
794 menu = GetInternalMenuInfo(hMenu);
795 if(menu == NULL) {
796 dprintf(("USER32: SetMenuContextHelpId(%x) No POPUPMENU structure found!", hMenu));
797 SetLastError(ERROR_INVALID_PARAMETER);
798 return FALSE;
799 }
800 dprintf(("USER32: SetMenuContextHelpId %x %d", hMenu, dwContextHelpId));
801 menu->dwContextHelpID = dwContextHelpId;
802 return(TRUE);
803}
804//******************************************************************************
805//******************************************************************************
806ODINFUNCTION1(DWORD, GetMenuContextHelpId,
807 HMENU, hMenu)
808{
809 POPUPMENU *menu;
810
811 menu = GetInternalMenuInfo(hMenu);
812 if(menu == NULL) {
813 dprintf(("USER32: GetMenuContextHelpId(%x) No POPUPMENU structure found!", hMenu));
814 SetLastError(ERROR_INVALID_PARAMETER);
815 return 0;
816 }
817 dprintf(("USER32: GetMenuContextHelpId %x %d", hMenu, menu->dwContextHelpID));
818 return menu->dwContextHelpID;
819}
820//******************************************************************************
821//******************************************************************************
822ODINFUNCTION5(BOOL, CheckMenuRadioItem,
823 HMENU, hMenu,
824 UINT, idFirst,
825 UINT, idLast,
826 UINT, idCheck,
827 UINT, uFlags)
828{
829 dprintf(("USER32: OS2CheckMenuRadioItem, not implemented\n"));
830 return(TRUE);
831}
832//******************************************************************************
833//******************************************************************************
834ODINFUNCTION5(BOOL, ChangeMenuA,
835 HMENU, hMenu,
836 UINT, pos,
837 LPCSTR, data,
838 UINT, id,
839 UINT, flags)
840{
841 dprintf(("USER32: ChangeMenuA flags %X\n", flags));
842
843 if (flags & MF_APPEND) return ODIN_AppendMenuA(hMenu, flags & ~MF_APPEND,
844 id, data );
845 if (flags & MF_DELETE) return ODIN_DeleteMenu(hMenu, pos, flags & ~MF_DELETE);
846 if (flags & MF_CHANGE) return ODIN_ModifyMenuA(hMenu, pos, flags & ~MF_CHANGE,
847 id, data );
848 if (flags & MF_REMOVE) return ODIN_RemoveMenu(hMenu,
849 flags & MF_BYPOSITION ? pos : id,
850 flags & ~MF_REMOVE );
851 /* Default: MF_INSERT */
852 return InsertMenuA( hMenu, pos, flags, id, data );
853}
854//******************************************************************************
855//******************************************************************************
856ODINFUNCTION5(BOOL, ChangeMenuW,
857 HMENU, hMenu,
858 UINT, pos,
859 LPCWSTR, data,
860 UINT, id,
861 UINT, flags)
862{
863 dprintf(("USER32: ChangeMenuW flags %X\n", flags));
864
865 if (flags & MF_APPEND) return ODIN_AppendMenuW(hMenu, flags & ~MF_APPEND,
866 id, data );
867 if (flags & MF_DELETE) return ODIN_DeleteMenu(hMenu, pos, flags & ~MF_DELETE);
868 if (flags & MF_CHANGE) return ODIN_ModifyMenuW(hMenu, pos, flags & ~MF_CHANGE,
869 id, data );
870 if (flags & MF_REMOVE) return ODIN_RemoveMenu(hMenu,
871 flags & MF_BYPOSITION ? pos : id,
872 flags & ~MF_REMOVE );
873 /* Default: MF_INSERT */
874 return InsertMenuW(hMenu, pos, flags, id, data);
875}
876//******************************************************************************
877//******************************************************************************
878ODINFUNCTION4(BOOL, SetMenuItemInfoA,
879 HMENU, hMenu,
880 UINT, par1,
881 BOOL, par2,
882 const MENUITEMINFOA *, lpmii)
883{
884 dprintf(("USER32: SetMenuItemInfoA faked %x", hMenu));
885
886 if (!hMenu) {
887 SetLastError(ERROR_INVALID_PARAMETER);
888 return FALSE;
889 }
890 return TRUE;
891}
892/*****************************************************************************
893 * Function : SetMenuItemInfoW
894 * Purpose : The SetMenuItemInfo function changes information about a menu item.
895 * Parameters:
896 * Variables :
897 * Result : If the function succeeds, the return value is TRUE.
898 * If the function fails, the return value is FALSE. To get extended
899 * error information, use the GetLastError function.
900 * Remark :
901 * Status : UNTESTED STUB
902 *
903 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
904 *****************************************************************************/
905
906ODINFUNCTION4(BOOL, SetMenuItemInfoW,
907 HMENU, hMenu,
908 UINT, uItem,
909 BOOL, fByPosition,
910 const MENUITEMINFOW *, lpmmi)
911{
912 dprintf(("USER32:SetMenuItemInfoW (%08xh,%08xh,%08xh,%08x) not implemented.\n",
913 hMenu,
914 uItem,
915 fByPosition,
916 lpmmi));
917
918 return (SetMenuItemInfoA(hMenu,
919 uItem,
920 fByPosition,
921 (const MENUITEMINFOA *)lpmmi));
922}
923/*****************************************************************************
924 * Function : GetMenuDefaultItem
925 * Purpose : TheGetMenuDefaultItem function determines the default menu item
926 * on the specified menu.
927 * Parameters:
928 * Variables :
929 * Result : If the function succeeds, the return value is the identifier or
930 * position of the menu item.
931 * If the function fails, the return value is - 1.
932 * Remark :
933 * Status : UNTESTED STUB
934 *
935 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
936 *****************************************************************************/
937
938ODINFUNCTION3(UINT, GetMenuDefaultItem,
939 HMENU, hMenu,
940 UINT, fByPos,
941 UINT, gmdiFlags)
942{
943 dprintf(("USER32:GetMenuDefaultItem (%08xh,%u,%08x) not implemented.\n",
944 hMenu,
945 fByPos,
946 gmdiFlags));
947
948 return (-1);
949}
950//******************************************************************************
951//******************************************************************************
952ODINFUNCTION3(BOOL, SetMenuDefaultItem,
953 HMENU, hMenu,
954 UINT, uItem,
955 UINT, fByPos)
956{
957 dprintf(("USER32: SetMenuDefaultItem, faked\n"));
958 return(TRUE);
959}
960//******************************************************************************
961//******************************************************************************
962BOOL GetMenuItemInfoAW(HMENU hMenu, UINT uItem, BOOL byPos, MENUITEMINFOA *lpmii, BOOL unicode)
963{
964 if(byPos) {
965 uItem = GetMenuItemID(hMenu, uItem);
966 }
967 if(ODIN_GetMenuState(hMenu, uItem, MF_BYCOMMAND) == -1) {
968 //item doesn't exist
969 dprintf(("USER32: GetMenuItemInfoAW %x item %d doesn't exist", hMenu, uItem));
970 SetLastError(ERROR_INVALID_PARAMETER);
971 return FALSE;
972 }
973 if (lpmii->fMask & MIIM_TYPE)
974 {
975 lpmii->fType = ODIN_GetMenuState(hMenu, uItem, MF_BYCOMMAND); //not correct
976// lpmii->fType = menu->fType;
977 if (unicode) {
978 lpmii->cch = ODIN_GetMenuStringW(hMenu, uItem, (LPWSTR)lpmii->dwTypeData, lpmii->cch, MF_BYCOMMAND);
979 }
980 else {
981 lpmii->cch = ODIN_GetMenuStringA(hMenu, uItem, (LPSTR)lpmii->dwTypeData, lpmii->cch, MF_BYCOMMAND);
982 }
983//TODO:
984#if 0
985 switch (MENU_ITEM_TYPE(menu->fType)) {
986 case MF_STRING:
987 if (menu->text && lpmii->dwTypeData && lpmii->cch) {
988 if (unicode) {
989 lstrcpynAtoW((LPWSTR) lpmii->dwTypeData, menu->text, lpmii->cch);
990 lpmii->cch = lstrlenW((LPWSTR)menu->text);
991 }
992 else {
993 lstrcpynA(lpmii->dwTypeData, menu->text, lpmii->cch);
994 lpmii->cch = lstrlenA(menu->text);
995 }
996 }
997 break;
998 case MF_OWNERDRAW:
999 case MF_BITMAP:
1000 lpmii->dwTypeData = menu->text;
1001 /* fall through */
1002 default:
1003 lpmii->cch = 0;
1004 }
1005#endif
1006 }
1007
1008 if (lpmii->fMask & MIIM_STRING) {
1009 if (unicode) {
1010 lpmii->cch = ODIN_GetMenuStringW(hMenu, uItem, (LPWSTR)lpmii->dwTypeData, lpmii->cch, MF_BYCOMMAND);
1011 }
1012 else {
1013 lpmii->cch = ODIN_GetMenuStringA(hMenu, uItem, (LPSTR)lpmii->dwTypeData, lpmii->cch, MF_BYCOMMAND);
1014 }
1015 }
1016
1017//TODO:
1018#if 0
1019 if (lpmii->fMask & MIIM_FTYPE)
1020 lpmii->fType = menu->fType;
1021
1022 if (lpmii->fMask & MIIM_BITMAP)
1023 lpmii->hbmpItem = menu->hbmpItem;
1024#endif
1025
1026 if (lpmii->fMask & MIIM_STATE)
1027 lpmii->fState = ODIN_GetMenuState(hMenu, uItem, MF_BYCOMMAND);
1028
1029 if (lpmii->fMask & MIIM_ID)
1030 lpmii->wID = uItem;
1031
1032//TODO:
1033#if 1
1034 lpmii->hSubMenu = 0;
1035 lpmii->hbmpChecked = 0;
1036 lpmii->hbmpUnchecked = 0;
1037 lpmii->dwItemData = 0;
1038#else
1039 if (lpmii->fMask & MIIM_SUBMENU)
1040 lpmii->hSubMenu = ODIN_GetSubMenu(hMenu, uItem); //need index, not id
1041
1042 if (lpmii->fMask & MIIM_CHECKMARKS) {
1043 lpmii->hbmpChecked = menu->hCheckBit;
1044 lpmii->hbmpUnchecked = menu->hUnCheckBit;
1045 }
1046 if (lpmii->fMask & MIIM_DATA)
1047 lpmii->dwItemData = menu->dwItemData;
1048#endif
1049
1050 return(FALSE);
1051}
1052//******************************************************************************
1053//******************************************************************************
1054ODINFUNCTION4(BOOL, GetMenuItemInfoA,
1055 HMENU, hMenu,
1056 UINT, uItem,
1057 BOOL, byPos,
1058 MENUITEMINFOA *, lpMenuItemInfo)
1059{
1060 return GetMenuItemInfoAW(hMenu, uItem, byPos, lpMenuItemInfo, FALSE);
1061}
1062/*****************************************************************************
1063 * Function : GetMenuItemInfoW
1064 * Purpose : The GetMenuItemInfo function retrieves information about a menu item.
1065 * Parameters:
1066 * Variables :
1067 * Result : If the function succeeds, the return value is TRUE.
1068 * If the function fails, the return value is FALSE. To get extended
1069 * error information, use the GetLastError function.
1070 * Remark :
1071 * Status : UNTESTED STUB
1072 *
1073 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
1074 *****************************************************************************/
1075
1076ODINFUNCTION4(BOOL, GetMenuItemInfoW,
1077 HMENU, hMenu,
1078 UINT, uItem,
1079 BOOL, byPos,
1080 MENUITEMINFOW *, lpMenuItemInfo)
1081{
1082 return GetMenuItemInfoAW(hMenu, uItem, byPos, (MENUITEMINFOA*)lpMenuItemInfo, TRUE);
1083}
1084/*****************************************************************************
1085 * Function : GetMenuItemRect
1086 * Purpose : The GetMenuItemRect function retrieves the bounding rectangle
1087 * for the specified menu item.
1088 * Parameters:
1089 * Variables :
1090 * Result : If the function succeeds, the return value is TRUE.
1091 * If the function fails, the return value is FALSE. To get
1092 * extended error information, use the GetLastError function.
1093 * Remark :
1094 * Status :
1095 *
1096 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
1097 *****************************************************************************/
1098
1099BOOL GetMenuItemRect(HWND hwnd, HMENU hMenu, UINT uItem, LPRECT lprcItem)
1100{
1101 BOOL rc;
1102
1103 rc = OSLibGetMenuItemRect(hMenu, uItem, lprcItem);
1104 dprintf(("GetMenuItemRect %x %x %x (%d,%d)(%d,%d)", hwnd, hMenu, uItem, lprcItem->top, lprcItem->left, lprcItem->bottom, lprcItem->right));
1105 return rc;
1106}
1107/*****************************************************************************
1108 * Function : InsertMenuItemA
1109 * Purpose : The InsertMenuItem function inserts a new menu item at the specified
1110 * position in a menu bar or pop-up menu.
1111 * Parameters:
1112 * Variables :
1113 * Result : If the function succeeds, the return value is TRUE.
1114 * If the function fails, the return value is FALSE. To get extended
1115 * error information, use the GetLastError function.
1116 * Remark :
1117 * Status : UNTESTED STUB
1118 *
1119 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
1120 *****************************************************************************/
1121
1122ODINFUNCTION4(BOOL, InsertMenuItemA,
1123 HMENU, hMenu,
1124 UINT, uItem,
1125 BOOL, fByPosition,
1126 const MENUITEMINFOA*, lpmii)
1127{
1128 DWORD dwType;
1129 BOOL rc;
1130
1131 dprintf(("USER32:InsertMenuItemA (%08xh,%08xh,%u,%08x) not correctly implemented.\n",
1132 hMenu,
1133 uItem,
1134 fByPosition,
1135 lpmii));
1136
1137 if(fByPosition) {
1138 dwType = lpmii->fType | MF_BYPOSITION;
1139 }
1140 else dwType = lpmii->fType | MF_BYCOMMAND;
1141
1142 if(lpmii->fMask & MIIM_SUBMENU && lpmii->hSubMenu) {
1143 rc &= ODIN_InsertMenuA(hMenu, uItem, dwType | MF_POPUP, lpmii->hSubMenu, lpmii->dwTypeData);
1144 }
1145 else
1146 if(lpmii->fMask & MIIM_ID) {
1147 rc = ODIN_InsertMenuA(hMenu, uItem, dwType, lpmii->wID, lpmii->dwTypeData);
1148 }
1149 if(lpmii->fMask & MIIM_STATE) {
1150 //TODO
1151 }
1152 return rc;
1153}
1154
1155
1156/*****************************************************************************
1157 * Function : InsertMenuItemW
1158 * Purpose : The InsertMenuItem function inserts a new menu item at the specified
1159 * position in a menu bar or pop-up menu.
1160 * Parameters:
1161 * Variables :
1162 * Result : If the function succeeds, the return value is TRUE.
1163 * If the function fails, the return value is FALSE. To get extended
1164 * error information, use the GetLastError function.
1165 * Remark :
1166 * Status : UNTESTED STUB
1167 *
1168 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
1169 *****************************************************************************/
1170
1171ODINFUNCTION4(BOOL, InsertMenuItemW,
1172 HMENU, hMenu,
1173 UINT, uItem,
1174 BOOL, fByPosition,
1175 const MENUITEMINFOW *, lpmii)
1176{
1177 dprintf(("USER32:InsertMenuItemW (%08xh,%08xh,%u,%08x) not correctly implemented.\n",
1178 hMenu,
1179 uItem,
1180 fByPosition,
1181 lpmii));
1182
1183 if(fByPosition) {
1184 return ODIN_InsertMenuW(hMenu, uItem, lpmii->fType | MF_BYPOSITION, (lpmii->fType & MF_POPUP) ? lpmii->hSubMenu : lpmii->wID, lpmii->dwTypeData);
1185 }
1186 else return ODIN_InsertMenuW(hMenu, uItem, lpmii->fType | MF_BYCOMMAND, (lpmii->fType & MF_POPUP) ? lpmii->hSubMenu : lpmii->wID, lpmii->dwTypeData);
1187}
1188/*****************************************************************************
1189 * Function : MenuItemFromPoint
1190 * Purpose : TheMenuItemFromPoint function determines which menu item, if
1191 * any, is at the specified location.
1192 * Parameters:
1193 * Variables :
1194 * Result : Returns the zero-based position of the menu item at the specified
1195 * location or -1 if no menu item is at the specified location.
1196 * Remark :
1197 * Status : UNTESTED STUB
1198 *
1199 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
1200 *****************************************************************************/
1201
1202ODINFUNCTION3(UINT, MenuItemFromPoint,
1203 HWND, hWnd,
1204 HMENU, hMenu,
1205 POINT, ptScreen)
1206{
1207 dprintf(("USER32:MenuItemFromPoint (%08xh,%08xh,%u) not implemented.\n",
1208 hWnd,
1209 hMenu,
1210 ptScreen));
1211
1212 return (-1);
1213}
1214
1215
1216/*****************************************************************************
1217 * Function : GetMenuInfo
1218 * Parameters:
1219 * Variables :
1220 * Result :
1221 * Remark :
1222 * Status : UNTESTED STUB win98/NT5.0
1223 *
1224 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
1225 *****************************************************************************/
1226
1227ODINFUNCTION2(BOOL, GetMenuInfo,
1228 HMENU, hMenu,
1229 LPMENUINFO, lpmi)
1230{
1231 POPUPMENU *menu;
1232
1233 menu = GetInternalMenuInfo(hMenu);
1234 if(menu == NULL) {
1235 dprintf(("USER32: GetMenuInfo(%08xh,%08xh) No POPUPMENU structure found!", hMenu, lpmi));
1236 SetLastError(ERROR_INVALID_PARAMETER);
1237 return FALSE;
1238 }
1239 dprintf(("USER32: GetMenuInfo(%08xh,%08xh)", hMenu, lpmi));
1240
1241 if (lpmi)
1242 {
1243 if (lpmi->fMask & MIM_BACKGROUND)
1244 lpmi->hbrBack = menu->hbrBack;
1245
1246 if (lpmi->fMask & MIM_HELPID)
1247 lpmi->dwContextHelpID = menu->dwContextHelpID;
1248
1249 if (lpmi->fMask & MIM_MAXHEIGHT)
1250 lpmi->cyMax = menu->cyMax;
1251
1252 if (lpmi->fMask & MIM_MENUDATA)
1253 lpmi->dwMenuData = menu->dwMenuData;
1254
1255 if (lpmi->fMask & MIM_STYLE)
1256 lpmi->dwStyle = menu->dwStyle;
1257
1258 return TRUE;
1259 }
1260 SetLastError(ERROR_INVALID_PARAMETER);
1261 return FALSE;
1262}
1263/*****************************************************************************
1264 * Function : SetMenuInfo
1265 * Purpose :
1266 * Parameters:
1267 * Variables :
1268 * Result :
1269 * Remark :
1270 * FIXME
1271 * MIM_APPLYTOSUBMENUS
1272 * actually use the items to draw the menu
1273 * Status : UNTESTED STUB win98/NT5.0
1274 *
1275 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
1276 *****************************************************************************/
1277
1278ODINFUNCTION2(BOOL, SetMenuInfo,
1279 HMENU, hMenu,
1280 LPCMENUINFO, lpmi)
1281{
1282 POPUPMENU *menu;
1283
1284 menu = GetInternalMenuInfo(hMenu);
1285 if(menu == NULL) {
1286 dprintf(("USER32: SetMenuInfo(%08xh,%08xh) No POPUPMENU structure found!", hMenu, lpmi));
1287 SetLastError(ERROR_INVALID_PARAMETER);
1288 return FALSE;
1289 }
1290
1291 dprintf(("USER32: SetMenuInfo(%08xh,%08xh)", hMenu, lpmi));
1292
1293 if (lpmi && (lpmi->cbSize==sizeof(MENUINFO)))
1294 {
1295 if (lpmi->fMask & MIM_BACKGROUND)
1296 menu->hbrBack = lpmi->hbrBack;
1297
1298 if (lpmi->fMask & MIM_HELPID)
1299 menu->dwContextHelpID = lpmi->dwContextHelpID;
1300
1301 if (lpmi->fMask & MIM_MAXHEIGHT)
1302 menu->cyMax = lpmi->cyMax;
1303
1304 if (lpmi->fMask & MIM_MENUDATA)
1305 menu->dwMenuData = lpmi->dwMenuData;
1306
1307 if (lpmi->fMask & MIM_STYLE)
1308 menu->dwStyle = lpmi->dwStyle;
1309
1310 return TRUE;
1311 }
1312 SetLastError(ERROR_INVALID_PARAMETER);
1313 return FALSE;
1314}
1315//******************************************************************************
1316//******************************************************************************
1317
Note: See TracBrowser for help on using the repository browser.