Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1 | /* |
| 2 | * Menus functions |
| 3 | */ |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 4 | static char RCSId[] = "$Id$"; |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 5 | static char Copyright[] = "Copyright Martin Ayotte, 1993"; |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 6 | |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 7 | /* |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 8 | #define DEBUG_MENU |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 9 | #define DEBUG_SYSMENU |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 10 | */ |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 11 | |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 12 | #include "windows.h" |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 13 | #include "sysmetrics.h" |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 14 | #include "menu.h" |
| 15 | #include "heap.h" |
| 16 | #include "win.h" |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 17 | |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 18 | #define SC_ABOUTWINE SC_SCREENSAVE+1 |
| 19 | #define SC_SYSMENU SC_SCREENSAVE+2 |
| 20 | #define SC_ABOUTWINEDLG SC_SCREENSAVE+3 |
| 21 | |
| 22 | extern HINSTANCE hSysRes; |
| 23 | HMENU hSysMenu = 0; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 24 | HBITMAP hStdCheck = 0; |
| 25 | HBITMAP hStdMnArrow = 0; |
| 26 | |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 27 | LPPOPUPMENU PopupMenuGetStorageHeader(HWND hwnd); |
| 28 | LPPOPUPMENU PopupMenuGetWindowAndStorage(HWND hwnd, WND **wndPtr); |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 29 | void StdDrawMenuBar(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop); |
| 30 | void MenuButtonDown(HWND hWnd, LPPOPUPMENU lppop, int x, int y); |
| 31 | void MenuButtonUp(HWND hWnd, LPPOPUPMENU lppop, int x, int y); |
| 32 | void MenuMouseMove(HWND hWnd, LPPOPUPMENU lppop, WORD wParam, int x, int y); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 33 | void StdDrawPopupMenu(HWND hwnd); |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 34 | LPMENUITEM MenuFindItem(LPPOPUPMENU lppop, int x, int y, WORD *lpRet); |
| 35 | LPMENUITEM MenuFindItemBySelKey(LPPOPUPMENU lppop, WORD key, WORD *lpRet); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 36 | void PopupMenuCalcSize(HWND hwnd); |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 37 | void MenuBarCalcSize(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 38 | LPMENUITEM GetMenuItemPtr(LPPOPUPMENU menu, WORD nPos); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 39 | WORD GetSelectionKey(LPSTR str); |
| 40 | LPSTR GetShortCutString(LPSTR str); |
| 41 | WORD GetShortCutPos(LPSTR str); |
| 42 | BOOL HideAllSubPopupMenu(LPPOPUPMENU menu); |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 43 | HMENU CopySysMenu(); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 44 | WORD * ParseMenuResource(WORD *first_item, int level, HMENU hMenu); |
| 45 | void SetMenuLogicalParent(HMENU hMenu, HWND hWnd); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 46 | |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 47 | BOOL FAR PASCAL AboutWine_Proc(HWND hDlg, WORD msg, WORD wParam, LONG lParam); |
| 48 | |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 49 | /*********************************************************************** |
| 50 | * PopupMenuWndProc |
| 51 | */ |
| 52 | LONG PopupMenuWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) |
| 53 | { |
| 54 | CREATESTRUCT *createStruct; |
| 55 | WORD wRet; |
| 56 | short x, y; |
| 57 | WND *wndPtr; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 58 | LPPOPUPMENU lppop, lppop2; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 59 | LPMENUITEM lpitem, lpitem2; |
| 60 | HMENU hSubMenu; |
| 61 | RECT rect; |
| 62 | HDC hDC; |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 63 | PAINTSTRUCT ps; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 64 | switch(message) |
| 65 | { |
| 66 | case WM_CREATE: |
| 67 | #ifdef DEBUG_MENU |
| 68 | printf("PopupMenu WM_CREATE lParam=%08X !\n", lParam); |
| 69 | #endif |
| 70 | createStruct = (CREATESTRUCT *)lParam; |
| 71 | lppop = (LPPOPUPMENU)createStruct->lpCreateParams; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 72 | if (lppop == NULL) break; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 73 | wndPtr = WIN_FindWndPtr(hwnd); |
| 74 | *((LPPOPUPMENU *)&wndPtr->wExtra[1]) = lppop; |
| 75 | #ifdef DEBUG_MENU |
| 76 | printf("PopupMenu WM_CREATE lppop=%08X !\n", lppop); |
| 77 | #endif |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 78 | if (hStdCheck == (HBITMAP)NULL) |
| 79 | hStdCheck = LoadBitmap((HANDLE)NULL, (LPSTR)OBM_CHECK); |
| 80 | if (hStdMnArrow == (HBITMAP)NULL) |
| 81 | hStdMnArrow = LoadBitmap((HANDLE)NULL, (LPSTR)OBM_MNARROW); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 82 | return 0; |
| 83 | case WM_DESTROY: |
| 84 | lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); |
| 85 | #ifdef DEBUG_MENU |
| 86 | printf("PopupMenu WM_DESTROY %lX !\n", lppop); |
| 87 | #endif |
| 88 | return 0; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 89 | case WM_COMMAND: |
| 90 | lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 91 | if (lppop->hWndParent != (HWND)NULL) { |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 92 | SendMessage(lppop->hWndParent, WM_COMMAND, wParam, lParam); |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 93 | #ifdef DEBUG_MENU |
| 94 | printf("PopupMenu // push to lower parent WM_COMMAND !\n"); |
| 95 | #endif |
| 96 | } |
| 97 | else { |
| 98 | if (lppop->SysFlag == 0) { |
| 99 | SendMessage(lppop->ownerWnd, WM_COMMAND, wParam, lParam); |
| 100 | #ifdef DEBUG_MENU |
| 101 | printf("PopupMenu // push to Owner WM_COMMAND !\n"); |
| 102 | #endif |
| 103 | } |
| 104 | else { |
| 105 | #ifdef DEBUG_SYSMENU |
| 106 | printf("PopupMenu // push to Owner WM_SYSCOMMAND !\n"); |
| 107 | #endif |
| 108 | SendMessage(lppop->ownerWnd, WM_SYSCOMMAND, wParam, lParam); |
| 109 | } |
| 110 | } |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 111 | if (lppop->BarFlags == 0) ShowWindow(hwnd, SW_HIDE); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 112 | break; |
| 113 | case WM_SHOWWINDOW: |
| 114 | lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 115 | if (wParam == 0 && lParam == 0L) { |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 116 | HideAllSubPopupMenu(lppop); |
| 117 | #ifdef DEBUG_MENU |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 118 | printf("PopupMenu WM_SHOWWINDOW -> HIDE!\n"); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 119 | #endif |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 120 | /* |
| 121 | UpdateWindow(lppop->ownerWnd); |
| 122 | */ |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 123 | break; |
| 124 | } |
| 125 | lppop->FocusedItem = (WORD)-1; |
| 126 | if (lppop->BarFlags == 0) { |
| 127 | PopupMenuCalcSize(hwnd); |
| 128 | #ifdef DEBUG_MENU |
| 129 | printf("PopupMenu WM_SHOWWINDOW Width=%d Height=%d !\n", |
| 130 | lppop->Width, lppop->Height); |
| 131 | #endif |
| 132 | SetWindowPos(hwnd, 0, 0, 0, lppop->Width + 2, lppop->Height, |
| 133 | SWP_NOZORDER | SWP_NOMOVE); |
| 134 | } |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 135 | break; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 136 | case WM_LBUTTONDOWN: |
| 137 | lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); |
| 138 | SetCapture(hwnd); |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 139 | MenuButtonDown(hwnd, lppop, LOWORD(lParam), HIWORD(lParam)); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 140 | break; |
| 141 | case WM_LBUTTONUP: |
| 142 | lppop = PopupMenuGetStorageHeader(hwnd); |
| 143 | ReleaseCapture(); |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 144 | MenuButtonUp(hwnd, lppop, LOWORD(lParam), HIWORD(lParam)); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 145 | break; |
| 146 | case WM_MOUSEMOVE: |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 147 | lppop = PopupMenuGetStorageHeader(hwnd); |
| 148 | MenuMouseMove(hwnd, lppop, wParam, LOWORD(lParam), HIWORD(lParam)); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 149 | break; |
| 150 | |
| 151 | case WM_KEYDOWN: |
| 152 | case WM_KEYUP: |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 153 | if (lParam < 0L) break; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 154 | lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 155 | if (lppop->FocusedItem == (WORD)-1) { |
| 156 | if (wParam == VK_UP || wParam == VK_DOWN || |
| 157 | wParam == VK_LEFT || wParam == VK_RIGHT) { |
| 158 | hDC = GetDC(hwnd); |
| 159 | lppop->FocusedItem = 0; |
| 160 | lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem); |
| 161 | if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) || |
| 162 | ((lpitem->item_flags & MF_STRING) == MF_STRING)) { |
| 163 | InvertRect(hDC, &lpitem->rect); |
| 164 | } |
| 165 | ReleaseDC(hwnd, hDC); |
| 166 | } |
| 167 | break; |
| 168 | } |
| 169 | switch(wParam) { |
| 170 | case VK_UP: |
| 171 | if (lppop->BarFlags != 0) break; |
| 172 | if (lppop->FocusedItem < 1) break; |
| 173 | lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem); |
| 174 | if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) |
| 175 | HideAllSubPopupMenu(lppop); |
| 176 | hDC = GetDC(hwnd); |
| 177 | if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) || |
| 178 | ((lpitem->item_flags & MF_STRING) == MF_STRING)) { |
| 179 | InvertRect(hDC, &lpitem->rect); |
| 180 | } |
| 181 | lppop->FocusedItem--; |
| 182 | lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem); |
| 183 | if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) || |
| 184 | ((lpitem->item_flags & MF_STRING) == MF_STRING)) { |
| 185 | InvertRect(hDC, &lpitem->rect); |
| 186 | } |
| 187 | ReleaseDC(hwnd, hDC); |
| 188 | break; |
| 189 | case VK_DOWN: |
| 190 | if (lppop->BarFlags != 0) goto ProceedSPACE; |
| 191 | if (lppop->FocusedItem >= lppop->nItems - 1) break; |
| 192 | lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem); |
| 193 | if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) |
| 194 | HideAllSubPopupMenu(lppop); |
| 195 | hDC = GetDC(hwnd); |
| 196 | if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) || |
| 197 | ((lpitem->item_flags & MF_STRING) == MF_STRING)) { |
| 198 | InvertRect(hDC, &lpitem->rect); |
| 199 | } |
| 200 | lppop->FocusedItem++; |
| 201 | lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem); |
| 202 | if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) || |
| 203 | ((lpitem->item_flags & MF_STRING) == MF_STRING)) { |
| 204 | InvertRect(hDC, &lpitem->rect); |
| 205 | } |
| 206 | ReleaseDC(hwnd, hDC); |
| 207 | break; |
| 208 | case VK_LEFT: |
| 209 | if (lppop->BarFlags == 0) { |
| 210 | if (lppop->hWndParent != 0) |
| 211 | SendMessage(lppop->hWndParent, WM_KEYDOWN, wParam, lParam); |
| 212 | break; |
| 213 | } |
| 214 | if (lppop->FocusedItem < 1) break; |
| 215 | lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem); |
| 216 | if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) |
| 217 | HideAllSubPopupMenu(lppop); |
| 218 | hDC = GetDC(hwnd); |
| 219 | if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) || |
| 220 | ((lpitem->item_flags & MF_STRING) == MF_STRING)) { |
| 221 | InvertRect(hDC, &lpitem->rect); |
| 222 | } |
| 223 | lppop->FocusedItem--; |
| 224 | lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem); |
| 225 | if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) || |
| 226 | ((lpitem->item_flags & MF_STRING) == MF_STRING)) { |
| 227 | InvertRect(hDC, &lpitem->rect); |
| 228 | } |
| 229 | ReleaseDC(hwnd, hDC); |
| 230 | break; |
| 231 | case VK_RIGHT: |
| 232 | if (lppop->BarFlags == 0) { |
| 233 | if (lppop->hWndParent != 0) |
| 234 | SendMessage(lppop->hWndParent, WM_KEYDOWN, wParam, lParam); |
| 235 | break; |
| 236 | } |
| 237 | if (lppop->FocusedItem >= lppop->nItems - 1) break; |
| 238 | lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem); |
| 239 | if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) |
| 240 | HideAllSubPopupMenu(lppop); |
| 241 | hDC = GetDC(hwnd); |
| 242 | if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) || |
| 243 | ((lpitem->item_flags & MF_STRING) == MF_STRING)) { |
| 244 | InvertRect(hDC, &lpitem->rect); |
| 245 | } |
| 246 | lppop->FocusedItem++; |
| 247 | lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem); |
| 248 | if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) || |
| 249 | ((lpitem->item_flags & MF_STRING) == MF_STRING)) { |
| 250 | InvertRect(hDC, &lpitem->rect); |
| 251 | } |
| 252 | ReleaseDC(hwnd, hDC); |
| 253 | break; |
| 254 | case VK_RETURN: |
| 255 | case VK_SPACE: |
| 256 | ProceedSPACE: |
| 257 | printf("PopupMenu VK_SPACE !\n"); |
| 258 | lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem); |
| 259 | if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) { |
| 260 | hSubMenu = (HMENU)lpitem->item_id; |
| 261 | lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu); |
| 262 | if (lppop2 == NULL) break; |
| 263 | lppop2->hWndParent = hwnd; |
| 264 | GetClientRect(hwnd, &rect); |
| 265 | if (lppop->BarFlags != 0) { |
| 266 | y = rect.bottom - rect.top; |
| 267 | TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, |
| 268 | lpitem->rect.left, 0, |
| 269 | 0, lppop->ownerWnd, (LPRECT)NULL); |
| 270 | } |
| 271 | else { |
| 272 | x = rect.right; |
| 273 | GetWindowRect(hwnd, &rect); |
| 274 | x += rect.left; |
| 275 | TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, |
| 276 | x, lpitem->rect.top, |
| 277 | 0, lppop->ownerWnd, (LPRECT)NULL); |
| 278 | } |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 279 | GlobalUnlock(hSubMenu); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 280 | break; |
| 281 | } |
| 282 | if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && |
| 283 | ((lpitem->item_flags & MF_POPUP) != MF_POPUP)) { |
| 284 | ShowWindow(lppop->hWnd, SW_HIDE); |
| 285 | if (lppop->hWndParent != (HWND)NULL) |
| 286 | SendMessage(lppop->hWndParent, WM_COMMAND, |
| 287 | lpitem->item_id, 0L); |
| 288 | else |
| 289 | SendMessage(lppop->ownerWnd, WM_COMMAND, |
| 290 | lpitem->item_id, 0L); |
| 291 | #ifdef DEBUG_MENU |
| 292 | printf("PopupMenu // SendMessage WM_COMMAND wParam=%d !\n", |
| 293 | lpitem->item_id); |
| 294 | #endif |
| 295 | } |
| 296 | break; |
| 297 | } |
| 298 | break; |
| 299 | case WM_CHAR: |
| 300 | if (lParam < 0L) break; |
| 301 | lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); |
| 302 | if (wParam == VK_ESCAPE) { |
| 303 | if (lppop->hWndParent != 0) { |
| 304 | lppop2 = PopupMenuGetWindowAndStorage( |
| 305 | lppop->hWndParent, &wndPtr); |
| 306 | HideAllSubPopupMenu(lppop2); |
| 307 | break; |
| 308 | } |
| 309 | if (lppop->FocusedItem != (WORD)-1) { |
| 310 | lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem); |
| 311 | hDC = GetDC(hwnd); |
| 312 | if (((lpitem2->item_flags & MF_POPUP) == MF_POPUP) || |
| 313 | ((lpitem2->item_flags & MF_STRING) == MF_STRING)) { |
| 314 | InvertRect(hDC, &lpitem2->rect); |
| 315 | } |
| 316 | ReleaseDC(hwnd, hDC); |
| 317 | lppop->FocusedItem = (WORD)-1; |
| 318 | } |
| 319 | } |
| 320 | if (wParam >= 'a' && wParam <= 'z') wParam -= 'a' - 'A'; |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 321 | lpitem = MenuFindItemBySelKey(lppop, wParam, &wRet); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 322 | if (lpitem != NULL) { |
| 323 | printf("Found wRet=%d !\n", wRet); |
| 324 | if (lppop->FocusedItem != (WORD)-1) { |
| 325 | lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem); |
| 326 | if ((lpitem2->item_flags & MF_POPUP) == MF_POPUP) |
| 327 | HideAllSubPopupMenu(lppop); |
| 328 | hDC = GetDC(hwnd); |
| 329 | if (((lpitem2->item_flags & MF_POPUP) == MF_POPUP) || |
| 330 | ((lpitem2->item_flags & MF_STRING) == MF_STRING)) { |
| 331 | InvertRect(hDC, &lpitem2->rect); |
| 332 | } |
| 333 | ReleaseDC(hwnd, hDC); |
| 334 | } |
| 335 | lppop->FocusedItem = wRet; |
| 336 | goto ProceedSPACE; |
| 337 | } |
| 338 | break; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 339 | case WM_PAINT: |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 340 | lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 341 | if (lppop->BarFlags == 0) { |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 342 | PopupMenuCalcSize(hwnd); |
| 343 | StdDrawPopupMenu(hwnd); |
| 344 | } |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 345 | break; |
| 346 | default: |
| 347 | return DefWindowProc( hwnd, message, wParam, lParam ); |
| 348 | } |
| 349 | return(0); |
| 350 | } |
| 351 | |
| 352 | |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 353 | void MenuButtonDown(HWND hWnd, LPPOPUPMENU lppop, int x, int y) |
| 354 | { |
| 355 | HDC hDC; |
| 356 | LPMENUITEM lpitem, lpitem2; |
| 357 | RECT rect; |
| 358 | HMENU hSubMenu; |
| 359 | WORD wRet; |
| 360 | LPPOPUPMENU lppop2; |
| 361 | lpitem = MenuFindItem(lppop, x, y, &wRet); |
| 362 | #ifdef DEBUG_MENU |
| 363 | printf("MenuButtonDown // x=%d y=%d // wRet=%d lpitem=%08X !\n", |
| 364 | x, y, wRet, lpitem); |
| 365 | #endif |
| 366 | if (lpitem != NULL) { |
| 367 | if (lppop->FocusedItem != (WORD)-1) { |
| 368 | HideAllSubPopupMenu(lppop); |
| 369 | lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem); |
| 370 | if (((lpitem2->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && |
| 371 | ((lpitem2->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) { |
| 372 | hDC = GetWindowDC(hWnd); |
| 373 | InvertRect(hDC, &lpitem2->rect); |
| 374 | ReleaseDC(hWnd, hDC); |
| 375 | } |
| 376 | } |
| 377 | lppop->FocusedItem = wRet; |
| 378 | if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && |
| 379 | ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) { |
| 380 | hDC = GetWindowDC(hWnd); |
| 381 | InvertRect(hDC, &lpitem->rect); |
| 382 | ReleaseDC(hWnd, hDC); |
| 383 | } |
| 384 | if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) { |
| 385 | hSubMenu = (HMENU)lpitem->item_id; |
| 386 | lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu); |
| 387 | if (lppop2 == NULL) return; |
| 388 | lppop2->hWndParent = hWnd; |
| 389 | if (lppop->BarFlags != 0) { |
| 390 | GetWindowRect(hWnd, &rect); |
| 391 | /* y = rect.top + lppop->Height; */ |
| 392 | y = rect.top + lppop->rect.bottom; |
| 393 | TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, |
| 394 | rect.left + lpitem->rect.left, |
| 395 | y, 0, lppop->ownerWnd, (LPRECT)NULL); |
| 396 | } |
| 397 | else { |
| 398 | x = lppop->rect.right; |
| 399 | GetWindowRect(hWnd, &rect); |
| 400 | x += rect.left; |
| 401 | TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, |
| 402 | x, rect.top + lpitem->rect.top, |
| 403 | 0, lppop->ownerWnd, (LPRECT)NULL); |
| 404 | } |
| 405 | GlobalUnlock(hSubMenu); |
| 406 | } |
| 407 | } |
| 408 | } |
| 409 | |
| 410 | |
| 411 | |
| 412 | void MenuButtonUp(HWND hWnd, LPPOPUPMENU lppop, int x, int y) |
| 413 | { |
| 414 | HDC hDC; |
| 415 | LPMENUITEM lpitem, lpitem2; |
| 416 | RECT rect; |
| 417 | HMENU hSubMenu; |
| 418 | WORD wRet; |
| 419 | LPPOPUPMENU lppop2; |
| 420 | lpitem = MenuFindItem(lppop, x, y, &wRet); |
| 421 | #ifdef DEBUG_MENU |
| 422 | printf("MenuButtonUp // x=%d y=%d // wRet=%d lpitem=%08X !\n", |
| 423 | x, y, wRet, lpitem); |
| 424 | #endif |
| 425 | if (lpitem != NULL) { |
| 426 | if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) { |
| 427 | return; |
| 428 | } |
| 429 | if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && |
| 430 | ((lpitem->item_flags & MF_POPUP) != MF_POPUP)) { |
| 431 | ShowWindow(lppop->hWnd, SW_HIDE); |
| 432 | if (lppop->hWndParent != (HWND)NULL) { |
| 433 | SendMessage(lppop->hWndParent, WM_COMMAND, |
| 434 | lpitem->item_id, 0L); |
| 435 | #ifdef DEBUG_MENU |
| 436 | printf("MenuButtonUp // WM_COMMAND to ParentMenu wParam=%d !\n", |
| 437 | lpitem->item_id); |
| 438 | #endif |
| 439 | } |
| 440 | else { |
| 441 | if (lppop->SysFlag == 0) { |
| 442 | #ifdef DEBUG_MENU |
| 443 | printf("PopupMenu // WM_COMMAND wParam=%d !\n", |
| 444 | lpitem->item_id); |
| 445 | #endif |
| 446 | SendMessage(lppop->ownerWnd, WM_COMMAND, |
| 447 | lpitem->item_id, 0L); |
| 448 | } |
| 449 | else { |
| 450 | if (lpitem->item_id == SC_ABOUTWINE) { |
| 451 | printf("SysMenu // Show 'About Wine ...' !\n"); |
| 452 | /* DialogBox(hSysRes, MAKEINTRESOURCE(SC_ABOUTWINEDLG), */ |
| 453 | DialogBox(hSysRes, MAKEINTRESOURCE(2), |
| 454 | GetParent(hWnd), (FARPROC)AboutWine_Proc); |
| 455 | } |
| 456 | else { |
| 457 | SendMessage(lppop->ownerWnd, WM_SYSCOMMAND, |
| 458 | lpitem->item_id, 0L); |
| 459 | #ifdef DEBUG_SYSMENU |
| 460 | printf("MenuButtonUp // WM_SYSCOMMAND wParam=%04X !\n", |
| 461 | lpitem->item_id); |
| 462 | #endif |
| 463 | } |
| 464 | } |
| 465 | } |
| 466 | #ifdef DEBUG_MENU |
| 467 | printf("MenuButtonUp // SendMessage WM_COMMAND wParam=%d !\n", |
| 468 | lpitem->item_id); |
| 469 | #endif |
| 470 | return; |
| 471 | } |
| 472 | } |
| 473 | if (lppop->FocusedItem != (WORD)-1) { |
| 474 | HideAllSubPopupMenu(lppop); |
| 475 | lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem); |
| 476 | if (((lpitem2->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && |
| 477 | ((lpitem2->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) { |
| 478 | hDC = GetWindowDC(hWnd); |
| 479 | InvertRect(hDC, &lpitem2->rect); |
| 480 | ReleaseDC(hWnd, hDC); |
| 481 | } |
| 482 | } |
| 483 | } |
| 484 | |
| 485 | |
| 486 | |
| 487 | void MenuMouseMove(HWND hWnd, LPPOPUPMENU lppop, WORD wParam, int x, int y) |
| 488 | { |
| 489 | HDC hDC; |
| 490 | LPMENUITEM lpitem, lpitem2; |
| 491 | RECT rect; |
| 492 | HMENU hSubMenu; |
| 493 | WORD wRet; |
| 494 | LPPOPUPMENU lppop2; |
| 495 | if ((wParam & MK_LBUTTON) != 0) { |
| 496 | lpitem = MenuFindItem(lppop, x, y, &wRet); |
| 497 | #ifdef DEBUG_MENU |
| 498 | printf("MenuMouseMove // x=%d y=%d // wRet=%d lpitem=%08X !\n", |
| 499 | x, y, wRet, lpitem); |
| 500 | #endif |
| 501 | if ((lpitem != NULL) && (lppop->FocusedItem != wRet)) { |
| 502 | lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem); |
| 503 | hDC = GetWindowDC(hWnd); |
| 504 | if (((lpitem2->item_flags & MF_POPUP) == MF_POPUP) || |
| 505 | ((lpitem2->item_flags & MF_STRING) == MF_STRING)) { |
| 506 | InvertRect(hDC, &lpitem2->rect); |
| 507 | } |
| 508 | if ((lpitem2->item_flags & MF_POPUP) == MF_POPUP) { |
| 509 | HideAllSubPopupMenu(lppop); |
| 510 | } |
| 511 | lppop->FocusedItem = wRet; |
| 512 | if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) || |
| 513 | ((lpitem->item_flags & MF_STRING) == MF_STRING)) { |
| 514 | InvertRect(hDC, &lpitem->rect); |
| 515 | } |
| 516 | if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) { |
| 517 | hSubMenu = (HMENU)lpitem->item_id; |
| 518 | lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu); |
| 519 | if (lppop2 == NULL) { |
| 520 | ReleaseDC(hWnd, hDC); |
| 521 | return; |
| 522 | } |
| 523 | if (lppop->BarFlags != 0) { |
| 524 | lppop2->hWndParent = hWnd; |
| 525 | GetWindowRect(hWnd, &rect); |
| 526 | rect.top += lppop->rect.bottom; |
| 527 | TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, |
| 528 | rect.left + lpitem->rect.left, rect.top, |
| 529 | 0, lppop->ownerWnd, (LPRECT)NULL); |
| 530 | } |
| 531 | GlobalUnlock(hSubMenu); |
| 532 | } |
| 533 | ReleaseDC(hWnd, hDC); |
| 534 | } |
| 535 | } |
| 536 | } |
| 537 | |
| 538 | |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 539 | |
| 540 | LPPOPUPMENU PopupMenuGetWindowAndStorage(HWND hwnd, WND **wndPtr) |
| 541 | { |
| 542 | WND *Ptr; |
| 543 | LPPOPUPMENU lppop; |
| 544 | *(wndPtr) = Ptr = WIN_FindWndPtr(hwnd); |
| 545 | if (Ptr == 0) { |
| 546 | printf("Bad Window handle on PopupMenu !\n"); |
| 547 | return 0; |
| 548 | } |
| 549 | lppop = *((LPPOPUPMENU *)&Ptr->wExtra[1]); |
| 550 | return lppop; |
| 551 | } |
| 552 | |
| 553 | |
| 554 | LPPOPUPMENU PopupMenuGetStorageHeader(HWND hwnd) |
| 555 | { |
| 556 | WND *Ptr; |
| 557 | LPPOPUPMENU lppop; |
| 558 | Ptr = WIN_FindWndPtr(hwnd); |
| 559 | if (Ptr == 0) { |
| 560 | printf("Bad Window handle on PopupMenu !\n"); |
| 561 | return 0; |
| 562 | } |
| 563 | lppop = *((LPPOPUPMENU *)&Ptr->wExtra[1]); |
| 564 | return lppop; |
| 565 | } |
| 566 | |
| 567 | |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 568 | void SetMenuLogicalParent(HMENU hMenu, HWND hWnd) |
| 569 | { |
| 570 | LPPOPUPMENU lppop; |
| 571 | lppop = (LPPOPUPMENU)GlobalLock(hMenu); |
| 572 | lppop->hWndParent = hWnd; |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 573 | GlobalUnlock(hMenu); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 574 | } |
| 575 | |
| 576 | |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 577 | void StdDrawPopupMenu(HWND hwnd) |
| 578 | { |
| 579 | WND *wndPtr; |
| 580 | LPPOPUPMENU lppop; |
| 581 | LPMENUITEM lpitem; |
| 582 | PAINTSTRUCT ps; |
| 583 | HBRUSH hBrush; |
| 584 | HPEN hOldPen; |
| 585 | HWND hWndParent; |
| 586 | HDC hDC, hMemDC; |
| 587 | RECT rect, rect2, rect3; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 588 | DWORD OldTextColor; |
| 589 | HFONT hOldFont; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 590 | HBITMAP hBitMap; |
| 591 | BITMAP bm; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 592 | UINT i, x; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 593 | hDC = BeginPaint( hwnd, &ps ); |
| 594 | if (!IsWindowVisible(hwnd)) { |
| 595 | EndPaint( hwnd, &ps ); |
| 596 | return; |
| 597 | } |
| 598 | lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); |
| 599 | if (lppop == NULL) goto EndOfPaint; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 600 | hBrush = GetStockObject(WHITE_BRUSH); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 601 | GetClientRect(hwnd, &rect); |
| 602 | GetClientRect(hwnd, &rect2); |
| 603 | FillRect(hDC, &rect, hBrush); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 604 | FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH)); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 605 | if (lppop->nItems == 0) goto EndOfPaint; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 606 | lpitem = lppop->firstItem; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 607 | if (lpitem == NULL) goto EndOfPaint; |
| 608 | for(i = 0; i < lppop->nItems; i++) { |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 609 | CopyRect(&rect2, &lpitem->rect); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 610 | if ((lpitem->item_flags & MF_SEPARATOR) == MF_SEPARATOR) { |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 611 | hOldPen = SelectObject(hDC, GetStockObject(BLACK_PEN)); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 612 | MoveTo(hDC, rect2.left, rect2.top + 1); |
| 613 | LineTo(hDC, rect2.right, rect2.top + 1); |
| 614 | SelectObject(hDC, hOldPen); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 615 | } |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 616 | if ((lpitem->item_flags & MF_CHECKED) == MF_CHECKED) { |
| 617 | hMemDC = CreateCompatibleDC(hDC); |
| 618 | if (lpitem->hCheckBit == 0) { |
| 619 | SelectObject(hMemDC, hStdCheck); |
| 620 | GetObject(hStdCheck, sizeof(BITMAP), (LPSTR)&bm); |
| 621 | } |
| 622 | else { |
| 623 | SelectObject(hMemDC, lpitem->hCheckBit); |
| 624 | GetObject(lpitem->hCheckBit, sizeof(BITMAP), (LPSTR)&bm); |
| 625 | } |
| 626 | BitBlt(hDC, rect2.left, rect2.top + 1, |
| 627 | bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); |
| 628 | DeleteDC(hMemDC); |
| 629 | } |
| 630 | else { |
| 631 | if (lpitem->hUnCheckBit != 0) { |
| 632 | hMemDC = CreateCompatibleDC(hDC); |
| 633 | SelectObject(hMemDC, lpitem->hUnCheckBit); |
| 634 | GetObject(lpitem->hUnCheckBit, sizeof(BITMAP), (LPSTR)&bm); |
| 635 | BitBlt(hDC, rect2.left, rect2.top + 1, |
| 636 | bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); |
| 637 | DeleteDC(hMemDC); |
| 638 | } |
| 639 | } |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 640 | if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) { |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 641 | hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text); |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 642 | rect2.left += lppop->CheckWidth; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 643 | hMemDC = CreateCompatibleDC(hDC); |
| 644 | SelectObject(hMemDC, hBitMap); |
| 645 | GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm); |
| 646 | BitBlt(hDC, rect2.left, rect2.top, |
| 647 | bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); |
| 648 | DeleteDC(hMemDC); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 649 | } |
| 650 | if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) && |
| 651 | ((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && |
| 652 | ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) { |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 653 | hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT)); |
| 654 | if ((lpitem->item_flags & MF_DISABLED) == MF_DISABLED) |
| 655 | OldTextColor = SetTextColor(hDC, 0x00C0C0C0L); |
| 656 | else |
| 657 | OldTextColor = SetTextColor(hDC, 0x00000000L); |
| 658 | CopyRect(&rect3, &lpitem->rect); |
| 659 | InflateRect(&rect3, 0, -2); |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 660 | rect3.left += lppop->CheckWidth; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 661 | if ((x = GetShortCutPos(lpitem->item_text)) != (WORD)-1) { |
| 662 | DrawText(hDC, lpitem->item_text, x, &rect3, |
| 663 | DT_LEFT | DT_VCENTER | DT_SINGLELINE); |
| 664 | DrawText(hDC, &lpitem->item_text[x], -1, &rect3, |
| 665 | DT_RIGHT | DT_VCENTER | DT_SINGLELINE); |
| 666 | } |
| 667 | else |
| 668 | DrawText(hDC, lpitem->item_text, -1, &rect3, |
| 669 | DT_LEFT | DT_VCENTER | DT_SINGLELINE); |
| 670 | SetTextColor(hDC, OldTextColor); |
| 671 | SelectObject(hDC, hOldFont); |
| 672 | CopyRect(&rect2, &lpitem->rect); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 673 | } |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 674 | if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) { |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 675 | CopyRect(&rect3, &lpitem->rect); |
| 676 | rect3.left = rect3.right - lppop->PopWidth; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 677 | hMemDC = CreateCompatibleDC(hDC); |
| 678 | SelectObject(hMemDC, hStdMnArrow); |
| 679 | GetObject(hStdMnArrow, sizeof(BITMAP), (LPSTR)&bm); |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 680 | BitBlt(hDC, rect3.left, rect3.top + 1, |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 681 | bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); |
| 682 | DeleteDC(hMemDC); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 683 | } |
| 684 | if (lpitem->next == NULL) goto EndOfPaint; |
| 685 | lpitem = (LPMENUITEM)lpitem->next; |
| 686 | } |
| 687 | EndOfPaint: |
| 688 | EndPaint( hwnd, &ps ); |
| 689 | } |
| 690 | |
| 691 | |
| 692 | |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 693 | void StdDrawMenuBar(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop) |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 694 | { |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 695 | LPMENUITEM lpitem; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 696 | HBRUSH hBrush; |
| 697 | HPEN hOldPen; |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 698 | HDC hMemDC; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 699 | RECT rect, rect2, rect3; |
| 700 | HFONT hOldFont; |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 701 | DWORD OldTextColor; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 702 | HBITMAP hBitMap; |
| 703 | BITMAP bm; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 704 | UINT i, textwidth; |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 705 | if (lppop == NULL || lprect == NULL) return; |
| 706 | #ifdef DEBUG_MENU |
| 707 | printf("StdDrawMenuBar(%04X, %08X, %08X); !\n", hDC, lprect, lppop); |
| 708 | #endif |
| 709 | MenuBarCalcSize(hDC, lprect, lppop); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 710 | hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT)); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 711 | hBrush = GetStockObject(WHITE_BRUSH); |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 712 | CopyRect(&rect, lprect); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 713 | FillRect(hDC, &rect, hBrush); |
| 714 | FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH)); |
| 715 | if (lppop->nItems == 0) goto EndOfPaint; |
| 716 | lpitem = lppop->firstItem; |
| 717 | if (lpitem == NULL) goto EndOfPaint; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 718 | for(i = 0; i < lppop->nItems; i++) { |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 719 | CopyRect(&rect2, &lpitem->rect); |
| 720 | if ((lpitem->item_flags & MF_CHECKED) == MF_CHECKED) { |
| 721 | hMemDC = CreateCompatibleDC(hDC); |
| 722 | if (lpitem->hCheckBit == 0) { |
| 723 | SelectObject(hMemDC, hStdCheck); |
| 724 | GetObject(hStdCheck, sizeof(BITMAP), (LPSTR)&bm); |
| 725 | } |
| 726 | else { |
| 727 | SelectObject(hMemDC, lpitem->hCheckBit); |
| 728 | GetObject(lpitem->hCheckBit, sizeof(BITMAP), (LPSTR)&bm); |
| 729 | } |
| 730 | BitBlt(hDC, rect2.left, rect2.top + 1, |
| 731 | bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); |
| 732 | DeleteDC(hMemDC); |
| 733 | } |
| 734 | else { |
| 735 | if (lpitem->hUnCheckBit != 0) { |
| 736 | hMemDC = CreateCompatibleDC(hDC); |
| 737 | SelectObject(hMemDC, lpitem->hUnCheckBit); |
| 738 | GetObject(lpitem->hUnCheckBit, sizeof(BITMAP), (LPSTR)&bm); |
| 739 | BitBlt(hDC, rect2.left, rect2.top + 1, |
| 740 | bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); |
| 741 | DeleteDC(hMemDC); |
| 742 | } |
| 743 | } |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 744 | if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) { |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 745 | hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 746 | hMemDC = CreateCompatibleDC(hDC); |
| 747 | SelectObject(hMemDC, hBitMap); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 748 | GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 749 | BitBlt(hDC, rect2.left, rect2.top, |
| 750 | bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); |
| 751 | DeleteDC(hMemDC); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 752 | } |
| 753 | if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) && |
| 754 | ((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && |
| 755 | ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) { |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 756 | hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT)); |
| 757 | if ((lpitem->item_flags & MF_DISABLED) == MF_DISABLED) |
| 758 | OldTextColor = SetTextColor(hDC, 0x00C0C0C0L); |
| 759 | else |
| 760 | OldTextColor = SetTextColor(hDC, 0x00000000L); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 761 | DrawText(hDC, lpitem->item_text, -1, &rect2, |
| 762 | DT_LEFT | DT_VCENTER | DT_SINGLELINE); |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 763 | SetTextColor(hDC, OldTextColor); |
| 764 | SelectObject(hDC, hOldFont); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 765 | } |
| 766 | if (lpitem->next == NULL) goto EndOfPaint; |
| 767 | lpitem = (LPMENUITEM)lpitem->next; |
| 768 | } |
| 769 | EndOfPaint: |
| 770 | SelectObject(hDC, hOldFont); |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 771 | } |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 772 | |
| 773 | |
| 774 | |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 775 | LPMENUITEM MenuFindItem(LPPOPUPMENU lppop, int x, int y, WORD *lpRet) |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 776 | { |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 777 | LPMENUITEM lpitem; |
| 778 | UINT i; |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 779 | if (lpRet != NULL) *lpRet = 0; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 780 | if (lppop == NULL) return NULL; |
| 781 | if (lppop->nItems == 0) return NULL; |
| 782 | lpitem = lppop->firstItem; |
| 783 | for(i = 0; i < lppop->nItems; i++) { |
| 784 | if (lpitem == NULL) return NULL; |
| 785 | #ifdef DEBUG_MENUFINDITEM |
| 786 | printf("FindItem // left=%d top=%d right=%d bottom=%d\n", |
| 787 | lpitem->rect.left, lpitem->rect.top, |
| 788 | lpitem->rect.right, lpitem->rect.bottom); |
| 789 | #endif |
| 790 | if (x > lpitem->rect.left && x < lpitem->rect.right && |
| 791 | y > lpitem->rect.top && y < lpitem->rect.bottom) { |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 792 | if (lpRet != NULL) *lpRet = i; |
| 793 | return lpitem; |
| 794 | } |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 795 | lpitem = (LPMENUITEM)lpitem->next; |
| 796 | } |
| 797 | return NULL; |
| 798 | } |
| 799 | |
| 800 | |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 801 | LPMENUITEM MenuFindItemBySelKey(LPPOPUPMENU lppop, WORD key, WORD *lpRet) |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 802 | { |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 803 | LPMENUITEM lpitem; |
| 804 | UINT i; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 805 | if (lppop == NULL) return NULL; |
| 806 | if (lppop->nItems == 0) return NULL; |
| 807 | lpitem = lppop->firstItem; |
| 808 | for(i = 0; i < lppop->nItems; i++) { |
| 809 | if (lpitem == NULL) return NULL; |
| 810 | #ifdef DEBUG_MENUFINDITEM |
| 811 | printf("FindItemBySelKey // key=%d lpitem->sel_key=%d\n", |
| 812 | key, lpitem->sel_key); |
| 813 | #endif |
| 814 | if (key == lpitem->sel_key) { |
| 815 | if (lpRet != NULL) *lpRet = i; |
| 816 | return lpitem; |
| 817 | } |
| 818 | lpitem = (LPMENUITEM)lpitem->next; |
| 819 | } |
| 820 | return NULL; |
| 821 | } |
| 822 | |
| 823 | |
| 824 | void PopupMenuCalcSize(HWND hwnd) |
| 825 | { |
| 826 | WND *wndPtr; |
| 827 | LPPOPUPMENU lppop; |
| 828 | LPMENUITEM lpitem; |
| 829 | HDC hDC; |
| 830 | RECT rect; |
| 831 | HBITMAP hBitMap; |
| 832 | BITMAP bm; |
| 833 | HFONT hOldFont; |
| 834 | UINT i, OldWidth, TempWidth; |
| 835 | DWORD dwRet; |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 836 | #ifdef DEBUG_MENUCALC |
| 837 | printf("PopupMenuCalcSize hWnd=%04X !\n", hWnd); |
| 838 | #endif |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 839 | lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); |
| 840 | if (lppop == NULL) return; |
| 841 | if (lppop->nItems == 0) return; |
| 842 | hDC = GetDC(hwnd); |
| 843 | lppop->Width = 20; |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 844 | lppop->CheckWidth = lppop->PopWidth = 0; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 845 | hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT)); |
| 846 | CalcAGAIN: |
| 847 | OldWidth = lppop->Width; |
| 848 | SetRect(&rect, 1, 1, OldWidth, 0); |
| 849 | lpitem = lppop->firstItem; |
| 850 | for(i = 0; i < lppop->nItems; i++) { |
| 851 | if (lpitem == NULL) break; |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 852 | #ifdef DEBUG_MENUCALC |
| 853 | printf("PopupMenuCalcSize item #%d !\n", i); |
| 854 | #endif |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 855 | rect.right = rect.left + lppop->Width; |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 856 | if ((lpitem->item_flags & MF_CHECKED) == MF_CHECKED) { |
| 857 | if (lpitem->hCheckBit != 0) |
| 858 | GetObject(lpitem->hCheckBit, sizeof(BITMAP), (LPSTR)&bm); |
| 859 | else |
| 860 | GetObject(hStdCheck, sizeof(BITMAP), (LPSTR)&bm); |
| 861 | lppop->CheckWidth = max(lppop->CheckWidth, bm.bmWidth); |
| 862 | } |
| 863 | else { |
| 864 | if (lpitem->hUnCheckBit != 0) { |
| 865 | GetObject(lpitem->hUnCheckBit, sizeof(BITMAP), (LPSTR)&bm); |
| 866 | lppop->CheckWidth = max(lppop->CheckWidth, bm.bmWidth); |
| 867 | } |
| 868 | } |
| 869 | if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) { |
| 870 | GetObject(hStdMnArrow, sizeof(BITMAP), (LPSTR)&bm); |
| 871 | lppop->PopWidth = max(lppop->PopWidth, bm.bmWidth); |
| 872 | } |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 873 | if ((lpitem->item_flags & MF_SEPARATOR) == MF_SEPARATOR) { |
| 874 | rect.bottom = rect.top + 3; |
| 875 | } |
| 876 | if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) { |
| 877 | hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text); |
| 878 | GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm); |
| 879 | rect.bottom = rect.top + bm.bmHeight; |
| 880 | lppop->Width = max(lppop->Width, bm.bmWidth); |
| 881 | } |
| 882 | if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) && |
| 883 | ((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && |
| 884 | ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) { |
| 885 | dwRet = GetTextExtent(hDC, (char *)lpitem->item_text, |
| 886 | strlen((char *)lpitem->item_text)); |
| 887 | rect.bottom = rect.top + HIWORD(dwRet); |
| 888 | InflateRect(&rect, 0, 2); |
| 889 | TempWidth = LOWORD(dwRet); |
| 890 | if (GetShortCutPos(lpitem->item_text) != (WORD)-1) |
| 891 | TempWidth += 15; |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 892 | TempWidth += lppop->CheckWidth; |
| 893 | TempWidth += lppop->PopWidth; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 894 | lppop->Width = max(lppop->Width, TempWidth); |
| 895 | } |
| 896 | CopyRect(&lpitem->rect, &rect); |
| 897 | rect.top = rect.bottom; |
| 898 | lpitem = (LPMENUITEM)lpitem->next; |
| 899 | } |
| 900 | if (OldWidth < lppop->Width) goto CalcAGAIN; |
| 901 | lppop->Height = rect.bottom; |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 902 | SetRect(&lppop->rect, 1, 1, lppop->Width, lppop->Height); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 903 | #ifdef DEBUG_MENUCALC |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 904 | printf("PopupMenuCalcSize w=%d h=%d !\n", lppop->Width, lppop->Height); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 905 | #endif |
| 906 | SelectObject(hDC, hOldFont); |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 907 | ReleaseDC(hwnd, hDC); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 908 | } |
| 909 | |
| 910 | |
| 911 | |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 912 | void MenuBarCalcSize(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop) |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 913 | { |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 914 | LPMENUITEM lpitem; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 915 | RECT rect; |
| 916 | HBITMAP hBitMap; |
| 917 | BITMAP bm; |
| 918 | HFONT hOldFont; |
| 919 | UINT i, OldHeight; |
| 920 | DWORD dwRet; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 921 | if (lppop == NULL) return; |
| 922 | if (lppop->nItems == 0) return; |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 923 | #ifdef DEBUG_MENUCALC |
| 924 | printf("MenuBarCalcSize left=%d top=%d right=%d bottom=%d !\n", |
| 925 | lprect->left, lprect->top, lprect->right, lprect->bottom); |
| 926 | #endif |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 927 | hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT)); |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 928 | lppop->Height = lprect->bottom - lprect->top; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 929 | CalcAGAIN: |
| 930 | OldHeight = lppop->Height; |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 931 | SetRect(&rect, lprect->left, lprect->top, 0, lprect->top + OldHeight); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 932 | lpitem = lppop->firstItem; |
| 933 | for(i = 0; i < lppop->nItems; i++) { |
| 934 | if (lpitem == NULL) break; |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 935 | rect.bottom = lprect->top + lppop->Height; |
| 936 | if (rect.right > lprect->right) |
| 937 | SetRect(&rect, lprect->left, rect.bottom, |
| 938 | 0, rect.bottom + SYSMETRICS_CYMENU); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 939 | if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) { |
| 940 | hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text); |
| 941 | GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm); |
| 942 | rect.right = rect.left + bm.bmWidth; |
| 943 | lppop->Height = max(lppop->Height, bm.bmHeight); |
| 944 | } |
| 945 | if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) && |
| 946 | ((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && |
| 947 | ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) { |
| 948 | dwRet = GetTextExtent(hDC, (char *)lpitem->item_text, |
| 949 | strlen((char *)lpitem->item_text)); |
| 950 | rect.right = rect.left + LOWORD(dwRet) + 10; |
| 951 | lppop->Height = max(lppop->Height, HIWORD(dwRet) + 10); |
| 952 | } |
| 953 | CopyRect(&lpitem->rect, &rect); |
| 954 | rect.left = rect.right; |
| 955 | lpitem = (LPMENUITEM)lpitem->next; |
| 956 | } |
| 957 | if (OldHeight < lppop->Height) goto CalcAGAIN; |
| 958 | lppop->Width = rect.right; |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 959 | lprect->bottom = lprect->top + lppop->Height; |
| 960 | CopyRect(&lppop->rect, lprect); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 961 | #ifdef DEBUG_MENUCALC |
| 962 | printf("MenuBarCalcSize w=%d h=%d !\n", |
| 963 | lppop->Width, lppop->Height); |
| 964 | #endif |
| 965 | SelectObject(hDC, hOldFont); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 966 | } |
| 967 | |
| 968 | |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 969 | |
| 970 | LPMENUITEM GetMenuItemPtr(LPPOPUPMENU menu, WORD nPos) |
| 971 | { |
| 972 | LPMENUITEM lpitem; |
| 973 | int i; |
| 974 | if (menu == NULL) return NULL; |
| 975 | lpitem = menu->firstItem; |
| 976 | for (i = 0; i < menu->nItems; i++) { |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 977 | if (lpitem == NULL) return NULL; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 978 | if (i == nPos) return(lpitem); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 979 | lpitem = (LPMENUITEM)lpitem->next; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 980 | } |
| 981 | return NULL; |
| 982 | } |
| 983 | |
| 984 | |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 985 | WORD GetSelectionKey(LPSTR str) |
| 986 | { |
| 987 | int i; |
| 988 | WORD sel_key; |
| 989 | for (i = 0; i < strlen(str); i++) { |
| 990 | if (str[i] == '&' && str[i + 1] != '&') |
| 991 | { |
| 992 | sel_key = str[i + 1]; |
| 993 | if (sel_key >= 'a' && sel_key <= 'z') sel_key -= 'a' - 'A'; |
| 994 | #ifdef DEBUG_MENU |
| 995 | printf("GetSelectionKey // %04X\n", sel_key); |
| 996 | #endif |
| 997 | return sel_key; |
| 998 | } |
| 999 | } |
| 1000 | #ifdef DEBUG_MENU |
| 1001 | printf("GetSelectionKey NULL \n"); |
| 1002 | #endif |
| 1003 | return 0; |
| 1004 | } |
| 1005 | |
| 1006 | |
| 1007 | |
| 1008 | LPSTR GetShortCutString(LPSTR str) |
| 1009 | { |
| 1010 | int i; |
| 1011 | LPSTR str2; |
| 1012 | for (i = 0; i < strlen(str); i++) { |
| 1013 | if (str[i] == '\t' && str[i + 1] != '\t') |
| 1014 | { |
| 1015 | str2 = &str[i + 1]; |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1016 | #ifdef DEBUG_MENUSHORTCUT |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1017 | printf("GetShortCutString // '%s' \n", str2); |
| 1018 | #endif |
| 1019 | return str2; |
| 1020 | } |
| 1021 | } |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1022 | #ifdef DEBUG_MENUSHORTCUT |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1023 | printf("GetShortCutString NULL \n"); |
| 1024 | #endif |
| 1025 | return NULL; |
| 1026 | } |
| 1027 | |
| 1028 | |
| 1029 | |
| 1030 | WORD GetShortCutPos(LPSTR str) |
| 1031 | { |
| 1032 | int i; |
| 1033 | for (i = 0; i < strlen(str); i++) { |
| 1034 | if (str[i] == '\t' && str[i + 1] != '\t') |
| 1035 | { |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1036 | #ifdef DEBUG_MENUSHORTCUT |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1037 | printf("GetShortCutPos = %d \n", i); |
| 1038 | #endif |
| 1039 | return i; |
| 1040 | } |
| 1041 | } |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1042 | #ifdef DEBUG_MENUSHORTCUT |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1043 | printf("GetShortCutString NULL \n"); |
| 1044 | #endif |
| 1045 | return -1; |
| 1046 | } |
| 1047 | |
| 1048 | |
| 1049 | |
| 1050 | BOOL HideAllSubPopupMenu(LPPOPUPMENU menu) |
| 1051 | { |
| 1052 | LPPOPUPMENU submenu; |
| 1053 | LPMENUITEM lpitem; |
| 1054 | BOOL someClosed = FALSE; |
| 1055 | int i; |
| 1056 | if (menu == NULL) return; |
| 1057 | lpitem = menu->firstItem; |
| 1058 | for (i = 0; i < menu->nItems; i++) { |
| 1059 | if (lpitem == NULL) return; |
| 1060 | if (lpitem->item_flags & MF_POPUP) { |
| 1061 | submenu = (LPPOPUPMENU) GlobalLock((HMENU)lpitem->item_id); |
| 1062 | if (submenu != NULL) { |
| 1063 | if (IsWindowVisible(submenu->hWnd)) { |
| 1064 | ShowWindow(submenu->hWnd, SW_HIDE); |
| 1065 | someClosed = TRUE; |
| 1066 | } |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1067 | GlobalUnlock((HMENU)lpitem->item_id); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1068 | } |
| 1069 | } |
| 1070 | lpitem = (LPMENUITEM)lpitem->next; |
| 1071 | } |
| 1072 | return someClosed; |
| 1073 | } |
| 1074 | |
| 1075 | |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1076 | |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1077 | |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 1078 | /********************************************************************** |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1079 | * ChangeMenu [USER.153] |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 1080 | */ |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1081 | BOOL ChangeMenu(HMENU hMenu, WORD nPos, LPSTR lpNewItem, |
| 1082 | WORD wItemID, WORD wFlags) |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 1083 | { |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1084 | if (wFlags & MF_APPEND) { |
| 1085 | return AppendMenu(hMenu, wFlags, wItemID, lpNewItem); |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 1086 | } |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1087 | if (wFlags & MF_DELETE) { |
| 1088 | return DeleteMenu(hMenu, wItemID, wFlags); |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 1089 | } |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1090 | if (wFlags & MF_INSERT) { |
| 1091 | return InsertMenu(hMenu, nPos, wFlags, wItemID, lpNewItem); |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 1092 | } |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1093 | if (wFlags & MF_CHANGE) { |
| 1094 | return ModifyMenu(hMenu, nPos, wFlags, wItemID, lpNewItem); |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 1095 | } |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1096 | if (wFlags & MF_REMOVE) { |
| 1097 | return RemoveMenu(hMenu, wItemID, wFlags); |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 1098 | } |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1099 | return FALSE; |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 1100 | } |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1101 | |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1102 | |
| 1103 | /********************************************************************** |
| 1104 | * CheckMenuItem [USER.154] |
| 1105 | */ |
| 1106 | BOOL CheckMenuItem(HMENU hMenu, WORD wItemID, WORD wFlags) |
| 1107 | { |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1108 | WND *wndPtr; |
| 1109 | LPPOPUPMENU menu; |
| 1110 | LPMENUITEM lpitem; |
| 1111 | int i; |
| 1112 | #ifdef DEBUG_MENU |
| 1113 | printf("CheckMenuItem (%04X, %04X, %04X) !\n", hMenu, wItemID, wFlags); |
| 1114 | #endif |
| 1115 | menu = (LPPOPUPMENU) GlobalLock(hMenu); |
| 1116 | if (menu == NULL) return FALSE; |
| 1117 | lpitem = menu->firstItem; |
| 1118 | for (i = 0; i < menu->nItems; i++) { |
| 1119 | if (lpitem == NULL) break; |
| 1120 | if (i == wItemID) { |
| 1121 | if (wFlags && MF_CHECKED) |
| 1122 | lpitem->item_flags |= MF_CHECKED; |
| 1123 | else |
| 1124 | lpitem->item_flags &= ((WORD)-1 ^ MF_CHECKED); |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1125 | GlobalUnlock(hMenu); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1126 | return(TRUE); |
| 1127 | } |
| 1128 | lpitem = (LPMENUITEM)lpitem->next; |
| 1129 | } |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1130 | GlobalUnlock(hMenu); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1131 | return FALSE; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1132 | } |
| 1133 | |
| 1134 | |
| 1135 | /********************************************************************** |
| 1136 | * EnableMenuItem [USER.155] |
| 1137 | */ |
| 1138 | BOOL EnableMenuItem(HMENU hMenu, WORD wItemID, WORD wFlags) |
| 1139 | { |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1140 | WND *wndPtr; |
| 1141 | LPPOPUPMENU menu; |
| 1142 | LPMENUITEM lpitem; |
| 1143 | int i; |
| 1144 | #ifdef DEBUG_MENU |
| 1145 | printf("EnableMenuItem (%04X, %04X, %04X) !\n", hMenu, wItemID, wFlags); |
| 1146 | #endif |
| 1147 | menu = (LPPOPUPMENU) GlobalLock(hMenu); |
| 1148 | if (menu == NULL) return FALSE; |
| 1149 | lpitem = menu->firstItem; |
| 1150 | for (i = 0; i < menu->nItems; i++) { |
| 1151 | if (lpitem == NULL) break; |
| 1152 | if (i == wItemID) { |
| 1153 | if (wFlags && MF_DISABLED) |
| 1154 | lpitem->item_flags |= MF_DISABLED; |
| 1155 | else |
| 1156 | lpitem->item_flags &= ((WORD)-1 ^ MF_DISABLED); |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1157 | GlobalUnlock(hMenu); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1158 | return(TRUE); |
| 1159 | } |
| 1160 | lpitem = (LPMENUITEM)lpitem->next; |
| 1161 | } |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1162 | GlobalUnlock(hMenu); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1163 | return FALSE; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1164 | } |
| 1165 | |
| 1166 | |
| 1167 | /********************************************************************** |
| 1168 | * InsertMenu [USER.410] |
| 1169 | */ |
| 1170 | BOOL InsertMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewItem) |
| 1171 | { |
| 1172 | WND *wndPtr; |
| 1173 | LPPOPUPMENU menu; |
| 1174 | HANDLE hNewItem; |
| 1175 | LPMENUITEM lpitem, lpitem2; |
| 1176 | int i; |
| 1177 | #ifdef DEBUG_MENU |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1178 | if (wFlags & MF_STRING) |
| 1179 | printf("InsertMenu (%04X, %04X, %04X, '%s') !\n", |
| 1180 | hMenu, wFlags, wItemID, lpNewItem); |
| 1181 | else |
| 1182 | printf("InsertMenu (%04X, %04X, %04X, %04X, %08X) !\n", |
| 1183 | hMenu, nPos, wFlags, wItemID, lpNewItem); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1184 | #endif |
| 1185 | menu = (LPPOPUPMENU) GlobalLock(hMenu); |
| 1186 | if (menu == NULL) return FALSE; |
| 1187 | lpitem = menu->firstItem; |
| 1188 | for (i = 0; i < menu->nItems; i++) { |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1189 | if (lpitem == NULL) break; |
| 1190 | if (i == nPos) break; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1191 | lpitem = (LPMENUITEM)lpitem->next; |
| 1192 | printf("InsertMenu // during loop items !\n"); |
| 1193 | } |
| 1194 | printf("InsertMenu // after loop items !\n"); |
| 1195 | hNewItem = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM)); |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1196 | if (hNewItem == 0) { |
| 1197 | GlobalUnlock(hMenu); |
| 1198 | return FALSE; |
| 1199 | } |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1200 | lpitem2 = (LPMENUITEM)GlobalLock(hNewItem); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1201 | if (lpitem2 == NULL) { |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1202 | GlobalFree(hNewItem); |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1203 | GlobalUnlock(hMenu); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1204 | return FALSE; |
| 1205 | } |
| 1206 | lpitem2->item_flags = wFlags; |
| 1207 | lpitem2->item_id = wItemID; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1208 | if (((wFlags & MF_BITMAP) != MF_BITMAP) && |
| 1209 | ((wFlags & MF_MENUBREAK) != MF_MENUBREAK) && |
| 1210 | ((wFlags & MF_STRING) != MF_SEPARATOR)) { |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1211 | lpitem2->item_text = lpNewItem; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1212 | lpitem2->sel_key = GetSelectionKey(lpitem2->item_text); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1213 | } |
| 1214 | else |
| 1215 | lpitem2->item_text = lpNewItem; |
| 1216 | lpitem2->prev = lpitem; |
| 1217 | if (lpitem->next != NULL) |
| 1218 | lpitem2->next = lpitem->next; |
| 1219 | else |
| 1220 | lpitem2->next = NULL; |
| 1221 | lpitem->next = lpitem2; |
| 1222 | lpitem2->child = NULL; |
| 1223 | lpitem2->parent = NULL; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1224 | menu->nItems++; |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1225 | GlobalUnlock(hMenu); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1226 | return TRUE; |
| 1227 | } |
| 1228 | |
| 1229 | |
| 1230 | /********************************************************************** |
| 1231 | * AppendMenu [USER.411] |
| 1232 | */ |
| 1233 | BOOL AppendMenu(HMENU hMenu, WORD wFlags, WORD wItemID, LPSTR lpNewItem) |
| 1234 | { |
| 1235 | WND *wndPtr; |
| 1236 | LPPOPUPMENU menu; |
| 1237 | HANDLE hNewItem; |
| 1238 | LPMENUITEM lpitem, lpitem2; |
| 1239 | #ifdef DEBUG_MENU |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1240 | if ((wFlags & (MF_BITMAP | MF_SEPARATOR | MF_MENUBREAK | MF_OWNERDRAW)) == 0) |
| 1241 | printf("AppendMenu (%04X, %04X, %04X, '%s') !\n", |
| 1242 | hMenu, wFlags, wItemID, lpNewItem); |
| 1243 | else |
| 1244 | printf("AppendMenu (%04X, %04X, %04X, %08X) !\n", |
| 1245 | hMenu, wFlags, wItemID, lpNewItem); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1246 | #endif |
| 1247 | menu = (LPPOPUPMENU) GlobalLock(hMenu); |
| 1248 | if (menu == NULL) return FALSE; |
| 1249 | lpitem = menu->firstItem; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1250 | if (lpitem != NULL) { |
| 1251 | while (lpitem->next != NULL) { |
| 1252 | lpitem = (LPMENUITEM)lpitem->next; |
| 1253 | } |
| 1254 | } |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1255 | hNewItem = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM)); |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1256 | if (hNewItem == 0) { |
| 1257 | GlobalUnlock(hMenu); |
| 1258 | return FALSE; |
| 1259 | } |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1260 | lpitem2 = (LPMENUITEM)GlobalLock(hNewItem); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1261 | if (lpitem2 == NULL) { |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1262 | GlobalFree(hNewItem); |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1263 | GlobalUnlock(hMenu); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1264 | return FALSE; |
| 1265 | } |
| 1266 | lpitem2->item_flags = wFlags; |
| 1267 | lpitem2->item_id = wItemID; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1268 | if (((wFlags & MF_BITMAP) != MF_BITMAP) && |
| 1269 | ((wFlags & MF_MENUBREAK) != MF_MENUBREAK) && |
| 1270 | ((wFlags & MF_STRING) != MF_SEPARATOR)) { |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1271 | lpitem2->item_text = lpNewItem; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1272 | lpitem2->sel_key = GetSelectionKey(lpitem2->item_text); |
| 1273 | lpitem2->shortcut = GetShortCutString(lpitem2->item_text); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1274 | } |
| 1275 | else |
| 1276 | lpitem2->item_text = lpNewItem; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1277 | if (lpitem == NULL) |
| 1278 | menu->firstItem = lpitem2; |
| 1279 | else |
| 1280 | lpitem->next = lpitem2; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1281 | lpitem2->prev = lpitem; |
| 1282 | lpitem2->next = NULL; |
| 1283 | lpitem2->child = NULL; |
| 1284 | lpitem2->parent = NULL; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1285 | lpitem2->hCheckBit = (HBITMAP)NULL; |
| 1286 | lpitem2->hUnCheckBit = (HBITMAP)NULL; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1287 | menu->nItems++; |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1288 | GlobalUnlock(hMenu); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1289 | return TRUE; |
| 1290 | } |
| 1291 | |
| 1292 | |
| 1293 | /********************************************************************** |
| 1294 | * RemoveMenu [USER.412] |
| 1295 | */ |
| 1296 | BOOL RemoveMenu(HMENU hMenu, WORD nPos, WORD wFlags) |
| 1297 | { |
| 1298 | WND *wndPtr; |
| 1299 | LPPOPUPMENU menu; |
| 1300 | LPMENUITEM lpitem; |
| 1301 | int i; |
| 1302 | #ifdef DEBUG_MENU |
| 1303 | printf("RemoveMenu (%04X, %04X, %04X) !\n", hMenu, nPos, wFlags); |
| 1304 | #endif |
| 1305 | menu = (LPPOPUPMENU) GlobalLock(hMenu); |
| 1306 | if (menu == NULL) return FALSE; |
| 1307 | lpitem = menu->firstItem; |
| 1308 | for (i = 0; i < menu->nItems; i++) { |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1309 | if (lpitem == NULL) break; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1310 | if (i == nPos) { |
| 1311 | lpitem->prev->next = lpitem->next; |
| 1312 | lpitem->next->prev = lpitem->prev; |
| 1313 | GlobalFree(HIWORD(lpitem)); |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1314 | GlobalUnlock(hMenu); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1315 | return(TRUE); |
| 1316 | } |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1317 | lpitem = (LPMENUITEM)lpitem->next; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1318 | printf("RemoveMenu // during loop items !\n"); |
| 1319 | } |
| 1320 | printf("RemoveMenu // after loop items !\n"); |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1321 | GlobalUnlock(hMenu); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1322 | return FALSE; |
| 1323 | } |
| 1324 | |
| 1325 | |
| 1326 | /********************************************************************** |
| 1327 | * DeleteMenu [USER.413] |
| 1328 | */ |
| 1329 | BOOL DeleteMenu(HMENU hMenu, WORD nPos, WORD wFlags) |
| 1330 | { |
| 1331 | #ifdef DEBUG_MENU |
| 1332 | printf("DeleteMenu (%04X, %04X, %04X) !\n", hMenu, nPos, wFlags); |
| 1333 | #endif |
| 1334 | return TRUE; |
| 1335 | } |
| 1336 | |
| 1337 | |
| 1338 | /********************************************************************** |
| 1339 | * ModifyMenu [USER.414] |
| 1340 | */ |
| 1341 | BOOL ModifyMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewItem) |
| 1342 | { |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1343 | WND *wndPtr; |
| 1344 | LPPOPUPMENU menu; |
| 1345 | LPMENUITEM lpitem; |
| 1346 | int i; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1347 | #ifdef DEBUG_MENU |
| 1348 | printf("ModifyMenu (%04X, %04X, %04X, %04X, %08X) !\n", |
| 1349 | hMenu, nPos, wFlags, wItemID, lpNewItem); |
| 1350 | #endif |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1351 | menu = (LPPOPUPMENU) GlobalLock(hMenu); |
| 1352 | if (menu == NULL) return FALSE; |
| 1353 | lpitem = menu->firstItem; |
| 1354 | for (i = 0; i < menu->nItems; i++) { |
| 1355 | if (lpitem == NULL) break; |
| 1356 | if (i == nPos) { |
| 1357 | lpitem->item_flags = wFlags; |
| 1358 | lpitem->item_id = wItemID; |
| 1359 | lpitem->item_text = lpNewItem; |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1360 | GlobalUnlock(hMenu); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1361 | return(TRUE); |
| 1362 | } |
| 1363 | lpitem = (LPMENUITEM)lpitem->next; |
| 1364 | } |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1365 | GlobalUnlock(hMenu); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1366 | return FALSE; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1367 | } |
| 1368 | |
| 1369 | |
| 1370 | /********************************************************************** |
| 1371 | * CreatePopupMenu [USER.415] |
| 1372 | */ |
| 1373 | HMENU CreatePopupMenu() |
| 1374 | { |
| 1375 | HANDLE hItem; |
| 1376 | HMENU hMenu; |
| 1377 | LPPOPUPMENU menu; |
| 1378 | #ifdef DEBUG_MENU |
| 1379 | printf("CreatePopupMenu !\n"); |
| 1380 | #endif |
| 1381 | hMenu = GlobalAlloc(GMEM_MOVEABLE, sizeof(POPUPMENU)); |
| 1382 | menu = (LPPOPUPMENU) GlobalLock(hMenu); |
| 1383 | if (menu == NULL) { |
| 1384 | GlobalFree(hMenu); |
| 1385 | return 0; |
| 1386 | } |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1387 | menu->nItems = 0; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1388 | menu->firstItem = NULL; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1389 | menu->ownerWnd = 0; |
| 1390 | menu->hWnd = 0; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1391 | menu->hWndParent = 0; |
| 1392 | menu->MouseFlags = 0; |
| 1393 | menu->BarFlags = 0; |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 1394 | menu->SysFlag = FALSE; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1395 | menu->Width = 100; |
| 1396 | menu->Height = 0; |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1397 | GlobalUnlock(hMenu); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1398 | return hMenu; |
| 1399 | } |
| 1400 | |
| 1401 | |
| 1402 | /********************************************************************** |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1403 | * TrackPopupMenu [USER.416] |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1404 | */ |
| 1405 | BOOL TrackPopupMenu(HMENU hMenu, WORD wFlags, short x, short y, |
| 1406 | short nReserved, HWND hWnd, LPRECT lpRect) |
| 1407 | { |
| 1408 | WND *wndPtr; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1409 | LPPOPUPMENU lppop; |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1410 | RECT rect; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1411 | #ifdef DEBUG_MENU |
| 1412 | printf("TrackPopupMenu (%04X, %04X, %d, %d, %04X, %04X, %08X) !\n", |
| 1413 | hMenu, wFlags, x, y, nReserved, hWnd, lpRect); |
| 1414 | #endif |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1415 | lppop = (LPPOPUPMENU) GlobalLock(hMenu); |
| 1416 | if (lppop == NULL) return FALSE; |
| 1417 | wndPtr = WIN_FindWndPtr(hWnd); |
| 1418 | lppop->ownerWnd = hWnd; |
| 1419 | if (lppop->hWnd == (HWND)NULL) { |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 1420 | lppop->hWnd = CreateWindow("POPUPMENU", "", WS_POPUP | WS_VISIBLE, |
| 1421 | x, y, lppop->Width, lppop->Height, (HWND)NULL, 0, |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1422 | wndPtr->hInstance, (LPSTR)lppop); |
| 1423 | } |
| 1424 | else { |
| 1425 | ShowWindow(lppop->hWnd, SW_SHOW); |
| 1426 | } |
| 1427 | if (lppop->BarFlags == 0) { |
| 1428 | PopupMenuCalcSize(lppop->hWnd); |
| 1429 | #ifdef DEBUG_MENU |
| 1430 | printf("TrackPopupMenu // x=%d y=%d Width=%d Height=%d\n", |
| 1431 | x, y, lppop->Width, lppop->Height); |
| 1432 | #endif |
| 1433 | SetWindowPos(lppop->hWnd, 0, x, y, lppop->Width + 2, lppop->Height, |
| 1434 | SWP_NOZORDER); |
| 1435 | } |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1436 | GlobalUnlock(hMenu); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1437 | return TRUE; |
| 1438 | } |
| 1439 | |
| 1440 | |
| 1441 | /********************************************************************** |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 1442 | * NC_TrackSysMenu [Internal] |
| 1443 | */ |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1444 | void NC_TrackSysMenu(HWND hWnd) |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 1445 | { |
| 1446 | RECT rect; |
| 1447 | LPPOPUPMENU lpsys; |
| 1448 | WND *wndPtr = WIN_FindWndPtr(hWnd); |
| 1449 | #ifdef DEBUG_MENU |
| 1450 | printf("NC_TrackSysMenu hWnd=%04X !\n", hWnd); |
| 1451 | #endif |
| 1452 | if (!wndPtr) return; |
| 1453 | lpsys = (LPPOPUPMENU)GlobalLock(wndPtr->hSysMenu); |
| 1454 | #ifdef DEBUG_MENU |
| 1455 | printf("NC_TrackSysMenu wndPtr->hSysMenu=%04X !\n", wndPtr->hSysMenu); |
| 1456 | #endif |
| 1457 | if (lpsys == NULL) return; |
| 1458 | #ifdef DEBUG_MENU |
| 1459 | printf("NC_TrackSysMenu wndPtr->hSysMenu=%04X !\n", wndPtr->hSysMenu); |
| 1460 | #endif |
| 1461 | lpsys->BarFlags = FALSE; |
| 1462 | lpsys->SysFlag = TRUE; |
| 1463 | if (!IsWindowVisible(lpsys->hWnd)) { |
| 1464 | GetWindowRect(hWnd, &rect); |
| 1465 | #ifdef DEBUG_MENU |
| 1466 | printf("NC_TrackSysMenu lpsys->hWnd=%04X !\n", lpsys->hWnd); |
| 1467 | #endif |
| 1468 | TrackPopupMenu(wndPtr->hSysMenu, TPM_LEFTBUTTON, |
| 1469 | rect.left, rect.top + SYSMETRICS_CYSIZE, |
| 1470 | 0, hWnd, (LPRECT)NULL); |
| 1471 | } |
| 1472 | else { |
| 1473 | ShowWindow(lpsys->hWnd, SW_HIDE); |
| 1474 | } |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1475 | GlobalUnlock(wndPtr->hSysMenu); |
| 1476 | } |
| 1477 | |
| 1478 | |
| 1479 | /********************************************************************** |
| 1480 | * GetMenuCheckMarkDimensions [USER.417] |
| 1481 | */ |
| 1482 | DWORD GetMenuCheckMarkDimensions() |
| 1483 | { |
| 1484 | BITMAP bm; |
| 1485 | if (hStdCheck == (HBITMAP)NULL) |
| 1486 | hStdCheck = LoadBitmap((HANDLE)NULL, (LPSTR)OBM_CHECK); |
| 1487 | GetObject(hStdCheck, sizeof(BITMAP), (LPSTR)&bm); |
| 1488 | return MAKELONG(bm.bmWidth, bm.bmHeight); |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 1489 | } |
| 1490 | |
| 1491 | |
| 1492 | /********************************************************************** |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1493 | * SetMenuItemBitmaps [USER.418] |
| 1494 | */ |
| 1495 | BOOL SetMenuItemBitmaps(HMENU hMenu, WORD nPos, WORD wFlags, |
| 1496 | HBITMAP hNewCheck, HBITMAP hNewUnCheck) |
| 1497 | { |
| 1498 | WND *wndPtr; |
| 1499 | LPPOPUPMENU menu; |
| 1500 | LPMENUITEM lpitem; |
| 1501 | int i; |
| 1502 | #ifdef DEBUG_MENU |
| 1503 | printf("SetMenuItemBitmaps (%04X, %04X, %04X, %04X, %08X) !\n", |
| 1504 | hMenu, nPos, wFlags, hNewCheck, hNewUnCheck); |
| 1505 | #endif |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1506 | menu = (LPPOPUPMENU) GlobalLock(hMenu); |
| 1507 | if (menu == NULL) return FALSE; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1508 | lpitem = menu->firstItem; |
| 1509 | for (i = 0; i < menu->nItems; i++) { |
| 1510 | if (lpitem == NULL) break; |
| 1511 | if (i == nPos) { |
| 1512 | lpitem->hCheckBit = hNewCheck; |
| 1513 | lpitem->hUnCheckBit = hNewUnCheck; |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1514 | GlobalUnlock(hMenu); |
| 1515 | return TRUE; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1516 | } |
| 1517 | lpitem = (LPMENUITEM)lpitem->next; |
| 1518 | } |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1519 | GlobalUnlock(hMenu); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1520 | return FALSE; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1521 | } |
| 1522 | |
| 1523 | |
| 1524 | /********************************************************************** |
| 1525 | * CreateMenu [USER.151] |
| 1526 | */ |
| 1527 | HMENU CreateMenu() |
| 1528 | { |
| 1529 | HANDLE hItem; |
| 1530 | HMENU hMenu; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1531 | LPPOPUPMENU menu; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1532 | #ifdef DEBUG_MENU |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1533 | printf("CreatePopupMenu !\n"); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1534 | #endif |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1535 | hMenu = GlobalAlloc(GMEM_MOVEABLE, sizeof(POPUPMENU)); |
| 1536 | menu = (LPPOPUPMENU) GlobalLock(hMenu); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1537 | if (menu == NULL) { |
| 1538 | GlobalFree(hMenu); |
| 1539 | return 0; |
| 1540 | } |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1541 | menu->nItems = 0; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1542 | menu->firstItem = NULL; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1543 | menu->ownerWnd = 0; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1544 | menu->hWnd = 0; |
| 1545 | menu->hWndParent = 0; |
| 1546 | menu->MouseFlags = 0; |
| 1547 | menu->BarFlags = TRUE; |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 1548 | menu->SysFlag = FALSE; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1549 | menu->Width = 100; |
| 1550 | menu->Height = 0; |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1551 | GlobalUnlock(hMenu); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1552 | return hMenu; |
| 1553 | } |
| 1554 | |
| 1555 | |
| 1556 | /********************************************************************** |
| 1557 | * DestroyMenu [USER.152] |
| 1558 | */ |
| 1559 | BOOL DestroyMenu(HMENU hMenu) |
| 1560 | { |
| 1561 | LPPOPUPMENU lppop; |
| 1562 | LPMENUITEM lpitem, lpitem2; |
| 1563 | #ifdef DEBUG_MENU |
| 1564 | printf("DestroyMenu (%04X) !\n", hMenu); |
| 1565 | #endif |
| 1566 | if (hMenu == 0) return FALSE; |
| 1567 | lppop = (LPPOPUPMENU) GlobalLock(hMenu); |
| 1568 | if (lppop == NULL) return FALSE; |
| 1569 | if (lppop->hWnd) DestroyWindow (lppop->hWnd); |
| 1570 | lpitem = lppop->firstItem; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1571 | while (lpitem != NULL) { |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1572 | #ifdef DEBUG_MENU |
| 1573 | printf("DestroyMenu (%04X) // during loop items !\n", hMenu); |
| 1574 | #endif |
| 1575 | if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) { |
| 1576 | DestroyMenu((HMENU)lpitem->item_id); |
| 1577 | } |
| 1578 | lpitem = (LPMENUITEM)lpitem->next; |
| 1579 | } |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1580 | GlobalUnlock(hMenu); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1581 | GlobalFree(hMenu); |
| 1582 | #ifdef DEBUG_MENU |
| 1583 | printf("DestroyMenu (%04X) // End !\n", hMenu); |
| 1584 | #endif |
| 1585 | return TRUE; |
| 1586 | } |
| 1587 | |
| 1588 | |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1589 | /********************************************************************** |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 1590 | * LoadMenu [USER.150] |
| 1591 | */ |
| 1592 | HMENU LoadMenu(HINSTANCE instance, char *menu_name) |
| 1593 | { |
| 1594 | HMENU hMenu; |
| 1595 | HANDLE hMenu_desc; |
| 1596 | MENU_HEADER *menu_desc; |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 1597 | #ifdef DEBUG_MENU |
| 1598 | if ((LONG)menu_name & 0xFFFF0000L) |
| 1599 | printf("LoadMenu: instance %02x, menu '%s'\n", instance, menu_name); |
| 1600 | else |
| 1601 | printf("LoadMenu: instance %02x, menu '%04X'\n", instance, menu_name); |
| 1602 | #endif |
| 1603 | if (instance == (HANDLE)NULL) instance = hSysRes; |
| 1604 | if (menu_name == NULL || |
| 1605 | (hMenu_desc = RSC_LoadMenu(instance, menu_name)) == 0 || |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1606 | (menu_desc = (MENU_HEADER *) GlobalLock(hMenu_desc)) == NULL) { |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 1607 | return 0; |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1608 | } |
| 1609 | hMenu = LoadMenuIndirect((LPSTR)menu_desc); |
| 1610 | /* |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 1611 | hMenu = CreateMenu(); |
| 1612 | ParseMenuResource((WORD *) (menu_desc + 1), 0, hMenu); |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1613 | GlobalUnlock(hMenu_desc); |
| 1614 | GlobalFree(hMenu_desc); |
| 1615 | */ |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 1616 | return hMenu; |
| 1617 | } |
| 1618 | |
| 1619 | |
| 1620 | /********************************************************************** |
| 1621 | * GetSystemMenu [USER.156] |
| 1622 | */ |
| 1623 | HMENU GetSystemMenu(HWND hWnd, BOOL bRevert) |
| 1624 | { |
| 1625 | WND *wndPtr; |
| 1626 | wndPtr = WIN_FindWndPtr(hWnd); |
| 1627 | if (!bRevert) { |
| 1628 | return wndPtr->hSysMenu; |
| 1629 | } |
| 1630 | else { |
| 1631 | DestroyMenu(wndPtr->hSysMenu); |
| 1632 | wndPtr->hSysMenu = CopySysMenu(); |
| 1633 | } |
| 1634 | return wndPtr->hSysMenu; |
| 1635 | } |
| 1636 | |
| 1637 | |
| 1638 | /********************************************************************** |
| 1639 | * GetMenu [USER.157] |
| 1640 | */ |
| 1641 | HMENU GetMenu(HWND hWnd) |
| 1642 | { |
| 1643 | WND * wndPtr = WIN_FindWndPtr(hWnd); |
| 1644 | if (wndPtr == NULL) return 0; |
| 1645 | return wndPtr->wIDmenu; |
| 1646 | } |
| 1647 | |
| 1648 | /********************************************************************** |
| 1649 | * SetMenu [USER.158] |
| 1650 | */ |
| 1651 | BOOL SetMenu(HWND hWnd, HMENU hMenu) |
| 1652 | { |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1653 | LPPOPUPMENU lppop; |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 1654 | WND * wndPtr = WIN_FindWndPtr(hWnd); |
| 1655 | if (wndPtr == NULL) return FALSE; |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1656 | #ifdef DEBUG_MENU |
| 1657 | printf("SetMenu(%04X, %04X);\n", hWnd, hMenu); |
| 1658 | #endif |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 1659 | wndPtr->wIDmenu = hMenu; |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1660 | if (hMenu == 0) return TRUE; |
| 1661 | lppop = (LPPOPUPMENU) GlobalLock(hMenu); |
| 1662 | if (lppop == NULL) return FALSE; |
| 1663 | lppop->ownerWnd = hWnd; |
| 1664 | GlobalUnlock(hMenu); |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 1665 | return TRUE; |
| 1666 | } |
| 1667 | |
| 1668 | |
| 1669 | /********************************************************************** |
| 1670 | * GetSubMenu [USER.159] |
| 1671 | */ |
| 1672 | HMENU GetSubMenu(HMENU hMenu, short nPos) |
| 1673 | { |
| 1674 | HMENU hSubMenu; |
| 1675 | LPPOPUPMENU lppop; |
| 1676 | LPMENUITEM lpitem; |
| 1677 | int i; |
| 1678 | #ifdef DEBUG_MENU |
| 1679 | printf("GetSubMenu (%04X, %04X) !\n", hMenu, nPos); |
| 1680 | #endif |
| 1681 | if (hMenu == 0) return 0; |
| 1682 | lppop = (LPPOPUPMENU) GlobalLock(hMenu); |
| 1683 | if (lppop == NULL) return 0; |
| 1684 | lpitem = lppop->firstItem; |
| 1685 | for (i = 0; i < lppop->nItems; i++) { |
| 1686 | if (lpitem == NULL) break; |
| 1687 | if (i == nPos) { |
| 1688 | if (lpitem->item_flags & MF_POPUP) |
| 1689 | return hSubMenu; |
| 1690 | else |
| 1691 | return 0; |
| 1692 | } |
| 1693 | lpitem = (LPMENUITEM)lpitem->next; |
| 1694 | } |
| 1695 | return 0; |
| 1696 | } |
| 1697 | |
| 1698 | |
| 1699 | /********************************************************************** |
| 1700 | * DrawMenuBar [USER.160] |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1701 | */ |
| 1702 | void DrawMenuBar(HWND hWnd) |
| 1703 | { |
| 1704 | WND *wndPtr; |
| 1705 | #ifdef DEBUG_MENU |
| 1706 | printf("DrawMenuBar (%04X)\n", hWnd); |
| 1707 | #endif |
| 1708 | wndPtr = WIN_FindWndPtr(hWnd); |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1709 | if (wndPtr != NULL && wndPtr->wIDmenu != 0) { |
| 1710 | #ifdef DEBUG_MENU |
| 1711 | printf("DrawMenuBar wIDmenu=%04X \n", wndPtr->wIDmenu); |
| 1712 | #endif |
| 1713 | SendMessage(hWnd, WM_NCPAINT, 1, 0L); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1714 | } |
| 1715 | } |
| 1716 | |
| 1717 | |
| 1718 | /********************************************************************** |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1719 | * LoadMenuIndirect [USER.220] |
| 1720 | */ |
| 1721 | HMENU LoadMenuIndirect(LPSTR menu_template) |
| 1722 | { |
| 1723 | HMENU hMenu; |
| 1724 | MENU_HEADER *menu_desc; |
| 1725 | #ifdef DEBUG_MENU |
| 1726 | printf("LoadMenuIndirect: menu_template '%08X'\n", menu_template); |
| 1727 | #endif |
| 1728 | hMenu = CreateMenu(); |
| 1729 | menu_desc = (MENU_HEADER *)menu_template; |
| 1730 | ParseMenuResource((WORD *)(menu_desc + 1), 0, hMenu); |
| 1731 | return hMenu; |
| 1732 | } |
| 1733 | |
| 1734 | |
| 1735 | /********************************************************************** |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 1736 | * CopySysMenu (Internal) |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1737 | */ |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 1738 | HMENU CopySysMenu() |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1739 | { |
| 1740 | HMENU hMenu; |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 1741 | LPPOPUPMENU menu; |
| 1742 | LPPOPUPMENU sysmenu; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1743 | #ifdef DEBUG_MENU |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 1744 | printf("CopySysMenu entry !\n"); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1745 | #endif |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 1746 | if (hSysMenu == 0) { |
| 1747 | hSysMenu = LoadMenu((HINSTANCE)NULL, MAKEINTRESOURCE(1)); |
| 1748 | /* hSysMenu = LoadMenu((HINSTANCE)NULL, MAKEINTRESOURCE(SC_SYSMENU));*/ |
| 1749 | /* hSysMenu = LoadMenu((HINSTANCE)NULL, "SYSMENU"); */ |
| 1750 | if (hSysMenu == 0) { |
| 1751 | printf("SysMenu not found in system resources !\n"); |
| 1752 | return (HMENU)NULL; |
| 1753 | } |
| 1754 | #ifdef DEBUG_MENU |
| 1755 | else |
| 1756 | printf("SysMenu loaded from system resources %04X !\n", hSysMenu); |
| 1757 | #endif |
| 1758 | } |
| 1759 | hMenu = GlobalAlloc(GMEM_MOVEABLE, sizeof(POPUPMENU)); |
| 1760 | menu = (LPPOPUPMENU) GlobalLock(hMenu); |
| 1761 | sysmenu = (LPPOPUPMENU) GlobalLock(hSysMenu); |
| 1762 | if (menu != NULL && sysmenu != NULL) { |
| 1763 | sysmenu->BarFlags = FALSE; |
| 1764 | memcpy(menu, sysmenu, sizeof(POPUPMENU)); |
| 1765 | } |
| 1766 | else { |
| 1767 | printf("CopySysMenu // Bad SysMenu pointers !\n"); |
| 1768 | if (menu != NULL) { |
| 1769 | GlobalUnlock(hMenu); |
| 1770 | GlobalFree(hMenu); |
| 1771 | } |
| 1772 | return (HMENU)NULL; |
| 1773 | } |
| 1774 | GlobalUnlock(hMenu); |
| 1775 | GlobalUnlock(hSysMenu); |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1776 | #ifdef DEBUG_MENU |
| 1777 | printf("CopySysMenu hMenu=%04X !\n", hMenu); |
| 1778 | #endif |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1779 | return hMenu; |
| 1780 | } |
| 1781 | |
| 1782 | |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 1783 | /********************************************************************** |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1784 | * ParseMenuResource (from Resource or Template) |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 1785 | */ |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1786 | WORD * ParseMenuResource(WORD *first_item, int level, HMENU hMenu) |
| 1787 | { |
| 1788 | WORD *item; |
| 1789 | WORD *next_item; |
| 1790 | HMENU hSubMenu; |
| 1791 | int i; |
| 1792 | |
| 1793 | level++; |
| 1794 | next_item = first_item; |
| 1795 | i = 0; |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 1796 | do { |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1797 | i++; |
| 1798 | item = next_item; |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 1799 | if (*item & MF_POPUP) { |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1800 | MENU_POPUPITEM *popup_item = (MENU_POPUPITEM *) item; |
| 1801 | next_item = (WORD *) (popup_item->item_text + |
| 1802 | strlen(popup_item->item_text) + 1); |
| 1803 | hSubMenu = CreatePopupMenu(); |
| 1804 | next_item = ParseMenuResource(next_item, level, hSubMenu); |
| 1805 | AppendMenu(hMenu, popup_item->item_flags, |
| 1806 | hSubMenu, popup_item->item_text); |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 1807 | } |
| 1808 | else { |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame^] | 1809 | MENUITEMTEMPLATE *normal_item = (MENUITEMTEMPLATE *) item; |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1810 | next_item = (WORD *) (normal_item->item_text + |
| 1811 | strlen(normal_item->item_text) + 1); |
| 1812 | AppendMenu(hMenu, normal_item->item_flags, |
| 1813 | normal_item->item_id, normal_item->item_text); |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 1814 | } |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1815 | } |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1816 | while (!(*item & MF_END)); |
Alexandre Julliard | cdd0923 | 1994-01-12 11:12:51 +0000 | [diff] [blame] | 1817 | return next_item; |
| 1818 | } |
| 1819 | |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 1820 | |