/* * Menus functions */ static char RCSId[] = "$Id$"; static char Copyright[] = "Copyright Martin Ayotte, 1993"; /* #define DEBUG_MENU */ #include #include #include "windows.h" #include "syscolor.h" #include "sysmetrics.h" #include "prototypes.h" #include "menu.h" #include "user.h" #include "heap.h" #include "win.h" #define SC_ABOUTWINE SC_SCREENSAVE+1 #define SC_SYSMENU SC_SCREENSAVE+2 #define SC_ABOUTWINEDLG SC_SCREENSAVE+3 /* Dimension of the menu bitmaps */ static WORD check_bitmap_width = 0, check_bitmap_height = 0; static WORD arrow_bitmap_width = 0, arrow_bitmap_height = 0; /* Space between 2 menu bar items */ #define MENU_BAR_ITEMS_SPACE 16 /* Height of a separator item */ #define SEPARATOR_HEIGHT 5 extern HINSTANCE hSysRes; HMENU hSysMenu = 0; HBITMAP hStdCheck = 0; HBITMAP hStdMnArrow = 0; static BOOL MenuHasFocus = FALSE; LPPOPUPMENU PopupMenuGetStorageHeader(HWND hwnd); LPPOPUPMENU PopupMenuGetWindowAndStorage(HWND hwnd, WND **wndPtr); void StdDrawMenuBar(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop, BOOL suppress_draw); BOOL MenuButtonDown(HWND hWnd, LPPOPUPMENU lppop, int x, int y); void MenuButtonUp(HWND hWnd, LPPOPUPMENU lppop, int x, int y); void MenuMouseMove(HWND hWnd, LPPOPUPMENU lppop, WORD wParam, int x, int y); void StdDrawPopupMenu(HWND hwnd); void ResetHiliteFlags(LPPOPUPMENU lppop); void SelectPrevItem(LPPOPUPMENU lppop); void SelectNextItem(LPPOPUPMENU lppop); BOOL ExecFocusedMenuItem(HWND hWnd, LPPOPUPMENU lppop); void MenuItemSelect(HWND hWnd, LPPOPUPMENU lppop, WORD wIndex); LPMENUITEM MenuFindItem(LPPOPUPMENU lppop, int x, int y, WORD *lpRet); LPMENUITEM MenuFindItemBySelKey(LPPOPUPMENU lppop, WORD key, WORD *lpRet); BOOL ActivateMenuBarFocus(HWND hWnd); BOOL MenuFocusLoop(HWND hWnd, LPPOPUPMENU lpmenu); LPMENUITEM FindMenuItem(HMENU hMenu, WORD nPos, WORD wFlags); LPMENUITEM GetMenuItemPtr(LPPOPUPMENU menu, WORD nPos); WORD GetSelectionKey(LPSTR str); LPSTR GetShortCutString(LPSTR str); int GetShortCutPos(LPSTR str); BOOL HideAllSubPopupMenu(LPPOPUPMENU menu); void InitStdBitmaps(); HMENU CopySysMenu(); WORD * ParseMenuResource(WORD *first_item, int level, HMENU hMenu); void SetMenuLogicalParent(HMENU hMenu, HWND hWnd); BOOL FAR PASCAL AboutWine_Proc(HWND hDlg, WORD msg, WORD wParam, LONG lParam); /*********************************************************************** * MENU_CalcItemSize * * Calculate the size of the menu item and store it in lpitem->rect. */ static void MENU_CalcItemSize( HDC hdc, LPMENUITEM lpitem, int orgX, int orgY, BOOL menuBar ) { DWORD dwSize; SetRect( &lpitem->rect, orgX, orgY, orgX, orgY ); if (lpitem->item_flags & MF_SEPARATOR) { lpitem->rect.bottom += SEPARATOR_HEIGHT; return; } if (!menuBar) lpitem->rect.right += check_bitmap_width+arrow_bitmap_width; if (lpitem->item_flags & MF_BITMAP) { BITMAP bm; HBITMAP hbitmap = (HBITMAP)LOWORD((LONG)lpitem->item_text); GetObject(hbitmap, sizeof(BITMAP), (LPSTR)&bm); lpitem->rect.right += bm.bmWidth; lpitem->rect.bottom += bm.bmHeight; return; } /* If we get here, then it is a text item */ if (menuBar) lpitem->rect.right += MENU_BAR_ITEMS_SPACE; dwSize = GetTextExtent( hdc, lpitem->item_text, strlen(lpitem->item_text)); lpitem->rect.right += LOWORD(dwSize); lpitem->rect.bottom += max( HIWORD(dwSize), SYSMETRICS_CYMENU ); } /*********************************************************************** * MENU_PopupMenuCalcSize * * Calculate the size of a popup menu. */ static void MENU_PopupMenuCalcSize( HWND hwnd ) { LPPOPUPMENU lppop; LPMENUITEM lpitem, lpitemStart, lptmp; WND *wndPtr; HDC hdc; int orgX, orgY, maxX; if (!(lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr))) return; SetRect( &lppop->rect, 0, 0, 0, 0 ); lppop->Width = lppop->Height = 0; if (lppop->nItems == 0) return; hdc = GetDC( hwnd ); maxX = 0; lpitemStart = lppop->firstItem; while (lpitemStart != NULL) { orgX = maxX; orgY = 0; /* Parse items until column break or end of menu */ for (lpitem = lpitemStart; lpitem != NULL; lpitem = lpitem->next) { if ((lpitem != lpitemStart) && (lpitem->item_flags & (MF_MENUBREAK | MF_MENUBARBREAK))) break; MENU_CalcItemSize( hdc, lpitem, orgX, orgY, FALSE ); maxX = max( maxX, lpitem->rect.right ); orgY = lpitem->rect.bottom; } /* Finish the column (set all items to the largest width found) */ for (lptmp = lpitemStart; lptmp != lpitem; lptmp = lptmp->next) { lptmp->rect.right = maxX; } /* And go to the next column */ lppop->Height = max( lppop->Height, orgY ); lpitemStart = lpitem; } lppop->Width = maxX; SetRect( &lppop->rect, 0, 0, lppop->Width, lppop->Height ); ReleaseDC( hwnd, hdc ); } /*********************************************************************** * MENU_MenuBarCalcSize * * Calculate the size of the menu bar. */ static void MENU_MenuBarCalcSize( HDC hdc, LPRECT lprect, LPPOPUPMENU lppop ) { LPMENUITEM lpitem, lpitemStart, lptmp; int orgX, orgY, maxY; if ((lprect == NULL) || (lppop == NULL)) return; if (lppop->nItems == 0) return; #ifdef DEBUG_MENUCALC printf("MenuBarCalcSize left=%d top=%d right=%d bottom=%d !\n", lprect->left, lprect->top, lprect->right, lprect->bottom); #endif lppop->Width = lprect->right - lprect->left; lppop->Height = 0; maxY = lprect->top; lpitemStart = lppop->firstItem; while (lpitemStart != NULL) { orgX = lprect->left; orgY = maxY; /* Parse items until line break or end of menu */ for (lpitem = lpitemStart; lpitem != NULL; lpitem = lpitem->next) { if ((lpitem != lpitemStart) && (lpitem->item_flags & (MF_MENUBREAK | MF_MENUBARBREAK))) break; MENU_CalcItemSize( hdc, lpitem, orgX, orgY, TRUE ); if (lpitem->rect.right > lprect->right) { if (lpitem != lpitemStart) break; else lpitem->rect.right = lprect->right; } maxY = max( maxY, lpitem->rect.bottom ); orgX = lpitem->rect.right; } /* Finish the line (set all items to the largest height found) */ for (lptmp = lpitemStart; lptmp != lpitem; lptmp = lptmp->next) { lptmp->rect.bottom = maxY; } /* And go to the next line */ lpitemStart = lpitem; } lprect->bottom = maxY; lppop->Height = lprect->bottom - lprect->top; CopyRect( &lppop->rect, lprect ); } /*********************************************************************** * MENU_DrawMenuItem * * Draw a single menu item. */ static void MENU_DrawMenuItem( HDC hdc, LPMENUITEM lpitem, LPRECT menuRect, BOOL menuBar ) { RECT rect; if (menuBar && (lpitem->item_flags & MF_SEPARATOR)) return; rect = lpitem->rect; /* Draw the background */ if (lpitem->item_flags & MF_HILITE) FillRect( hdc, &rect, sysColorObjects.hbrushHighlight ); else FillRect( hdc, &rect, sysColorObjects.hbrushMenu ); SetBkMode( hdc, TRANSPARENT ); /* Draw the separator bar (if any) */ if (!menuBar && (lpitem->item_flags & MF_MENUBARBREAK)) { SelectObject( hdc, sysColorObjects.hpenWindowFrame ); MoveTo( hdc, rect.left, menuRect->top ); LineTo( hdc, rect.left, menuRect->bottom ); } if (lpitem->item_flags & MF_SEPARATOR) { SelectObject( hdc, sysColorObjects.hpenWindowFrame ); MoveTo( hdc, rect.left, rect.top + SEPARATOR_HEIGHT/2 ); LineTo( hdc, rect.right, rect.top + SEPARATOR_HEIGHT/2 ); } if (!menuBar) { /* Draw the check mark */ if (lpitem->item_flags & MF_CHECKED) { HDC hMemDC = CreateCompatibleDC( hdc ); if (lpitem->hCheckBit == 0) SelectObject(hMemDC, hStdCheck); else SelectObject(hMemDC, lpitem->hCheckBit); BitBlt( hdc, rect.left, (rect.top + rect.bottom - check_bitmap_height) / 2, check_bitmap_width, check_bitmap_height, hMemDC, 0, 0, SRCCOPY ); DeleteDC( hMemDC ); } else /* Not checked */ { if (lpitem->hUnCheckBit != 0) { HDC hMemDC = CreateCompatibleDC( hdc ); SelectObject(hMemDC, lpitem->hUnCheckBit); BitBlt( hdc, rect.left, (rect.top + rect.bottom - check_bitmap_height) / 2, check_bitmap_width, check_bitmap_height, hMemDC, 0, 0, SRCCOPY ); DeleteDC( hMemDC ); } } /* Draw the popup-menu arrow */ if (lpitem->item_flags & MF_POPUP) { HDC hMemDC = CreateCompatibleDC( hdc ); SelectObject(hMemDC, hStdMnArrow); BitBlt( hdc, rect.right-arrow_bitmap_width, (rect.top + rect.bottom - arrow_bitmap_height) / 2, arrow_bitmap_width, arrow_bitmap_height, hMemDC, 0, 0, SRCCOPY ); DeleteDC(hMemDC); } rect.left += check_bitmap_width; rect.right -= arrow_bitmap_width; } /* Setup colors */ if (lpitem->item_flags & MF_HILITE) { SetTextColor( hdc, GetSysColor( COLOR_HIGHLIGHTTEXT ) ); SetBkColor( hdc, GetSysColor( COLOR_HIGHLIGHT ) ); } else { if (lpitem->item_flags & MF_GRAYED) SetTextColor( hdc, GetSysColor( COLOR_GRAYTEXT ) ); else SetTextColor( hdc, GetSysColor( COLOR_MENUTEXT ) ); SetBkColor( hdc, GetSysColor( COLOR_MENU ) ); } /* Draw the item text or bitmap */ if (lpitem->item_flags & MF_BITMAP) { HBITMAP hbitmap = (HBITMAP)LOWORD((LONG)lpitem->item_text); HDC hMemDC = CreateCompatibleDC( hdc ); SelectObject( hMemDC, hbitmap ); BitBlt( hdc, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, hMemDC, 0, 0, SRCCOPY ); DeleteDC( hMemDC ); return; } else /* No bitmap */ { int x = GetShortCutPos(lpitem->item_text); if (menuBar) { rect.left += MENU_BAR_ITEMS_SPACE / 2; rect.right -= MENU_BAR_ITEMS_SPACE / 2; } if (x != -1) { DrawText( hdc, lpitem->item_text, x, &rect, DT_LEFT | DT_VCENTER | DT_SINGLELINE ); DrawText( hdc, lpitem->item_text + x, -1, &rect, DT_RIGHT | DT_VCENTER | DT_SINGLELINE ); } else DrawText( hdc, lpitem->item_text, -1, &rect, DT_LEFT | DT_VCENTER | DT_SINGLELINE ); } } /*********************************************************************** * 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; PAINTSTRUCT ps; switch(message) { case WM_CREATE: #ifdef DEBUG_MENU printf("PopupMenu WM_CREATE lParam=%08X !\n", lParam); #endif createStruct = (CREATESTRUCT *)lParam; lppop = (LPPOPUPMENU)createStruct->lpCreateParams; if (lppop == NULL) break; wndPtr = WIN_FindWndPtr(hwnd); *((LPPOPUPMENU *)&wndPtr->wExtra[1]) = lppop; #ifdef DEBUG_MENU printf("PopupMenu WM_CREATE lppop=%08X !\n", lppop); #endif InitStdBitmaps(); #ifdef DEBUG_MENU printf("PopupMenu End of WM_CREATE !\n"); #endif ResetHiliteFlags(lppop); return 0; case WM_DESTROY: lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); #ifdef DEBUG_MENU printf("PopupMenu WM_DESTROY %lX !\n", lppop); #endif return 0; case WM_COMMAND: #ifdef DEBUG_MENU printf("PopupMenuWndProc // WM_COMMAND received !\n"); #endif lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); if (lppop == NULL) break; if (lppop->SysFlag) { MenuHasFocus = FALSE; if (wParam == SC_ABOUTWINE) { printf("SysMenu // Show 'About Wine ...' !\n"); /* DialogBox(hSysRes, MAKEINTRESOURCE(SC_ABOUTWINEDLG), */ DialogBox(hSysRes, MAKEINTRESOURCE(2), GetParent(hwnd), (FARPROC)AboutWine_Proc); } else { #ifdef DEBUG_MENU printf("PopupMenuWndProc // push to Owner WM_SYSCOMMAND !\n"); #endif PostMessage(lppop->ownerWnd, WM_SYSCOMMAND, wParam, lParam); } break; } #ifdef DEBUG_MENU printf("PopupMenuWndProc // push to Owner WM_COMMAND !\n"); #endif MenuHasFocus = FALSE; PostMessage(lppop->hWndParent, WM_COMMAND, wParam, lParam); break; case WM_SHOWWINDOW: #ifdef DEBUG_MENU printf("PopupMenuWndProc // WM_SHOWWINDOW received !\n"); #endif lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); if (lppop == NULL) break; if (wParam == 0 && lParam == 0L) { ResetHiliteFlags(lppop); HideAllSubPopupMenu(lppop); #ifdef DEBUG_MENU printf("PopupMenuWndProc hWnd=%04X WM_SHOWWINDOW -> HIDE!\n", hwnd); #endif if (lppop->SysFlag) MenuHasFocus = FALSE; SetFocus(lppop->hWndPrev); if (GetCapture() != 0) ReleaseCapture(); break; } lppop->FocusedItem = (WORD)-1; break; case WM_LBUTTONDOWN: lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); if (lppop == NULL) break; SetCapture(hwnd); MenuButtonDown(hwnd, lppop, LOWORD(lParam), HIWORD(lParam)); break; case WM_LBUTTONUP: lppop = PopupMenuGetStorageHeader(hwnd); if (lppop == NULL) break; ReleaseCapture(); MenuButtonUp(hwnd, lppop, LOWORD(lParam), HIWORD(lParam)); break; case WM_MOUSEMOVE: lppop = PopupMenuGetStorageHeader(hwnd); if (lppop == NULL) break; MenuMouseMove(hwnd, lppop, wParam, LOWORD(lParam), HIWORD(lParam)); break; case WM_KEYUP: #ifdef DEBUG_MENU printf("PopupMenuWndProc hWnd=%04X WM_KEYUP w=%04X l=%08X !\n", hwnd, wParam, lParam); #endif break; case WM_KEYDOWN: #ifdef DEBUG_MENU printf("PopupMenuWndProc hWnd=%04X WM_KEYDOWN w=%04X l=%08X !\n", hwnd, wParam, lParam); #endif if (lParam < 0L) break; lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); if (lppop == NULL) break; switch(wParam) { case VK_HOME: if (lppop->FocusedItem == 0) break; MenuItemSelect(hwnd, lppop, 0); break; case VK_UP: if (lppop->BarFlag) break; SelectPrevItem(lppop); break; case VK_DOWN: if (lppop->BarFlag) goto ProceedSPACE; SelectNextItem(lppop); break; case VK_LEFT: if (lppop->SysFlag != 0) { ShowWindow(hwnd, SW_HIDE); hwnd = lppop->hWndParent; lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); printf("VK_LEFT // try to put focus on MenuBar %08X !\n", lppop); if (lppop == NULL) break; MenuItemSelect(hwnd, lppop, lppop->nItems - 1); break; } if (lppop->BarFlag) { if (lppop->FocusedItem < 1) { MenuItemSelect(hwnd, lppop, -1); NC_TrackSysMenu(hwnd); break; } if (HideAllSubPopupMenu(lppop)) { MenuItemSelect(hwnd, lppop, lppop->FocusedItem - 1); goto ProceedSPACE; } } if (lppop->hWndParent != 0) { PostMessage(lppop->hWndParent, WM_KEYDOWN, wParam, lParam); break; } MenuItemSelect(hwnd, lppop, lppop->FocusedItem - 1); break; case VK_RIGHT: if (lppop->SysFlag != 0) { ShowWindow(hwnd, SW_HIDE); hwnd = lppop->hWndParent; lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); printf("VK_RIGHT // try to put focus on MenuBar %08X !\n", lppop); if (lppop == NULL) break; MenuItemSelect(hwnd, lppop, 0); break; } if (lppop->BarFlag) { if (lppop->FocusedItem >= lppop->nItems - 1) { MenuItemSelect(hwnd, lppop, -1); NC_TrackSysMenu(hwnd); break; } if (HideAllSubPopupMenu(lppop)) { MenuItemSelect(hwnd, lppop, lppop->FocusedItem + 1); goto ProceedSPACE; } } if (lppop->hWndParent != 0) { PostMessage(lppop->hWndParent, WM_KEYDOWN, wParam, lParam); break; } MenuItemSelect(hwnd, lppop, lppop->FocusedItem + 1); break; default: break; } break; case WM_CHAR: #ifdef DEBUG_MENU printf("PopupMenuWndProc hWnd=%04X WM_CHAR wParam=%04X !\n", hwnd, wParam); #endif if (lParam < 0L) break; hwnd = GetFocus(); lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); if (lppop == NULL) break; switch(wParam) { case VK_RETURN: case VK_SPACE: ProceedSPACE: lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); ExecFocusedMenuItem(hwnd, lppop); break; case VK_ESCAPE: if (lppop->BarFlag) { #ifdef DEBUG_MENU printf("VK_ESCAPE // Unselect all MenuBar's Items !\n"); #endif if (lppop->FocusedItem != (WORD)-1) MenuItemSelect(hwnd, lppop, -1); } if (lppop->SysFlag) { #ifdef DEBUG_MENU printf("VK_ESCAPE // SysMenu !\n"); #endif ShowWindow(hwnd, SW_HIDE); break; } if (lppop->hWndParent != 0) { #ifdef DEBUG_MENU printf("VK_ESCAPE // Hide only SubPopup !\n"); #endif lppop2 = PopupMenuGetWindowAndStorage(lppop->hWndParent, &wndPtr); if (lppop2 == NULL) break; HideAllSubPopupMenu(lppop2); break; } else { #ifdef DEBUG_MENU printf("VK_ESCAPE // Hide Root Popup !\n"); #endif ShowWindow(hwnd, SW_HIDE); MenuHasFocus = FALSE; } break; default: if (wParam >= 'a' && wParam <= 'z') wParam -= 'a' - 'A'; lpitem = MenuFindItemBySelKey(lppop, wParam, &wRet); if (lpitem != NULL) { printf("ShortKey Found wRet=%d !\n", wRet); MenuItemSelect(hwnd, lppop, wRet); lppop->FocusedItem = wRet; goto ProceedSPACE; } printf("ShortKey Not Found wParam=%04X wRet=%d lpitem=%08X !\n", wParam, wRet, lpitem); if (lppop->hWndParent != (HWND)NULL) SendMessage(lppop->hWndParent, WM_MENUCHAR, wParam, MAKELONG(0, 0)); else SendMessage(lppop->ownerWnd, WM_MENUCHAR, wParam, MAKELONG(0, 0)); break; } break; case WM_PAINT: #ifdef DEBUG_MENU printf("PopupMenuWndProc // WM_PAINT received !\n"); #endif StdDrawPopupMenu(hwnd); break; default: return DefWindowProc(hwnd, message, wParam, lParam); } return 0; } BOOL ExecFocusedMenuItem(HWND hWnd, LPPOPUPMENU lppop) { short x, y; LPPOPUPMENU lppop2; LPMENUITEM lpitem; HMENU hSubMenu; RECT rect; lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem); if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) { hSubMenu = (HMENU)lpitem->item_id; lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu); if (lppop2 == NULL) return FALSE; lppop2->hWndParent = hWnd; GetClientRect(hWnd, &rect); if (lppop->BarFlag) { GetWindowRect(hWnd, &rect); y = rect.top + lpitem->rect.bottom; TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, rect.left + lpitem->rect.left, y, 0, lppop->ownerWnd, (LPRECT)NULL); } else { x = lppop->rect.right; GetWindowRect(hWnd, &rect); x += rect.left; TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, x, rect.top + lpitem->rect.top, 0, lppop->ownerWnd, (LPRECT)NULL); } GlobalUnlock(hSubMenu); return TRUE; } if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && ((lpitem->item_flags & MF_POPUP) != MF_POPUP)) { MenuHasFocus = FALSE; if (lppop->BarFlag) { PostMessage(lppop->ownerWnd, WM_COMMAND, lpitem->item_id, 0L); } else { ShowWindow(lppop->hWnd, SW_HIDE); SendMessage(lppop->hWnd, WM_COMMAND, lpitem->item_id, 0L); } } return TRUE; } BOOL MenuButtonDown(HWND hWnd, LPPOPUPMENU lppop, int x, int y) { HDC hDC; LPMENUITEM lpitem, lpitem2; RECT rect; HMENU hSubMenu; WORD wRet; LPPOPUPMENU lppop2; if (lppop == NULL) return; lpitem = MenuFindItem(lppop, x, y, &wRet); #ifdef DEBUG_MENU printf("MenuButtonDown hWnd=%04X x=%d y=%d // wRet=%d lpitem=%08X !\n", hWnd, x, y, wRet, lpitem); #endif if (lpitem != NULL) { if (lppop->FocusedItem != (WORD)-1 && wRet == lppop->FocusedItem) { lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem); if ((lpitem2->item_flags & MF_POPUP) == MF_POPUP) { hSubMenu = (HMENU)lpitem2->item_id; lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu); if (lppop2 == NULL) return FALSE; if (IsWindowVisible(lppop2->hWnd)) { ShowWindow(lppop2->hWnd, SW_HIDE); return TRUE; } } } MenuItemSelect(hWnd, lppop, wRet); if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) { hSubMenu = (HMENU)lpitem->item_id; lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu); if (lppop2 == NULL) return FALSE; lppop2->hWndParent = hWnd; if (lppop->BarFlag) { GetWindowRect(hWnd, &rect); y = rect.top + lpitem->rect.bottom; ReleaseCapture(); if (MenuHasFocus) { TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, rect.left + lpitem->rect.left, y, 0, lppop->ownerWnd, (LPRECT)NULL); } else { MenuHasFocus = TRUE; TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, rect.left + lpitem->rect.left, y, 0, lppop->ownerWnd, (LPRECT)NULL); MenuHasFocus = FALSE; MenuFocusLoop(hWnd, lppop); return TRUE; } } else { x = lppop->rect.right; GetWindowRect(hWnd, &rect); x += rect.left; TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, x, rect.top + lpitem->rect.top, 0, lppop->ownerWnd, (LPRECT)NULL); } GlobalUnlock(hSubMenu); return TRUE; } if (lppop->BarFlag && !MenuHasFocus) { MenuFocusLoop(hWnd, lppop); } return TRUE; } printf("MenuButtonDown // x=%d y=%d // Not Found !\n", x, y); if (GetCapture() != 0) ReleaseCapture(); MenuHasFocus = FALSE; ShowWindow(lppop->hWnd, SW_HIDE); return FALSE; } void MenuButtonUp(HWND hWnd, LPPOPUPMENU lppop, int x, int y) { HDC hDC; LPMENUITEM lpitem, lpitem2; RECT rect; HMENU hSubMenu; WORD wRet; LPPOPUPMENU lppop2; if (lppop == NULL) return; lpitem = MenuFindItem(lppop, x, y, &wRet); #ifdef DEBUG_MENU printf("MenuButtonUp // x=%d y=%d // wRet=%d lpitem=%08X !\n", x, y, wRet, lpitem); #endif if (lpitem != NULL) { if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) { return; } if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && ((lpitem->item_flags & MF_POPUP) != MF_POPUP)) { MenuHasFocus = FALSE; if (lppop->BarFlag) { PostMessage(lppop->ownerWnd, WM_COMMAND, lpitem->item_id, 0L); } else { ShowWindow(lppop->hWnd, SW_HIDE); SendMessage(lppop->hWnd, WM_COMMAND, lpitem->item_id, 0L); } return; } } if (lppop->FocusedItem != (WORD)-1) { MenuItemSelect(hWnd, lppop, lppop->FocusedItem); } } void MenuMouseMove(HWND hWnd, LPPOPUPMENU lppop, WORD wParam, int x, int y) { HDC hDC; RECT rect; HMENU hSubMenu; LPMENUITEM lpitem, lpitem2; LPPOPUPMENU lppop2; WORD wRet; if (GetKeyState(VK_LBUTTON) != 0) { lpitem = MenuFindItem(lppop, x, y, &wRet); #ifdef DEBUG_MENU printf("MenuMouseMove // x=%d y=%d // wRet=%d lpitem=%08X !\n", x, y, wRet, lpitem); #endif if ((lpitem != NULL) && (lppop->FocusedItem != wRet)) { lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem); hDC = GetWindowDC(hWnd); if ((lpitem2 != NULL ) && (lpitem2->item_flags & MF_POPUP) == MF_POPUP) { HideAllSubPopupMenu(lppop); } MenuItemSelect(hWnd, lppop, wRet); if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) { hSubMenu = (HMENU)lpitem->item_id; lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu); if (lppop2 == NULL) { ReleaseDC(hWnd, hDC); return; } if (lppop->BarFlag) { lppop2->hWndParent = hWnd; GetWindowRect(hWnd, &rect); rect.top += lpitem->rect.bottom; TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, rect.left + lpitem->rect.left, rect.top, 0, lppop->ownerWnd, (LPRECT)NULL); } GlobalUnlock(hSubMenu); } ReleaseDC(hWnd, hDC); } } } void SelectPrevItem(LPPOPUPMENU lppop) { int nIndex; LPMENUITEM lpitem; if (lppop == NULL) return; nIndex = lppop->FocusedItem; if (nIndex < 1) { if (nIndex == -1) nIndex = 0; else nIndex = lppop->nItems - 1; lpitem = GetMenuItemPtr(lppop, nIndex); } else { nIndex--; lpitem = GetMenuItemPtr(lppop, nIndex); } while (lpitem != NULL && lpitem->item_flags & MF_SEPARATOR) { nIndex--; lpitem = GetMenuItemPtr(lppop, nIndex); } MenuItemSelect(lppop->hWnd, lppop, nIndex); } void SelectNextItem(LPPOPUPMENU lppop) { int nIndex; LPMENUITEM lpitem; if (lppop == NULL) return; nIndex = lppop->FocusedItem; if ((nIndex == -1) || (nIndex >= lppop->nItems - 1)) { nIndex = 0; lpitem = GetMenuItemPtr(lppop, nIndex); } else { nIndex++; lpitem = GetMenuItemPtr(lppop, nIndex); } while (lpitem != NULL && (lpitem->item_flags & MF_SEPARATOR)) { nIndex++; lpitem = GetMenuItemPtr(lppop, nIndex); } MenuItemSelect(lppop->hWnd, lppop, nIndex); } void ResetHiliteFlags(LPPOPUPMENU lppop) { LPMENUITEM lpitem; int i; #ifdef DEBUG_MENU printf("ResetHiliteFlags lppop=%08X\n", lppop); #endif if (lppop == NULL) return; lpitem = lppop->firstItem; for(i = 0; i < lppop->nItems; i++) { if (lpitem == NULL) return; lpitem->item_flags &= ~MF_HILITE; lpitem = (LPMENUITEM)lpitem->next; } } void MenuItemSelect(HWND hWnd, LPPOPUPMENU lppop, WORD wIndex) { LPMENUITEM lpitem; HDC hdc; if (lppop == NULL) return; if (lppop->BarFlag) hdc = GetDCEx( hWnd, 0, DCX_CACHE | DCX_WINDOW ); else hdc = GetDC( hWnd ); /* Clear previous highlighted item */ if (lppop->FocusedItem != (WORD)-1) { if ((lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem)) != NULL) { lpitem->item_flags &= ~MF_HILITE; if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) HideAllSubPopupMenu(lppop); MENU_DrawMenuItem( hdc, lpitem, &lppop->rect, lppop->BarFlag ); } } /* Highlight new item (if any) */ lppop->FocusedItem = wIndex; if (lppop->FocusedItem != (WORD)-1) { if ((lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem)) != NULL) { lpitem->item_flags |= MF_HILITE; MENU_DrawMenuItem( hdc, lpitem, &lppop->rect, lppop->BarFlag ); SendMessage(hWnd, WM_MENUSELECT, lpitem->item_id, MAKELONG(0, lpitem->item_flags)); } } ReleaseDC( hWnd, hdc ); } LPPOPUPMENU PopupMenuGetWindowAndStorage(HWND hwnd, WND **wndPtr) { WND *Ptr; LPPOPUPMENU lppop; *(wndPtr) = Ptr = WIN_FindWndPtr(hwnd); if (Ptr == 0) { printf("PopupMenuGetWindowAndStorage // Bad Window handle !\n"); return NULL; } lppop = *((LPPOPUPMENU *)&Ptr->wExtra[1]); if (lppop == NULL) { lppop = (LPPOPUPMENU) GlobalLock(Ptr->wIDmenu); if (lppop == NULL) { printf("PopupMenuGetWindowAndStorage // Bad Menu Handle !\n"); return NULL; } } return lppop; } LPPOPUPMENU PopupMenuGetStorageHeader(HWND hwnd) { WND *Ptr; LPPOPUPMENU lppop; Ptr = WIN_FindWndPtr(hwnd); if (Ptr == 0) { printf("Bad Window handle on PopupMenu !\n"); return 0; } lppop = *((LPPOPUPMENU *)&Ptr->wExtra[1]); return lppop; } void SetMenuLogicalParent(HMENU hMenu, HWND hWnd) { LPPOPUPMENU lppop; lppop = (LPPOPUPMENU)GlobalLock(hMenu); lppop->hWndParent = hWnd; GlobalUnlock(hMenu); } void StdDrawPopupMenu(HWND hwnd) { WND *wndPtr; LPPOPUPMENU lppop; LPMENUITEM lpitem; PAINTSTRUCT ps; RECT rect; HDC hDC; hDC = BeginPaint(hwnd, &ps); GetClientRect(hwnd, &rect); FillRect(hDC, &rect, sysColorObjects.hbrushMenu ); lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); for (lpitem = lppop->firstItem; lpitem != NULL; lpitem = lpitem->next ) { MENU_DrawMenuItem( hDC, lpitem, &rect, FALSE ); } EndPaint( hwnd, &ps ); } void StdDrawMenuBar(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop, BOOL suppress_draw) { LPMENUITEM lpitem; if (lppop == NULL || lprect == NULL) return; #ifdef DEBUG_MENU printf("StdDrawMenuBar(%04X, %08X, %08X); !\n", hDC, lprect, lppop); #endif if (lppop->Height == 0) MENU_MenuBarCalcSize(hDC, lprect, lppop); if (suppress_draw) return; FillRect(hDC, lprect, sysColorObjects.hbrushMenu ); SelectObject( hDC, sysColorObjects.hpenWindowFrame ); MoveTo( hDC, lprect->left, lprect->bottom ); LineTo( hDC, lprect->right, lprect->bottom ); if (lppop->nItems == 0) return; for (lpitem = lppop->firstItem; lpitem != NULL; lpitem = lpitem->next ) { MENU_DrawMenuItem( hDC, lpitem, lprect, TRUE ); } } LPMENUITEM MenuFindItem(LPPOPUPMENU lppop, int x, int y, WORD *lpRet) { LPMENUITEM lpitem; UINT i; if (lpRet != NULL) *lpRet = 0; if (lppop == NULL) return NULL; if (lppop->nItems == 0) return NULL; lpitem = lppop->firstItem; for(i = 0; i < lppop->nItems; i++) { if (lpitem == NULL) return NULL; #ifdef DEBUG_MENUFINDITEM printf("FindItem // left=%d top=%d right=%d bottom=%d\n", lpitem->rect.left, lpitem->rect.top, lpitem->rect.right, lpitem->rect.bottom); #endif if (x > lpitem->rect.left && x < lpitem->rect.right && y > lpitem->rect.top && y < lpitem->rect.bottom) { if (lpRet != NULL) *lpRet = i; return lpitem; } lpitem = (LPMENUITEM)lpitem->next; } return NULL; } LPMENUITEM MenuFindItemBySelKey(LPPOPUPMENU lppop, WORD key, WORD *lpRet) { LPMENUITEM lpitem; UINT i; if (lppop == NULL) return NULL; if (lppop->nItems == 0) return NULL; lpitem = lppop->firstItem; for(i = 0; i < lppop->nItems; i++) { if (lpitem == NULL) return NULL; #ifdef DEBUG_MENUFINDITEM printf("FindItemBySelKey // key=%04X lpitem->sel_key=%04X\n", key, lpitem->sel_key); #endif if (key == lpitem->sel_key) { if (lpRet != NULL) *lpRet = i; return lpitem; } lpitem = (LPMENUITEM)lpitem->next; } return NULL; } /*********************************************************************** * MENU_GetMenuBarHeight * * Compute the size of the menu bar height. Used by NC_HandleNCCalcSize(). */ WORD MENU_GetMenuBarHeight( HWND hwnd, WORD menubarWidth, int orgX, int orgY ) { HDC hdc; RECT rectBar; WND *wndPtr; LPPOPUPMENU lppop; if (!(lppop = PopupMenuGetWindowAndStorage( hwnd, &wndPtr ))) return 0; if (!wndPtr) return 0; hdc = GetDC( hwnd ); SetRect( &rectBar, orgX, orgY, orgX+menubarWidth, orgY+SYSMETRICS_CYMENU ); MENU_MenuBarCalcSize( hdc, &rectBar, lppop ); ReleaseDC( hwnd, hdc ); printf( "MENU_GetMenuBarHeight: returning %d\n", lppop->Height ); return lppop->Height; } /*********************************************************************** * FindMenuItem */ LPMENUITEM FindMenuItem(HMENU hMenu, WORD nPos, WORD wFlags) { LPPOPUPMENU menu; LPMENUITEM lpitem; int i; menu = (LPPOPUPMENU) GlobalLock(hMenu); if (menu == NULL) { GlobalUnlock(hMenu); return FALSE; } lpitem = menu->firstItem; if (wFlags & MF_BYPOSITION) { for (i = 0; i < nPos; i++, lpitem = lpitem->next) if (lpitem == NULL) return NULL; } else { for (i = 0; i < menu->nItems && lpitem != NULL; i++) { if (lpitem->item_id == nPos) return lpitem; lpitem = lpitem->next; } return NULL; } return lpitem; } LPMENUITEM GetMenuItemPtr(LPPOPUPMENU menu, WORD nPos) { LPMENUITEM lpitem; int i; if (menu == NULL) return NULL; lpitem = menu->firstItem; for (i = 0; i < menu->nItems; i++) { if (lpitem == NULL) return NULL; if (i == nPos) return(lpitem); lpitem = (LPMENUITEM)lpitem->next; } return NULL; } WORD GetSelectionKey(LPSTR str) { int i; WORD sel_key; for (i = 0; i < strlen(str); i++) { if (str[i] == '&' && str[i + 1] != '&') { sel_key = str[i + 1]; if (sel_key >= 'a' && sel_key <= 'z') sel_key -= 'a' - 'A'; #ifdef DEBUG_MENU printf("GetSelectionKey // %04X\n", sel_key); #endif return sel_key; } } #ifdef DEBUG_MENU printf("GetSelectionKey NULL \n"); #endif return 0; } LPSTR GetShortCutString(LPSTR str) { int i; LPSTR str2; for (i = 0; i < strlen(str); i++) { if (str[i] == '\t' && str[i + 1] != '\t') { str2 = &str[i + 1]; #ifdef DEBUG_MENUSHORTCUT printf("GetShortCutString // '%s' \n", str2); #endif return str2; } } #ifdef DEBUG_MENUSHORTCUT printf("GetShortCutString NULL \n"); #endif return NULL; } int GetShortCutPos(LPSTR str) { int i; for (i = 0; i < strlen(str); i++) { if (str[i] == '\t' && str[i + 1] != '\t') { #ifdef DEBUG_MENUSHORTCUT printf("GetShortCutPos = %d \n", i); #endif return i; } } #ifdef DEBUG_MENUSHORTCUT printf("GetShortCutString NULL \n"); #endif return -1; } BOOL HideAllSubPopupMenu(LPPOPUPMENU menu) { LPPOPUPMENU submenu; LPMENUITEM lpitem; BOOL someClosed = FALSE; int i; if (menu == NULL) return; lpitem = menu->firstItem; for (i = 0; i < menu->nItems; i++) { if (lpitem == NULL) return; if (lpitem->item_flags & MF_POPUP) { submenu = (LPPOPUPMENU) GlobalLock((HMENU)lpitem->item_id); if (submenu != NULL) { if (IsWindowVisible(submenu->hWnd)) { ShowWindow(submenu->hWnd, SW_HIDE); someClosed = TRUE; } GlobalUnlock((HMENU)lpitem->item_id); } } lpitem = (LPMENUITEM)lpitem->next; } return someClosed; } /********************************************************************** * ChangeMenu [USER.153] */ BOOL ChangeMenu(HMENU hMenu, WORD nPos, LPSTR lpNewItem, WORD wItemID, WORD wFlags) { if (wFlags & MF_APPEND) return AppendMenu(hMenu, wFlags, wItemID, lpNewItem); if (wFlags & MF_DELETE) return DeleteMenu(hMenu, wItemID, wFlags); if (wFlags & MF_INSERT) return InsertMenu(hMenu, nPos, wFlags, wItemID, lpNewItem); if (wFlags & MF_CHANGE) return ModifyMenu(hMenu, nPos, wFlags, wItemID, lpNewItem); if (wFlags & MF_REMOVE) return RemoveMenu(hMenu, wItemID, wFlags); return FALSE; } /********************************************************************** * CheckMenuItem [USER.154] */ BOOL CheckMenuItem(HMENU hMenu, WORD wItemID, WORD wFlags) { LPMENUITEM lpitem; #ifdef DEBUG_MENU printf("CheckMenuItem (%04X, %04X, %04X) !\n", hMenu, wItemID, wFlags); #endif lpitem = FindMenuItem(hMenu, wItemID, wFlags); if (lpitem != NULL) { if ((wFlags & MF_CHECKED) == MF_CHECKED) lpitem->item_flags |= MF_CHECKED; else lpitem->item_flags &= ((WORD)-1 ^ MF_CHECKED); #ifdef DEBUG_MENU printf("CheckMenuItem // Found !\n"); #endif return(TRUE); } return FALSE; } /********************************************************************** * EnableMenuItem [USER.155] */ BOOL EnableMenuItem(HMENU hMenu, WORD wItemID, WORD wFlags) { LPMENUITEM lpitem; #ifdef DEBUG_MENU printf("EnableMenuItem (%04X, %04X, %04X) !\n", hMenu, wItemID, wFlags); #endif if (!(lpitem = FindMenuItem(hMenu, wItemID, wFlags))) return FALSE; /* We can't have MF_GRAYED and MF_DISABLED together */ if (wFlags & MF_GRAYED) { lpitem->item_flags = (lpitem->item_flags & ~MF_DISABLED) | MF_GRAYED; } else if (wFlags & MF_DISABLED) { lpitem->item_flags = (lpitem->item_flags & ~MF_GRAYED) | MF_DISABLED; } else /* MF_ENABLED */ { lpitem->item_flags &= ~(MF_GRAYED | MF_DISABLED); } return TRUE; } /********************************************************************** * GetMenuString [USER.161] */ int GetMenuString(HMENU hMenu, WORD wItemID, LPSTR str, short nMaxSiz, WORD wFlags) { LPMENUITEM lpitem; int maxsiz; #ifdef DEBUG_MENU printf("GetMenuString(%04X, %04X, %08X, %d, %04X);\n", hMenu, wItemID, str, nMaxSiz, wFlags); #endif if (str == NULL) return FALSE; lpitem = FindMenuItem(hMenu, wItemID, wFlags); if (lpitem != NULL) { if (lpitem->item_text != NULL) { maxsiz = min(nMaxSiz - 1, strlen(lpitem->item_text)); strncpy(str, lpitem->item_text, maxsiz + 1); } else maxsiz = 0; #ifdef DEBUG_MENU printf("GetMenuString // Found !\n"); #endif return maxsiz; } return 0; } /********************************************************************** * HiliteMenuItem [USER.162] */ BOOL HiliteMenuItem(HWND hWnd, HMENU hMenu, WORD wItemID, WORD wHilite) { LPPOPUPMENU menu; LPMENUITEM lpitem; #ifdef DEBUG_MENU printf("HiliteMenuItem(%04X, %04X, %04X, %04X);\n", hWnd, hMenu, wItemID, wHilite); #endif menu = (LPPOPUPMENU) GlobalLock(hMenu); if (menu == NULL) return FALSE; lpitem = FindMenuItem(hMenu, wItemID, wHilite); if (lpitem == NULL) return FALSE; return FALSE; } /********************************************************************** * GetMenuState [USER.250] */ WORD GetMenuState(HMENU hMenu, WORD wItemID, WORD wFlags) { LPPOPUPMENU menu; LPMENUITEM lpitem; #ifdef DEBUG_MENU printf("GetMenuState(%04X, %04X, %04X);\n", hMenu, wItemID, wFlags); #endif menu = (LPPOPUPMENU) GlobalLock(hMenu); if (menu == NULL) return -1; lpitem = FindMenuItem(hMenu, wItemID, wFlags); if (lpitem == NULL) return -1; return lpitem->item_flags; } /********************************************************************** * GetMenuItemCount [USER.263] */ WORD GetMenuItemCount(HMENU hMenu) { LPPOPUPMENU menu; #ifdef DEBUG_MENU printf("GetMenuItemCount(%04X);\n", hMenu); #endif menu = (LPPOPUPMENU) GlobalLock(hMenu); if (menu == NULL) return (WORD)-1; #ifdef DEBUG_MENU printf("GetMenuItemCount(%04X) return %d \n", hMenu, menu->nItems); #endif return menu->nItems; } /********************************************************************** * GetMenuItemID [USER.264] */ WORD GetMenuItemID(HMENU hMenu, int nPos) { WORD i; LPPOPUPMENU menu; LPMENUITEM lpitem; printf("GetMenuItemID(%04X, %d);\n", hMenu, nPos); menu = (LPPOPUPMENU) GlobalLock(hMenu); if (menu == NULL) return -1; lpitem = menu->firstItem; for (i = 0; i < menu->nItems; i++) { if (lpitem == NULL) break; if (i == nPos) { #ifdef DEBUG_MENU printf("GetMenuItemID // Found !\n"); #endif return lpitem->item_id; } lpitem = (LPMENUITEM)lpitem->next; } return -1; } /********************************************************************** * InsertMenu [USER.410] */ BOOL InsertMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewItem) { LPPOPUPMENU menu; HANDLE hNewItem; LPMENUITEM lpitem, lpitem2; #ifdef DEBUG_MENU if ((wFlags & (MF_BITMAP | MF_SEPARATOR | MF_MENUBREAK | MF_OWNERDRAW)) == 0) printf("InsertMenu (%04X, %04X, %04X, '%s') !\n", hMenu, wFlags, wItemID, lpNewItem); else printf("InsertMenu (%04X, %04X, %04X, %04X, %08X) !\n", hMenu, nPos, wFlags, wItemID, lpNewItem); #endif menu = (LPPOPUPMENU) GlobalLock(hMenu); if (menu == NULL) return FALSE; lpitem = FindMenuItem(hMenu, nPos, wFlags); if (lpitem == NULL) lpitem = menu->firstItem; hNewItem = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM)); if (hNewItem == 0) { GlobalUnlock(hMenu); return FALSE; } lpitem2 = (LPMENUITEM)GlobalLock(hNewItem); if (lpitem2 == NULL) { GlobalFree(hNewItem); GlobalUnlock(hMenu); return FALSE; } lpitem2->hItem = hNewItem; lpitem2->item_flags = wFlags; lpitem2->item_id = wItemID; if (!(wFlags & (MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK | MF_MENUBREAK | MF_SEPARATOR))) { lpitem2->hText = GlobalAlloc(GMEM_MOVEABLE, strlen(lpNewItem) + 1); lpitem2->item_text = GlobalLock(lpitem2->hText); if (lpitem2->item_text != NULL) strcpy(lpitem2->item_text, lpNewItem); else { printf("InsertMenu // Bad Alloc !\n"); return FALSE; } lpitem2->sel_key = GetSelectionKey(lpitem2->item_text); } else { lpitem2->item_text = lpNewItem; } if (lpitem == NULL) { menu->firstItem = lpitem2; lpitem2->prev = NULL; lpitem2->next = NULL; } else { lpitem2->prev = lpitem; lpitem2->next = lpitem->next; if (lpitem2->next != NULL) lpitem2->next->prev = lpitem2; lpitem->next = lpitem2; } menu->nItems++; GlobalUnlock(hMenu); return TRUE; } /********************************************************************** * AppendMenu [USER.411] */ BOOL AppendMenu(HMENU hMenu, WORD wFlags, WORD wItemID, LPSTR lpNewItem) { LPPOPUPMENU menu; HANDLE hNewItem; LPMENUITEM lpitem, lpitem2; #ifdef DEBUG_MENU if ((wFlags & (MF_BITMAP | MF_SEPARATOR | MF_MENUBREAK | MF_OWNERDRAW)) == 0) printf("AppendMenu (%04X, %04X, %04X, '%s') !\n", hMenu, wFlags, wItemID, lpNewItem); else printf("AppendMenu (%04X, %04X, %04X, %08X) !\n", hMenu, wFlags, wItemID, lpNewItem); #endif menu = (LPPOPUPMENU) GlobalLock(hMenu); if (menu == NULL) return FALSE; lpitem = menu->firstItem; if (lpitem != NULL) { while (lpitem->next != NULL) { lpitem = (LPMENUITEM)lpitem->next; } } hNewItem = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM)); if (hNewItem == 0) { GlobalUnlock(hMenu); return FALSE; } lpitem2 = (LPMENUITEM)GlobalLock(hNewItem); lpitem2->hItem = hNewItem; if (lpitem2 == NULL) { GlobalFree(hNewItem); GlobalUnlock(hMenu); return FALSE; } lpitem2->item_flags = wFlags; lpitem2->item_id = wItemID; if (!(wFlags & (MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK | MF_MENUBREAK | MF_SEPARATOR))) { lpitem2->hText = GlobalAlloc(GMEM_MOVEABLE, strlen(lpNewItem) + 1); lpitem2->item_text = GlobalLock(lpitem2->hText); if (lpitem2->item_text != NULL) strcpy(lpitem2->item_text, lpNewItem); else { printf("AppendMenu // Bad Alloc !\n"); return FALSE; } lpitem2->sel_key = GetSelectionKey(lpitem2->item_text); } else { lpitem2->item_text = lpNewItem; } if (lpitem == NULL) menu->firstItem = lpitem2; else lpitem->next = lpitem2; lpitem2->prev = lpitem; lpitem2->next = NULL; lpitem2->hCheckBit = (HBITMAP)NULL; lpitem2->hUnCheckBit = (HBITMAP)NULL; menu->nItems++; GlobalUnlock(hMenu); return TRUE; } /********************************************************************** * RemoveMenu [USER.412] */ BOOL RemoveMenu(HMENU hMenu, WORD nPos, WORD wFlags) { LPPOPUPMENU menu; LPMENUITEM lpitem; int i; #ifdef DEBUG_MENU printf("RemoveMenu (%04X, %04X, %04X) !\n", hMenu, nPos, wFlags); #endif menu = (LPPOPUPMENU) GlobalLock(hMenu); if (menu == NULL) return FALSE; lpitem = menu->firstItem; for (i = 0; i < menu->nItems; i++) { if (lpitem == NULL) break; if (i == nPos) { lpitem->prev->next = lpitem->next; lpitem->next->prev = lpitem->prev; if (!(lpitem->item_flags & (MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK | MF_MENUBREAK | MF_SEPARATOR))) { GlobalUnlock(lpitem->hText); GlobalFree(lpitem->hText); } GlobalFree(lpitem->hItem); GlobalUnlock(hMenu); return TRUE; } lpitem = (LPMENUITEM)lpitem->next; printf("RemoveMenu // during loop items !\n"); } printf("RemoveMenu // after loop items !\n"); GlobalUnlock(hMenu); return FALSE; } /********************************************************************** * DeleteMenu [USER.413] */ BOOL DeleteMenu(HMENU hMenu, WORD nPos, WORD wFlags) { LPPOPUPMENU menu; LPMENUITEM lpitem; int i; #ifdef DEBUG_MENU printf("DeleteMenu (%04X, %04X, %04X) !\n", hMenu, nPos, wFlags); #endif menu = (LPPOPUPMENU) GlobalLock(hMenu); if (menu == NULL) { GlobalUnlock(hMenu); return FALSE; } lpitem = FindMenuItem(hMenu, nPos, wFlags); if (lpitem != NULL) { if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) DestroyMenu((HMENU)lpitem->item_id); if (!(lpitem->item_flags & (MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK | MF_MENUBREAK | MF_SEPARATOR))) { GlobalUnlock(lpitem->hText); GlobalFree(lpitem->hText); } if (lpitem->prev) lpitem->prev->next = lpitem->next; if (lpitem->next) lpitem->next->prev = lpitem->prev; GlobalFree(lpitem->hItem); GlobalUnlock(hMenu); return TRUE; } GlobalUnlock(hMenu); return FALSE; } /********************************************************************** * ModifyMenu [USER.414] */ BOOL ModifyMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewItem) { LPPOPUPMENU menu; LPMENUITEM lpitem; int i; #ifdef DEBUG_MENU if ((wFlags & (MF_BITMAP | MF_SEPARATOR | MF_MENUBREAK | MF_OWNERDRAW)) == 0) printf("ModifyMenu (%04X, %04X, %04X, %04X, '%s') !\n", hMenu, nPos, wFlags, wItemID, lpNewItem); else printf("ModifyMenu (%04X, %04X, %04X, %04X, %08X) !\n", hMenu, nPos, wFlags, wItemID, lpNewItem); #endif menu = (LPPOPUPMENU) GlobalLock(hMenu); if (menu == NULL) return FALSE; lpitem = menu->firstItem; for (i = 0; i < menu->nItems; i++) { if (lpitem == NULL) break; if (i == nPos) { lpitem->item_flags = wFlags; lpitem->item_id = wItemID; if (!(lpitem->item_flags & (MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK | MF_MENUBREAK | MF_SEPARATOR))) { GlobalUnlock(lpitem->hText); GlobalFree(lpitem->hText); lpitem->hText = GlobalAlloc(GMEM_MOVEABLE, strlen(lpNewItem) + 1); lpitem->item_text = GlobalLock(lpitem->hText); printf("ModifyMenu %08X %08X '%s') !\n", lpitem->item_text, lpNewItem, lpNewItem); if (lpitem->item_text != NULL) strcpy(lpitem->item_text, lpNewItem); else printf("ModifyMenu // Bad Alloc !\n"); } else lpitem->item_text = lpNewItem; GlobalUnlock(hMenu); return(TRUE); } lpitem = (LPMENUITEM)lpitem->next; } GlobalUnlock(hMenu); return FALSE; } /********************************************************************** * CreatePopupMenu [USER.415] */ HMENU CreatePopupMenu() { HANDLE hItem; HMENU hMenu; LPPOPUPMENU menu; #ifdef DEBUG_MENU printf("CreatePopupMenu !\n"); #endif hMenu = GlobalAlloc(GMEM_MOVEABLE, sizeof(POPUPMENU)); menu = (LPPOPUPMENU) GlobalLock(hMenu); if (menu == NULL) { GlobalFree(hMenu); return 0; } menu->nItems = 0; menu->firstItem = NULL; menu->ownerWnd = 0; menu->hWndPrev = 0; menu->hWnd = 0; menu->hWndParent = 0; menu->MouseFlags = 0; menu->BarFlag = FALSE; menu->SysFlag = FALSE; menu->ChildFlag = TRUE; menu->Width = 100; menu->Height = 0; GlobalUnlock(hMenu); #ifdef DEBUG_MENU printf("CreatePopupMenu // return %04X\n", hMenu); #endif return hMenu; } /********************************************************************** * TrackPopupMenu [USER.416] */ BOOL TrackPopupMenu(HMENU hMenu, WORD wFlags, short x, short y, short nReserved, HWND hWnd, LPRECT lpRect) { WND *wndPtr; LPPOPUPMENU lppop; RECT rect; #ifdef DEBUG_MENU printf("TrackPopupMenu (%04X, %04X, %d, %d, %04X, %04X, %08X) !\n", hMenu, wFlags, x, y, nReserved, hWnd, lpRect); #endif lppop = (LPPOPUPMENU) GlobalLock(hMenu); if (lppop == NULL) { printf("TrackPopupMenu // Bad menu handle %04X !\n", hMenu); return FALSE; } wndPtr = WIN_FindWndPtr(hWnd); if (wndPtr == NULL) { printf("TrackPopupMenu // Bad window handle %04X !\n", hWnd); return FALSE; } lppop->ownerWnd = hWnd; lppop->hWndPrev = GetFocus(); if (lppop->hWnd == (HWND)NULL) { lppop->hWnd = CreateWindow(POPUPMENU_CLASS_NAME, "", WS_POPUP | WS_BORDER, x, y, lppop->Width, lppop->Height, (HWND)NULL, 0, wndPtr->hInstance, (LPSTR)lppop); if (lppop->hWnd == 0) { printf("TrackPopupMenu // Can't create PopupMenu window !\n"); return FALSE; } } if (!lppop->BarFlag) { MENU_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 + 2, SWP_NOACTIVATE | SWP_NOZORDER); } ShowWindow(lppop->hWnd, SW_SHOWNOACTIVATE); SetFocus(lppop->hWnd); if (!MenuHasFocus) { #ifdef DEBUG_MENU printf("TrackPopupMenu // before MenuFocusLoop !\n"); #endif MenuFocusLoop(hWnd, NULL); #ifdef DEBUG_MENU printf("TrackPopupMenu // after MenuFocusLoop !\n"); #endif } GlobalUnlock(hMenu); return TRUE; } BOOL ActivateMenuBarFocus(HWND hWnd) { WND *wndPtr; LPPOPUPMENU lpmenu; BOOL bRet; MSG msg; if (MenuHasFocus) return FALSE; wndPtr = WIN_FindWndPtr(hWnd); if (wndPtr == NULL) return FALSE; #ifdef DEBUG_MENU printf("ActivateMenuBarFocus (%04X) !\n", hWnd); #endif while((wndPtr->dwStyle & WS_CHILD) == WS_CHILD) { hWnd = GetParent(hWnd); printf("ActivateMenuBarFocus // next Parent=%04X !\n", hWnd); wndPtr = WIN_FindWndPtr(hWnd); if (wndPtr == NULL) return FALSE; } if ((wndPtr->dwStyle & WS_CHILD) == 0 && wndPtr->wIDmenu != 0) { lpmenu = (LPPOPUPMENU) GlobalLock(wndPtr->wIDmenu); if (lpmenu == NULL) return FALSE; lpmenu->hWndPrev = GetFocus(); SetFocus(hWnd); MenuItemSelect(hWnd, lpmenu, 0); bRet = MenuFocusLoop(hWnd, lpmenu); GlobalUnlock(wndPtr->wIDmenu); return bRet; } return FALSE; } BOOL MenuFocusLoop(HWND hWnd, LPPOPUPMENU lpmenu) { MSG msg; #ifdef DEBUG_MENU printf("Enter in Menu Focus Loop !\n"); #endif MenuHasFocus = TRUE; while(TRUE) { if (!MenuHasFocus) break; if (!GetMessage(&msg, (HWND)NULL, 0, 0)) break; TranslateMessage(&msg); if (hWnd == msg.hwnd && lpmenu != NULL) { if ((msg.message == WM_SYSKEYDOWN && msg.wParam == VK_MENU) || (msg.message == WM_CHAR && msg.wParam == VK_ESCAPE)) { HideAllSubPopupMenu(lpmenu); break; } ScreenToClient(hWnd, &msg.pt); msg.pt.y += lpmenu->rect.bottom; switch(msg.message) { case WM_LBUTTONDOWN: case WM_NCLBUTTONDOWN: SetCapture(hWnd); MenuButtonDown(hWnd, lpmenu, msg.pt.x, msg.pt.y); break; case WM_LBUTTONUP: case WM_NCLBUTTONUP: MenuButtonUp(hWnd, lpmenu, msg.pt.x, msg.pt.y); ReleaseCapture(); break; case WM_MOUSEMOVE: case WM_NCMOUSEMOVE: MenuMouseMove(hWnd, lpmenu, msg.wParam, msg.pt.x, msg.pt.y); break; case WM_KEYDOWN: case WM_KEYUP: case WM_CHAR: PopupMenuWndProc(hWnd, msg.message, msg.wParam, msg.lParam); default: DispatchMessage(&msg); } } else DispatchMessage(&msg); } EndOfFocus: MenuHasFocus = FALSE; if (lpmenu != NULL) MenuItemSelect(hWnd, lpmenu, -1); #ifdef DEBUG_MENU printf("End of Menu Focus Loop !\n"); #endif return TRUE; } /********************************************************************** * NC_TrackSysMenu [Internal] */ void NC_TrackSysMenu(HWND hWnd) { RECT rect; LPPOPUPMENU lpsys; WND *wndPtr = WIN_FindWndPtr(hWnd); #ifdef DEBUG_MENU printf("NC_TrackSysMenu hWnd=%04X !\n", hWnd); #endif if (!wndPtr) return; lpsys = (LPPOPUPMENU)GlobalLock(wndPtr->hSysMenu); #ifdef DEBUG_MENU printf("NC_TrackSysMenu wndPtr->hSysMenu=%04X !\n", wndPtr->hSysMenu); #endif if (lpsys == NULL) return; #ifdef DEBUG_MENU printf("NC_TrackSysMenu wndPtr->hSysMenu=%04X !\n", wndPtr->hSysMenu); #endif lpsys->BarFlag = FALSE; lpsys->SysFlag = TRUE; lpsys->ChildFlag = FALSE; lpsys->hWndParent = hWnd; if (!IsWindowVisible(lpsys->hWnd)) { GetWindowRect(hWnd, &rect); #ifdef DEBUG_MENU printf("NC_TrackSysMenu lpsys->hWnd=%04X !\n", lpsys->hWnd); #endif if (MenuHasFocus) { TrackPopupMenu(wndPtr->hSysMenu, TPM_LEFTBUTTON, rect.left, rect.top + SYSMETRICS_CYSIZE, 0, hWnd, (LPRECT)NULL); } else { MenuHasFocus = TRUE; TrackPopupMenu(wndPtr->hSysMenu, TPM_LEFTBUTTON, rect.left, rect.top + SYSMETRICS_CYSIZE, 0, hWnd, (LPRECT)NULL); MenuHasFocus = FALSE; #ifdef DEBUG_MENU printf("NC_TrackSysMenu // before MenuFocusLoop !\n"); #endif MenuFocusLoop(hWnd, NULL); #ifdef DEBUG_MENU printf("NC_TrackSysMenu // after MenuFocusLoop !\n"); #endif } } else { ShowWindow(lpsys->hWnd, SW_HIDE); } GlobalUnlock(wndPtr->hSysMenu); } /********************************************************************** * GetMenuCheckMarkDimensions [USER.417] */ DWORD GetMenuCheckMarkDimensions() { InitStdBitmaps(); return MAKELONG( check_bitmap_width, check_bitmap_height ); } /********************************************************************** * SetMenuItemBitmaps [USER.418] */ BOOL SetMenuItemBitmaps(HMENU hMenu, WORD nPos, WORD wFlags, HBITMAP hNewCheck, HBITMAP hNewUnCheck) { LPPOPUPMENU menu; LPMENUITEM lpitem; int i; #ifdef DEBUG_MENU printf("SetMenuItemBitmaps (%04X, %04X, %04X, %04X, %08X) !\n", hMenu, nPos, wFlags, hNewCheck, hNewUnCheck); #endif menu = (LPPOPUPMENU) GlobalLock(hMenu); if (menu == NULL) return FALSE; lpitem = menu->firstItem; for (i = 0; i < menu->nItems; i++) { if (lpitem == NULL) break; if (i == nPos) { lpitem->hCheckBit = hNewCheck; lpitem->hUnCheckBit = hNewUnCheck; GlobalUnlock(hMenu); return TRUE; } lpitem = (LPMENUITEM)lpitem->next; } GlobalUnlock(hMenu); return FALSE; } /********************************************************************** * CreateMenu [USER.151] */ HMENU CreateMenu() { HANDLE hItem; HMENU hMenu; LPPOPUPMENU menu; #ifdef DEBUG_MENU printf("CreateMenu !\n"); #endif hMenu = GlobalAlloc(GMEM_MOVEABLE, sizeof(POPUPMENU)); menu = (LPPOPUPMENU) GlobalLock(hMenu); if (menu == NULL) { GlobalFree(hMenu); return 0; } menu->nItems = 0; menu->firstItem = NULL; menu->hWndPrev = 0; menu->ownerWnd = 0; menu->hWnd = 0; menu->hWndParent = 0; menu->MouseFlags = 0; menu->BarFlag = TRUE; menu->SysFlag = FALSE; menu->ChildFlag = TRUE; menu->Width = 100; menu->Height = 0; GlobalUnlock(hMenu); #ifdef DEBUG_MENU printf("CreateMenu // return %04X\n", hMenu); #endif return hMenu; } /********************************************************************** * DestroyMenu [USER.152] */ BOOL DestroyMenu(HMENU hMenu) { LPPOPUPMENU lppop; LPMENUITEM lpitem, lpitem2; #ifdef DEBUG_MENU printf("DestroyMenu (%04X) !\n", hMenu); #endif if (hMenu == 0) return FALSE; lppop = (LPPOPUPMENU) GlobalLock(hMenu); if (lppop == NULL) return FALSE; if (lppop->hWnd) DestroyWindow (lppop->hWnd); lpitem = lppop->firstItem; while (lpitem != NULL) { #ifdef DEBUG_MENU printf("DestroyMenu (%04X) // during loop items !\n", hMenu); #endif if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) { DestroyMenu((HMENU)lpitem->item_id); } lpitem = (LPMENUITEM)lpitem->next; } GlobalUnlock(hMenu); GlobalFree(hMenu); #ifdef DEBUG_MENU printf("DestroyMenu (%04X) // End !\n", hMenu); #endif return TRUE; } /********************************************************************** * LoadMenu [USER.150] */ HMENU LoadMenu(HINSTANCE instance, char *menu_name) { HMENU hMenu; HANDLE hMenu_desc; MENU_HEADER *menu_desc; #ifdef DEBUG_MENU if ((LONG)menu_name & 0xFFFF0000L) printf("LoadMenu: instance %02x, menu '%s'\n", instance, menu_name); else printf("LoadMenu: instance %02x, menu '%04X'\n", instance, menu_name); #endif if (instance == (HANDLE)NULL) instance = hSysRes; if (menu_name == NULL || (hMenu_desc = RSC_LoadMenu(instance, menu_name)) == 0 || (menu_desc = (MENU_HEADER *) GlobalLock(hMenu_desc)) == NULL) { return 0; } hMenu = LoadMenuIndirect((LPSTR)menu_desc); return hMenu; } /********************************************************************** * GetSystemMenu [USER.156] */ HMENU GetSystemMenu(HWND hWnd, BOOL bRevert) { WND *wndPtr; wndPtr = WIN_FindWndPtr(hWnd); if (!bRevert) { return wndPtr->hSysMenu; } else { DestroyMenu(wndPtr->hSysMenu); wndPtr->hSysMenu = CopySysMenu(); } return wndPtr->hSysMenu; } /********************************************************************** * SetSystemMenu [USER.280] */ BOOL SetSystemMenu(HWND hWnd, HMENU newHmenu) { WND *wndPtr; if ((wndPtr = WIN_FindWndPtr(hWnd)) != NULL) wndPtr->hSysMenu = newHmenu; } /********************************************************************** * GetMenu [USER.157] */ HMENU GetMenu(HWND hWnd) { WND * wndPtr = WIN_FindWndPtr(hWnd); if (wndPtr == NULL) return 0; return wndPtr->wIDmenu; } /********************************************************************** * SetMenu [USER.158] */ BOOL SetMenu(HWND hWnd, HMENU hMenu) { RECT rect; LPPOPUPMENU lpmenu; WORD flags; WND * wndPtr = WIN_FindWndPtr(hWnd); if (wndPtr == NULL) { printf("SetMenu(%04X, %04X) // Bad window handle !\n", hWnd, hMenu); return FALSE; } #ifdef DEBUG_MENU printf("SetMenu(%04X, %04X);\n", hWnd, hMenu); #endif if (GetCapture() == hWnd) ReleaseCapture(); wndPtr->wIDmenu = hMenu; if (hMenu != 0) { lpmenu = (LPPOPUPMENU) GlobalLock(hMenu); if (lpmenu == NULL) { printf("SetMenu(%04X, %04X) // Bad menu handle !\n", hWnd, hMenu); return FALSE; } lpmenu->ownerWnd = hWnd; lpmenu->Height = 0; /* Make sure we recalculate the size */ ResetHiliteFlags(lpmenu); GlobalUnlock(hMenu); } SetWindowPos( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED ); return TRUE; } /********************************************************************** * GetSubMenu [USER.159] */ HMENU GetSubMenu(HMENU hMenu, short nPos) { HMENU hSubMenu; LPPOPUPMENU lppop; LPMENUITEM lpitem; int i; #ifdef DEBUG_MENU printf("GetSubMenu (%04X, %04X) !\n", hMenu, nPos); #endif if (hMenu == 0) return 0; lppop = (LPPOPUPMENU) GlobalLock(hMenu); if (lppop == NULL) return 0; lpitem = lppop->firstItem; for (i = 0; i < lppop->nItems; i++) { if (lpitem == NULL) break; if (i == nPos) { #ifdef DEBUG_MENU printf(" found %04x\n", lpitem->item_id); #endif if (lpitem->item_flags & MF_POPUP) return lpitem->item_id; else return 0; } lpitem = (LPMENUITEM)lpitem->next; } return 0; } /********************************************************************** * DrawMenuBar [USER.160] */ void DrawMenuBar(HWND hWnd) { WND *wndPtr; LPPOPUPMENU lppop; #ifdef DEBUG_MENU printf("DrawMenuBar (%04X)\n", hWnd); #endif wndPtr = WIN_FindWndPtr(hWnd); if (wndPtr != NULL && (wndPtr->dwStyle & WS_CHILD) == 0 && wndPtr->wIDmenu != 0) { #ifdef DEBUG_MENU printf("DrawMenuBar wIDmenu=%04X \n", wndPtr->wIDmenu); #endif lppop = (LPPOPUPMENU) GlobalLock(wndPtr->wIDmenu); if (lppop == NULL) return; lppop->Height = 0; /* Make sure we call MENU_MenuBarCalcSize */ SetWindowPos( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED ); GlobalUnlock(wndPtr->wIDmenu); } } /********************************************************************** * LoadMenuIndirect [USER.220] */ HMENU LoadMenuIndirect(LPSTR menu_template) { HMENU hMenu; MENU_HEADER *menu_desc; LPPOPUPMENU lppop; #ifdef DEBUG_MENU printf("LoadMenuIndirect: menu_template '%08X'\n", menu_template); #endif hMenu = CreateMenu(); menu_desc = (MENU_HEADER *)menu_template; ParseMenuResource((WORD *)(menu_desc + 1), 0, hMenu); lppop = (LPPOPUPMENU) GlobalLock(hMenu); ResetHiliteFlags(lppop); GlobalUnlock(hMenu); return hMenu; } /********************************************************************** * InitStdBitmaps (Internal) */ void InitStdBitmaps() { BITMAP bm; if (hStdCheck == (HBITMAP)NULL) { hStdCheck = LoadBitmap((HANDLE)NULL, (LPSTR)OBM_CHECK); GetObject( hStdCheck, sizeof(BITMAP), (LPSTR)&bm ); check_bitmap_width = bm.bmWidth; check_bitmap_height = bm.bmHeight; } if (hStdMnArrow == (HBITMAP)NULL) { hStdMnArrow = LoadBitmap((HANDLE)NULL, (LPSTR)OBM_MNARROW); GetObject( hStdMnArrow, sizeof(BITMAP), (LPSTR)&bm ); arrow_bitmap_width = bm.bmWidth; arrow_bitmap_height = bm.bmHeight; } } /********************************************************************** * CopySysMenu (Internal) */ HMENU CopySysMenu() { HMENU hMenu; LPPOPUPMENU menu; LPPOPUPMENU sysmenu; #ifdef DEBUG_MENU printf("CopySysMenu entry !\n"); #endif if (hSysMenu == 0) { /* hSysMenu = LoadMenu((HINSTANCE)NULL, MAKEINTRESOURCE(1)); */ /* hSysMenu = LoadMenu((HINSTANCE)NULL, MAKEINTRESOURCE(SC_SYSMENU));*/ hSysMenu = LoadMenu((HINSTANCE)NULL, "SYSMENU"); if (hSysMenu == 0) { printf("SysMenu not found in system resources !\n"); return (HMENU)NULL; } #ifdef DEBUG_MENU else printf("SysMenu loaded from system resources %04X !\n", hSysMenu); #endif } hMenu = GlobalAlloc(GMEM_MOVEABLE, sizeof(POPUPMENU)); menu = (LPPOPUPMENU) GlobalLock(hMenu); sysmenu = (LPPOPUPMENU) GlobalLock(hSysMenu); if (menu != NULL && sysmenu != NULL) { sysmenu->BarFlag = FALSE; sysmenu->SysFlag = TRUE; memcpy(menu, sysmenu, sizeof(POPUPMENU)); } else { printf("CopySysMenu // Bad SysMenu pointers !\n"); if (menu != NULL) { GlobalUnlock(hMenu); GlobalFree(hMenu); } return (HMENU)NULL; } GlobalUnlock(hMenu); GlobalUnlock(hSysMenu); #ifdef DEBUG_MENU printf("CopySysMenu hMenu=%04X !\n", hMenu); #endif return hMenu; } /********************************************************************** * ParseMenuResource (from Resource or Template) */ WORD * ParseMenuResource(WORD *first_item, int level, HMENU hMenu) { WORD *item; WORD *next_item; HMENU hSubMenu; int i; level++; next_item = first_item; i = 0; do { i++; item = next_item; if (*item & MF_POPUP) { MENU_POPUPITEM *popup_item = (MENU_POPUPITEM *) item; next_item = (WORD *) (popup_item->item_text + strlen(popup_item->item_text) + 1); hSubMenu = CreatePopupMenu(); next_item = ParseMenuResource(next_item, level, hSubMenu); AppendMenu(hMenu, popup_item->item_flags, hSubMenu, popup_item->item_text); } else { MENUITEMTEMPLATE *normal_item = (MENUITEMTEMPLATE *) item; next_item = (WORD *) (normal_item->item_text + strlen(normal_item->item_text) + 1); if (strlen(normal_item->item_text) == 0 && normal_item->item_id == 0) normal_item->item_flags |= MF_SEPARATOR; AppendMenu(hMenu, normal_item->item_flags, normal_item->item_id, normal_item->item_text); } } while (!(*item & MF_END)); return next_item; } /********************************************************************** * IsMenu(USER.358) */ BOOL IsMenu(HMENU hMenu) { LPPOPUPMENU menu; menu = (LPPOPUPMENU) GlobalLock(hMenu); if (menu == NULL) return FALSE; GlobalUnlock(hMenu); return TRUE; }