| 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 <X11/Xaw/SmeBSB.h> |
| #include <X11/Xaw/SmeLine.h> |
| #include <X11/Xaw/SimpleMenu.h> |
| #include "WinMenuButto.h" |
| #include "SmeMenuButto.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 |
| |