Thu Jan 13 11:45:13 1994 John Richardson <jrichard@cs.uml.edu> * [window/win.c] Added functions EnableWindow, IsWindowEnabled, and helper WIN_SetSensitive. * [window/event.c] Added checks for WS_DISABLED windows in EVENT_key, EVENT_MotionNotify, EVENT_ButtonPress, EVENT_ButtonRelease, EVENT_ConfigureNotify, EVENT_FocusIn, EVENT_FocusOut, and EVENT_EnterNotify. Key and button presses beep for a disabled window. If anyone finds better places for these checks, please tell me. Jan 17, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) * [misc/message.c] Cleanup on buttons answer value returned. * [control/combo.c] Now use OBM_COMBO bitmap dropdown button. Mon Jan 17 21:56:45 1994 Erik Bos (erik@trashcan.hacktic.nl) * [misc/comm/c] A few bugfixes. Tue Jan 18 06:36:48 1994 julliard@di.epfl.ch (Alexandre Julliard) * [loader/cursor.c] Added X cursor for IDC_SIZENS and IDC_SIZEWE. * [include/options.h] [misc/main.c] (New files) Rewrote main() function to get rid of Xt application context, and added command-line option parsing. * [objects/color.c] Use of a private map now configurable with command-line option. * [windows/defwnd.c] Added WM_SYSCOMMAND handling, and better WM_SETCURSOR handling. * [windows/event.c] Removed ConfigureNotify event handler (no longer needed). * [windows/message.c] Send WM_SETCURSOR message on mouse events. * [windows/nonclient.c] Use OEM bitmaps for the drawing of the non-client area. Added caption bar buttons handling, and moving and resizing of the window via the window frame (bypassing the window manager). * [windows/painting.c] Bug fix in BeginPaint(). * [windows/win.c] Set the override_redirect flag for windows (to bypass window manager). * [windows/winpos.c] Implemented WindowFromPoint(), ChildWindowFromPoint(), BringWindowToTop(), Get/SetInternalWindowPos(), Get/SetWindowPlacement(). Mon Jan 17 20:48:24 1994 Bob Amstadt (bob@pooh) * [memory/heap.c] Added support for multiple local heaps.
2007 lines
53 KiB
C
2007 lines
53 KiB
C
static char RCSId[] = "$Id$";
|
||
static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
|
||
static char Copyright2[] = "Copyright Martin Ayotte, 1993";
|
||
|
||
/*
|
||
#define DEBUG_MENU
|
||
*/
|
||
#define USE_POPUPMENU
|
||
|
||
#include <X11/Intrinsic.h>
|
||
#include <X11/StringDefs.h>
|
||
#include "windows.h"
|
||
#include "menu.h"
|
||
#include "heap.h"
|
||
#include "win.h"
|
||
#include "bitmaps/check_bitmap"
|
||
#include "bitmaps/nocheck_bitmap"
|
||
|
||
HBITMAP hStdCheck = 0;
|
||
HBITMAP hStdMnArrow = 0;
|
||
|
||
static LPMENUBAR firstMenu = NULL;
|
||
static MENUITEM *parentItem;
|
||
static MENUITEM *siblingItem;
|
||
static int lastLevel;
|
||
static int menuId = 0;
|
||
static Pixmap checkBitmap = XtUnspecifiedPixmap;
|
||
static Pixmap nocheckBitmap = XtUnspecifiedPixmap;
|
||
|
||
LPPOPUPMENU PopupMenuGetStorageHeader(HWND hwnd);
|
||
LPPOPUPMENU PopupMenuGetWindowAndStorage(HWND hwnd, WND **wndPtr);
|
||
void StdDrawMenuBar(HWND hwnd);
|
||
void StdDrawPopupMenu(HWND hwnd);
|
||
LPMENUITEM MenuFindItem(HWND hwnd, int x, int y, WORD *lpRet);
|
||
LPMENUITEM MenuFindItemBySelKey(HWND hwnd, WORD key, WORD *lpRet);
|
||
void PopupMenuCalcSize(HWND hwnd);
|
||
void MenuBarCalcSize(HWND hwnd);
|
||
LPMENUITEM GetMenuItemPtr(LPPOPUPMENU menu, WORD nPos);
|
||
WORD GetSelectionKey(LPSTR str);
|
||
LPSTR GetShortCutString(LPSTR str);
|
||
WORD GetShortCutPos(LPSTR str);
|
||
BOOL HideAllSubPopupMenu(LPPOPUPMENU menu);
|
||
WORD * ParseMenuResource(WORD *first_item, int level, HMENU hMenu);
|
||
void SetMenuLogicalParent(HMENU hMenu, HWND hWnd);
|
||
|
||
/***********************************************************************
|
||
* PopupMenuWndProc
|
||
*/
|
||
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;
|
||
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
|
||
/*
|
||
if (lppop->BarFlags == 0) {
|
||
PopupMenuCalcSize(hwnd);
|
||
printf("PopupMenu WM_CREATE Width=%d Height=%d !\n",
|
||
lppop->Width, lppop->Height);
|
||
SetWindowPos(hwnd, 0, 0, 0, lppop->Width + 2, lppop->Height,
|
||
SWP_NOZORDER | SWP_NOMOVE);
|
||
}
|
||
else {
|
||
MenuBarCalcSize(hwnd);
|
||
SetWindowPos(hwnd, 0, 0, -16, lppop->Width, lppop->Height,
|
||
SWP_NOZORDER);
|
||
}
|
||
*/
|
||
if (hStdCheck == (HBITMAP)NULL)
|
||
hStdCheck = LoadBitmap((HANDLE)NULL, (LPSTR)OBM_CHECK);
|
||
if (hStdMnArrow == (HBITMAP)NULL)
|
||
hStdMnArrow = LoadBitmap((HANDLE)NULL, (LPSTR)OBM_MNARROW);
|
||
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:
|
||
lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
|
||
#ifdef DEBUG_MENU
|
||
printf("PopupMenu // push to lower parent WM_COMMAND !\n");
|
||
#endif
|
||
if (lppop->hWndParent != (HWND)NULL)
|
||
SendMessage(lppop->hWndParent, WM_COMMAND, wParam, lParam);
|
||
else
|
||
SendMessage(lppop->ownerWnd, WM_COMMAND, wParam, lParam);
|
||
if (lppop->BarFlags == 0) ShowWindow(hwnd, SW_HIDE);
|
||
break;
|
||
case WM_SHOWWINDOW:
|
||
lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
|
||
if (wParam == 0) {
|
||
HideAllSubPopupMenu(lppop);
|
||
#ifdef DEBUG_MENU
|
||
printf("PopupMenu WM_SHOWWINDOW -> HIDE!\n");
|
||
#endif
|
||
break;
|
||
}
|
||
lppop->FocusedItem = (WORD)-1;
|
||
if (lppop->BarFlags == 0) {
|
||
PopupMenuCalcSize(hwnd);
|
||
#ifdef DEBUG_MENU
|
||
printf("PopupMenu WM_SHOWWINDOW Width=%d Height=%d !\n",
|
||
lppop->Width, lppop->Height);
|
||
#endif
|
||
SetWindowPos(hwnd, 0, 0, 0, lppop->Width + 2, lppop->Height,
|
||
SWP_NOZORDER | SWP_NOMOVE);
|
||
}
|
||
else {
|
||
MenuBarCalcSize(hwnd);
|
||
#ifdef DEBUG_MENU
|
||
printf("MenuBarMenu WM_SHOWWINDOW Width=%d Height=%d !\n",
|
||
lppop->Width, lppop->Height);
|
||
#endif
|
||
SetWindowPos(hwnd, 0, 0, -16, lppop->Width, lppop->Height,
|
||
SWP_NOZORDER);
|
||
}
|
||
break;
|
||
case WM_LBUTTONDOWN:
|
||
lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
|
||
SetCapture(hwnd);
|
||
lpitem = MenuFindItem(hwnd, LOWORD(lParam), HIWORD(lParam), &wRet);
|
||
#ifdef DEBUG_MENU
|
||
printf("PopupMenu WM_LBUTTONDOWN wRet=%d lpitem=%08X !\n", wRet, lpitem);
|
||
#endif
|
||
if (lpitem != NULL) {
|
||
if (lppop->FocusedItem != (WORD)-1) {
|
||
HideAllSubPopupMenu(lppop);
|
||
lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem);
|
||
if (((lpitem2->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
|
||
((lpitem2->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) {
|
||
hDC = GetDC(hwnd);
|
||
InvertRect(hDC, &lpitem2->rect);
|
||
ReleaseDC(hwnd, hDC);
|
||
}
|
||
}
|
||
lppop->FocusedItem = wRet;
|
||
if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
|
||
((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) {
|
||
hDC = GetDC(hwnd);
|
||
InvertRect(hDC, &lpitem->rect);
|
||
ReleaseDC(hwnd, hDC);
|
||
}
|
||
if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
|
||
hSubMenu = (HMENU)lpitem->item_id;
|
||
lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu);
|
||
if (lppop2 == NULL) break;
|
||
lppop2->hWndParent = hwnd;
|
||
GetClientRect(hwnd, &rect);
|
||
if (lppop->BarFlags != 0) {
|
||
y = rect.bottom - rect.top;
|
||
TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON,
|
||
lpitem->rect.left, 0,
|
||
0, lppop->ownerWnd, (LPRECT)NULL);
|
||
}
|
||
else {
|
||
x = rect.right;
|
||
GetWindowRect(hwnd, &rect);
|
||
x += rect.left;
|
||
TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON,
|
||
x, lpitem->rect.top,
|
||
0, lppop->ownerWnd, (LPRECT)NULL);
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
break;
|
||
case WM_LBUTTONUP:
|
||
lppop = PopupMenuGetStorageHeader(hwnd);
|
||
ReleaseCapture();
|
||
lpitem = MenuFindItem(hwnd, LOWORD(lParam), HIWORD(lParam), &wRet);
|
||
#ifdef DEBUG_MENU
|
||
printf("PopupMenu WM_LBUTTONUP wRet=%d lpitem=%08X !\n", wRet, lpitem);
|
||
#endif
|
||
if (lpitem != NULL) {
|
||
if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
|
||
break;
|
||
}
|
||
if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
|
||
((lpitem->item_flags & MF_POPUP) != MF_POPUP)) {
|
||
ShowWindow(lppop->hWnd, SW_HIDE);
|
||
if (lppop->hWndParent != (HWND)NULL)
|
||
SendMessage(lppop->hWndParent, WM_COMMAND,
|
||
lpitem->item_id, 0L);
|
||
else
|
||
SendMessage(lppop->ownerWnd, WM_COMMAND,
|
||
lpitem->item_id, 0L);
|
||
#ifdef DEBUG_MENU
|
||
printf("PopupMenu // SendMessage WM_COMMAND wParam=%d !\n",
|
||
lpitem->item_id);
|
||
#endif
|
||
break;
|
||
}
|
||
}
|
||
if (lppop->FocusedItem != (WORD)-1) {
|
||
HideAllSubPopupMenu(lppop);
|
||
lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem);
|
||
if (((lpitem2->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
|
||
((lpitem2->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) {
|
||
hDC = GetDC(hwnd);
|
||
InvertRect(hDC, &lpitem2->rect);
|
||
ReleaseDC(hwnd, hDC);
|
||
}
|
||
}
|
||
break;
|
||
case WM_MOUSEMOVE:
|
||
if ((wParam & MK_LBUTTON) != 0) {
|
||
lppop = PopupMenuGetStorageHeader(hwnd);
|
||
lpitem = MenuFindItem(hwnd, LOWORD(lParam), HIWORD(lParam), &wRet);
|
||
if ((lpitem != NULL) && (lppop->FocusedItem != wRet)) {
|
||
lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem);
|
||
hDC = GetDC(hwnd);
|
||
if (((lpitem2->item_flags & MF_POPUP) == MF_POPUP) ||
|
||
((lpitem2->item_flags & MF_STRING) == MF_STRING)) {
|
||
InvertRect(hDC, &lpitem2->rect);
|
||
}
|
||
if ((lpitem2->item_flags & MF_POPUP) == MF_POPUP) {
|
||
HideAllSubPopupMenu(lppop);
|
||
}
|
||
lppop->FocusedItem = wRet;
|
||
if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) ||
|
||
((lpitem->item_flags & MF_STRING) == MF_STRING)) {
|
||
InvertRect(hDC, &lpitem->rect);
|
||
}
|
||
if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
|
||
hSubMenu = (HMENU)lpitem->item_id;
|
||
lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu);
|
||
if (lppop2 == NULL) break;
|
||
if (lppop->BarFlags != 0) {
|
||
lppop2->hWndParent = hwnd;
|
||
GetClientRect(hwnd, &rect);
|
||
y = rect.bottom - rect.top;
|
||
TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON,
|
||
lpitem->rect.left, 0,
|
||
0, lppop->ownerWnd, (LPRECT)NULL);
|
||
}
|
||
}
|
||
ReleaseDC(hwnd, hDC);
|
||
}
|
||
}
|
||
break;
|
||
|
||
case WM_KEYDOWN:
|
||
case WM_KEYUP:
|
||
if (lParam < 0L) break;
|
||
lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
|
||
if (lppop->FocusedItem == (WORD)-1) {
|
||
if (wParam == VK_UP || wParam == VK_DOWN ||
|
||
wParam == VK_LEFT || wParam == VK_RIGHT) {
|
||
hDC = GetDC(hwnd);
|
||
lppop->FocusedItem = 0;
|
||
lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem);
|
||
if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) ||
|
||
((lpitem->item_flags & MF_STRING) == MF_STRING)) {
|
||
InvertRect(hDC, &lpitem->rect);
|
||
}
|
||
ReleaseDC(hwnd, hDC);
|
||
}
|
||
break;
|
||
}
|
||
switch(wParam) {
|
||
case VK_UP:
|
||
if (lppop->BarFlags != 0) break;
|
||
if (lppop->FocusedItem < 1) break;
|
||
lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem);
|
||
if ((lpitem->item_flags & MF_POPUP) == MF_POPUP)
|
||
HideAllSubPopupMenu(lppop);
|
||
hDC = GetDC(hwnd);
|
||
if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) ||
|
||
((lpitem->item_flags & MF_STRING) == MF_STRING)) {
|
||
InvertRect(hDC, &lpitem->rect);
|
||
}
|
||
lppop->FocusedItem--;
|
||
lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem);
|
||
if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) ||
|
||
((lpitem->item_flags & MF_STRING) == MF_STRING)) {
|
||
InvertRect(hDC, &lpitem->rect);
|
||
}
|
||
ReleaseDC(hwnd, hDC);
|
||
break;
|
||
case VK_DOWN:
|
||
if (lppop->BarFlags != 0) goto ProceedSPACE;
|
||
if (lppop->FocusedItem >= lppop->nItems - 1) break;
|
||
lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem);
|
||
if ((lpitem->item_flags & MF_POPUP) == MF_POPUP)
|
||
HideAllSubPopupMenu(lppop);
|
||
hDC = GetDC(hwnd);
|
||
if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) ||
|
||
((lpitem->item_flags & MF_STRING) == MF_STRING)) {
|
||
InvertRect(hDC, &lpitem->rect);
|
||
}
|
||
lppop->FocusedItem++;
|
||
lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem);
|
||
if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) ||
|
||
((lpitem->item_flags & MF_STRING) == MF_STRING)) {
|
||
InvertRect(hDC, &lpitem->rect);
|
||
}
|
||
ReleaseDC(hwnd, hDC);
|
||
break;
|
||
case VK_LEFT:
|
||
if (lppop->BarFlags == 0) {
|
||
if (lppop->hWndParent != 0)
|
||
SendMessage(lppop->hWndParent, WM_KEYDOWN, wParam, lParam);
|
||
break;
|
||
}
|
||
if (lppop->FocusedItem < 1) break;
|
||
lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem);
|
||
if ((lpitem->item_flags & MF_POPUP) == MF_POPUP)
|
||
HideAllSubPopupMenu(lppop);
|
||
hDC = GetDC(hwnd);
|
||
if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) ||
|
||
((lpitem->item_flags & MF_STRING) == MF_STRING)) {
|
||
InvertRect(hDC, &lpitem->rect);
|
||
}
|
||
lppop->FocusedItem--;
|
||
lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem);
|
||
if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) ||
|
||
((lpitem->item_flags & MF_STRING) == MF_STRING)) {
|
||
InvertRect(hDC, &lpitem->rect);
|
||
}
|
||
ReleaseDC(hwnd, hDC);
|
||
break;
|
||
case VK_RIGHT:
|
||
if (lppop->BarFlags == 0) {
|
||
if (lppop->hWndParent != 0)
|
||
SendMessage(lppop->hWndParent, WM_KEYDOWN, wParam, lParam);
|
||
break;
|
||
}
|
||
if (lppop->FocusedItem >= lppop->nItems - 1) break;
|
||
lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem);
|
||
if ((lpitem->item_flags & MF_POPUP) == MF_POPUP)
|
||
HideAllSubPopupMenu(lppop);
|
||
hDC = GetDC(hwnd);
|
||
if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) ||
|
||
((lpitem->item_flags & MF_STRING) == MF_STRING)) {
|
||
InvertRect(hDC, &lpitem->rect);
|
||
}
|
||
lppop->FocusedItem++;
|
||
lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem);
|
||
if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) ||
|
||
((lpitem->item_flags & MF_STRING) == MF_STRING)) {
|
||
InvertRect(hDC, &lpitem->rect);
|
||
}
|
||
ReleaseDC(hwnd, hDC);
|
||
break;
|
||
case VK_RETURN:
|
||
case VK_SPACE:
|
||
ProceedSPACE:
|
||
printf("PopupMenu VK_SPACE !\n");
|
||
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) break;
|
||
lppop2->hWndParent = hwnd;
|
||
GetClientRect(hwnd, &rect);
|
||
if (lppop->BarFlags != 0) {
|
||
y = rect.bottom - rect.top;
|
||
TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON,
|
||
lpitem->rect.left, 0,
|
||
0, lppop->ownerWnd, (LPRECT)NULL);
|
||
}
|
||
else {
|
||
x = rect.right;
|
||
GetWindowRect(hwnd, &rect);
|
||
x += rect.left;
|
||
TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON,
|
||
x, lpitem->rect.top,
|
||
0, lppop->ownerWnd, (LPRECT)NULL);
|
||
}
|
||
break;
|
||
}
|
||
if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
|
||
((lpitem->item_flags & MF_POPUP) != MF_POPUP)) {
|
||
ShowWindow(lppop->hWnd, SW_HIDE);
|
||
if (lppop->hWndParent != (HWND)NULL)
|
||
SendMessage(lppop->hWndParent, WM_COMMAND,
|
||
lpitem->item_id, 0L);
|
||
else
|
||
SendMessage(lppop->ownerWnd, WM_COMMAND,
|
||
lpitem->item_id, 0L);
|
||
#ifdef DEBUG_MENU
|
||
printf("PopupMenu // SendMessage WM_COMMAND wParam=%d !\n",
|
||
lpitem->item_id);
|
||
#endif
|
||
}
|
||
break;
|
||
}
|
||
break;
|
||
case WM_CHAR:
|
||
if (lParam < 0L) break;
|
||
lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
|
||
if (wParam == VK_ESCAPE) {
|
||
if (lppop->hWndParent != 0) {
|
||
lppop2 = PopupMenuGetWindowAndStorage(
|
||
lppop->hWndParent, &wndPtr);
|
||
HideAllSubPopupMenu(lppop2);
|
||
break;
|
||
}
|
||
if (lppop->FocusedItem != (WORD)-1) {
|
||
lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem);
|
||
hDC = GetDC(hwnd);
|
||
if (((lpitem2->item_flags & MF_POPUP) == MF_POPUP) ||
|
||
((lpitem2->item_flags & MF_STRING) == MF_STRING)) {
|
||
InvertRect(hDC, &lpitem2->rect);
|
||
}
|
||
ReleaseDC(hwnd, hDC);
|
||
lppop->FocusedItem = (WORD)-1;
|
||
}
|
||
}
|
||
if (wParam >= 'a' && wParam <= 'z') wParam -= 'a' - 'A';
|
||
lpitem = MenuFindItemBySelKey(hwnd, wParam, &wRet);
|
||
if (lpitem != NULL) {
|
||
printf("Found wRet=%d !\n", wRet);
|
||
if (lppop->FocusedItem != (WORD)-1) {
|
||
lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem);
|
||
if ((lpitem2->item_flags & MF_POPUP) == MF_POPUP)
|
||
HideAllSubPopupMenu(lppop);
|
||
hDC = GetDC(hwnd);
|
||
if (((lpitem2->item_flags & MF_POPUP) == MF_POPUP) ||
|
||
((lpitem2->item_flags & MF_STRING) == MF_STRING)) {
|
||
InvertRect(hDC, &lpitem2->rect);
|
||
}
|
||
ReleaseDC(hwnd, hDC);
|
||
}
|
||
lppop->FocusedItem = wRet;
|
||
goto ProceedSPACE;
|
||
}
|
||
break;
|
||
case WM_PAINT:
|
||
lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
|
||
if (lppop->BarFlags != 0) {
|
||
MenuBarCalcSize(hwnd);
|
||
printf("PopupMenu WM_PAINT Width=%d Height=%d !\n",
|
||
lppop->Width, lppop->Height);
|
||
StdDrawMenuBar(hwnd);
|
||
}
|
||
else{
|
||
PopupMenuCalcSize(hwnd);
|
||
StdDrawPopupMenu(hwnd);
|
||
}
|
||
break;
|
||
default:
|
||
return DefWindowProc( hwnd, message, wParam, lParam );
|
||
}
|
||
return(0);
|
||
}
|
||
|
||
|
||
|
||
LPPOPUPMENU PopupMenuGetWindowAndStorage(HWND hwnd, WND **wndPtr)
|
||
{
|
||
WND *Ptr;
|
||
LPPOPUPMENU lppop;
|
||
*(wndPtr) = Ptr = WIN_FindWndPtr(hwnd);
|
||
if (Ptr == 0) {
|
||
printf("Bad Window handle on PopupMenu !\n");
|
||
return 0;
|
||
}
|
||
lppop = *((LPPOPUPMENU *)&Ptr->wExtra[1]);
|
||
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;
|
||
}
|
||
|
||
|
||
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;
|
||
HFONT hOldFont;
|
||
HBITMAP hBitMap;
|
||
BITMAP bm;
|
||
UINT i, x;
|
||
hDC = BeginPaint( hwnd, &ps );
|
||
if (!IsWindowVisible(hwnd)) {
|
||
EndPaint( hwnd, &ps );
|
||
return;
|
||
}
|
||
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++) {
|
||
if ((lpitem->item_flags & MF_SEPARATOR) == MF_SEPARATOR) {
|
||
CopyRect(&rect2, &lpitem->rect);
|
||
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_BITMAP) == MF_BITMAP) {
|
||
hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text);
|
||
CopyRect(&rect2, &lpitem->rect);
|
||
hMemDC = CreateCompatibleDC(hDC);
|
||
SelectObject(hMemDC, hBitMap);
|
||
GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm);
|
||
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));
|
||
if ((lpitem->item_flags & MF_DISABLED) == MF_DISABLED)
|
||
OldTextColor = SetTextColor(hDC, 0x00C0C0C0L);
|
||
else
|
||
OldTextColor = SetTextColor(hDC, 0x00000000L);
|
||
CopyRect(&rect3, &lpitem->rect);
|
||
InflateRect(&rect3, 0, -2);
|
||
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);
|
||
SetTextColor(hDC, OldTextColor);
|
||
SelectObject(hDC, hOldFont);
|
||
CopyRect(&rect2, &lpitem->rect);
|
||
}
|
||
if ((lpitem->item_flags & MF_CHECKED) == MF_CHECKED) {
|
||
CopyRect(&rect3, &rect2);
|
||
rect3.left = rect3.right - rect3.bottom + rect3.top;
|
||
hMemDC = CreateCompatibleDC(hDC);
|
||
if (lpitem->hCheckBit == 0)
|
||
SelectObject(hMemDC, hStdCheck);
|
||
else
|
||
SelectObject(hMemDC, lpitem->hCheckBit);
|
||
GetObject(hStdCheck, sizeof(BITMAP), (LPSTR)&bm);
|
||
BitBlt(hDC, rect3.left, rect3.top,
|
||
bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
|
||
DeleteDC(hMemDC);
|
||
printf("StdDrawPopupMenu // MF_CHECKED hStdCheck=%04X !\n", hStdCheck);
|
||
}
|
||
else {
|
||
if (lpitem->hUnCheckBit != 0)
|
||
SelectObject(hMemDC, lpitem->hUnCheckBit);
|
||
}
|
||
if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
|
||
CopyRect(&rect3, &rect2);
|
||
rect3.left = rect3.right - rect3.bottom + rect3.top;
|
||
hMemDC = CreateCompatibleDC(hDC);
|
||
SelectObject(hMemDC, hStdMnArrow);
|
||
GetObject(hStdMnArrow, sizeof(BITMAP), (LPSTR)&bm);
|
||
BitBlt(hDC, rect3.left, rect3.top,
|
||
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(HWND hwnd)
|
||
{
|
||
WND *wndPtr;
|
||
LPPOPUPMENU lppop;
|
||
LPMENUITEM lpitem;
|
||
PAINTSTRUCT ps;
|
||
HBRUSH hBrush;
|
||
HPEN hOldPen;
|
||
HWND hWndParent;
|
||
HDC hDC, hMemDC;
|
||
RECT rect, rect2, rect3;
|
||
HFONT hOldFont;
|
||
HBITMAP hBitMap;
|
||
BITMAP bm;
|
||
UINT i, textwidth;
|
||
hDC = BeginPaint( hwnd, &ps );
|
||
if (!IsWindowVisible(hwnd)) {
|
||
EndPaint( hwnd, &ps );
|
||
return;
|
||
}
|
||
hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT));
|
||
lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
|
||
if (lppop == NULL) goto EndOfPaint;
|
||
hBrush = GetStockObject(WHITE_BRUSH);
|
||
GetClientRect(hwnd, &rect);
|
||
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++) {
|
||
if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) {
|
||
hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text);
|
||
CopyRect(&rect2, &lpitem->rect);
|
||
hMemDC = CreateCompatibleDC(hDC);
|
||
SelectObject(hMemDC, hBitMap);
|
||
GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm);
|
||
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)) {
|
||
CopyRect(&rect2, &lpitem->rect);
|
||
DrawText(hDC, lpitem->item_text, -1, &rect2,
|
||
DT_LEFT | DT_VCENTER | DT_SINGLELINE);
|
||
}
|
||
if ((lpitem->item_flags & MF_CHECKED) == MF_CHECKED) {
|
||
CopyRect(&rect3, &rect2);
|
||
rect3.left = rect3.right - rect3.bottom + rect3.top;
|
||
hMemDC = CreateCompatibleDC(hDC);
|
||
SelectObject(hMemDC, hStdCheck);
|
||
GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm);
|
||
BitBlt(hDC, rect3.left, rect3.top,
|
||
bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
|
||
DeleteDC(hMemDC);
|
||
}
|
||
if (lpitem->next == NULL) goto EndOfPaint;
|
||
lpitem = (LPMENUITEM)lpitem->next;
|
||
}
|
||
EndOfPaint:
|
||
SelectObject(hDC, hOldFont);
|
||
EndPaint( hwnd, &ps );
|
||
}
|
||
|
||
|
||
|
||
LPMENUITEM MenuFindItem(HWND hwnd, int x, int y, WORD *lpRet)
|
||
{
|
||
WND *wndPtr;
|
||
LPPOPUPMENU lppop;
|
||
LPMENUITEM lpitem;
|
||
UINT i;
|
||
lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
|
||
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(HWND hwnd, WORD key, WORD *lpRet)
|
||
{
|
||
WND *wndPtr;
|
||
LPPOPUPMENU lppop;
|
||
LPMENUITEM lpitem;
|
||
UINT i;
|
||
lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
|
||
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=%d lpitem->sel_key=%d\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;
|
||
lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
|
||
if (lppop == NULL) return;
|
||
if (lppop->nItems == 0) return;
|
||
hDC = GetDC(hwnd);
|
||
lppop->Width = 20;
|
||
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;
|
||
rect.right = rect.left + lppop->Width;
|
||
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;
|
||
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;
|
||
#ifdef DEBUG_MENUCALC
|
||
printf("PopupMenuCalcSize w=%d h=%d !\n",
|
||
lppop->Width, lppop->Height);
|
||
#endif
|
||
SelectObject(hDC, hOldFont);
|
||
ReleaseDC(0, hDC);
|
||
}
|
||
|
||
|
||
|
||
void MenuBarCalcSize(HWND hwnd)
|
||
{
|
||
WND *wndPtr;
|
||
LPPOPUPMENU lppop;
|
||
LPMENUITEM lpitem;
|
||
HDC hDC;
|
||
RECT rect;
|
||
HBITMAP hBitMap;
|
||
BITMAP bm;
|
||
HFONT hOldFont;
|
||
UINT i, OldHeight;
|
||
DWORD dwRet;
|
||
lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
|
||
if (lppop == NULL) return;
|
||
if (lppop->nItems == 0) return;
|
||
hDC = GetDC(hwnd);
|
||
hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT));
|
||
lppop->Height = 10;
|
||
CalcAGAIN:
|
||
OldHeight = lppop->Height;
|
||
SetRect(&rect, 1, 1, 0, OldHeight);
|
||
lpitem = lppop->firstItem;
|
||
for(i = 0; i < lppop->nItems; i++) {
|
||
if (lpitem == NULL) break;
|
||
rect.bottom = rect.top + lppop->Height;
|
||
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;
|
||
lppop->Height = max(lppop->Height, 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;
|
||
lppop->Height = max(lppop->Height, HIWORD(dwRet) + 10);
|
||
}
|
||
CopyRect(&lpitem->rect, &rect);
|
||
rect.left = rect.right;
|
||
lpitem = (LPMENUITEM)lpitem->next;
|
||
}
|
||
if (OldHeight < lppop->Height) goto CalcAGAIN;
|
||
lppop->Width = rect.right;
|
||
#ifdef DEBUG_MENUCALC
|
||
printf("MenuBarCalcSize w=%d h=%d !\n",
|
||
lppop->Width, lppop->Height);
|
||
#endif
|
||
SelectObject(hDC, hOldFont);
|
||
ReleaseDC(hwnd, hDC);
|
||
}
|
||
|
||
|
||
|
||
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_MENU
|
||
printf("GetShortCutString // '%s' \n", str2);
|
||
#endif
|
||
return str2;
|
||
}
|
||
}
|
||
#ifdef DEBUG_MENU
|
||
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_MENU
|
||
printf("GetShortCutPos = %d \n", i);
|
||
#endif
|
||
return i;
|
||
}
|
||
}
|
||
#ifdef DEBUG_MENU
|
||
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;
|
||
}
|
||
}
|
||
}
|
||
lpitem = (LPMENUITEM)lpitem->next;
|
||
}
|
||
return someClosed;
|
||
}
|
||
|
||
|
||
#ifdef USE_XTMENU
|
||
|
||
/**********************************************************************
|
||
* MENU_CheckWidget
|
||
*/
|
||
void
|
||
MENU_CheckWidget(Widget w, Boolean check)
|
||
{
|
||
if (checkBitmap == XtUnspecifiedPixmap)
|
||
{
|
||
Display *display = XtDisplayOfObject(w);
|
||
|
||
checkBitmap = XCreateBitmapFromData(display,
|
||
DefaultRootWindow(display),
|
||
check_bitmap_bits,
|
||
check_bitmap_width,
|
||
check_bitmap_height);
|
||
nocheckBitmap = XCreateBitmapFromData(display,
|
||
DefaultRootWindow(display),
|
||
nocheck_bitmap_bits,
|
||
nocheck_bitmap_width,
|
||
nocheck_bitmap_height);
|
||
}
|
||
|
||
if (check)
|
||
XtVaSetValues(w, XtNleftBitmap, checkBitmap, NULL);
|
||
else
|
||
XtVaSetValues(w, XtNleftBitmap, nocheckBitmap, NULL);
|
||
}
|
||
|
||
/**********************************************************************
|
||
* MENU_ParseMenu
|
||
*/
|
||
WORD *
|
||
MENU_ParseMenu(WORD *first_item,
|
||
int level,
|
||
int limit,
|
||
int (*action)(WORD *item, int level, void *app_data),
|
||
void *app_data)
|
||
{
|
||
WORD *item;
|
||
WORD *next_item;
|
||
int i;
|
||
|
||
level++;
|
||
next_item = first_item;
|
||
i = 0;
|
||
do
|
||
{
|
||
i++;
|
||
item = next_item;
|
||
(*action)(item, level, app_data);
|
||
if (*item & MF_POPUP)
|
||
{
|
||
MENU_POPUPITEM *popup_item = (MENU_POPUPITEM *) item;
|
||
|
||
next_item = (WORD *) (popup_item->item_text +
|
||
strlen(popup_item->item_text) + 1);
|
||
next_item = MENU_ParseMenu(next_item, level, 0, action, app_data);
|
||
}
|
||
else
|
||
{
|
||
MENU_NORMALITEM *normal_item = (MENU_NORMALITEM *) item;
|
||
|
||
next_item = (WORD *) (normal_item->item_text +
|
||
strlen(normal_item->item_text) + 1);
|
||
}
|
||
}
|
||
while (!(*item & MF_END) && i != limit);
|
||
|
||
return next_item;
|
||
}
|
||
|
||
/**********************************************************************
|
||
* MENU_FindMenuBar
|
||
*/
|
||
LPMENUBAR
|
||
MENU_FindMenuBar(MENUITEM *this_item)
|
||
{
|
||
MENUITEM *root;
|
||
LPMENUBAR menu;
|
||
|
||
/*
|
||
* Find root item on menu bar.
|
||
*/
|
||
for (root = this_item; root->parent != NULL; root = root->parent)
|
||
;
|
||
for ( ; root->prev != NULL; root = root->prev)
|
||
;
|
||
|
||
/*
|
||
* Find menu bar for the root item.
|
||
*/
|
||
for (menu = firstMenu;
|
||
menu != NULL && menu->firstItem != root;
|
||
menu = menu->next)
|
||
;
|
||
|
||
return menu;
|
||
}
|
||
|
||
/**********************************************************************
|
||
* MENU_SelectionCallback
|
||
*/
|
||
static void
|
||
MENU_SelectionCallback(Widget w, XtPointer client_data, XtPointer call_data)
|
||
{
|
||
MENUITEM *this_item = (MENUITEM *) client_data;
|
||
LPMENUBAR menu;
|
||
WND *wndPtr;
|
||
|
||
if (this_item->menu_w != NULL || (this_item->item_flags & MF_DISABLED))
|
||
return;
|
||
|
||
/*
|
||
* Find menu bar for the root item.
|
||
*/
|
||
menu = MENU_FindMenuBar(this_item);
|
||
if (menu != NULL)
|
||
{
|
||
wndPtr = WIN_FindWndPtr(menu->ownerWnd);
|
||
if (wndPtr == NULL)
|
||
return;
|
||
|
||
#ifdef DEBUG_MENU
|
||
printf("Selected '%s' (%d).\n",
|
||
this_item->item_text, this_item->item_id);
|
||
#endif
|
||
|
||
CallWindowProc(wndPtr->lpfnWndProc, menu->ownerWnd, WM_COMMAND,
|
||
this_item->item_id, 0);
|
||
}
|
||
}
|
||
|
||
/**********************************************************************
|
||
* MENU_CreateItems
|
||
*/
|
||
int
|
||
MENU_CreateItems(WORD *item, int level, void *app_data)
|
||
{
|
||
MENU_POPUPITEM *popup_item;
|
||
MENU_NORMALITEM *normal_item;
|
||
MENUITEM *this_item;
|
||
Arg this_args[10];
|
||
int n_args = 0;
|
||
LPMENUBAR menu = (LPMENUBAR) app_data;
|
||
|
||
if (menu->nItems == 0)
|
||
this_item = menu->firstItem;
|
||
else
|
||
this_item = (MENUITEM *) GlobalQuickAlloc(sizeof(MENUITEM));
|
||
|
||
if (this_item == NULL)
|
||
return 0;
|
||
|
||
if (level > lastLevel)
|
||
{
|
||
parentItem = siblingItem;
|
||
siblingItem = NULL;
|
||
}
|
||
|
||
while (level < lastLevel)
|
||
{
|
||
siblingItem = parentItem;
|
||
if (siblingItem != NULL)
|
||
parentItem = siblingItem->parent;
|
||
else
|
||
parentItem = NULL;
|
||
|
||
lastLevel--;
|
||
}
|
||
lastLevel = level;
|
||
|
||
this_item->next = NULL;
|
||
this_item->prev = siblingItem;
|
||
this_item->child = NULL;
|
||
this_item->parent = parentItem;
|
||
|
||
if (siblingItem != NULL)
|
||
siblingItem->next = this_item;
|
||
if (parentItem != NULL && parentItem->child == NULL)
|
||
parentItem->child = this_item;
|
||
|
||
siblingItem = this_item;
|
||
|
||
if (*item & MF_POPUP)
|
||
{
|
||
popup_item = (MENU_POPUPITEM *) item;
|
||
this_item->item_flags = popup_item->item_flags;
|
||
this_item->item_id = -1;
|
||
this_item->item_text = popup_item->item_text;
|
||
|
||
#ifdef DEBUG_MENU
|
||
printf("%d: popup %s\n", level, this_item->item_text);
|
||
#endif
|
||
}
|
||
else
|
||
{
|
||
normal_item = (MENU_NORMALITEM *) item;
|
||
this_item->item_flags = normal_item->item_flags;
|
||
this_item->item_id = normal_item->item_id;
|
||
this_item->item_text = normal_item->item_text;
|
||
|
||
#ifdef DEBUG_MENU
|
||
printf("%d: normal %s (%04x)\n", level, this_item->item_text,
|
||
this_item->item_flags);
|
||
#endif
|
||
}
|
||
|
||
if (level == 1)
|
||
{
|
||
menu->nItems++;
|
||
|
||
if (this_item->prev != NULL)
|
||
{
|
||
XtSetArg(this_args[n_args], XtNhorizDistance, 10);
|
||
n_args++;
|
||
XtSetArg(this_args[n_args], XtNfromHoriz, this_item->prev->w);
|
||
n_args++;
|
||
}
|
||
|
||
if (this_item->item_flags & MF_POPUP)
|
||
{
|
||
sprintf(this_item->menu_name, "Menu%d", menuId++);
|
||
XtSetArg(this_args[n_args], XtNmenuName, this_item->menu_name);
|
||
n_args++;
|
||
|
||
this_item->w = XtCreateManagedWidget(this_item->item_text,
|
||
winMenuButtonWidgetClass,
|
||
menu->parentWidget,
|
||
this_args, n_args);
|
||
this_item->menu_w = XtCreatePopupShell(this_item->menu_name,
|
||
simpleMenuWidgetClass,
|
||
this_item->w,
|
||
NULL, 0);
|
||
}
|
||
else
|
||
{
|
||
this_item->w = XtCreateManagedWidget(this_item->item_text,
|
||
winCommandWidgetClass,
|
||
menu->parentWidget,
|
||
this_args, n_args);
|
||
this_item->menu_w = NULL;
|
||
XtAddCallback(this_item->w, XtNcallback, MENU_SelectionCallback,
|
||
(XtPointer) this_item);
|
||
}
|
||
|
||
if (menu->firstItem == NULL)
|
||
menu->firstItem = this_item;
|
||
}
|
||
else
|
||
{
|
||
if ((this_item->item_flags & MF_MENUBREAK) ||
|
||
(strlen(this_item->item_text) == 0))
|
||
{
|
||
XtSetArg(this_args[n_args], XtNheight, 10);
|
||
n_args++;
|
||
this_item->w = XtCreateManagedWidget("separator",
|
||
smeLineObjectClass,
|
||
this_item->parent->menu_w,
|
||
this_args, n_args);
|
||
}
|
||
else
|
||
{
|
||
XtSetArg(this_args[n_args], XtNmenuName, this_item->menu_name);
|
||
n_args++;
|
||
this_item->w = XtCreateManagedWidget(this_item->item_text,
|
||
smeMenuButtonObjectClass,
|
||
this_item->parent->menu_w,
|
||
this_args, n_args);
|
||
|
||
if (this_item->item_flags & MF_POPUP)
|
||
{
|
||
sprintf(this_item->menu_name, "Menu%d", menuId++);
|
||
this_item->menu_w = XtCreatePopupShell(this_item->menu_name,
|
||
simpleMenuWidgetClass,
|
||
this_item->parent->menu_w,
|
||
NULL, 0);
|
||
}
|
||
else
|
||
{
|
||
this_item->menu_w = NULL;
|
||
XtAddCallback(this_item->w, XtNcallback,
|
||
MENU_SelectionCallback, (XtPointer) this_item);
|
||
}
|
||
}
|
||
}
|
||
|
||
if (this_item->w != NULL)
|
||
{
|
||
if (this_item->item_flags & MF_GRAYED)
|
||
XtSetSensitive(this_item->w, False);
|
||
if (this_item->item_flags & MF_DISABLED)
|
||
XtVaSetValues(this_item->w, XtNinactive, True, NULL);
|
||
if (this_item->item_flags & MF_CHECKED)
|
||
MENU_CheckWidget(this_item->w, True);
|
||
}
|
||
|
||
return 1;
|
||
}
|
||
|
||
/**********************************************************************
|
||
* MENU_UseMenu
|
||
*/
|
||
LPMENUBAR
|
||
MENU_UseMenu(Widget parent, HANDLE instance, HWND wnd, HMENU hmenu, int width)
|
||
{
|
||
LPMENUBAR menubar;
|
||
MENUITEM *menu;
|
||
MENU_HEADER *menu_desc;
|
||
|
||
menu = (MENUITEM *) GlobalLock(hmenu);
|
||
if (hmenu == 0 || menu == NULL)
|
||
{
|
||
return NULL;
|
||
}
|
||
|
||
menubar = MENU_FindMenuBar(menu);
|
||
if (menubar == NULL)
|
||
{
|
||
GlobalUnlock(hmenu);
|
||
return NULL;
|
||
}
|
||
|
||
menubar->nItems = 0;
|
||
menubar->parentWidget = parent;
|
||
menubar->ownerWnd = wnd;
|
||
|
||
menu_desc = (MENU_HEADER *) GlobalLock(menubar->menuDescription);
|
||
|
||
parentItem = NULL;
|
||
siblingItem = NULL;
|
||
lastLevel = 0;
|
||
MENU_ParseMenu((WORD *) (menu_desc + 1), 0, 0, MENU_CreateItems, menubar);
|
||
|
||
menubar->menuBarWidget = menubar->firstItem->w;
|
||
|
||
menubar->next = firstMenu;
|
||
firstMenu = menubar;
|
||
|
||
return menubar;
|
||
}
|
||
|
||
/**********************************************************************
|
||
* MENU_CreateMenuBar
|
||
*/
|
||
LPMENUBAR
|
||
MENU_CreateMenuBar(Widget parent, HANDLE instance, HWND wnd,
|
||
char *menu_name, int width)
|
||
{
|
||
LPMENUBAR menubar;
|
||
HMENU hmenu;
|
||
MENUITEM *menu;
|
||
MENU_HEADER *menu_desc;
|
||
|
||
#ifdef DEBUG_MENU
|
||
printf("CreateMenuBar: instance %02x, menu '%s', width %d\n",
|
||
instance, menu_name, width);
|
||
#endif
|
||
|
||
hmenu = LoadMenu(instance, menu_name);
|
||
return MENU_UseMenu(parent, instance, wnd, hmenu, width);
|
||
}
|
||
|
||
/**********************************************************************
|
||
* MENU_FindItem
|
||
*/
|
||
MENUITEM *
|
||
MENU_FindItem(MENUITEM *menu, WORD item_id, WORD flags)
|
||
{
|
||
MENUITEM *item;
|
||
WORD position;
|
||
|
||
if (flags & MF_BYPOSITION)
|
||
{
|
||
item = menu;
|
||
for (position = 0; item != NULL && position != item_id; position++)
|
||
item = item->next;
|
||
|
||
if (position == item_id)
|
||
return item;
|
||
}
|
||
else
|
||
{
|
||
for ( ; menu != NULL; menu = menu->next)
|
||
{
|
||
if (menu->item_id == item_id && menu->child == NULL)
|
||
return menu;
|
||
if (menu->child != NULL)
|
||
{
|
||
item = MENU_FindItem(menu->child, item_id, flags);
|
||
if (item != NULL)
|
||
return item;
|
||
}
|
||
}
|
||
}
|
||
|
||
return NULL;
|
||
}
|
||
|
||
/**********************************************************************
|
||
* MENU_CollapseMenu
|
||
*/
|
||
static void
|
||
MENU_CollapseBranch(MENUITEM *item, Boolean first_flag)
|
||
{
|
||
MENUITEM *next_item;
|
||
|
||
for ( ; item != NULL; item = next_item)
|
||
{
|
||
next_item = item->next;
|
||
|
||
if (item->child != NULL)
|
||
MENU_CollapseBranch(item->child, False);
|
||
|
||
if (item->w != NULL)
|
||
XtDestroyWidget(item->w);
|
||
if (item->menu_w != NULL)
|
||
XtDestroyWidget(item->menu_w);
|
||
|
||
if (first_flag)
|
||
{
|
||
item->prev = NULL;
|
||
item->child = NULL;
|
||
item->next = NULL;
|
||
item->parent = NULL;
|
||
item->item_flags = 0;
|
||
item->item_id = 0;
|
||
item->item_text = NULL;
|
||
item->w = NULL;
|
||
item->menu_w = NULL;
|
||
|
||
first_flag = False;
|
||
}
|
||
else
|
||
{
|
||
GlobalFree((unsigned int) item);
|
||
}
|
||
}
|
||
}
|
||
|
||
void
|
||
MENU_CollapseMenu(LPMENUBAR menubar)
|
||
{
|
||
MENU_CollapseBranch(menubar->firstItem, True);
|
||
|
||
menubar->nItems = 0;
|
||
menubar->parentWidget = NULL;
|
||
menubar->ownerWnd = 0;
|
||
menubar->menuBarWidget = NULL;
|
||
}
|
||
|
||
|
||
/**********************************************************************
|
||
* CheckMenu
|
||
*/
|
||
BOOL
|
||
CheckMenu(HMENU hmenu, WORD item_id, WORD check_flags)
|
||
{
|
||
MENUITEM *item;
|
||
Pixmap left_bitmap;
|
||
|
||
if ((item = (MENUITEM *) GlobalLock(hmenu)) == NULL)
|
||
return -1;
|
||
|
||
item = MENU_FindItem(item, item_id, check_flags);
|
||
if (item == NULL)
|
||
{
|
||
GlobalUnlock(hmenu);
|
||
return -1;
|
||
}
|
||
|
||
XtVaGetValues(item->w, XtNleftBitmap, &left_bitmap, NULL);
|
||
MENU_CheckWidget(item->w, (check_flags & MF_CHECKED));
|
||
|
||
if (left_bitmap == XtUnspecifiedPixmap)
|
||
return MF_UNCHECKED;
|
||
else
|
||
return MF_CHECKED;
|
||
}
|
||
|
||
|
||
/**********************************************************************
|
||
* LoadMenu
|
||
*/
|
||
HMENU
|
||
LoadMenu(HINSTANCE instance, char *menu_name)
|
||
{
|
||
HANDLE hmenubar;
|
||
LPMENUBAR menu;
|
||
HANDLE hmenu_desc;
|
||
HMENU hmenu;
|
||
MENU_HEADER *menu_desc;
|
||
|
||
#ifdef DEBUG_MENU
|
||
printf("LoadMenu: instance %02x, menu '%s'\n",
|
||
instance, menu_name);
|
||
#endif
|
||
|
||
if (menu_name == NULL ||
|
||
(hmenu_desc = RSC_LoadMenu(instance, menu_name)) == 0 ||
|
||
(menu_desc = (MENU_HEADER *) GlobalLock(hmenu_desc)) == NULL)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
hmenubar = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUBAR));
|
||
menu = (LPMENUBAR) GlobalLock(hmenubar);
|
||
if (menu == NULL)
|
||
{
|
||
GlobalFree(hmenu_desc);
|
||
GlobalFree(hmenubar);
|
||
return 0;
|
||
}
|
||
|
||
hmenu = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM));
|
||
if (hmenu == 0)
|
||
{
|
||
GlobalFree(hmenu_desc);
|
||
GlobalFree(hmenubar);
|
||
return 0;
|
||
}
|
||
|
||
menu->menuDescription = hmenu_desc;
|
||
menu->nItems = 0;
|
||
menu->parentWidget = NULL;
|
||
menu->firstItem = (MENUITEM *) GlobalLock(hmenu);
|
||
menu->ownerWnd = 0;
|
||
menu->menuBarWidget = NULL;
|
||
|
||
menu->firstItem->next = NULL;
|
||
menu->firstItem->prev = NULL;
|
||
menu->firstItem->child = NULL;
|
||
menu->firstItem->parent = NULL;
|
||
menu->firstItem->item_flags = 0;
|
||
menu->firstItem->item_id = 0;
|
||
menu->firstItem->item_text = NULL;
|
||
menu->firstItem->w = NULL;
|
||
menu->firstItem->menu_w = NULL;
|
||
|
||
menu->next = firstMenu;
|
||
firstMenu = menu;
|
||
|
||
return GlobalHandleFromPointer(menu->firstItem);
|
||
}
|
||
|
||
#endif
|
||
|
||
|
||
/**********************************************************************
|
||
* CheckMenuItem [USER.154]
|
||
*/
|
||
BOOL CheckMenuItem(HMENU hMenu, WORD wItemID, WORD wFlags)
|
||
{
|
||
WND *wndPtr;
|
||
LPPOPUPMENU menu;
|
||
LPMENUITEM lpitem;
|
||
int i;
|
||
#ifdef DEBUG_MENU
|
||
printf("CheckMenuItem (%04X, %04X, %04X) !\n", hMenu, wItemID, 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 == wItemID) {
|
||
if (wFlags && MF_CHECKED)
|
||
lpitem->item_flags |= MF_CHECKED;
|
||
else
|
||
lpitem->item_flags &= ((WORD)-1 ^ MF_CHECKED);
|
||
return(TRUE);
|
||
}
|
||
lpitem = (LPMENUITEM)lpitem->next;
|
||
}
|
||
return FALSE;
|
||
}
|
||
|
||
|
||
/**********************************************************************
|
||
* EnableMenuItem [USER.155]
|
||
*/
|
||
BOOL EnableMenuItem(HMENU hMenu, WORD wItemID, WORD wFlags)
|
||
{
|
||
WND *wndPtr;
|
||
LPPOPUPMENU menu;
|
||
LPMENUITEM lpitem;
|
||
int i;
|
||
#ifdef DEBUG_MENU
|
||
printf("EnableMenuItem (%04X, %04X, %04X) !\n", hMenu, wItemID, 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 == wItemID) {
|
||
if (wFlags && MF_DISABLED)
|
||
lpitem->item_flags |= MF_DISABLED;
|
||
else
|
||
lpitem->item_flags &= ((WORD)-1 ^ MF_DISABLED);
|
||
return(TRUE);
|
||
}
|
||
lpitem = (LPMENUITEM)lpitem->next;
|
||
}
|
||
return FALSE;
|
||
}
|
||
|
||
|
||
/**********************************************************************
|
||
* InsertMenu [USER.410]
|
||
*/
|
||
BOOL InsertMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewItem)
|
||
{
|
||
WND *wndPtr;
|
||
LPPOPUPMENU menu;
|
||
HANDLE hNewItem;
|
||
LPMENUITEM lpitem, lpitem2;
|
||
int i;
|
||
#ifdef DEBUG_MENU
|
||
printf("InsertMenu (%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) break;
|
||
lpitem = (LPMENUITEM)lpitem->next;
|
||
printf("InsertMenu // during loop items !\n");
|
||
}
|
||
printf("InsertMenu // after loop items !\n");
|
||
hNewItem = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM));
|
||
if (hNewItem == 0) return FALSE;
|
||
lpitem2 = (LPMENUITEM)GlobalLock(hNewItem);
|
||
if (lpitem2 == NULL) {
|
||
GlobalFree(hNewItem);
|
||
return FALSE;
|
||
}
|
||
lpitem2->item_flags = wFlags;
|
||
lpitem2->item_id = wItemID;
|
||
if (((wFlags & MF_BITMAP) != MF_BITMAP) &&
|
||
((wFlags & MF_MENUBREAK) != MF_MENUBREAK) &&
|
||
((wFlags & MF_STRING) != MF_SEPARATOR)) {
|
||
lpitem2->item_text = lpNewItem;
|
||
lpitem2->sel_key = GetSelectionKey(lpitem2->item_text);
|
||
}
|
||
else
|
||
lpitem2->item_text = lpNewItem;
|
||
lpitem2->prev = lpitem;
|
||
if (lpitem->next != NULL)
|
||
lpitem2->next = lpitem->next;
|
||
else
|
||
lpitem2->next = NULL;
|
||
lpitem->next = lpitem2;
|
||
lpitem2->child = NULL;
|
||
lpitem2->parent = NULL;
|
||
lpitem2->w = NULL;
|
||
lpitem2->menu_w = NULL;
|
||
menu->nItems++;
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
/**********************************************************************
|
||
* AppendMenu [USER.411]
|
||
*/
|
||
BOOL AppendMenu(HMENU hMenu, WORD wFlags, WORD wItemID, LPSTR lpNewItem)
|
||
{
|
||
WND *wndPtr;
|
||
LPPOPUPMENU menu;
|
||
HANDLE hNewItem;
|
||
LPMENUITEM lpitem, lpitem2;
|
||
#ifdef DEBUG_MENU
|
||
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) return FALSE;
|
||
lpitem2 = (LPMENUITEM)GlobalLock(hNewItem);
|
||
if (lpitem2 == NULL) {
|
||
GlobalFree(hNewItem);
|
||
return FALSE;
|
||
}
|
||
lpitem2->item_flags = wFlags;
|
||
lpitem2->item_id = wItemID;
|
||
if (((wFlags & MF_BITMAP) != MF_BITMAP) &&
|
||
((wFlags & MF_MENUBREAK) != MF_MENUBREAK) &&
|
||
((wFlags & MF_STRING) != MF_SEPARATOR)) {
|
||
lpitem2->item_text = lpNewItem;
|
||
lpitem2->sel_key = GetSelectionKey(lpitem2->item_text);
|
||
lpitem2->shortcut = GetShortCutString(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->child = NULL;
|
||
lpitem2->parent = NULL;
|
||
lpitem2->w = NULL;
|
||
lpitem2->menu_w = NULL;
|
||
lpitem2->hCheckBit = (HBITMAP)NULL;
|
||
lpitem2->hUnCheckBit = (HBITMAP)NULL;
|
||
menu->nItems++;
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
/**********************************************************************
|
||
* RemoveMenu [USER.412]
|
||
*/
|
||
BOOL RemoveMenu(HMENU hMenu, WORD nPos, WORD wFlags)
|
||
{
|
||
WND *wndPtr;
|
||
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;
|
||
GlobalFree(HIWORD(lpitem));
|
||
return(TRUE);
|
||
}
|
||
lpitem = (LPMENUITEM)lpitem->next;
|
||
printf("RemoveMenu // during loop items !\n");
|
||
}
|
||
printf("RemoveMenu // after loop items !\n");
|
||
return FALSE;
|
||
}
|
||
|
||
|
||
/**********************************************************************
|
||
* DeleteMenu [USER.413]
|
||
*/
|
||
BOOL DeleteMenu(HMENU hMenu, WORD nPos, WORD wFlags)
|
||
{
|
||
#ifdef DEBUG_MENU
|
||
printf("DeleteMenu (%04X, %04X, %04X) !\n", hMenu, nPos, wFlags);
|
||
#endif
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
/**********************************************************************
|
||
* ModifyMenu [USER.414]
|
||
*/
|
||
BOOL ModifyMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewItem)
|
||
{
|
||
WND *wndPtr;
|
||
LPPOPUPMENU menu;
|
||
LPMENUITEM lpitem;
|
||
int i;
|
||
#ifdef DEBUG_MENU
|
||
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;
|
||
lpitem->item_text = lpNewItem;
|
||
return(TRUE);
|
||
}
|
||
lpitem = (LPMENUITEM)lpitem->next;
|
||
}
|
||
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->hWnd = 0;
|
||
menu->hWndParent = 0;
|
||
menu->MouseFlags = 0;
|
||
menu->BarFlags = 0;
|
||
menu->Width = 100;
|
||
menu->Height = 0;
|
||
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;
|
||
#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) return FALSE;
|
||
wndPtr = WIN_FindWndPtr(hWnd);
|
||
lppop->ownerWnd = hWnd;
|
||
if (lppop->hWnd == (HWND)NULL) {
|
||
lppop->hWnd = CreateWindow("POPUPMENU", "", WS_CHILD | WS_VISIBLE,
|
||
x, y, lppop->Width, lppop->Height, hWnd, 0,
|
||
wndPtr->hInstance, (LPSTR)lppop);
|
||
}
|
||
else {
|
||
ShowWindow(lppop->hWnd, SW_SHOW);
|
||
}
|
||
if (lppop->BarFlags == 0) {
|
||
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);
|
||
}
|
||
else {
|
||
MenuBarCalcSize(lppop->hWnd);
|
||
#ifdef DEBUG_MENU
|
||
printf("TrackMenuBar // x=%d y=%d Width=%d Height=%d\n",
|
||
x, y, lppop->Width, lppop->Height);
|
||
#endif
|
||
SetWindowPos(lppop->hWnd, 0, 0, -16, lppop->Width, lppop->Height,
|
||
SWP_NOZORDER);
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
/**********************************************************************
|
||
* SetMenuItemBitmaps [USER.418]
|
||
*/
|
||
BOOL SetMenuItemBitmaps(HMENU hMenu, WORD nPos, WORD wFlags,
|
||
HBITMAP hNewCheck, HBITMAP hNewUnCheck)
|
||
{
|
||
WND *wndPtr;
|
||
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;
|
||
return(TRUE);
|
||
}
|
||
lpitem = (LPMENUITEM)lpitem->next;
|
||
}
|
||
return FALSE;
|
||
}
|
||
|
||
|
||
/**********************************************************************
|
||
* CreateMenu [USER.151]
|
||
*/
|
||
HMENU CreateMenu()
|
||
{
|
||
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->hWnd = 0;
|
||
menu->hWndParent = 0;
|
||
menu->MouseFlags = 0;
|
||
menu->BarFlags = TRUE;
|
||
menu->Width = 100;
|
||
menu->Height = 0;
|
||
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;
|
||
}
|
||
GlobalFree(hMenu);
|
||
#ifdef DEBUG_MENU
|
||
printf("DestroyMenu (%04X) // End !\n", hMenu);
|
||
#endif
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
#ifdef USE_POPUPMENU
|
||
|
||
|
||
/**********************************************************************
|
||
* DrawMenuBar [USER.152]
|
||
*/
|
||
void DrawMenuBar(HWND hWnd)
|
||
{
|
||
WND *wndPtr;
|
||
#ifdef DEBUG_MENU
|
||
printf("DrawMenuBar (%04X)\n", hWnd);
|
||
#endif
|
||
wndPtr = WIN_FindWndPtr(hWnd);
|
||
if (wndPtr != NULL && wndPtr->hWndMenuBar != 0) {
|
||
InvalidateRect(wndPtr->hWndMenuBar, NULL, TRUE);
|
||
UpdateWindow(wndPtr->hWndMenuBar);
|
||
}
|
||
}
|
||
|
||
|
||
/**********************************************************************
|
||
* LoadMenu [USER.152]
|
||
*/
|
||
HMENU LoadMenu(HINSTANCE instance, char *menu_name)
|
||
{
|
||
HMENU hMenu;
|
||
HANDLE hMenu_desc;
|
||
MENU_HEADER *menu_desc;
|
||
|
||
#ifdef DEBUG_MENU
|
||
printf("LoadMenu: instance %02x, menu '%s'\n",
|
||
instance, menu_name);
|
||
#endif
|
||
if (menu_name == NULL ||
|
||
(hMenu_desc = RSC_LoadMenu(instance, menu_name)) == 0 ||
|
||
(menu_desc = (MENU_HEADER *) GlobalLock(hMenu_desc)) == NULL)
|
||
{
|
||
return 0;
|
||
}
|
||
hMenu = CreateMenu();
|
||
ParseMenuResource((WORD *) (menu_desc + 1), 0, hMenu);
|
||
|
||
return hMenu;
|
||
}
|
||
|
||
|
||
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
|
||
{
|
||
MENU_NORMALITEM *normal_item = (MENU_NORMALITEM *) item;
|
||
next_item = (WORD *) (normal_item->item_text +
|
||
strlen(normal_item->item_text) + 1);
|
||
AppendMenu(hMenu, normal_item->item_flags,
|
||
normal_item->item_id, normal_item->item_text);
|
||
}
|
||
}
|
||
while (!(*item & MF_END));
|
||
|
||
return next_item;
|
||
}
|
||
|
||
#endif
|
||
|