mirror of
https://github.com/reactos/wine.git
synced 2024-11-29 14:40:56 +00:00
988ca977ab
Mon Jun 20 14:26:41 1994 Bob Amstadt (bob@pooh) * [objects/bitmap.c] Allow negative bitmap sizes. Sun Jun 19 12:00:04 1994 David Metcalfe <david@prism.demon.co.uk> * [controls/edit.c] Improved selection display. Added processing for WM_SETFONT, EM_REPLACESEL, EM_LINELENGTH, EM_UNDO, EM_EMPTYUNDOBUFFER, EM_GETHANDLE, EM_SETHANDLE messages. Text buffer now stored on application's local heap. * [windows/graphics.c] Corrected bug in Rectangle(). XFillRectangle has the same width as Rectangle, but XDrawRectangle is one pixel wider for the same co-ordinates. * [memory/heap.c] [include/heap.h] Added HEAP_LocalSize function. * [windows/event.c] [windows/keyboard.c] Improvements to KeyStateTable and addition of AsyncKeyStateTable. Added supporting code to GetKeyState and GetAsyncKeyState and merged mouse button states into GetKeyboardState. * [loader/resource.c] [include/accel.h] Added recognition of SHIFT, CONTROL and ALT keys to TranslateAccelerator. * [objects/metafile.c] [objects/font.c] [objects/bitblt.c] A bit more metafile support. Sun Jun 19 17:29:00 MET DST 1994 Erik Bos (erik@hacktic.nl) * [loader/resource.c] SizeofResource() and AllocResource() added, AccessResource() updated. * [if1632/kernel.spec] FreeLibrary() used for FreeModule(). * [windows/graphics.c] Rectangle(): swap left & right corners when right < left, swap top & bottom when botton < top. Jun 19, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) * [controls/combo.c] Fix bug in window style of the associated listbox. * [controls/menu.c] Skip separators in keyboard navigation by using new internal functions SelectPrevItem() & SelectNextItem(), * [misc/profile.c] Bug fix in GetPrivateProfileInt(), was limited to 4 digit, IntBuf must be alloc to (5+1)=6. char instead of 5. * [misc/main.c] Put code in functions SetEnvironment() & GetEnvironment(). * [misc/shell.c] Start putting some code in ExtractIcon() function. * [misc/mmsystem.c] Some code for MMTimer functions & timers list. * [miscemu/int31.c] Few stubs for DPMI interrupt calls. Nothing work yet. Mon Jun 20 07:37:43 EDT 1994 John Richardson (jrichard@cs.uml.edu) * include/win.h (tagWND): Added icon fields icon, hIcon and rectClientSave to the tagWND struct. * windows/Imakefile Added icon.c to the list of files to compile * windows/dce.c (GetDCEx): Added some checks for iconic mode and pass icon window as drawable, not the real window. * windows/defwnd.c (DefWindowProc) Added PAINTICON default windows procedure. * windows/event.c (EVENT_Expose) Added check for iconic window expose. If iconic window is exposed send a WM_PAINTICON message * windows/icon.c New file. ICON_Iconify, ICON_findIconFromPoint, ICON_Deiconify. * windows/mdi.c (DefMDIChildProc) Test for IsIconic during a SC_RESTORE, this doesn't work yet. * windows/message.c (hardware_event) Looks for icon as well as window now. * windows/nonclient.c (NC_HandleSysCommand, NC_DoNCPaintIcon) Added iconify/deiconify in NC_HandleSysCommand, new function NC_DoNCPaintIcon which paints an icon. * windows/painting.c (BeginPaint) Made a BeginPaint select the STOCK_BLACK_PEN, STOCK_WHITE_BRUSH, and STOCK_SYSTEM_FONT objects since this is (hopefully) default windows behavior. * windows/win.h (CreateWindowEx) Set the default background color of a window to be white. Create icon window, turn off MINIMIZE if it is on, since I don't know what to do with it as of yet... register the icon with the hwnd of its window so we can identify where icon messages are coming from. Mon Jun 20 10:15:59 1994 Miguel de Icaza (miguel@sphinx) * windows/event.c: Added a hack to define XPointer when using X11R4. * toolkit/hello.c: Test application for WineLib. To compile you'll need: gcc -Iinclude -DWINELIB -g hello.c -c, and to link you'll need: gcc hello.o libwine.a -lX11 -L/usr/openwin/lib -lm * toolkit/heap.c: Extended the size of the block size per chunk. * misc/stress.c (GetFreeFileHandles): Fixed typo. * misc/main.c (main): Changes to allow compilation under SunOS. * loader/library.c: Changed some ifdefs to compile WineLib.
2447 lines
64 KiB
C
2447 lines
64 KiB
C
/*
|
|
* Menus functions
|
|
*/
|
|
static char RCSId[] = "$Id$";
|
|
static char Copyright[] = "Copyright Martin Ayotte, 1993";
|
|
|
|
/*
|
|
#define DEBUG_MENU
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include "windows.h"
|
|
#include "sysmetrics.h"
|
|
#include "prototypes.h"
|
|
#include "menu.h"
|
|
#include "user.h"
|
|
#include "heap.h"
|
|
#include "win.h"
|
|
|
|
#define SC_ABOUTWINE SC_SCREENSAVE+1
|
|
#define SC_SYSMENU SC_SCREENSAVE+2
|
|
#define SC_ABOUTWINEDLG SC_SCREENSAVE+3
|
|
|
|
extern HINSTANCE hSysRes;
|
|
HMENU hSysMenu = 0;
|
|
HBITMAP hStdCheck = 0;
|
|
HBITMAP hStdMnArrow = 0;
|
|
static BOOL MenuHasFocus = FALSE;
|
|
|
|
LPPOPUPMENU PopupMenuGetStorageHeader(HWND hwnd);
|
|
LPPOPUPMENU PopupMenuGetWindowAndStorage(HWND hwnd, WND **wndPtr);
|
|
void StdDrawMenuBar(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop,
|
|
BOOL suppress_draw);
|
|
BOOL MenuButtonDown(HWND hWnd, LPPOPUPMENU lppop, int x, int y);
|
|
void MenuButtonUp(HWND hWnd, LPPOPUPMENU lppop, int x, int y);
|
|
void MenuMouseMove(HWND hWnd, LPPOPUPMENU lppop, WORD wParam, int x, int y);
|
|
void StdDrawPopupMenu(HWND hwnd);
|
|
void ResetHiliteFlags(LPPOPUPMENU lppop);
|
|
void SelectPrevItem(LPPOPUPMENU lppop);
|
|
void SelectNextItem(LPPOPUPMENU lppop);
|
|
BOOL ExecFocusedMenuItem(HWND hWnd, LPPOPUPMENU lppop);
|
|
void MenuItemSelect(HWND hWnd, LPPOPUPMENU lppop, WORD wIndex);
|
|
LPMENUITEM MenuFindItem(LPPOPUPMENU lppop, int x, int y, WORD *lpRet);
|
|
LPMENUITEM MenuFindItemBySelKey(LPPOPUPMENU lppop, WORD key, WORD *lpRet);
|
|
BOOL ActivateMenuBarFocus(HWND hWnd);
|
|
BOOL MenuFocusLoop(HWND hWnd, LPPOPUPMENU lpmenu);
|
|
void PopupMenuCalcSize(HWND hwnd);
|
|
void MenuBarCalcSize(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop);
|
|
LPMENUITEM FindMenuItem(HMENU hMenu, WORD nPos, WORD wFlags);
|
|
LPMENUITEM GetMenuItemPtr(LPPOPUPMENU menu, WORD nPos);
|
|
WORD GetSelectionKey(LPSTR str);
|
|
LPSTR GetShortCutString(LPSTR str);
|
|
WORD GetShortCutPos(LPSTR str);
|
|
BOOL HideAllSubPopupMenu(LPPOPUPMENU menu);
|
|
void InitStdBitmaps();
|
|
HMENU CopySysMenu();
|
|
WORD * ParseMenuResource(WORD *first_item, int level, HMENU hMenu);
|
|
void SetMenuLogicalParent(HMENU hMenu, HWND hWnd);
|
|
|
|
BOOL FAR PASCAL AboutWine_Proc(HWND hDlg, WORD msg, WORD wParam, LONG lParam);
|
|
|
|
/***********************************************************************
|
|
* PopupMenuWndProc
|
|
SetWindow
|
|
SetWindow
|
|
*/
|
|
LONG PopupMenuWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam )
|
|
{
|
|
CREATESTRUCT *createStruct;
|
|
WORD wRet;
|
|
short x, y;
|
|
WND *wndPtr;
|
|
LPPOPUPMENU lppop, lppop2;
|
|
LPMENUITEM lpitem, lpitem2;
|
|
HMENU hSubMenu;
|
|
RECT rect;
|
|
HDC hDC;
|
|
PAINTSTRUCT ps;
|
|
switch(message) {
|
|
case WM_CREATE:
|
|
#ifdef DEBUG_MENU
|
|
printf("PopupMenu WM_CREATE lParam=%08X !\n", lParam);
|
|
#endif
|
|
createStruct = (CREATESTRUCT *)lParam;
|
|
lppop = (LPPOPUPMENU)createStruct->lpCreateParams;
|
|
if (lppop == NULL) break;
|
|
wndPtr = WIN_FindWndPtr(hwnd);
|
|
*((LPPOPUPMENU *)&wndPtr->wExtra[1]) = lppop;
|
|
#ifdef DEBUG_MENU
|
|
printf("PopupMenu WM_CREATE lppop=%08X !\n", lppop);
|
|
#endif
|
|
InitStdBitmaps();
|
|
#ifdef DEBUG_MENU
|
|
printf("PopupMenu End of WM_CREATE !\n");
|
|
#endif
|
|
ResetHiliteFlags(lppop);
|
|
return 0;
|
|
case WM_DESTROY:
|
|
lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
|
|
#ifdef DEBUG_MENU
|
|
printf("PopupMenu WM_DESTROY %lX !\n", lppop);
|
|
#endif
|
|
return 0;
|
|
case WM_COMMAND:
|
|
#ifdef DEBUG_MENU
|
|
printf("PopupMenuWndProc // WM_COMMAND received !\n");
|
|
#endif
|
|
lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
|
|
if (lppop == NULL) break;
|
|
if (lppop->SysFlag) {
|
|
MenuHasFocus = FALSE;
|
|
if (wParam == SC_ABOUTWINE) {
|
|
printf("SysMenu // Show 'About Wine ...' !\n");
|
|
/* DialogBox(hSysRes, MAKEINTRESOURCE(SC_ABOUTWINEDLG), */
|
|
DialogBox(hSysRes, MAKEINTRESOURCE(2),
|
|
GetParent(hwnd), (FARPROC)AboutWine_Proc);
|
|
}
|
|
else {
|
|
#ifdef DEBUG_MENU
|
|
printf("PopupMenuWndProc // push to Owner WM_SYSCOMMAND !\n");
|
|
#endif
|
|
PostMessage(lppop->ownerWnd, WM_SYSCOMMAND, wParam, lParam);
|
|
}
|
|
break;
|
|
}
|
|
#ifdef DEBUG_MENU
|
|
printf("PopupMenuWndProc // push to Owner WM_COMMAND !\n");
|
|
#endif
|
|
MenuHasFocus = FALSE;
|
|
PostMessage(lppop->hWndParent, WM_COMMAND, wParam, lParam);
|
|
break;
|
|
case WM_SHOWWINDOW:
|
|
#ifdef DEBUG_MENU
|
|
printf("PopupMenuWndProc // WM_SHOWWINDOW received !\n");
|
|
#endif
|
|
lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
|
|
if (lppop == NULL) break;
|
|
if (wParam == 0 && lParam == 0L) {
|
|
ResetHiliteFlags(lppop);
|
|
HideAllSubPopupMenu(lppop);
|
|
#ifdef DEBUG_MENU
|
|
printf("PopupMenuWndProc hWnd=%04X WM_SHOWWINDOW -> HIDE!\n", hwnd);
|
|
#endif
|
|
if (lppop->SysFlag) MenuHasFocus = FALSE;
|
|
SetFocus(lppop->hWndPrev);
|
|
if (GetCapture() != 0) ReleaseCapture();
|
|
break;
|
|
}
|
|
lppop->FocusedItem = (WORD)-1;
|
|
if (!lppop->BarFlag) {
|
|
PopupMenuCalcSize(hwnd);
|
|
/* ResetHiliteFlags(lppop); */
|
|
#ifdef DEBUG_MENU
|
|
printf("PopupMenuWndProc hWnd=%04X WM_SHOWWINDOW Width=%d Height=%d !\n",
|
|
hwnd, lppop->Width, lppop->Height);
|
|
#endif
|
|
SetWindowPos(hwnd, 0, 0, 0, lppop->Width + 2, lppop->Height,
|
|
SWP_NOZORDER | SWP_NOMOVE);
|
|
#ifdef DEBUG_MENU
|
|
printf("PopupMenuWndProc // End of WM_SHOWWINDOW !\n");
|
|
#endif
|
|
}
|
|
break;
|
|
case WM_LBUTTONDOWN:
|
|
lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
|
|
if (lppop == NULL) break;
|
|
SetCapture(hwnd);
|
|
MenuButtonDown(hwnd, lppop, LOWORD(lParam), HIWORD(lParam));
|
|
break;
|
|
case WM_LBUTTONUP:
|
|
lppop = PopupMenuGetStorageHeader(hwnd);
|
|
if (lppop == NULL) break;
|
|
ReleaseCapture();
|
|
MenuButtonUp(hwnd, lppop, LOWORD(lParam), HIWORD(lParam));
|
|
break;
|
|
case WM_MOUSEMOVE:
|
|
lppop = PopupMenuGetStorageHeader(hwnd);
|
|
if (lppop == NULL) break;
|
|
MenuMouseMove(hwnd, lppop, wParam, LOWORD(lParam), HIWORD(lParam));
|
|
break;
|
|
|
|
case WM_KEYUP:
|
|
#ifdef DEBUG_MENU
|
|
printf("PopupMenuWndProc hWnd=%04X WM_KEYUP w=%04X l=%08X !\n",
|
|
hwnd, wParam, lParam);
|
|
#endif
|
|
break;
|
|
case WM_KEYDOWN:
|
|
#ifdef DEBUG_MENU
|
|
printf("PopupMenuWndProc hWnd=%04X WM_KEYDOWN w=%04X l=%08X !\n",
|
|
hwnd, wParam, lParam);
|
|
#endif
|
|
if (lParam < 0L) break;
|
|
lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
|
|
if (lppop == NULL) break;
|
|
switch(wParam) {
|
|
case VK_HOME:
|
|
if (lppop->FocusedItem == 0) break;
|
|
MenuItemSelect(hwnd, lppop, 0);
|
|
break;
|
|
case VK_UP:
|
|
if (lppop->BarFlag) break;
|
|
SelectPrevItem(lppop);
|
|
break;
|
|
case VK_DOWN:
|
|
if (lppop->BarFlag) goto ProceedSPACE;
|
|
SelectNextItem(lppop);
|
|
break;
|
|
case VK_LEFT:
|
|
if (lppop->SysFlag != 0) {
|
|
ShowWindow(hwnd, SW_HIDE);
|
|
hwnd = lppop->hWndParent;
|
|
lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
|
|
printf("VK_LEFT // try to put focus on MenuBar %08X !\n", lppop);
|
|
if (lppop == NULL) break;
|
|
MenuItemSelect(hwnd, lppop, lppop->nItems - 1);
|
|
break;
|
|
}
|
|
if (lppop->BarFlag) {
|
|
if (lppop->FocusedItem < 1) {
|
|
MenuItemSelect(hwnd, lppop, -1);
|
|
NC_TrackSysMenu(hwnd);
|
|
break;
|
|
}
|
|
if (HideAllSubPopupMenu(lppop)) {
|
|
MenuItemSelect(hwnd, lppop, lppop->FocusedItem - 1);
|
|
goto ProceedSPACE;
|
|
}
|
|
}
|
|
if (lppop->hWndParent != 0) {
|
|
PostMessage(lppop->hWndParent, WM_KEYDOWN, wParam, lParam);
|
|
break;
|
|
}
|
|
MenuItemSelect(hwnd, lppop, lppop->FocusedItem - 1);
|
|
break;
|
|
case VK_RIGHT:
|
|
if (lppop->SysFlag != 0) {
|
|
ShowWindow(hwnd, SW_HIDE);
|
|
hwnd = lppop->hWndParent;
|
|
lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
|
|
printf("VK_RIGHT // try to put focus on MenuBar %08X !\n", lppop);
|
|
if (lppop == NULL) break;
|
|
MenuItemSelect(hwnd, lppop, 0);
|
|
break;
|
|
}
|
|
if (lppop->BarFlag) {
|
|
if (lppop->FocusedItem >= lppop->nItems - 1) {
|
|
MenuItemSelect(hwnd, lppop, -1);
|
|
NC_TrackSysMenu(hwnd);
|
|
break;
|
|
}
|
|
if (HideAllSubPopupMenu(lppop)) {
|
|
MenuItemSelect(hwnd, lppop, lppop->FocusedItem + 1);
|
|
goto ProceedSPACE;
|
|
}
|
|
}
|
|
if (lppop->hWndParent != 0) {
|
|
PostMessage(lppop->hWndParent, WM_KEYDOWN, wParam, lParam);
|
|
break;
|
|
}
|
|
MenuItemSelect(hwnd, lppop, lppop->FocusedItem + 1);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
case WM_CHAR:
|
|
#ifdef DEBUG_MENU
|
|
printf("PopupMenuWndProc hWnd=%04X WM_CHAR wParam=%04X !\n", hwnd, wParam);
|
|
#endif
|
|
if (lParam < 0L) break;
|
|
hwnd = GetFocus();
|
|
lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
|
|
if (lppop == NULL) break;
|
|
switch(wParam) {
|
|
case VK_RETURN:
|
|
case VK_SPACE:
|
|
ProceedSPACE: lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
|
|
ExecFocusedMenuItem(hwnd, lppop);
|
|
break;
|
|
case VK_ESCAPE:
|
|
if (lppop->BarFlag) {
|
|
#ifdef DEBUG_MENU
|
|
printf("VK_ESCAPE // Unselect all MenuBar's Items !\n");
|
|
#endif
|
|
if (lppop->FocusedItem != (WORD)-1)
|
|
MenuItemSelect(hwnd, lppop, -1);
|
|
}
|
|
if (lppop->SysFlag) {
|
|
#ifdef DEBUG_MENU
|
|
printf("VK_ESCAPE // SysMenu !\n");
|
|
#endif
|
|
ShowWindow(hwnd, SW_HIDE);
|
|
break;
|
|
}
|
|
if (lppop->hWndParent != 0) {
|
|
#ifdef DEBUG_MENU
|
|
printf("VK_ESCAPE // Hide only SubPopup !\n");
|
|
#endif
|
|
lppop2 = PopupMenuGetWindowAndStorage(lppop->hWndParent, &wndPtr);
|
|
if (lppop2 == NULL) break;
|
|
HideAllSubPopupMenu(lppop2);
|
|
break;
|
|
}
|
|
else {
|
|
#ifdef DEBUG_MENU
|
|
printf("VK_ESCAPE // Hide Root Popup !\n");
|
|
#endif
|
|
ShowWindow(hwnd, SW_HIDE);
|
|
MenuHasFocus = FALSE;
|
|
}
|
|
break;
|
|
default:
|
|
if (wParam >= 'a' && wParam <= 'z') wParam -= 'a' - 'A';
|
|
lpitem = MenuFindItemBySelKey(lppop, wParam, &wRet);
|
|
if (lpitem != NULL) {
|
|
printf("ShortKey Found wRet=%d !\n", wRet);
|
|
MenuItemSelect(hwnd, lppop, wRet);
|
|
lppop->FocusedItem = wRet;
|
|
goto ProceedSPACE;
|
|
}
|
|
printf("ShortKey Not Found wParam=%04X wRet=%d lpitem=%08X !\n",
|
|
wParam, wRet, lpitem);
|
|
if (lppop->hWndParent != (HWND)NULL)
|
|
SendMessage(lppop->hWndParent, WM_MENUCHAR, wParam,
|
|
MAKELONG(0, 0));
|
|
else
|
|
SendMessage(lppop->ownerWnd, WM_MENUCHAR, wParam,
|
|
MAKELONG(0, 0));
|
|
break;
|
|
}
|
|
break;
|
|
case WM_PAINT:
|
|
#ifdef DEBUG_MENU
|
|
printf("PopupMenuWndProc // WM_PAINT received !\n");
|
|
#endif
|
|
lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
|
|
if (lppop == NULL) break;
|
|
if (!lppop->BarFlag) {
|
|
PopupMenuCalcSize(hwnd);
|
|
StdDrawPopupMenu(hwnd);
|
|
}
|
|
break;
|
|
default:
|
|
return DefWindowProc(hwnd, message, wParam, lParam);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
BOOL ExecFocusedMenuItem(HWND hWnd, LPPOPUPMENU lppop)
|
|
{
|
|
short x, y;
|
|
LPPOPUPMENU lppop2;
|
|
LPMENUITEM lpitem;
|
|
HMENU hSubMenu;
|
|
RECT rect;
|
|
lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem);
|
|
if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
|
|
hSubMenu = (HMENU)lpitem->item_id;
|
|
lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu);
|
|
if (lppop2 == NULL) return FALSE;
|
|
lppop2->hWndParent = hWnd;
|
|
GetClientRect(hWnd, &rect);
|
|
if (lppop->BarFlag) {
|
|
GetWindowRect(hWnd, &rect);
|
|
y = rect.top + lppop->rect.bottom;
|
|
TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON,
|
|
rect.left + lpitem->rect.left,
|
|
y, 0, lppop->ownerWnd, (LPRECT)NULL);
|
|
}
|
|
else {
|
|
x = lppop->rect.right;
|
|
GetWindowRect(hWnd, &rect);
|
|
x += rect.left;
|
|
TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON,
|
|
x, rect.top + lpitem->rect.top,
|
|
0, lppop->ownerWnd, (LPRECT)NULL);
|
|
}
|
|
GlobalUnlock(hSubMenu);
|
|
return TRUE;
|
|
}
|
|
if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
|
|
((lpitem->item_flags & MF_POPUP) != MF_POPUP)) {
|
|
MenuHasFocus = FALSE;
|
|
if (lppop->BarFlag) {
|
|
PostMessage(lppop->ownerWnd, WM_COMMAND, lpitem->item_id, 0L);
|
|
}
|
|
else {
|
|
ShowWindow(lppop->hWnd, SW_HIDE);
|
|
SendMessage(lppop->hWnd, WM_COMMAND, lpitem->item_id, 0L);
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
BOOL MenuButtonDown(HWND hWnd, LPPOPUPMENU lppop, int x, int y)
|
|
{
|
|
HDC hDC;
|
|
LPMENUITEM lpitem, lpitem2;
|
|
RECT rect;
|
|
HMENU hSubMenu;
|
|
WORD wRet;
|
|
LPPOPUPMENU lppop2;
|
|
if (lppop == NULL) return;
|
|
lpitem = MenuFindItem(lppop, x, y, &wRet);
|
|
#ifdef DEBUG_MENU
|
|
printf("MenuButtonDown hWnd=%04X x=%d y=%d // wRet=%d lpitem=%08X !\n",
|
|
hWnd, x, y, wRet, lpitem);
|
|
#endif
|
|
if (lpitem != NULL) {
|
|
if (lppop->FocusedItem != (WORD)-1 && wRet == lppop->FocusedItem) {
|
|
lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem);
|
|
if ((lpitem2->item_flags & MF_POPUP) == MF_POPUP) {
|
|
hSubMenu = (HMENU)lpitem2->item_id;
|
|
lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu);
|
|
if (lppop2 == NULL) return FALSE;
|
|
if (IsWindowVisible(lppop2->hWnd)) {
|
|
ShowWindow(lppop2->hWnd, SW_HIDE);
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
MenuItemSelect(hWnd, lppop, wRet);
|
|
if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
|
|
hSubMenu = (HMENU)lpitem->item_id;
|
|
lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu);
|
|
if (lppop2 == NULL) return FALSE;
|
|
lppop2->hWndParent = hWnd;
|
|
if (lppop->BarFlag) {
|
|
GetWindowRect(hWnd, &rect);
|
|
y = rect.top + lppop->rect.bottom;
|
|
ReleaseCapture();
|
|
if (MenuHasFocus) {
|
|
TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON,
|
|
rect.left + lpitem->rect.left,
|
|
y, 0, lppop->ownerWnd, (LPRECT)NULL);
|
|
}
|
|
else {
|
|
MenuHasFocus = TRUE;
|
|
TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON,
|
|
rect.left + lpitem->rect.left,
|
|
y, 0, lppop->ownerWnd, (LPRECT)NULL);
|
|
MenuHasFocus = FALSE;
|
|
MenuFocusLoop(hWnd, lppop);
|
|
return TRUE;
|
|
}
|
|
}
|
|
else {
|
|
x = lppop->rect.right;
|
|
GetWindowRect(hWnd, &rect);
|
|
x += rect.left;
|
|
TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON,
|
|
x, rect.top + lpitem->rect.top,
|
|
0, lppop->ownerWnd, (LPRECT)NULL);
|
|
}
|
|
GlobalUnlock(hSubMenu);
|
|
return TRUE;
|
|
}
|
|
if (lppop->BarFlag && !MenuHasFocus) {
|
|
MenuFocusLoop(hWnd, lppop);
|
|
}
|
|
return TRUE;
|
|
}
|
|
printf("MenuButtonDown // x=%d y=%d // Not Found !\n", x, y);
|
|
if (GetCapture() != 0) ReleaseCapture();
|
|
MenuHasFocus = FALSE;
|
|
ShowWindow(lppop->hWnd, SW_HIDE);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
void MenuButtonUp(HWND hWnd, LPPOPUPMENU lppop, int x, int y)
|
|
{
|
|
HDC hDC;
|
|
LPMENUITEM lpitem, lpitem2;
|
|
RECT rect;
|
|
HMENU hSubMenu;
|
|
WORD wRet;
|
|
LPPOPUPMENU lppop2;
|
|
if (lppop == NULL) return;
|
|
lpitem = MenuFindItem(lppop, x, y, &wRet);
|
|
#ifdef DEBUG_MENU
|
|
printf("MenuButtonUp // x=%d y=%d // wRet=%d lpitem=%08X !\n",
|
|
x, y, wRet, lpitem);
|
|
#endif
|
|
if (lpitem != NULL) {
|
|
if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
|
|
return;
|
|
}
|
|
if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
|
|
((lpitem->item_flags & MF_POPUP) != MF_POPUP)) {
|
|
MenuHasFocus = FALSE;
|
|
if (lppop->BarFlag) {
|
|
PostMessage(lppop->ownerWnd, WM_COMMAND, lpitem->item_id, 0L);
|
|
}
|
|
else {
|
|
ShowWindow(lppop->hWnd, SW_HIDE);
|
|
SendMessage(lppop->hWnd, WM_COMMAND, lpitem->item_id, 0L);
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
if (lppop->FocusedItem != (WORD)-1) {
|
|
MenuItemSelect(hWnd, lppop, lppop->FocusedItem);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void MenuMouseMove(HWND hWnd, LPPOPUPMENU lppop, WORD wParam, int x, int y)
|
|
{
|
|
HDC hDC;
|
|
RECT rect;
|
|
HMENU hSubMenu;
|
|
LPMENUITEM lpitem, lpitem2;
|
|
LPPOPUPMENU lppop2;
|
|
WORD wRet;
|
|
|
|
if (GetKeyState(VK_LBUTTON) != 0)
|
|
{
|
|
lpitem = MenuFindItem(lppop, x, y, &wRet);
|
|
#ifdef DEBUG_MENU
|
|
printf("MenuMouseMove // x=%d y=%d // wRet=%d lpitem=%08X !\n",
|
|
x, y, wRet, lpitem);
|
|
#endif
|
|
if ((lpitem != NULL) && (lppop->FocusedItem != wRet))
|
|
{
|
|
lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem);
|
|
hDC = GetWindowDC(hWnd);
|
|
if ((lpitem2 != NULL ) &&
|
|
(lpitem2->item_flags & MF_POPUP) == MF_POPUP)
|
|
{
|
|
HideAllSubPopupMenu(lppop);
|
|
}
|
|
MenuItemSelect(hWnd, lppop, wRet);
|
|
if ((lpitem->item_flags & MF_POPUP) == MF_POPUP)
|
|
{
|
|
hSubMenu = (HMENU)lpitem->item_id;
|
|
lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu);
|
|
if (lppop2 == NULL)
|
|
{
|
|
ReleaseDC(hWnd, hDC);
|
|
return;
|
|
}
|
|
if (lppop->BarFlag)
|
|
{
|
|
lppop2->hWndParent = hWnd;
|
|
GetWindowRect(hWnd, &rect);
|
|
rect.top += lppop->rect.bottom;
|
|
TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON,
|
|
rect.left + lpitem->rect.left, rect.top,
|
|
0, lppop->ownerWnd, (LPRECT)NULL);
|
|
}
|
|
GlobalUnlock(hSubMenu);
|
|
}
|
|
ReleaseDC(hWnd, hDC);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void SelectPrevItem(LPPOPUPMENU lppop)
|
|
{
|
|
int nIndex;
|
|
LPMENUITEM lpitem;
|
|
if (lppop == NULL) return;
|
|
nIndex = lppop->FocusedItem;
|
|
if (nIndex < 1) {
|
|
if (nIndex == -1)
|
|
nIndex = 0;
|
|
else
|
|
nIndex = lppop->nItems - 1;
|
|
lpitem = GetMenuItemPtr(lppop, nIndex);
|
|
}
|
|
else {
|
|
nIndex--;
|
|
lpitem = GetMenuItemPtr(lppop, nIndex);
|
|
}
|
|
while (lpitem != NULL && lpitem->item_flags & MF_HILITE) {
|
|
nIndex--;
|
|
lpitem = GetMenuItemPtr(lppop, nIndex);
|
|
}
|
|
MenuItemSelect(lppop->hWnd, lppop, nIndex);
|
|
}
|
|
|
|
|
|
void SelectNextItem(LPPOPUPMENU lppop)
|
|
{
|
|
int nIndex;
|
|
LPMENUITEM lpitem;
|
|
if (lppop == NULL) return;
|
|
nIndex = lppop->FocusedItem;
|
|
if ((nIndex == -1) || (nIndex >= lppop->nItems - 1)) {
|
|
nIndex = 0;
|
|
lpitem = GetMenuItemPtr(lppop, nIndex);
|
|
}
|
|
else {
|
|
nIndex++;
|
|
lpitem = GetMenuItemPtr(lppop, nIndex);
|
|
}
|
|
while (lpitem != NULL && (lpitem->item_flags & MF_SEPARATOR)) {
|
|
nIndex++;
|
|
lpitem = GetMenuItemPtr(lppop, nIndex);
|
|
}
|
|
MenuItemSelect(lppop->hWnd, lppop, nIndex);
|
|
}
|
|
|
|
|
|
void ResetHiliteFlags(LPPOPUPMENU lppop)
|
|
{
|
|
LPMENUITEM lpitem;
|
|
int i;
|
|
#ifdef DEBUG_MENU
|
|
printf("ResetHiliteFlags lppop=%08X\n", lppop);
|
|
#endif
|
|
if (lppop == NULL) return;
|
|
lpitem = lppop->firstItem;
|
|
for(i = 0; i < lppop->nItems; i++) {
|
|
if (lpitem == NULL) return;
|
|
lpitem->item_flags &= 0xFFFF ^ MF_HILITE;
|
|
lpitem = (LPMENUITEM)lpitem->next;
|
|
}
|
|
}
|
|
|
|
|
|
void MenuItemSelect0(HWND hWnd, LPPOPUPMENU lppop,
|
|
LPMENUITEM lpitem, WORD wIndex)
|
|
{
|
|
LPMENUITEM lpprev;
|
|
|
|
if (lppop == NULL)
|
|
return;
|
|
if (lppop->FocusedItem != (WORD)-1)
|
|
{
|
|
lpprev = GetMenuItemPtr(lppop, lppop->FocusedItem);
|
|
if (lpprev != NULL)
|
|
{
|
|
lpprev->item_flags &= MF_HILITE ^ 0xFFFF;
|
|
if ((lpprev->item_flags & MF_POPUP) == MF_POPUP)
|
|
HideAllSubPopupMenu(lppop);
|
|
if (lppop->BarFlag)
|
|
DrawMenuBar(hWnd);
|
|
else
|
|
{
|
|
InvalidateRect(hWnd, &lpprev->rect, TRUE);
|
|
UpdateWindow(hWnd);
|
|
}
|
|
}
|
|
}
|
|
lppop->FocusedItem = wIndex;
|
|
if (lpitem == NULL || wIndex == (WORD)-1)
|
|
{
|
|
ResetHiliteFlags(lppop);
|
|
if (lppop->BarFlag) DrawMenuBar(hWnd);
|
|
}
|
|
else
|
|
{
|
|
lpitem->item_flags |= MF_HILITE;
|
|
if (lppop->BarFlag)
|
|
DrawMenuBar(hWnd);
|
|
else
|
|
{
|
|
InvalidateRect(hWnd, &lpitem->rect, TRUE);
|
|
UpdateWindow(hWnd);
|
|
}
|
|
SendMessage(hWnd, WM_MENUSELECT, lpitem->item_id,
|
|
MAKELONG(0, lpitem->item_flags));
|
|
}
|
|
}
|
|
|
|
|
|
void MenuItemSelect(HWND hWnd, LPPOPUPMENU lppop, WORD wIndex)
|
|
{
|
|
LPMENUITEM lpitem;
|
|
lpitem = GetMenuItemPtr(lppop, wIndex);
|
|
MenuItemSelect0(hWnd, lppop, lpitem, wIndex);
|
|
}
|
|
|
|
|
|
LPPOPUPMENU PopupMenuGetWindowAndStorage(HWND hwnd, WND **wndPtr)
|
|
{
|
|
WND *Ptr;
|
|
LPPOPUPMENU lppop;
|
|
*(wndPtr) = Ptr = WIN_FindWndPtr(hwnd);
|
|
if (Ptr == 0) {
|
|
printf("PopupMenuGetWindowAndStorage // Bad Window handle !\n");
|
|
return NULL;
|
|
}
|
|
lppop = *((LPPOPUPMENU *)&Ptr->wExtra[1]);
|
|
if (lppop == NULL) {
|
|
lppop = (LPPOPUPMENU) GlobalLock(Ptr->wIDmenu);
|
|
if (lppop == NULL) {
|
|
printf("PopupMenuGetWindowAndStorage // Bad Menu Handle !\n");
|
|
return NULL;
|
|
}
|
|
}
|
|
return lppop;
|
|
}
|
|
|
|
|
|
LPPOPUPMENU PopupMenuGetStorageHeader(HWND hwnd)
|
|
{
|
|
WND *Ptr;
|
|
LPPOPUPMENU lppop;
|
|
Ptr = WIN_FindWndPtr(hwnd);
|
|
if (Ptr == 0) {
|
|
printf("Bad Window handle on PopupMenu !\n");
|
|
return 0;
|
|
}
|
|
lppop = *((LPPOPUPMENU *)&Ptr->wExtra[1]);
|
|
return lppop;
|
|
}
|
|
|
|
|
|
void SetMenuLogicalParent(HMENU hMenu, HWND hWnd)
|
|
{
|
|
LPPOPUPMENU lppop;
|
|
lppop = (LPPOPUPMENU)GlobalLock(hMenu);
|
|
lppop->hWndParent = hWnd;
|
|
GlobalUnlock(hMenu);
|
|
}
|
|
|
|
|
|
void StdDrawPopupMenu(HWND hwnd)
|
|
{
|
|
WND *wndPtr;
|
|
LPPOPUPMENU lppop;
|
|
LPMENUITEM lpitem;
|
|
PAINTSTRUCT ps;
|
|
HBRUSH hBrush;
|
|
HPEN hOldPen;
|
|
HWND hWndParent;
|
|
HDC hDC, hMemDC;
|
|
RECT rect, rect2, rect3;
|
|
DWORD OldTextColor;
|
|
int OldBkMode;
|
|
HFONT hOldFont;
|
|
HBITMAP hBitMap;
|
|
BITMAP bm;
|
|
UINT i, x;
|
|
hDC = BeginPaint(hwnd, &ps);
|
|
if (!IsWindowVisible(hwnd)) {
|
|
EndPaint(hwnd, &ps);
|
|
return;
|
|
}
|
|
InitStdBitmaps();
|
|
lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
|
|
if (lppop == NULL) goto EndOfPaint;
|
|
hBrush = GetStockObject(WHITE_BRUSH);
|
|
GetClientRect(hwnd, &rect);
|
|
GetClientRect(hwnd, &rect2);
|
|
FillRect(hDC, &rect, hBrush);
|
|
FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH));
|
|
if (lppop->nItems == 0) goto EndOfPaint;
|
|
lpitem = lppop->firstItem;
|
|
if (lpitem == NULL) goto EndOfPaint;
|
|
for(i = 0; i < lppop->nItems; i++) {
|
|
CopyRect(&rect2, &lpitem->rect);
|
|
if ((lpitem->item_flags & MF_SEPARATOR) == MF_SEPARATOR) {
|
|
hOldPen = SelectObject(hDC, GetStockObject(BLACK_PEN));
|
|
MoveTo(hDC, rect2.left, rect2.top + 1);
|
|
LineTo(hDC, rect2.right, rect2.top + 1);
|
|
SelectObject(hDC, hOldPen);
|
|
}
|
|
if ((lpitem->item_flags & MF_CHECKED) == MF_CHECKED) {
|
|
hMemDC = CreateCompatibleDC(hDC);
|
|
if (lpitem->hCheckBit == 0) {
|
|
SelectObject(hMemDC, hStdCheck);
|
|
GetObject(hStdCheck, sizeof(BITMAP), (LPSTR)&bm);
|
|
}
|
|
else {
|
|
SelectObject(hMemDC, lpitem->hCheckBit);
|
|
GetObject(lpitem->hCheckBit, sizeof(BITMAP), (LPSTR)&bm);
|
|
}
|
|
BitBlt(hDC, rect2.left, rect2.top + 1,
|
|
bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
|
|
DeleteDC(hMemDC);
|
|
}
|
|
else {
|
|
if (lpitem->hUnCheckBit != 0) {
|
|
hMemDC = CreateCompatibleDC(hDC);
|
|
SelectObject(hMemDC, lpitem->hUnCheckBit);
|
|
GetObject(lpitem->hUnCheckBit, sizeof(BITMAP), (LPSTR)&bm);
|
|
BitBlt(hDC, rect2.left, rect2.top + 1,
|
|
bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
|
|
DeleteDC(hMemDC);
|
|
}
|
|
}
|
|
if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) {
|
|
hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text);
|
|
rect2.left += lppop->CheckWidth;
|
|
hMemDC = CreateCompatibleDC(hDC);
|
|
SelectObject(hMemDC, hBitMap);
|
|
GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm);
|
|
#ifdef DEBUG_MENU
|
|
printf("StdDrawPopupMenu // MF_BITMAP hBit=%04X w=%d h=%d\n",
|
|
hBitMap, bm.bmWidth, bm.bmHeight);
|
|
#endif
|
|
BitBlt(hDC, rect2.left, rect2.top,
|
|
bm.bmWidth, bm.bmHeight,
|
|
hMemDC, 0, 0, SRCCOPY);
|
|
DeleteDC(hMemDC);
|
|
if ((lpitem->item_flags & MF_HILITE) == MF_HILITE)
|
|
InvertRect(hDC, &lpitem->rect);
|
|
}
|
|
if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) &&
|
|
((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
|
|
((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) {
|
|
hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT));
|
|
OldBkMode = SetBkMode(hDC, TRANSPARENT);
|
|
if ((lpitem->item_flags & MF_DISABLED) == MF_DISABLED)
|
|
OldTextColor = SetTextColor(hDC, 0x00C0C0C0L);
|
|
else {
|
|
if ((lpitem->item_flags & MF_HILITE) == MF_HILITE)
|
|
OldTextColor = SetTextColor(hDC, 0x00FFFFFFL);
|
|
else
|
|
OldTextColor = SetTextColor(hDC, 0x00000000L);
|
|
}
|
|
CopyRect(&rect3, &lpitem->rect);
|
|
if ((lpitem->item_flags & MF_HILITE) == MF_HILITE)
|
|
FillRect(hDC, &rect3, GetStockObject(BLACK_BRUSH));
|
|
InflateRect(&rect3, 0, -2);
|
|
rect3.left += lppop->CheckWidth;
|
|
hOldPen = SelectObject(hDC, GetStockObject(BLACK_PEN));
|
|
if ((x = GetShortCutPos(lpitem->item_text)) != (WORD)-1) {
|
|
DrawText(hDC, lpitem->item_text, x, &rect3,
|
|
DT_LEFT | DT_VCENTER | DT_SINGLELINE);
|
|
DrawText(hDC, &lpitem->item_text[x], -1, &rect3,
|
|
DT_RIGHT | DT_VCENTER | DT_SINGLELINE);
|
|
}
|
|
else
|
|
DrawText(hDC, lpitem->item_text, -1, &rect3,
|
|
DT_LEFT | DT_VCENTER | DT_SINGLELINE);
|
|
SelectObject(hDC, hOldPen);
|
|
SetTextColor(hDC, OldTextColor);
|
|
SetBkMode(hDC, OldBkMode);
|
|
SelectObject(hDC, hOldFont);
|
|
CopyRect(&rect2, &lpitem->rect);
|
|
}
|
|
if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
|
|
CopyRect(&rect3, &lpitem->rect);
|
|
rect3.left = rect3.right - lppop->PopWidth;
|
|
hMemDC = CreateCompatibleDC(hDC);
|
|
SelectObject(hMemDC, hStdMnArrow);
|
|
GetObject(hStdMnArrow, sizeof(BITMAP), (LPSTR)&bm);
|
|
BitBlt(hDC, rect3.left, rect3.top + 1,
|
|
bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
|
|
DeleteDC(hMemDC);
|
|
}
|
|
if (lpitem->next == NULL) goto EndOfPaint;
|
|
lpitem = (LPMENUITEM)lpitem->next;
|
|
}
|
|
EndOfPaint:
|
|
EndPaint( hwnd, &ps );
|
|
}
|
|
|
|
|
|
|
|
void StdDrawMenuBar(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop,
|
|
BOOL suppress_draw)
|
|
{
|
|
LPMENUITEM lpitem;
|
|
HBRUSH hBrush;
|
|
HPEN hOldPen;
|
|
HDC hMemDC;
|
|
RECT rect, rect2, rect3;
|
|
HFONT hOldFont;
|
|
DWORD OldTextColor;
|
|
int OldBkMode;
|
|
HBITMAP hBitMap;
|
|
BITMAP bm;
|
|
UINT i, textwidth;
|
|
if (lppop == NULL || lprect == NULL) return;
|
|
#ifdef DEBUG_MENU
|
|
printf("StdDrawMenuBar(%04X, %08X, %08X); !\n", hDC, lprect, lppop);
|
|
#endif
|
|
MenuBarCalcSize(hDC, lprect, lppop);
|
|
if (suppress_draw) return;
|
|
hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT));
|
|
hOldPen = SelectObject(hDC, GetStockObject(BLACK_PEN));
|
|
hBrush = GetStockObject(WHITE_BRUSH);
|
|
CopyRect(&rect, lprect);
|
|
FillRect(hDC, &rect, hBrush);
|
|
FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH));
|
|
if (lppop->nItems == 0) goto EndOfPaint;
|
|
lpitem = lppop->firstItem;
|
|
if (lpitem == NULL) goto EndOfPaint;
|
|
for(i = 0; i < lppop->nItems; i++) {
|
|
CopyRect(&rect2, &lpitem->rect);
|
|
#ifdef DEBUG_MENU
|
|
printf("StdDrawMenuBar // start left=%d\n", rect2.left);
|
|
#endif
|
|
if ((lpitem->item_flags & MF_CHECKED) == MF_CHECKED) {
|
|
hMemDC = CreateCompatibleDC(hDC);
|
|
if (lpitem->hCheckBit == 0) {
|
|
SelectObject(hMemDC, hStdCheck);
|
|
GetObject(hStdCheck, sizeof(BITMAP), (LPSTR)&bm);
|
|
}
|
|
else {
|
|
SelectObject(hMemDC, lpitem->hCheckBit);
|
|
GetObject(lpitem->hCheckBit, sizeof(BITMAP), (LPSTR)&bm);
|
|
}
|
|
BitBlt(hDC, rect2.left, rect2.top + 1,
|
|
bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
|
|
rect2.left += bm.bmWidth;
|
|
#ifdef DEBUG_MENU
|
|
printf("StdDrawMenuBar // MF_CHECKED bm.bmWidth=%d\n", bm.bmWidth);
|
|
#endif
|
|
DeleteDC(hMemDC);
|
|
}
|
|
else {
|
|
if (lpitem->hUnCheckBit != 0) {
|
|
hMemDC = CreateCompatibleDC(hDC);
|
|
SelectObject(hMemDC, lpitem->hUnCheckBit);
|
|
GetObject(lpitem->hUnCheckBit, sizeof(BITMAP), (LPSTR)&bm);
|
|
BitBlt(hDC, rect2.left, rect2.top + 1,
|
|
bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
|
|
rect2.left += bm.bmWidth;
|
|
#ifdef DEBUG_MENU
|
|
printf("StdDrawMenuBar // MF_UNCHECKED bm.bmWidth=%d\n", bm.bmWidth);
|
|
#endif
|
|
DeleteDC(hMemDC);
|
|
}
|
|
}
|
|
if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) {
|
|
hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text);
|
|
hMemDC = CreateCompatibleDC(hDC);
|
|
SelectObject(hMemDC, hBitMap);
|
|
GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm);
|
|
#ifdef DEBUG_MENU
|
|
printf("StdDrawMenuBar // MF_BITMAP hBit=%04X w=%d h=%d\n",
|
|
hBitMap, bm.bmWidth, bm.bmHeight);
|
|
#endif
|
|
BitBlt(hDC, rect2.left, rect2.top,
|
|
bm.bmWidth, bm.bmHeight,
|
|
hMemDC, 0, 0, SRCCOPY);
|
|
DeleteDC(hMemDC);
|
|
}
|
|
if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) &&
|
|
((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
|
|
((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) {
|
|
hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT));
|
|
OldBkMode = SetBkMode(hDC, TRANSPARENT);
|
|
if ((lpitem->item_flags & MF_DISABLED) == MF_DISABLED)
|
|
OldTextColor = SetTextColor(hDC, 0x00C0C0C0L);
|
|
else {
|
|
if ((lpitem->item_flags & MF_HILITE) == MF_HILITE)
|
|
OldTextColor = SetTextColor(hDC, 0x00FFFFFFL);
|
|
else
|
|
OldTextColor = SetTextColor(hDC, 0x00000000L);
|
|
}
|
|
if ((lpitem->item_flags & MF_HILITE) == MF_HILITE)
|
|
FillRect(hDC, &rect2, GetStockObject(BLACK_BRUSH));
|
|
#ifdef DEBUG_MENU
|
|
printf("StdDrawMenuBar // rect2.left=%d\n", rect2.left);
|
|
#endif
|
|
DrawText(hDC, lpitem->item_text, -1, &rect2,
|
|
DT_LEFT | DT_VCENTER | DT_SINGLELINE);
|
|
SetTextColor(hDC, OldTextColor);
|
|
SetBkMode(hDC, OldBkMode);
|
|
SelectObject(hDC, hOldFont);
|
|
}
|
|
if (lpitem->next == NULL) goto EndOfPaint;
|
|
lpitem = (LPMENUITEM)lpitem->next;
|
|
}
|
|
EndOfPaint:
|
|
SelectObject(hDC, hOldPen);
|
|
SelectObject(hDC, hOldFont);
|
|
}
|
|
|
|
|
|
|
|
LPMENUITEM MenuFindItem(LPPOPUPMENU lppop, int x, int y, WORD *lpRet)
|
|
{
|
|
LPMENUITEM lpitem;
|
|
UINT i;
|
|
if (lpRet != NULL) *lpRet = 0;
|
|
if (lppop == NULL) return NULL;
|
|
if (lppop->nItems == 0) return NULL;
|
|
lpitem = lppop->firstItem;
|
|
for(i = 0; i < lppop->nItems; i++) {
|
|
if (lpitem == NULL) return NULL;
|
|
#ifdef DEBUG_MENUFINDITEM
|
|
printf("FindItem // left=%d top=%d right=%d bottom=%d\n",
|
|
lpitem->rect.left, lpitem->rect.top,
|
|
lpitem->rect.right, lpitem->rect.bottom);
|
|
#endif
|
|
if (x > lpitem->rect.left && x < lpitem->rect.right &&
|
|
y > lpitem->rect.top && y < lpitem->rect.bottom) {
|
|
if (lpRet != NULL) *lpRet = i;
|
|
return lpitem;
|
|
}
|
|
lpitem = (LPMENUITEM)lpitem->next;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
LPMENUITEM MenuFindItemBySelKey(LPPOPUPMENU lppop, WORD key, WORD *lpRet)
|
|
{
|
|
LPMENUITEM lpitem;
|
|
UINT i;
|
|
if (lppop == NULL) return NULL;
|
|
|
|
if (lppop->nItems == 0) return NULL;
|
|
lpitem = lppop->firstItem;
|
|
for(i = 0; i < lppop->nItems; i++) {
|
|
if (lpitem == NULL) return NULL;
|
|
#ifdef DEBUG_MENUFINDITEM
|
|
printf("FindItemBySelKey // key=%04X lpitem->sel_key=%04X\n",
|
|
key, lpitem->sel_key);
|
|
#endif
|
|
if (key == lpitem->sel_key) {
|
|
if (lpRet != NULL) *lpRet = i;
|
|
return lpitem;
|
|
}
|
|
lpitem = (LPMENUITEM)lpitem->next;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
void PopupMenuCalcSize(HWND hwnd)
|
|
{
|
|
WND *wndPtr;
|
|
LPPOPUPMENU lppop;
|
|
LPMENUITEM lpitem;
|
|
HDC hDC;
|
|
RECT rect;
|
|
HBITMAP hBitMap;
|
|
BITMAP bm;
|
|
HFONT hOldFont;
|
|
UINT i, OldWidth, TempWidth;
|
|
DWORD dwRet;
|
|
#ifdef DEBUG_MENUCALC
|
|
printf("PopupMenuCalcSize hWnd=%04X !\n", hWnd);
|
|
#endif
|
|
InitStdBitmaps();
|
|
lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
|
|
if (lppop == NULL) return;
|
|
if (lppop->nItems == 0) return;
|
|
hDC = GetDC(hwnd);
|
|
lppop->Width = 20;
|
|
lppop->CheckWidth = lppop->PopWidth = 0;
|
|
hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT));
|
|
CalcAGAIN:
|
|
OldWidth = lppop->Width;
|
|
SetRect(&rect, 1, 1, OldWidth, 0);
|
|
lpitem = lppop->firstItem;
|
|
for(i = 0; i < lppop->nItems; i++) {
|
|
if (lpitem == NULL) break;
|
|
#ifdef DEBUG_MENUCALC
|
|
printf("PopupMenuCalcSize item #%d !\n", i);
|
|
#endif
|
|
rect.right = rect.left + lppop->Width;
|
|
if ((lpitem->item_flags & MF_CHECKED) == MF_CHECKED) {
|
|
if (lpitem->hCheckBit != 0)
|
|
GetObject(lpitem->hCheckBit, sizeof(BITMAP), (LPSTR)&bm);
|
|
else
|
|
GetObject(hStdCheck, sizeof(BITMAP), (LPSTR)&bm);
|
|
lppop->CheckWidth = max(lppop->CheckWidth, bm.bmWidth);
|
|
}
|
|
else {
|
|
if (lpitem->hUnCheckBit != 0) {
|
|
GetObject(lpitem->hUnCheckBit, sizeof(BITMAP), (LPSTR)&bm);
|
|
lppop->CheckWidth = max(lppop->CheckWidth, bm.bmWidth);
|
|
}
|
|
}
|
|
if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
|
|
GetObject(hStdMnArrow, sizeof(BITMAP), (LPSTR)&bm);
|
|
lppop->PopWidth = max(lppop->PopWidth, bm.bmWidth);
|
|
}
|
|
if ((lpitem->item_flags & MF_SEPARATOR) == MF_SEPARATOR) {
|
|
rect.bottom = rect.top + 3;
|
|
}
|
|
if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) {
|
|
hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text);
|
|
GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm);
|
|
rect.bottom = rect.top + bm.bmHeight;
|
|
lppop->Width = max(lppop->Width, bm.bmWidth);
|
|
}
|
|
if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) &&
|
|
((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
|
|
((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) {
|
|
dwRet = GetTextExtent(hDC, (char *)lpitem->item_text,
|
|
strlen((char *)lpitem->item_text));
|
|
rect.bottom = rect.top + HIWORD(dwRet);
|
|
InflateRect(&rect, 0, 2);
|
|
TempWidth = LOWORD(dwRet);
|
|
if (GetShortCutPos(lpitem->item_text) != (WORD)-1)
|
|
TempWidth += 15;
|
|
TempWidth += lppop->CheckWidth;
|
|
TempWidth += lppop->PopWidth;
|
|
lppop->Width = max(lppop->Width, TempWidth);
|
|
}
|
|
CopyRect(&lpitem->rect, &rect);
|
|
rect.top = rect.bottom;
|
|
lpitem = (LPMENUITEM)lpitem->next;
|
|
}
|
|
if (OldWidth < lppop->Width) goto CalcAGAIN;
|
|
lppop->Height = rect.bottom;
|
|
SetRect(&lppop->rect, 1, 1, lppop->Width, lppop->Height);
|
|
#ifdef DEBUG_MENUCALC
|
|
printf("PopupMenuCalcSize w=%d h=%d !\n", lppop->Width, lppop->Height);
|
|
#endif
|
|
SelectObject(hDC, hOldFont);
|
|
ReleaseDC(hwnd, hDC);
|
|
}
|
|
|
|
|
|
|
|
void MenuBarCalcSize(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop)
|
|
{
|
|
LPMENUITEM lpitem;
|
|
LPMENUITEM lpitem2;
|
|
RECT rect;
|
|
HBITMAP hBitMap;
|
|
BITMAP bm;
|
|
HFONT hOldFont;
|
|
UINT i, j;
|
|
UINT OldHeight, LineHeight;
|
|
DWORD dwRet;
|
|
if (lprect == NULL) return;
|
|
if (lppop == NULL) return;
|
|
if (lppop->nItems == 0) return;
|
|
InitStdBitmaps();
|
|
#ifdef DEBUG_MENUCALC
|
|
printf("MenuBarCalcSize left=%d top=%d right=%d bottom=%d !\n",
|
|
lprect->left, lprect->top, lprect->right, lprect->bottom);
|
|
#endif
|
|
hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT));
|
|
lppop->CheckWidth = 0;
|
|
LineHeight = OldHeight = SYSMETRICS_CYMENU + 2;
|
|
SetRect(&rect, lprect->left, lprect->top, 0, lprect->top + LineHeight);
|
|
lpitem2 = lppop->firstItem;
|
|
while (lpitem != NULL) {
|
|
lpitem = lpitem2;
|
|
while(rect.right < lprect->right) {
|
|
if (lpitem == NULL) break;
|
|
rect.right = rect.left;
|
|
if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) {
|
|
hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text);
|
|
GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm);
|
|
rect.right = rect.left + bm.bmWidth;
|
|
LineHeight = max(LineHeight, bm.bmHeight);
|
|
}
|
|
if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) &&
|
|
((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
|
|
((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) {
|
|
dwRet = GetTextExtent(hDC, (char *)lpitem->item_text,
|
|
strlen((char *)lpitem->item_text));
|
|
rect.right = rect.left + LOWORD(dwRet) + 10;
|
|
dwRet = max(SYSMETRICS_CYMENU, (HIWORD(dwRet) + 6));
|
|
LineHeight = max(LineHeight, (WORD)dwRet);
|
|
}
|
|
if ((lpitem->item_flags & MF_CHECKED) == MF_CHECKED) {
|
|
if (lpitem->hCheckBit != 0)
|
|
GetObject(lpitem->hCheckBit, sizeof(BITMAP), (LPSTR)&bm);
|
|
else
|
|
GetObject(hStdCheck, sizeof(BITMAP), (LPSTR)&bm);
|
|
rect.right += bm.bmWidth;
|
|
LineHeight = max(LineHeight, bm.bmHeight);
|
|
}
|
|
else {
|
|
if (lpitem->hUnCheckBit != 0) {
|
|
GetObject(lpitem->hUnCheckBit, sizeof(BITMAP), (LPSTR)&bm);
|
|
rect.right += bm.bmWidth;
|
|
LineHeight = max(LineHeight, bm.bmHeight);
|
|
}
|
|
}
|
|
CopyRect(&lpitem->rect, &rect);
|
|
rect.left = rect.right;
|
|
lpitem = (LPMENUITEM)lpitem->next;
|
|
}
|
|
if (LineHeight == OldHeight) {
|
|
lpitem2 = lpitem;
|
|
LineHeight = OldHeight = SYSMETRICS_CYMENU + 1;
|
|
if (lpitem != NULL)
|
|
SetRect(&rect, lprect->left, rect.bottom,
|
|
0, rect.bottom + LineHeight);
|
|
}
|
|
else {
|
|
OldHeight = LineHeight;
|
|
SetRect(&rect, lprect->left, rect.top, 0, rect.top + LineHeight);
|
|
}
|
|
}
|
|
lppop->Width = lprect->right - lprect->left;
|
|
lppop->Height = rect.bottom - lprect->top;
|
|
lprect->bottom = lprect->top + lppop->Height;
|
|
CopyRect(&lppop->rect, lprect);
|
|
#ifdef DEBUG_MENUCALC
|
|
printf("MenuBarCalcSize w=%d h=%d !\n", lppop->Width, lppop->Height);
|
|
#endif
|
|
SelectObject(hDC, hOldFont);
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
* FindMenuItem
|
|
*/
|
|
LPMENUITEM FindMenuItem(HMENU hMenu, WORD nPos, WORD wFlags)
|
|
{
|
|
LPPOPUPMENU menu;
|
|
LPMENUITEM lpitem;
|
|
int i;
|
|
menu = (LPPOPUPMENU) GlobalLock(hMenu);
|
|
if (menu == NULL) {
|
|
GlobalUnlock(hMenu);
|
|
return FALSE;
|
|
}
|
|
lpitem = menu->firstItem;
|
|
if (wFlags & MF_BYPOSITION) {
|
|
for (i = 0; i < nPos; i++, lpitem = lpitem->next)
|
|
if (lpitem == NULL) return NULL;
|
|
}
|
|
else {
|
|
for (i = 0; i < menu->nItems && lpitem != NULL; i++) {
|
|
if (lpitem->item_id == nPos) return lpitem;
|
|
lpitem = lpitem->next;
|
|
}
|
|
return NULL;
|
|
}
|
|
return lpitem;
|
|
}
|
|
|
|
|
|
LPMENUITEM GetMenuItemPtr(LPPOPUPMENU menu, WORD nPos)
|
|
{
|
|
LPMENUITEM lpitem;
|
|
int i;
|
|
if (menu == NULL) return NULL;
|
|
lpitem = menu->firstItem;
|
|
for (i = 0; i < menu->nItems; i++) {
|
|
if (lpitem == NULL) return NULL;
|
|
if (i == nPos) return(lpitem);
|
|
lpitem = (LPMENUITEM)lpitem->next;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
WORD GetSelectionKey(LPSTR str)
|
|
{
|
|
int i;
|
|
WORD sel_key;
|
|
for (i = 0; i < strlen(str); i++) {
|
|
if (str[i] == '&' && str[i + 1] != '&') {
|
|
sel_key = str[i + 1];
|
|
if (sel_key >= 'a' && sel_key <= 'z') sel_key -= 'a' - 'A';
|
|
#ifdef DEBUG_MENU
|
|
printf("GetSelectionKey // %04X\n", sel_key);
|
|
#endif
|
|
return sel_key;
|
|
}
|
|
}
|
|
#ifdef DEBUG_MENU
|
|
printf("GetSelectionKey NULL \n");
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
LPSTR GetShortCutString(LPSTR str)
|
|
{
|
|
int i;
|
|
LPSTR str2;
|
|
for (i = 0; i < strlen(str); i++) {
|
|
if (str[i] == '\t' && str[i + 1] != '\t') {
|
|
str2 = &str[i + 1];
|
|
#ifdef DEBUG_MENUSHORTCUT
|
|
printf("GetShortCutString // '%s' \n", str2);
|
|
#endif
|
|
return str2;
|
|
}
|
|
}
|
|
#ifdef DEBUG_MENUSHORTCUT
|
|
printf("GetShortCutString NULL \n");
|
|
#endif
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
WORD GetShortCutPos(LPSTR str)
|
|
{
|
|
int i;
|
|
for (i = 0; i < strlen(str); i++) {
|
|
if (str[i] == '\t' && str[i + 1] != '\t') {
|
|
#ifdef DEBUG_MENUSHORTCUT
|
|
printf("GetShortCutPos = %d \n", i);
|
|
#endif
|
|
return i;
|
|
}
|
|
}
|
|
#ifdef DEBUG_MENUSHORTCUT
|
|
printf("GetShortCutString NULL \n");
|
|
#endif
|
|
return -1;
|
|
}
|
|
|
|
|
|
|
|
BOOL HideAllSubPopupMenu(LPPOPUPMENU menu)
|
|
{
|
|
LPPOPUPMENU submenu;
|
|
LPMENUITEM lpitem;
|
|
BOOL someClosed = FALSE;
|
|
int i;
|
|
if (menu == NULL) return;
|
|
lpitem = menu->firstItem;
|
|
for (i = 0; i < menu->nItems; i++) {
|
|
if (lpitem == NULL) return;
|
|
if (lpitem->item_flags & MF_POPUP) {
|
|
submenu = (LPPOPUPMENU) GlobalLock((HMENU)lpitem->item_id);
|
|
if (submenu != NULL) {
|
|
if (IsWindowVisible(submenu->hWnd)) {
|
|
ShowWindow(submenu->hWnd, SW_HIDE);
|
|
someClosed = TRUE;
|
|
}
|
|
GlobalUnlock((HMENU)lpitem->item_id);
|
|
}
|
|
}
|
|
lpitem = (LPMENUITEM)lpitem->next;
|
|
}
|
|
return someClosed;
|
|
}
|
|
|
|
|
|
|
|
|
|
/**********************************************************************
|
|
* ChangeMenu [USER.153]
|
|
*/
|
|
BOOL ChangeMenu(HMENU hMenu, WORD nPos, LPSTR lpNewItem,
|
|
WORD wItemID, WORD wFlags)
|
|
{
|
|
if (wFlags & MF_APPEND)
|
|
return AppendMenu(hMenu, wFlags, wItemID, lpNewItem);
|
|
if (wFlags & MF_DELETE)
|
|
return DeleteMenu(hMenu, wItemID, wFlags);
|
|
if (wFlags & MF_INSERT)
|
|
return InsertMenu(hMenu, nPos, wFlags, wItemID, lpNewItem);
|
|
if (wFlags & MF_CHANGE)
|
|
return ModifyMenu(hMenu, nPos, wFlags, wItemID, lpNewItem);
|
|
if (wFlags & MF_REMOVE)
|
|
return RemoveMenu(hMenu, wItemID, wFlags);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* CheckMenuItem [USER.154]
|
|
*/
|
|
BOOL CheckMenuItem(HMENU hMenu, WORD wItemID, WORD wFlags)
|
|
{
|
|
LPMENUITEM lpitem;
|
|
#ifdef DEBUG_MENU
|
|
printf("CheckMenuItem (%04X, %04X, %04X) !\n", hMenu, wItemID, wFlags);
|
|
#endif
|
|
lpitem = FindMenuItem(hMenu, wItemID, wFlags);
|
|
if (lpitem != NULL) {
|
|
if ((wFlags & MF_CHECKED) == MF_CHECKED)
|
|
lpitem->item_flags |= MF_CHECKED;
|
|
else
|
|
lpitem->item_flags &= ((WORD)-1 ^ MF_CHECKED);
|
|
#ifdef DEBUG_MENU
|
|
printf("CheckMenuItem // Found !\n");
|
|
#endif
|
|
return(TRUE);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* EnableMenuItem [USER.155]
|
|
*/
|
|
BOOL EnableMenuItem(HMENU hMenu, WORD wItemID, WORD wFlags)
|
|
{
|
|
LPMENUITEM lpitem;
|
|
#ifdef DEBUG_MENU
|
|
printf("EnableMenuItem (%04X, %04X, %04X) !\n", hMenu, wItemID, wFlags);
|
|
#endif
|
|
lpitem = FindMenuItem(hMenu, wItemID, wFlags);
|
|
if (lpitem != NULL) {
|
|
if (wFlags && MF_DISABLED)
|
|
lpitem->item_flags |= MF_DISABLED;
|
|
else
|
|
lpitem->item_flags &= ((WORD)-1 ^ MF_DISABLED);
|
|
#ifdef DEBUG_MENU
|
|
printf("EnableMenuItem // Found !\n");
|
|
#endif
|
|
return(TRUE);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* GetMenuString [USER.161]
|
|
*/
|
|
int GetMenuString(HMENU hMenu, WORD wItemID,
|
|
LPSTR str, short nMaxSiz, WORD wFlags)
|
|
{
|
|
LPMENUITEM lpitem;
|
|
int maxsiz;
|
|
#ifdef DEBUG_MENU
|
|
printf("GetMenuString(%04X, %04X, %08X, %d, %04X);\n",
|
|
hMenu, wItemID, str, nMaxSiz, wFlags);
|
|
#endif
|
|
if (str == NULL) return FALSE;
|
|
lpitem = FindMenuItem(hMenu, wItemID, wFlags);
|
|
if (lpitem != NULL) {
|
|
if (lpitem->item_text != NULL) {
|
|
maxsiz = min(nMaxSiz - 1, strlen(lpitem->item_text));
|
|
strncpy(str, lpitem->item_text, maxsiz + 1);
|
|
}
|
|
else
|
|
maxsiz = 0;
|
|
#ifdef DEBUG_MENU
|
|
printf("GetMenuString // Found !\n");
|
|
#endif
|
|
return maxsiz;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* HiliteMenuItem [USER.162]
|
|
*/
|
|
BOOL HiliteMenuItem(HWND hWnd, HMENU hMenu, WORD wItemID, WORD wHilite)
|
|
{
|
|
LPPOPUPMENU menu;
|
|
LPMENUITEM lpitem;
|
|
#ifdef DEBUG_MENU
|
|
printf("HiliteMenuItem(%04X, %04X, %04X, %04X);\n",
|
|
hWnd, hMenu, wItemID, wHilite);
|
|
#endif
|
|
menu = (LPPOPUPMENU) GlobalLock(hMenu);
|
|
if (menu == NULL) return FALSE;
|
|
lpitem = FindMenuItem(hMenu, wItemID, wHilite);
|
|
if (lpitem == NULL) return FALSE;
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* GetMenuState [USER.250]
|
|
*/
|
|
WORD GetMenuState(HMENU hMenu, WORD wItemID, WORD wFlags)
|
|
{
|
|
LPPOPUPMENU menu;
|
|
LPMENUITEM lpitem;
|
|
#ifdef DEBUG_MENU
|
|
printf("GetMenuState(%04X, %04X, %04X);\n", hMenu, wItemID, wFlags);
|
|
#endif
|
|
menu = (LPPOPUPMENU) GlobalLock(hMenu);
|
|
if (menu == NULL) return -1;
|
|
lpitem = FindMenuItem(hMenu, wItemID, wFlags);
|
|
if (lpitem == NULL) return -1;
|
|
return lpitem->item_flags;
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* GetMenuItemCount [USER.263]
|
|
*/
|
|
WORD GetMenuItemCount(HMENU hMenu)
|
|
{
|
|
LPPOPUPMENU menu;
|
|
#ifdef DEBUG_MENU
|
|
printf("GetMenuItemCount(%04X);\n", hMenu);
|
|
#endif
|
|
menu = (LPPOPUPMENU) GlobalLock(hMenu);
|
|
if (menu == NULL) return (WORD)-1;
|
|
#ifdef DEBUG_MENU
|
|
printf("GetMenuItemCount(%04X) return %d \n", hMenu, menu->nItems);
|
|
#endif
|
|
return menu->nItems;
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* GetMenuItemID [USER.264]
|
|
*/
|
|
WORD GetMenuItemID(HMENU hMenu, int nPos)
|
|
{
|
|
WORD i;
|
|
LPPOPUPMENU menu;
|
|
LPMENUITEM lpitem;
|
|
printf("GetMenuItemID(%04X, %d);\n", hMenu, nPos);
|
|
menu = (LPPOPUPMENU) GlobalLock(hMenu);
|
|
if (menu == NULL) return -1;
|
|
lpitem = menu->firstItem;
|
|
for (i = 0; i < menu->nItems; i++) {
|
|
if (lpitem == NULL) break;
|
|
if (i == nPos) {
|
|
#ifdef DEBUG_MENU
|
|
printf("GetMenuItemID // Found !\n");
|
|
#endif
|
|
return lpitem->item_id;
|
|
}
|
|
lpitem = (LPMENUITEM)lpitem->next;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* InsertMenu [USER.410]
|
|
*/
|
|
BOOL InsertMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewItem)
|
|
{
|
|
LPPOPUPMENU menu;
|
|
HANDLE hNewItem;
|
|
LPMENUITEM lpitem, lpitem2;
|
|
#ifdef DEBUG_MENU
|
|
if ((wFlags & (MF_BITMAP | MF_SEPARATOR | MF_MENUBREAK | MF_OWNERDRAW)) == 0)
|
|
printf("InsertMenu (%04X, %04X, %04X, '%s') !\n",
|
|
hMenu, wFlags, wItemID, lpNewItem);
|
|
else
|
|
printf("InsertMenu (%04X, %04X, %04X, %04X, %08X) !\n",
|
|
hMenu, nPos, wFlags, wItemID, lpNewItem);
|
|
#endif
|
|
menu = (LPPOPUPMENU) GlobalLock(hMenu);
|
|
if (menu == NULL) return FALSE;
|
|
lpitem = FindMenuItem(hMenu, nPos, wFlags);
|
|
if (lpitem == NULL) lpitem = menu->firstItem;
|
|
hNewItem = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM));
|
|
if (hNewItem == 0) {
|
|
GlobalUnlock(hMenu);
|
|
return FALSE;
|
|
}
|
|
lpitem2 = (LPMENUITEM)GlobalLock(hNewItem);
|
|
if (lpitem2 == NULL) {
|
|
GlobalFree(hNewItem);
|
|
GlobalUnlock(hMenu);
|
|
return FALSE;
|
|
}
|
|
lpitem2->hItem = hNewItem;
|
|
lpitem2->item_flags = wFlags;
|
|
lpitem2->item_id = wItemID;
|
|
if (!(wFlags & (MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK |
|
|
MF_MENUBREAK | MF_SEPARATOR))) {
|
|
lpitem2->hText = GlobalAlloc(GMEM_MOVEABLE, strlen(lpNewItem) + 1);
|
|
lpitem2->item_text = GlobalLock(lpitem2->hText);
|
|
if (lpitem2->item_text != NULL)
|
|
strcpy(lpitem2->item_text, lpNewItem);
|
|
else {
|
|
printf("InsertMenu // Bad Alloc !\n");
|
|
return FALSE;
|
|
}
|
|
lpitem2->sel_key = GetSelectionKey(lpitem2->item_text);
|
|
}
|
|
else {
|
|
lpitem2->item_text = lpNewItem;
|
|
}
|
|
if (lpitem == NULL) {
|
|
menu->firstItem = lpitem2;
|
|
lpitem2->prev = NULL;
|
|
lpitem2->next = NULL;
|
|
}
|
|
else {
|
|
lpitem2->prev = lpitem;
|
|
lpitem2->next = lpitem->next;
|
|
if (lpitem2->next != NULL) lpitem2->next->prev = lpitem2;
|
|
lpitem->next = lpitem2;
|
|
}
|
|
menu->nItems++;
|
|
GlobalUnlock(hMenu);
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* AppendMenu [USER.411]
|
|
*/
|
|
BOOL AppendMenu(HMENU hMenu, WORD wFlags, WORD wItemID, LPSTR lpNewItem)
|
|
{
|
|
LPPOPUPMENU menu;
|
|
HANDLE hNewItem;
|
|
LPMENUITEM lpitem, lpitem2;
|
|
#ifdef DEBUG_MENU
|
|
if ((wFlags & (MF_BITMAP | MF_SEPARATOR | MF_MENUBREAK | MF_OWNERDRAW)) == 0)
|
|
printf("AppendMenu (%04X, %04X, %04X, '%s') !\n",
|
|
hMenu, wFlags, wItemID, lpNewItem);
|
|
else
|
|
printf("AppendMenu (%04X, %04X, %04X, %08X) !\n",
|
|
hMenu, wFlags, wItemID, lpNewItem);
|
|
#endif
|
|
menu = (LPPOPUPMENU) GlobalLock(hMenu);
|
|
if (menu == NULL) return FALSE;
|
|
lpitem = menu->firstItem;
|
|
if (lpitem != NULL) {
|
|
while (lpitem->next != NULL) {
|
|
lpitem = (LPMENUITEM)lpitem->next;
|
|
}
|
|
}
|
|
hNewItem = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM));
|
|
if (hNewItem == 0) {
|
|
GlobalUnlock(hMenu);
|
|
return FALSE;
|
|
}
|
|
lpitem2 = (LPMENUITEM)GlobalLock(hNewItem);
|
|
lpitem2->hItem = hNewItem;
|
|
if (lpitem2 == NULL) {
|
|
GlobalFree(hNewItem);
|
|
GlobalUnlock(hMenu);
|
|
return FALSE;
|
|
}
|
|
lpitem2->item_flags = wFlags;
|
|
lpitem2->item_id = wItemID;
|
|
if (!(wFlags & (MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK |
|
|
MF_MENUBREAK | MF_SEPARATOR))) {
|
|
lpitem2->hText = GlobalAlloc(GMEM_MOVEABLE, strlen(lpNewItem) + 1);
|
|
lpitem2->item_text = GlobalLock(lpitem2->hText);
|
|
if (lpitem2->item_text != NULL)
|
|
strcpy(lpitem2->item_text, lpNewItem);
|
|
else {
|
|
printf("AppendMenu // Bad Alloc !\n");
|
|
return FALSE;
|
|
}
|
|
lpitem2->sel_key = GetSelectionKey(lpitem2->item_text);
|
|
}
|
|
else {
|
|
lpitem2->item_text = lpNewItem;
|
|
}
|
|
if (lpitem == NULL)
|
|
menu->firstItem = lpitem2;
|
|
else
|
|
lpitem->next = lpitem2;
|
|
lpitem2->prev = lpitem;
|
|
lpitem2->next = NULL;
|
|
lpitem2->hCheckBit = (HBITMAP)NULL;
|
|
lpitem2->hUnCheckBit = (HBITMAP)NULL;
|
|
menu->nItems++;
|
|
GlobalUnlock(hMenu);
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* RemoveMenu [USER.412]
|
|
*/
|
|
BOOL RemoveMenu(HMENU hMenu, WORD nPos, WORD wFlags)
|
|
{
|
|
LPPOPUPMENU menu;
|
|
LPMENUITEM lpitem;
|
|
int i;
|
|
#ifdef DEBUG_MENU
|
|
printf("RemoveMenu (%04X, %04X, %04X) !\n", hMenu, nPos, wFlags);
|
|
#endif
|
|
menu = (LPPOPUPMENU) GlobalLock(hMenu);
|
|
if (menu == NULL) return FALSE;
|
|
lpitem = menu->firstItem;
|
|
for (i = 0; i < menu->nItems; i++) {
|
|
if (lpitem == NULL) break;
|
|
if (i == nPos) {
|
|
lpitem->prev->next = lpitem->next;
|
|
lpitem->next->prev = lpitem->prev;
|
|
if (!(lpitem->item_flags &
|
|
(MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK |
|
|
MF_MENUBREAK | MF_SEPARATOR))) {
|
|
GlobalUnlock(lpitem->hText);
|
|
GlobalFree(lpitem->hText);
|
|
}
|
|
GlobalFree(lpitem->hItem);
|
|
GlobalUnlock(hMenu);
|
|
return TRUE;
|
|
}
|
|
lpitem = (LPMENUITEM)lpitem->next;
|
|
printf("RemoveMenu // during loop items !\n");
|
|
}
|
|
printf("RemoveMenu // after loop items !\n");
|
|
GlobalUnlock(hMenu);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* DeleteMenu [USER.413]
|
|
*/
|
|
BOOL DeleteMenu(HMENU hMenu, WORD nPos, WORD wFlags)
|
|
{
|
|
LPPOPUPMENU menu;
|
|
LPMENUITEM lpitem;
|
|
int i;
|
|
#ifdef DEBUG_MENU
|
|
printf("DeleteMenu (%04X, %04X, %04X) !\n", hMenu, nPos, wFlags);
|
|
#endif
|
|
menu = (LPPOPUPMENU) GlobalLock(hMenu);
|
|
if (menu == NULL) {
|
|
GlobalUnlock(hMenu);
|
|
return FALSE;
|
|
}
|
|
lpitem = FindMenuItem(hMenu, nPos, wFlags);
|
|
if (lpitem != NULL) {
|
|
if ((lpitem->item_flags & MF_POPUP) == MF_POPUP)
|
|
DestroyMenu((HMENU)lpitem->item_id);
|
|
if (!(lpitem->item_flags &
|
|
(MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK |
|
|
MF_MENUBREAK | MF_SEPARATOR))) {
|
|
GlobalUnlock(lpitem->hText);
|
|
GlobalFree(lpitem->hText);
|
|
}
|
|
if (lpitem->prev) lpitem->prev->next = lpitem->next;
|
|
if (lpitem->next) lpitem->next->prev = lpitem->prev;
|
|
GlobalFree(lpitem->hItem);
|
|
GlobalUnlock(hMenu);
|
|
return TRUE;
|
|
}
|
|
GlobalUnlock(hMenu);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* ModifyMenu [USER.414]
|
|
*/
|
|
BOOL ModifyMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewItem)
|
|
{
|
|
LPPOPUPMENU menu;
|
|
LPMENUITEM lpitem;
|
|
int i;
|
|
#ifdef DEBUG_MENU
|
|
if ((wFlags & (MF_BITMAP | MF_SEPARATOR | MF_MENUBREAK | MF_OWNERDRAW)) == 0)
|
|
printf("ModifyMenu (%04X, %04X, %04X, %04X, '%s') !\n",
|
|
hMenu, nPos, wFlags, wItemID, lpNewItem);
|
|
else
|
|
printf("ModifyMenu (%04X, %04X, %04X, %04X, %08X) !\n",
|
|
hMenu, nPos, wFlags, wItemID, lpNewItem);
|
|
#endif
|
|
menu = (LPPOPUPMENU) GlobalLock(hMenu);
|
|
if (menu == NULL) return FALSE;
|
|
lpitem = menu->firstItem;
|
|
for (i = 0; i < menu->nItems; i++) {
|
|
if (lpitem == NULL) break;
|
|
if (i == nPos) {
|
|
lpitem->item_flags = wFlags;
|
|
lpitem->item_id = wItemID;
|
|
if (!(lpitem->item_flags &
|
|
(MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK |
|
|
MF_MENUBREAK | MF_SEPARATOR))) {
|
|
GlobalUnlock(lpitem->hText);
|
|
GlobalFree(lpitem->hText);
|
|
lpitem->hText = GlobalAlloc(GMEM_MOVEABLE, strlen(lpNewItem) + 1);
|
|
lpitem->item_text = GlobalLock(lpitem->hText);
|
|
printf("ModifyMenu %08X %08X '%s') !\n",
|
|
lpitem->item_text, lpNewItem, lpNewItem);
|
|
if (lpitem->item_text != NULL)
|
|
strcpy(lpitem->item_text, lpNewItem);
|
|
else
|
|
printf("ModifyMenu // Bad Alloc !\n");
|
|
}
|
|
else
|
|
lpitem->item_text = lpNewItem;
|
|
GlobalUnlock(hMenu);
|
|
return(TRUE);
|
|
}
|
|
lpitem = (LPMENUITEM)lpitem->next;
|
|
}
|
|
GlobalUnlock(hMenu);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* CreatePopupMenu [USER.415]
|
|
*/
|
|
HMENU CreatePopupMenu()
|
|
{
|
|
HANDLE hItem;
|
|
HMENU hMenu;
|
|
LPPOPUPMENU menu;
|
|
#ifdef DEBUG_MENU
|
|
printf("CreatePopupMenu !\n");
|
|
#endif
|
|
hMenu = GlobalAlloc(GMEM_MOVEABLE, sizeof(POPUPMENU));
|
|
menu = (LPPOPUPMENU) GlobalLock(hMenu);
|
|
if (menu == NULL) {
|
|
GlobalFree(hMenu);
|
|
return 0;
|
|
}
|
|
menu->nItems = 0;
|
|
menu->firstItem = NULL;
|
|
menu->ownerWnd = 0;
|
|
menu->hWndPrev = 0;
|
|
menu->hWnd = 0;
|
|
menu->hWndParent = 0;
|
|
menu->MouseFlags = 0;
|
|
menu->BarFlag = FALSE;
|
|
menu->SysFlag = FALSE;
|
|
menu->ChildFlag = TRUE;
|
|
menu->Width = 100;
|
|
menu->Height = 0;
|
|
GlobalUnlock(hMenu);
|
|
#ifdef DEBUG_MENU
|
|
printf("CreatePopupMenu // return %04X\n", hMenu);
|
|
#endif
|
|
return hMenu;
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* TrackPopupMenu [USER.416]
|
|
*/
|
|
BOOL TrackPopupMenu(HMENU hMenu, WORD wFlags, short x, short y,
|
|
short nReserved, HWND hWnd, LPRECT lpRect)
|
|
{
|
|
WND *wndPtr;
|
|
LPPOPUPMENU lppop;
|
|
RECT rect;
|
|
#ifdef DEBUG_MENU
|
|
printf("TrackPopupMenu (%04X, %04X, %d, %d, %04X, %04X, %08X) !\n",
|
|
hMenu, wFlags, x, y, nReserved, hWnd, lpRect);
|
|
#endif
|
|
lppop = (LPPOPUPMENU) GlobalLock(hMenu);
|
|
if (lppop == NULL) {
|
|
printf("TrackPopupMenu // Bad menu handle %04X !\n", hMenu);
|
|
return FALSE;
|
|
}
|
|
wndPtr = WIN_FindWndPtr(hWnd);
|
|
if (wndPtr == NULL) {
|
|
printf("TrackPopupMenu // Bad window handle %04X !\n", hWnd);
|
|
return FALSE;
|
|
}
|
|
lppop->ownerWnd = hWnd;
|
|
lppop->hWndPrev = GetFocus();
|
|
if (lppop->hWnd == (HWND)NULL) {
|
|
lppop->hWnd = CreateWindow("POPUPMENU", "", WS_POPUP | WS_VISIBLE,
|
|
x, y, lppop->Width, lppop->Height, (HWND)NULL, 0,
|
|
wndPtr->hInstance, (LPSTR)lppop);
|
|
if (lppop->hWnd == 0) {
|
|
printf("TrackPopupMenu // Can't create PopupMenu window !\n");
|
|
return FALSE;
|
|
}
|
|
}
|
|
else {
|
|
ShowWindow(lppop->hWnd, SW_SHOW);
|
|
}
|
|
if (!lppop->BarFlag) {
|
|
PopupMenuCalcSize(lppop->hWnd);
|
|
#ifdef DEBUG_MENU
|
|
printf("TrackPopupMenu // x=%d y=%d Width=%d Height=%d\n",
|
|
x, y, lppop->Width, lppop->Height);
|
|
#endif
|
|
SetWindowPos(lppop->hWnd, 0, x, y, lppop->Width + 2, lppop->Height,
|
|
SWP_NOZORDER);
|
|
}
|
|
SetFocus(lppop->hWnd);
|
|
if (!MenuHasFocus) {
|
|
#ifdef DEBUG_MENU
|
|
printf("TrackPopupMenu // before MenuFocusLoop !\n");
|
|
#endif
|
|
MenuFocusLoop(hWnd, NULL);
|
|
#ifdef DEBUG_MENU
|
|
printf("TrackPopupMenu // after MenuFocusLoop !\n");
|
|
#endif
|
|
}
|
|
GlobalUnlock(hMenu);
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL ActivateMenuBarFocus(HWND hWnd)
|
|
{
|
|
WND *wndPtr;
|
|
LPPOPUPMENU lpmenu;
|
|
BOOL bRet;
|
|
MSG msg;
|
|
if (MenuHasFocus) return FALSE;
|
|
wndPtr = WIN_FindWndPtr(hWnd);
|
|
if (wndPtr == NULL) return FALSE;
|
|
#ifdef DEBUG_MENU
|
|
printf("ActivateMenuBarFocus (%04X) !\n", hWnd);
|
|
#endif
|
|
while((wndPtr->dwStyle & WS_CHILD) == WS_CHILD) {
|
|
hWnd = GetParent(hWnd);
|
|
printf("ActivateMenuBarFocus // next Parent=%04X !\n", hWnd);
|
|
wndPtr = WIN_FindWndPtr(hWnd);
|
|
if (wndPtr == NULL) return FALSE;
|
|
}
|
|
if ((wndPtr->dwStyle & WS_CHILD) == 0 && wndPtr->wIDmenu != 0) {
|
|
lpmenu = (LPPOPUPMENU) GlobalLock(wndPtr->wIDmenu);
|
|
if (lpmenu == NULL) return FALSE;
|
|
lpmenu->hWndPrev = GetFocus();
|
|
SetFocus(hWnd);
|
|
MenuItemSelect(hWnd, lpmenu, 0);
|
|
bRet = MenuFocusLoop(hWnd, lpmenu);
|
|
GlobalUnlock(wndPtr->wIDmenu);
|
|
return bRet;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
BOOL MenuFocusLoop(HWND hWnd, LPPOPUPMENU lpmenu)
|
|
{
|
|
MSG msg;
|
|
#ifdef DEBUG_MENU
|
|
printf("Enter in Menu Focus Loop !\n");
|
|
#endif
|
|
MenuHasFocus = TRUE;
|
|
while(TRUE) {
|
|
if (!MenuHasFocus) break;
|
|
if (!GetMessage(&msg, (HWND)NULL, 0, 0)) break;
|
|
TranslateMessage(&msg);
|
|
if (hWnd == msg.hwnd && lpmenu != NULL) {
|
|
if ((msg.message == WM_SYSKEYDOWN && msg.wParam == VK_MENU) ||
|
|
(msg.message == WM_CHAR && msg.wParam == VK_ESCAPE)) {
|
|
HideAllSubPopupMenu(lpmenu);
|
|
break;
|
|
}
|
|
ScreenToClient(hWnd, &msg.pt);
|
|
msg.pt.y += lpmenu->rect.bottom;
|
|
switch(msg.message) {
|
|
case WM_LBUTTONDOWN:
|
|
case WM_NCLBUTTONDOWN:
|
|
SetCapture(hWnd);
|
|
MenuButtonDown(hWnd, lpmenu, msg.pt.x, msg.pt.y);
|
|
break;
|
|
case WM_LBUTTONUP:
|
|
case WM_NCLBUTTONUP:
|
|
MenuButtonUp(hWnd, lpmenu, msg.pt.x, msg.pt.y);
|
|
ReleaseCapture();
|
|
break;
|
|
case WM_MOUSEMOVE:
|
|
case WM_NCMOUSEMOVE:
|
|
MenuMouseMove(hWnd, lpmenu, msg.wParam, msg.pt.x, msg.pt.y);
|
|
break;
|
|
case WM_KEYDOWN:
|
|
case WM_KEYUP:
|
|
case WM_CHAR:
|
|
PopupMenuWndProc(hWnd, msg.message, msg.wParam, msg.lParam);
|
|
default:
|
|
DispatchMessage(&msg);
|
|
}
|
|
}
|
|
else
|
|
DispatchMessage(&msg);
|
|
}
|
|
EndOfFocus:
|
|
MenuHasFocus = FALSE;
|
|
if (lpmenu != NULL) MenuItemSelect(hWnd, lpmenu, -1);
|
|
#ifdef DEBUG_MENU
|
|
printf("End of Menu Focus Loop !\n");
|
|
#endif
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* NC_TrackSysMenu [Internal]
|
|
*/
|
|
void NC_TrackSysMenu(HWND hWnd)
|
|
{
|
|
RECT rect;
|
|
LPPOPUPMENU lpsys;
|
|
WND *wndPtr = WIN_FindWndPtr(hWnd);
|
|
#ifdef DEBUG_MENU
|
|
printf("NC_TrackSysMenu hWnd=%04X !\n", hWnd);
|
|
#endif
|
|
if (!wndPtr) return;
|
|
lpsys = (LPPOPUPMENU)GlobalLock(wndPtr->hSysMenu);
|
|
#ifdef DEBUG_MENU
|
|
printf("NC_TrackSysMenu wndPtr->hSysMenu=%04X !\n", wndPtr->hSysMenu);
|
|
#endif
|
|
if (lpsys == NULL) return;
|
|
#ifdef DEBUG_MENU
|
|
printf("NC_TrackSysMenu wndPtr->hSysMenu=%04X !\n", wndPtr->hSysMenu);
|
|
#endif
|
|
lpsys->BarFlag = FALSE;
|
|
lpsys->SysFlag = TRUE;
|
|
lpsys->ChildFlag = FALSE;
|
|
lpsys->hWndParent = hWnd;
|
|
if (!IsWindowVisible(lpsys->hWnd)) {
|
|
GetWindowRect(hWnd, &rect);
|
|
#ifdef DEBUG_MENU
|
|
printf("NC_TrackSysMenu lpsys->hWnd=%04X !\n", lpsys->hWnd);
|
|
#endif
|
|
if (MenuHasFocus) {
|
|
TrackPopupMenu(wndPtr->hSysMenu, TPM_LEFTBUTTON,
|
|
rect.left, rect.top + SYSMETRICS_CYSIZE,
|
|
0, hWnd, (LPRECT)NULL);
|
|
}
|
|
else {
|
|
MenuHasFocus = TRUE;
|
|
TrackPopupMenu(wndPtr->hSysMenu, TPM_LEFTBUTTON,
|
|
rect.left, rect.top + SYSMETRICS_CYSIZE,
|
|
0, hWnd, (LPRECT)NULL);
|
|
MenuHasFocus = FALSE;
|
|
#ifdef DEBUG_MENU
|
|
printf("NC_TrackSysMenu // before MenuFocusLoop !\n");
|
|
#endif
|
|
MenuFocusLoop(hWnd, NULL);
|
|
#ifdef DEBUG_MENU
|
|
printf("NC_TrackSysMenu // after MenuFocusLoop !\n");
|
|
#endif
|
|
}
|
|
}
|
|
else {
|
|
ShowWindow(lpsys->hWnd, SW_HIDE);
|
|
}
|
|
GlobalUnlock(wndPtr->hSysMenu);
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* GetMenuCheckMarkDimensions [USER.417]
|
|
*/
|
|
DWORD GetMenuCheckMarkDimensions()
|
|
{
|
|
BITMAP bm;
|
|
InitStdBitmaps();
|
|
GetObject(hStdCheck, sizeof(BITMAP), (LPSTR)&bm);
|
|
return MAKELONG(bm.bmWidth, bm.bmHeight);
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* SetMenuItemBitmaps [USER.418]
|
|
*/
|
|
BOOL SetMenuItemBitmaps(HMENU hMenu, WORD nPos, WORD wFlags,
|
|
HBITMAP hNewCheck, HBITMAP hNewUnCheck)
|
|
{
|
|
LPPOPUPMENU menu;
|
|
LPMENUITEM lpitem;
|
|
int i;
|
|
#ifdef DEBUG_MENU
|
|
printf("SetMenuItemBitmaps (%04X, %04X, %04X, %04X, %08X) !\n",
|
|
hMenu, nPos, wFlags, hNewCheck, hNewUnCheck);
|
|
#endif
|
|
menu = (LPPOPUPMENU) GlobalLock(hMenu);
|
|
if (menu == NULL) return FALSE;
|
|
lpitem = menu->firstItem;
|
|
for (i = 0; i < menu->nItems; i++) {
|
|
if (lpitem == NULL) break;
|
|
if (i == nPos) {
|
|
lpitem->hCheckBit = hNewCheck;
|
|
lpitem->hUnCheckBit = hNewUnCheck;
|
|
GlobalUnlock(hMenu);
|
|
return TRUE;
|
|
}
|
|
lpitem = (LPMENUITEM)lpitem->next;
|
|
}
|
|
GlobalUnlock(hMenu);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* CreateMenu [USER.151]
|
|
*/
|
|
HMENU CreateMenu()
|
|
{
|
|
HANDLE hItem;
|
|
HMENU hMenu;
|
|
LPPOPUPMENU menu;
|
|
#ifdef DEBUG_MENU
|
|
printf("CreateMenu !\n");
|
|
#endif
|
|
hMenu = GlobalAlloc(GMEM_MOVEABLE, sizeof(POPUPMENU));
|
|
menu = (LPPOPUPMENU) GlobalLock(hMenu);
|
|
if (menu == NULL) {
|
|
GlobalFree(hMenu);
|
|
return 0;
|
|
}
|
|
menu->nItems = 0;
|
|
menu->firstItem = NULL;
|
|
menu->hWndPrev = 0;
|
|
menu->ownerWnd = 0;
|
|
menu->hWnd = 0;
|
|
menu->hWndParent = 0;
|
|
menu->MouseFlags = 0;
|
|
menu->BarFlag = TRUE;
|
|
menu->SysFlag = FALSE;
|
|
menu->ChildFlag = TRUE;
|
|
menu->Width = 100;
|
|
menu->Height = 0;
|
|
GlobalUnlock(hMenu);
|
|
#ifdef DEBUG_MENU
|
|
printf("CreateMenu // return %04X\n", hMenu);
|
|
#endif
|
|
return hMenu;
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* DestroyMenu [USER.152]
|
|
*/
|
|
BOOL DestroyMenu(HMENU hMenu)
|
|
{
|
|
LPPOPUPMENU lppop;
|
|
LPMENUITEM lpitem, lpitem2;
|
|
#ifdef DEBUG_MENU
|
|
printf("DestroyMenu (%04X) !\n", hMenu);
|
|
#endif
|
|
if (hMenu == 0) return FALSE;
|
|
lppop = (LPPOPUPMENU) GlobalLock(hMenu);
|
|
if (lppop == NULL) return FALSE;
|
|
if (lppop->hWnd) DestroyWindow (lppop->hWnd);
|
|
lpitem = lppop->firstItem;
|
|
while (lpitem != NULL) {
|
|
#ifdef DEBUG_MENU
|
|
printf("DestroyMenu (%04X) // during loop items !\n", hMenu);
|
|
#endif
|
|
if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
|
|
DestroyMenu((HMENU)lpitem->item_id);
|
|
}
|
|
lpitem = (LPMENUITEM)lpitem->next;
|
|
}
|
|
GlobalUnlock(hMenu);
|
|
GlobalFree(hMenu);
|
|
#ifdef DEBUG_MENU
|
|
printf("DestroyMenu (%04X) // End !\n", hMenu);
|
|
#endif
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* LoadMenu [USER.150]
|
|
*/
|
|
HMENU LoadMenu(HINSTANCE instance, char *menu_name)
|
|
{
|
|
HMENU hMenu;
|
|
HANDLE hMenu_desc;
|
|
MENU_HEADER *menu_desc;
|
|
#ifdef DEBUG_MENU
|
|
if ((LONG)menu_name & 0xFFFF0000L)
|
|
printf("LoadMenu: instance %02x, menu '%s'\n", instance, menu_name);
|
|
else
|
|
printf("LoadMenu: instance %02x, menu '%04X'\n", instance, menu_name);
|
|
#endif
|
|
if (instance == (HANDLE)NULL) instance = hSysRes;
|
|
if (menu_name == NULL ||
|
|
(hMenu_desc = RSC_LoadMenu(instance, menu_name)) == 0 ||
|
|
(menu_desc = (MENU_HEADER *) GlobalLock(hMenu_desc)) == NULL) {
|
|
return 0;
|
|
}
|
|
hMenu = LoadMenuIndirect((LPSTR)menu_desc);
|
|
return hMenu;
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* GetSystemMenu [USER.156]
|
|
*/
|
|
HMENU GetSystemMenu(HWND hWnd, BOOL bRevert)
|
|
{
|
|
WND *wndPtr;
|
|
wndPtr = WIN_FindWndPtr(hWnd);
|
|
if (!bRevert) {
|
|
return wndPtr->hSysMenu;
|
|
}
|
|
else {
|
|
DestroyMenu(wndPtr->hSysMenu);
|
|
wndPtr->hSysMenu = CopySysMenu();
|
|
}
|
|
return wndPtr->hSysMenu;
|
|
}
|
|
|
|
/**********************************************************************
|
|
* SetSystemMenu [USER.280]
|
|
*/
|
|
BOOL SetSystemMenu(HWND hWnd, HMENU newHmenu)
|
|
{
|
|
WND *wndPtr;
|
|
|
|
if ((wndPtr = WIN_FindWndPtr(hWnd)) != NULL)
|
|
wndPtr->hSysMenu = newHmenu;
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* GetMenu [USER.157]
|
|
*/
|
|
HMENU GetMenu(HWND hWnd)
|
|
{
|
|
WND * wndPtr = WIN_FindWndPtr(hWnd);
|
|
if (wndPtr == NULL) return 0;
|
|
return wndPtr->wIDmenu;
|
|
}
|
|
|
|
/**********************************************************************
|
|
* SetMenu [USER.158]
|
|
*/
|
|
BOOL SetMenu(HWND hWnd, HMENU hMenu)
|
|
{
|
|
RECT rect;
|
|
LPPOPUPMENU lpmenu;
|
|
WORD flags;
|
|
WND * wndPtr = WIN_FindWndPtr(hWnd);
|
|
if (wndPtr == NULL) {
|
|
printf("SetMenu(%04X, %04X) // Bad window handle !\n", hWnd, hMenu);
|
|
return FALSE;
|
|
}
|
|
#ifdef DEBUG_MENU
|
|
printf("SetMenu(%04X, %04X);\n", hWnd, hMenu);
|
|
#endif
|
|
if (GetCapture() == hWnd) ReleaseCapture();
|
|
if (wndPtr->window != 0) {
|
|
flags = SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED;
|
|
/* if (!IsWindowVisible(hWnd)) flags |= SWP_NOREDRAW; */
|
|
flags |= SWP_NOREDRAW;
|
|
if (hMenu == 0) {
|
|
wndPtr->wIDmenu = hMenu;
|
|
printf("SetMenu(%04X, %04X) // Menu removed, need NC recalc!\n", hWnd, hMenu);
|
|
SetWindowPos(hWnd, 0, 0, 0, 0, 0, flags);
|
|
return TRUE;
|
|
}
|
|
wndPtr->wIDmenu = hMenu;
|
|
SetWindowPos(hWnd, 0, 0, 0, 0, 0, flags);
|
|
}
|
|
lpmenu = (LPPOPUPMENU) GlobalLock(hMenu);
|
|
if (lpmenu == NULL) {
|
|
printf("SetMenu(%04X, %04X) // Bad menu handle !\n", hWnd, hMenu);
|
|
return FALSE;
|
|
}
|
|
lpmenu->ownerWnd = hWnd;
|
|
ResetHiliteFlags(lpmenu);
|
|
GlobalUnlock(hMenu);
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
/**********************************************************************
|
|
* GetSubMenu [USER.159]
|
|
*/
|
|
HMENU GetSubMenu(HMENU hMenu, short nPos)
|
|
{
|
|
HMENU hSubMenu;
|
|
LPPOPUPMENU lppop;
|
|
LPMENUITEM lpitem;
|
|
int i;
|
|
#ifdef DEBUG_MENU
|
|
printf("GetSubMenu (%04X, %04X) !\n", hMenu, nPos);
|
|
#endif
|
|
if (hMenu == 0) return 0;
|
|
lppop = (LPPOPUPMENU) GlobalLock(hMenu);
|
|
if (lppop == NULL) return 0;
|
|
lpitem = lppop->firstItem;
|
|
for (i = 0; i < lppop->nItems; i++) {
|
|
if (lpitem == NULL) break;
|
|
if (i == nPos) {
|
|
#ifdef DEBUG_MENU
|
|
printf(" found %04x\n", lpitem->item_id);
|
|
#endif
|
|
if (lpitem->item_flags & MF_POPUP)
|
|
return lpitem->item_id;
|
|
else
|
|
return 0;
|
|
}
|
|
lpitem = (LPMENUITEM)lpitem->next;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* DrawMenuBar [USER.160]
|
|
*/
|
|
void DrawMenuBar(HWND hWnd)
|
|
{
|
|
WND *wndPtr;
|
|
LPPOPUPMENU lppop;
|
|
HDC hDC;
|
|
#ifdef DEBUG_MENU
|
|
printf("DrawMenuBar (%04X)\n", hWnd);
|
|
#endif
|
|
wndPtr = WIN_FindWndPtr(hWnd);
|
|
if (wndPtr != NULL && (wndPtr->dwStyle & WS_CHILD) == 0 &&
|
|
wndPtr->wIDmenu != 0) {
|
|
#ifdef DEBUG_MENU
|
|
printf("DrawMenuBar wIDmenu=%04X \n", wndPtr->wIDmenu);
|
|
#endif
|
|
lppop = (LPPOPUPMENU) GlobalLock(wndPtr->wIDmenu);
|
|
if (lppop == NULL) return;
|
|
if (lppop->Height != 0) {
|
|
int oldHeight;
|
|
oldHeight = lppop->Height;
|
|
hDC = GetWindowDC(hWnd);
|
|
StdDrawMenuBar(hDC, &lppop->rect, lppop, TRUE);
|
|
ReleaseDC(hWnd, hDC);
|
|
if (oldHeight != lppop->Height) {
|
|
printf("DrawMenuBar // menubar changed oldHeight=%d != lppop->Height=%d\n",
|
|
oldHeight, lppop->Height);
|
|
/* Reduce ClientRect according to MenuBar height */
|
|
wndPtr->rectClient.top -= oldHeight;
|
|
wndPtr->rectClient.top += lppop->Height;
|
|
SendMessage(hWnd, WM_NCPAINT, 1, 0L);
|
|
}
|
|
else
|
|
StdDrawMenuBar(hDC, &lppop->rect, lppop, FALSE);
|
|
}
|
|
else
|
|
SendMessage(hWnd, WM_NCPAINT, 1, 0L);
|
|
GlobalUnlock(wndPtr->wIDmenu);
|
|
}
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* LoadMenuIndirect [USER.220]
|
|
*/
|
|
HMENU LoadMenuIndirect(LPSTR menu_template)
|
|
{
|
|
HMENU hMenu;
|
|
MENU_HEADER *menu_desc;
|
|
LPPOPUPMENU lppop;
|
|
#ifdef DEBUG_MENU
|
|
printf("LoadMenuIndirect: menu_template '%08X'\n", menu_template);
|
|
#endif
|
|
hMenu = CreateMenu();
|
|
menu_desc = (MENU_HEADER *)menu_template;
|
|
ParseMenuResource((WORD *)(menu_desc + 1), 0, hMenu);
|
|
lppop = (LPPOPUPMENU) GlobalLock(hMenu);
|
|
ResetHiliteFlags(lppop);
|
|
GlobalUnlock(hMenu);
|
|
return hMenu;
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* InitStdBitmaps (Internal)
|
|
*/
|
|
void InitStdBitmaps()
|
|
{
|
|
if (hStdCheck == (HBITMAP)NULL)
|
|
hStdCheck = LoadBitmap((HANDLE)NULL, (LPSTR)OBM_CHECK);
|
|
if (hStdMnArrow == (HBITMAP)NULL)
|
|
hStdMnArrow = LoadBitmap((HANDLE)NULL, (LPSTR)OBM_MNARROW);
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* CopySysMenu (Internal)
|
|
*/
|
|
HMENU CopySysMenu()
|
|
{
|
|
HMENU hMenu;
|
|
LPPOPUPMENU menu;
|
|
LPPOPUPMENU sysmenu;
|
|
#ifdef DEBUG_MENU
|
|
printf("CopySysMenu entry !\n");
|
|
#endif
|
|
if (hSysMenu == 0) {
|
|
/* hSysMenu = LoadMenu((HINSTANCE)NULL, MAKEINTRESOURCE(1)); */
|
|
/* hSysMenu = LoadMenu((HINSTANCE)NULL, MAKEINTRESOURCE(SC_SYSMENU));*/
|
|
hSysMenu = LoadMenu((HINSTANCE)NULL, "SYSMENU");
|
|
if (hSysMenu == 0) {
|
|
printf("SysMenu not found in system resources !\n");
|
|
return (HMENU)NULL;
|
|
}
|
|
#ifdef DEBUG_MENU
|
|
else
|
|
printf("SysMenu loaded from system resources %04X !\n", hSysMenu);
|
|
#endif
|
|
}
|
|
hMenu = GlobalAlloc(GMEM_MOVEABLE, sizeof(POPUPMENU));
|
|
menu = (LPPOPUPMENU) GlobalLock(hMenu);
|
|
sysmenu = (LPPOPUPMENU) GlobalLock(hSysMenu);
|
|
if (menu != NULL && sysmenu != NULL) {
|
|
sysmenu->BarFlag = FALSE;
|
|
sysmenu->SysFlag = TRUE;
|
|
memcpy(menu, sysmenu, sizeof(POPUPMENU));
|
|
}
|
|
else {
|
|
printf("CopySysMenu // Bad SysMenu pointers !\n");
|
|
if (menu != NULL) {
|
|
GlobalUnlock(hMenu);
|
|
GlobalFree(hMenu);
|
|
}
|
|
return (HMENU)NULL;
|
|
}
|
|
GlobalUnlock(hMenu);
|
|
GlobalUnlock(hSysMenu);
|
|
#ifdef DEBUG_MENU
|
|
printf("CopySysMenu hMenu=%04X !\n", hMenu);
|
|
#endif
|
|
return hMenu;
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* ParseMenuResource (from Resource or Template)
|
|
*/
|
|
WORD * ParseMenuResource(WORD *first_item, int level, HMENU hMenu)
|
|
{
|
|
WORD *item;
|
|
WORD *next_item;
|
|
HMENU hSubMenu;
|
|
int i;
|
|
|
|
level++;
|
|
next_item = first_item;
|
|
i = 0;
|
|
do {
|
|
i++;
|
|
item = next_item;
|
|
if (*item & MF_POPUP) {
|
|
MENU_POPUPITEM *popup_item = (MENU_POPUPITEM *) item;
|
|
next_item = (WORD *) (popup_item->item_text +
|
|
strlen(popup_item->item_text) + 1);
|
|
hSubMenu = CreatePopupMenu();
|
|
next_item = ParseMenuResource(next_item, level, hSubMenu);
|
|
AppendMenu(hMenu, popup_item->item_flags,
|
|
hSubMenu, popup_item->item_text);
|
|
}
|
|
else {
|
|
MENUITEMTEMPLATE *normal_item = (MENUITEMTEMPLATE *) item;
|
|
next_item = (WORD *) (normal_item->item_text +
|
|
strlen(normal_item->item_text) + 1);
|
|
if (strlen(normal_item->item_text) == 0 && normal_item->item_id == 0)
|
|
normal_item->item_flags |= MF_SEPARATOR;
|
|
AppendMenu(hMenu, normal_item->item_flags,
|
|
normal_item->item_id, normal_item->item_text);
|
|
}
|
|
}
|
|
while (!(*item & MF_END));
|
|
return next_item;
|
|
}
|
|
|
|
/**********************************************************************
|
|
* IsMenu(USER.358)
|
|
*/
|
|
BOOL IsMenu(HMENU hMenu)
|
|
{
|
|
LPPOPUPMENU menu;
|
|
|
|
menu = (LPPOPUPMENU) GlobalLock(hMenu);
|
|
if (menu == NULL)
|
|
return FALSE;
|
|
|
|
GlobalUnlock(hMenu);
|
|
return TRUE;
|
|
}
|