Changeset 10190 for trunk/src/user32/menu.c
- Timestamp:
- Jul 31, 2003, 5:58:58 PM (22 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/user32/menu.c
r10102 r10190 44 44 #include "oslibmsg.h" 45 45 #include "oslibwin.h" 46 #include "heapstring.h" 47 46 48 47 49 HBRUSH WIN32API GetOS2ColorBrush(int nIndex); … … 55 57 DECLARE_DEBUG_CHANNEL(accel); 56 58 57 #define HACCEL_16(h32) 59 #define HACCEL_16(h32) (LOWORD(h32)) 58 60 59 61 /* internal popup menu window messages */ 60 62 61 #define MM_SETMENUHANDLE 62 #define MM_GETMENUHANDLE 63 #define MM_SETMENUHANDLE (WM_USER + 0) 64 #define MM_GETMENUHANDLE (WM_USER + 1) 63 65 64 66 /* Menu item structure */ 65 67 typedef struct { 66 68 /* ----------- MENUITEMINFO Stuff ----------- */ 67 UINT fType; 68 UINT fState; 69 UINT wID; 70 HMENU hSubMenu; 71 HBITMAP hCheckBit; 72 HBITMAP hUnCheckBit; 73 LPWSTR text; 74 DWORD dwItemData; 75 DWORD dwTypeData; 76 HBITMAP hbmpItem; 69 UINT fType; /* Item type. */ 70 UINT fState; /* Item state. */ 71 UINT wID; /* Item id. */ 72 HMENU hSubMenu; /* Pop-up menu. */ 73 HBITMAP hCheckBit; /* Bitmap when checked. */ 74 HBITMAP hUnCheckBit; /* Bitmap when unchecked. */ 75 LPWSTR text; /* Item text or bitmap handle. */ 76 DWORD dwItemData; /* Application defined. */ 77 DWORD dwTypeData; /* depends on fMask */ 78 HBITMAP hbmpItem; /* bitmap in win98 style menus */ 77 79 /* ----------- Wine stuff ----------- */ 78 RECT rect; 79 UINT xTab; 80 RECT rect; /* Item area (relative to menu window) */ 81 UINT xTab; /* X position of text after Tab */ 80 82 } MENUITEM; 81 83 … … 84 86 WORD wFlags; /* Menu flags (MF_POPUP, MF_SYSMENU) */ 85 87 WORD wMagic; /* Magic number */ 86 WORD 87 WORD 88 WORD Width; /* Width of the whole menu */ 89 WORD Height; /* Height of the whole menu */ 88 90 UINT nItems; /* Number of items in the menu */ 89 91 HWND hWnd; /* Window containing the menu */ 90 92 MENUITEM *items; /* Array of menu items */ 91 93 UINT FocusedItem; /* Currently focused item */ 92 HWND 94 HWND hwndOwner; /* window receiving the messages for ownerdraw */ 93 95 BOOL bTimeToHide; /* Request hiding when receiving a second click in the top-level menu item */ 94 96 /* ------------ MENUINFO members ------ */ 95 DWORD dwStyle;/* Extended mennu style */96 UINT cyMax;/* max hight of the whole menu, 0 is screen hight */97 HBRUSH hbrBack;/* brush for menu background */98 DWORD 99 DWORD dwMenuData;/* application defined value */97 DWORD dwStyle; /* Extended mennu style */ 98 UINT cyMax; /* max hight of the whole menu, 0 is screen hight */ 99 HBRUSH hbrBack; /* brush for menu background */ 100 DWORD dwContextHelpID; 101 DWORD dwMenuData; /* application defined value */ 100 102 HMENU hSysMenuOwner; /* Handle to the dummy sys menu holder */ 101 103 } POPUPMENU, *LPPOPUPMENU; … … 105 107 #define TF_ENDMENU 0x0001 106 108 #define TF_SUSPENDPOPUP 0x0002 107 #define TF_SKIPREMOVE 109 #define TF_SKIPREMOVE 0x0004 108 110 109 111 typedef struct 110 112 { 111 UINT 112 HMENU 113 HMENU 114 HWND 115 POINT 113 UINT trackFlags; 114 HMENU hCurrentMenu; /* current submenu (can be equal to hTopMenu)*/ 115 HMENU hTopMenu; /* initial menu */ 116 HWND hOwnerWnd; /* where notifications are sent */ 117 POINT pt; 116 118 } MTRACKER; 117 119 118 120 #define MENU_MAGIC 0x554d /* 'MU' */ 119 121 120 #define ITEM_PREV 121 #define ITEM_NEXT 122 #define ITEM_PREV -1 123 #define ITEM_NEXT 1 122 124 123 125 /* Internal MENU_TrackMenu() flags */ 124 #define TPM_INTERNAL 125 #define TPM_ENTERIDLEEX 0x80000000/* set owner window for WM_ENTERIDLE */126 #define TPM_BUTTONDOWN 0x40000000/* menu was clicked before tracking */126 #define TPM_INTERNAL 0xF0000000 127 #define TPM_ENTERIDLEEX 0x80000000 /* set owner window for WM_ENTERIDLE */ 128 #define TPM_BUTTONDOWN 0x40000000 /* menu was clicked before tracking */ 127 129 #define TPM_POPUPMENU 0x20000000 /* menu is a popup menu */ 128 130 129 131 /* popup menu shade thickness */ 130 #define POPUP_XSHADE 131 #define POPUP_YSHADE 132 #define POPUP_XSHADE 4 133 #define POPUP_YSHADE 4 132 134 133 135 /* Space between 2 menu bar items */ … … 151 153 152 154 #define IS_SYSTEM_MENU(menu) \ 153 155 (!((menu)->wFlags & MF_POPUP) && (menu)->wFlags & MF_SYSMENU) 154 156 155 157 #define IS_SYSTEM_POPUP(menu) \ 156 158 ((menu)->wFlags & MF_POPUP && (menu)->wFlags & MF_SYSMENU) 157 159 158 160 #define TYPE_MASK (MFT_STRING | MFT_BITMAP | MFT_OWNERDRAW | MFT_SEPARATOR | \ 159 160 161 161 MFT_MENUBARBREAK | MFT_MENUBREAK | MFT_RADIOCHECK | \ 162 MFT_RIGHTORDER | MFT_RIGHTJUSTIFY | \ 163 MF_POPUP | MF_SYSMENU | MF_HELP) 162 164 #define STATE_MASK (~TYPE_MASK) 163 165 … … 168 170 static HBITMAP hBmpSysMenu = 0; 169 171 170 static HBRUSH 171 static HFONT 172 static HFONT 172 static HBRUSH hShadeBrush = 0; 173 static HFONT hMenuFont = 0; 174 static HFONT hMenuFontBold = 0; 173 175 174 176 static HMENU MENU_DefSysPopup = 0; /* Default system menu popup */ … … 217 219 218 220 static void do_debug_print_menuitem(const char *prefix, MENUITEM * mp, 219 221 const char *postfix) 220 222 { 221 223 TRACE("%s ", prefix); 222 224 if (mp) { 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 MENUFLAG(MFT_RIGHTJUSTIFY, "right");/* same as MF_HELP */250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 225 UINT flags = mp->fType; 226 int typ = MENU_ITEM_TYPE(flags); 227 DPRINTF( "{ ID=0x%x", mp->wID); 228 if (flags & MF_POPUP) 229 DPRINTF( ", Sub=0x%x", mp->hSubMenu); 230 if (flags) { 231 int count = 0; 232 DPRINTF( ", Typ="); 233 if (typ == MFT_STRING) 234 /* Nothing */ ; 235 else if (typ == MFT_SEPARATOR) 236 MENUOUT("sep"); 237 else if (typ == MFT_OWNERDRAW) 238 MENUOUT("own"); 239 else if (typ == MFT_BITMAP) 240 MENUOUT("bit"); 241 else 242 MENUOUT("???"); 243 flags -= typ; 244 245 MENUFLAG(MF_POPUP, "pop"); 246 MENUFLAG(MFT_MENUBARBREAK, "barbrk"); 247 MENUFLAG(MFT_MENUBREAK, "brk"); 248 MENUFLAG(MFT_RADIOCHECK, "radio"); 249 MENUFLAG(MFT_RIGHTORDER, "rorder"); 250 MENUFLAG(MF_SYSMENU, "sys"); 251 MENUFLAG(MFT_RIGHTJUSTIFY, "right"); /* same as MF_HELP */ 252 253 if (flags) 254 DPRINTF( "+0x%x", flags); 255 } 256 flags = mp->fState; 257 if (flags) { 258 int count = 0; 259 DPRINTF( ", State="); 260 MENUFLAG(MFS_GRAYED, "grey"); 261 MENUFLAG(MFS_DEFAULT, "default"); 262 MENUFLAG(MFS_DISABLED, "dis"); 263 MENUFLAG(MFS_CHECKED, "check"); 264 MENUFLAG(MFS_HILITE, "hi"); 265 MENUFLAG(MF_USECHECKBITMAPS, "usebit"); 266 MENUFLAG(MF_MOUSESELECT, "mouse"); 267 if (flags) 268 DPRINTF( "+0x%x", flags); 269 } 270 if (mp->hCheckBit) 271 DPRINTF( ", Chk=0x%x", mp->hCheckBit); 272 if (mp->hUnCheckBit) 273 DPRINTF( ", Unc=0x%x", mp->hUnCheckBit); 274 275 if (typ == MFT_STRING) { 276 if (mp->text) 277 DPRINTF( ", Text=%s", debugstr_w(mp->text)); 278 else 279 DPRINTF( ", Text=Null"); 280 } else if (mp->text == NULL) 281 /* Nothing */ ; 282 else 283 DPRINTF( ", Text=%p", mp->text); 284 if (mp->dwItemData) 285 DPRINTF( ", ItemData=0x%08lx", mp->dwItemData); 286 DPRINTF( " }"); 285 287 } else { 286 288 DPRINTF( "NULL"); 287 289 } 288 290 … … 355 357 POPUPMENU* menu = MENU_GetMenu(hMenu); 356 358 menu->wFlags |= MF_SYSMENU | MF_POPUP; 357 359 SetMenuDefaultItem(hMenu, SC_CLOSE, FALSE); 358 360 #ifdef __WIN32OS2__ 359 361 if(!fDisableOdinSysMenuItems) { … … 372 374 } 373 375 else 374 376 ERR("Unable to load default system menu\n" ); 375 377 376 378 TRACE("returning %x.\n", hMenu ); … … 395 397 if ((hMenu = CreateMenu())) 396 398 { 397 398 399 400 401 402 403 404 405 406 407 399 POPUPMENU *menu = MENU_GetMenu(hMenu); 400 menu->wFlags = MF_SYSMENU; 401 menu->hWnd = WIN_GetFullHandle( hWnd ); 402 403 if (hPopupMenu == (HMENU)(-1)) 404 hPopupMenu = MENU_CopySysPopup(); 405 else if( !hPopupMenu ) hPopupMenu = MENU_DefSysPopup; 406 407 if (hPopupMenu) 408 { 409 InsertMenuA( hMenu, -1, MF_SYSMENU | MF_POPUP | MF_BYPOSITION, hPopupMenu, NULL ); 408 410 409 411 menu->items[0].fType = MF_SYSMENU | MF_POPUP; … … 411 413 if ((menu = MENU_GetMenu(hPopupMenu))) menu->wFlags |= MF_SYSMENU; 412 414 413 414 415 416 415 TRACE("GetSysMenu hMenu=%04x (%04x)\n", hMenu, hPopupMenu ); 416 return hMenu; 417 } 418 DestroyMenu( hMenu ); 417 419 } 418 420 ERR("failed to load system menu!\n"); … … 432 434 433 435 static unsigned char shade_bits[16] = { 0x55, 0, 0xAA, 0, 434 435 436 436 0x55, 0, 0xAA, 0, 437 0x55, 0, 0xAA, 0, 438 0x55, 0, 0xAA, 0 }; 437 439 438 440 /* Load menu bitmaps */ … … 443 445 if (hStdMnArrow) 444 446 { 445 446 447 448 447 BITMAP bm; 448 GetObjectA( hStdMnArrow, sizeof(bm), &bm ); 449 arrow_bitmap_width = bm.bmWidth; 450 arrow_bitmap_height = bm.bmHeight; 449 451 } else 450 452 return FALSE; 451 453 452 454 if (! (hBitmap = CreateBitmap( 8, 8, 1, 1, shade_bits))) 453 455 return FALSE; 454 456 455 457 if(!(hShadeBrush = CreatePatternBrush( hBitmap ))) 456 458 return FALSE; 457 459 458 460 DeleteObject( hBitmap ); 459 461 if (!(MENU_DefSysPopup = MENU_CopySysPopup())) 460 462 return FALSE; 461 463 462 464 ncm.cbSize = sizeof (NONCLIENTMETRICSA); 463 465 if (!(SystemParametersInfoA(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSA), &ncm, 0))) 464 466 return FALSE; 465 467 466 468 if (!(hMenuFont = CreateFontIndirectA( &ncm.lfMenuFont ))) 467 469 return FALSE; 468 470 469 471 ncm.lfMenuFont.lfWeight += 300; 470 472 if ( ncm.lfMenuFont.lfWeight > 1000) 471 473 ncm.lfMenuFont.lfWeight = 1000; 472 474 473 475 if (!(hMenuFontBold = CreateFontIndirectA( &ncm.lfMenuFont ))) 474 476 return FALSE; 475 477 476 478 return TRUE; … … 500 502 /* The menu item must keep its state if it's disabled */ 501 503 if(gray) 502 504 EnableMenuItem( hmenu, SC_CLOSE, MF_GRAYED); 503 505 } 504 506 … … 518 520 519 521 if(!menu) 520 522 return NO_SELECTED_ITEM; 521 523 522 524 i = menu->FocusedItem + 1; 523 525 if( i == NO_SELECTED_ITEM ) 524 526 return i; 525 527 526 528 for( ; i < menu->nItems; ++i ) { 527 528 529 if (menu->items[i].fType & MF_MENUBARBREAK) 530 return i; 529 531 } 530 532 … … 547 549 548 550 if( !menu ) 549 551 return NO_SELECTED_ITEM; 550 552 551 553 if( menu->FocusedItem == 0 || menu->FocusedItem == NO_SELECTED_ITEM ) 552 554 return NO_SELECTED_ITEM; 553 555 554 556 /* Find the start of the column */ 555 557 556 558 for(i = menu->FocusedItem; i != 0 && 557 558 559 !(menu->items[i].fType & MF_MENUBARBREAK); 560 --i); /* empty */ 559 561 560 562 if(i == 0) 561 563 return NO_SELECTED_ITEM; 562 564 563 565 for(--i; i != 0; --i) { 564 565 566 if (menu->items[i].fType & MF_MENUBARBREAK) 567 break; 566 568 } 567 569 … … 587 589 if (wFlags & MF_BYPOSITION) 588 590 { 589 590 591 if (*nPos >= menu->nItems) return NULL; 592 return &menu->items[*nPos]; 591 593 } 592 594 else 593 595 { 594 596 MENUITEM *item = menu->items; 595 596 597 598 599 600 601 602 603 604 605 597 for (i = 0; i < menu->nItems; i++, item++) 598 { 599 if (item->wID == *nPos) 600 { 601 *nPos = i; 602 return item; 603 } 604 else if (item->fType & MF_POPUP) 605 { 606 HMENU hsubmenu = item->hSubMenu; 607 MENUITEM *subitem = MENU_FindItem( &hsubmenu, nPos, wFlags ); 606 608 #ifdef __WIN32OS2__ 607 609 //YD: 2000-12-01: extra check added for loops in menus 608 610 if (subitem && subitem!=item) 609 611 #else 610 612 if (subitem) 611 613 #endif 612 613 614 615 616 617 614 { 615 *hmenu = hsubmenu; 616 return subitem; 617 } 618 } 619 } 618 620 } 619 621 return NULL; … … 671 673 */ 672 674 static MENUITEM *MENU_FindItemByCoords( POPUPMENU *menu, 673 675 POINT pt, UINT *pos ) 674 676 { 675 677 MENUITEM *item; … … 682 684 for (i = 0; i < menu->nItems; i++, item++) 683 685 { 684 685 686 687 688 689 686 if ((pt.x >= item->rect.left) && (pt.x < item->rect.right) && 687 (pt.y >= item->rect.top) && (pt.y < item->rect.bottom)) 688 { 689 if (pos) *pos = i; 690 return item; 691 } 690 692 } 691 693 return NULL; … … 700 702 */ 701 703 static UINT MENU_FindItemByKey( HWND hwndOwner, HMENU hmenu, 702 704 UINT key, BOOL forceMenuChar ) 703 705 { 704 706 TRACE("\tlooking for '%c' in [%04x]\n", (char)key, (UINT16)hmenu ); … … 708 710 if (hmenu) 709 711 { 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 712 POPUPMENU *menu = MENU_GetMenu( hmenu ); 713 MENUITEM *item = menu->items; 714 LONG menuchar; 715 716 if( !forceMenuChar ) 717 { 718 UINT i; 719 720 key = toupper(key); 721 for (i = 0; i < menu->nItems; i++, item++) 722 { 723 if (item->text && (IS_STRING_ITEM(item->fType))) 724 { 725 WCHAR *p = item->text - 2; 726 do 727 { 728 p = strchrW (p + 2, '&'); 729 } 730 while (p != NULL && p [1] == '&'); 731 if (p && (toupper(p[1]) == key)) return i; 732 } 733 } 734 } 735 menuchar = SendMessageA( hwndOwner, WM_MENUCHAR, 734 736 MAKEWPARAM( key, menu->wFlags ), hmenu ); 735 736 737 if (HIWORD(menuchar) == 2) return LOWORD(menuchar); 738 if (HIWORD(menuchar) == 1) return (UINT)(-2); 737 739 } 738 740 return (UINT)(-1); … … 888 890 */ 889 891 static void MENU_CalcItemSize( HDC hdc, MENUITEM *lpitem, HWND hwndOwner, 890 892 INT orgX, INT orgY, BOOL menuBar ) 891 893 { 892 894 WCHAR *p; … … 895 897 TRACE("dc=0x%04x owner=0x%04x (%d,%d)\n", hdc, hwndOwner, orgX, orgY); 896 898 debug_print_menuitem("MENU_CalcItemSize: menuitem:", lpitem, 897 899 (menuBar ? " (MenuBar)" : "")); 898 900 899 901 SetRect( &lpitem->rect, orgX, orgY, orgX, orgY ); … … 918 920 lpitem->rect.right += mis.itemWidth; 919 921 920 921 922 922 if (menuBar) 923 { 924 lpitem->rect.right += MENU_BAR_ITEMS_SPACE; 923 925 924 926 … … 926 928 height for the menu and the height value is ignored */ 927 929 928 929 930 931 930 if (TWEAK_WineLook == WIN31_LOOK) 931 lpitem->rect.bottom += GetSystemMetrics(SM_CYMENU); 932 else 933 lpitem->rect.bottom += GetSystemMetrics(SM_CYMENU)-1; 932 934 } 933 935 else 934 936 lpitem->rect.bottom += mis.itemHeight; 935 937 936 938 TRACE("id=%04x size=%dx%d\n", 937 939 lpitem->wID, mis.itemWidth, mis.itemHeight); 938 940 /* Fall through to get check/arrow width calculation. */ … … 941 943 if (lpitem->fType & MF_SEPARATOR) 942 944 { 943 944 945 lpitem->rect.bottom += SEPARATOR_HEIGHT; 946 return; 945 947 } 946 948 947 949 if (!menuBar) 948 950 { 949 950 951 951 lpitem->rect.right += 2 * check_bitmap_width; 952 if (lpitem->fType & MF_POPUP) 953 lpitem->rect.right += arrow_bitmap_width; 952 954 } 953 955 … … 975 977 { SIZE size; 976 978 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 979 GetTextExtentPoint32W(hdc, lpitem->text, strlenW(lpitem->text), &size); 980 981 lpitem->rect.right += size.cx; 982 if (TWEAK_WineLook == WIN31_LOOK) 983 lpitem->rect.bottom += max( size.cy, GetSystemMetrics(SM_CYMENU) ); 984 else 985 lpitem->rect.bottom += max(size.cy, GetSystemMetrics(SM_CYMENU)-1); 986 lpitem->xTab = 0; 987 988 if (menuBar) 989 { 990 lpitem->rect.right += MENU_BAR_ITEMS_SPACE; 991 } 992 else if ((p = strchrW( lpitem->text, '\t' )) != NULL) 993 { 994 /* Item contains a tab (only meaningful in popup menus) */ 995 GetTextExtentPoint32W(hdc, lpitem->text, (int)(p - lpitem->text) , &size); 996 lpitem->xTab = check_bitmap_width + MENU_TAB_SPACE + size.cx; 997 lpitem->rect.right += MENU_TAB_SPACE; 998 } 999 else 1000 { 1001 if (strchrW( lpitem->text, '\b' )) 1002 lpitem->rect.right += MENU_TAB_SPACE; 1003 lpitem->xTab = lpitem->rect.right - check_bitmap_width 1004 - arrow_bitmap_width; 1005 } 1004 1006 } 1005 1007 TRACE("(%d,%d)-(%d,%d)\n", lpitem->rect.left, lpitem->rect.top, lpitem->rect.right, lpitem->rect.bottom); … … 1034 1036 while (start < lppop->nItems) 1035 1037 { 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1038 lpitem = &lppop->items[start]; 1039 orgX = maxX; 1040 orgY = (TWEAK_WineLook == WIN31_LOOK) ? GetSystemMetrics(SM_CYBORDER) : 2; 1041 1042 maxTab = maxTabWidth = 0; 1043 1044 /* Parse items until column break or end of menu */ 1045 for (i = start; i < lppop->nItems; i++, lpitem++) 1046 { 1047 if ((i != start) && 1048 (lpitem->fType & (MF_MENUBREAK | MF_MENUBARBREAK))) break; 1049 1050 MENU_CalcItemSize( hdc, lpitem, hwndOwner, orgX, orgY, FALSE ); 1051 1052 if (lpitem->fType & MF_MENUBARBREAK) orgX++; 1053 maxX = max( maxX, lpitem->rect.right ); 1054 orgY = lpitem->rect.bottom; 1055 if (IS_STRING_ITEM(lpitem->fType) && lpitem->xTab) 1056 { 1057 maxTab = max( maxTab, lpitem->xTab ); 1058 maxTabWidth = max(maxTabWidth,lpitem->rect.right-lpitem->xTab); 1059 } 1060 } 1061 1062 /* Finish the column (set all items to the largest width found) */ 1063 maxX = max( maxX, maxTab + maxTabWidth ); 1064 for (lpitem = &lppop->items[start]; start < i; start++, lpitem++) 1065 { 1066 lpitem->rect.right = maxX; 1067 if (IS_STRING_ITEM(lpitem->fType) && lpitem->xTab) 1068 lpitem->xTab = maxTab; 1069 1070 } 1071 lppop->Height = max( lppop->Height, orgY ); 1070 1072 } 1071 1073 … … 1075 1077 if(TWEAK_WineLook > WIN31_LOOK) 1076 1078 { 1077 1078 1079 lppop->Height += 2; 1080 lppop->Width += 2; 1079 1081 } 1080 1082 … … 1113 1115 while (start < lppop->nItems) 1114 1116 { 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1117 lpitem = &lppop->items[start]; 1118 orgX = lprect->left; 1119 orgY = maxY; 1120 1121 /* Parse items until line break or end of menu */ 1122 for (i = start; i < lppop->nItems; i++, lpitem++) 1123 { 1124 if ((helpPos == -1) && (lpitem->fType & MF_RIGHTJUSTIFY)) helpPos = i; 1125 if ((i != start) && 1126 (lpitem->fType & (MF_MENUBREAK | MF_MENUBARBREAK))) break; 1127 1128 TRACE("calling MENU_CalcItemSize org=(%d, %d)\n", 1129 orgX, orgY ); 1130 debug_print_menuitem (" item: ", lpitem, ""); 1131 MENU_CalcItemSize( hdc, lpitem, hwndOwner, orgX, orgY, TRUE ); 1132 1133 if (lpitem->rect.right > lprect->right) 1134 { 1135 if (i != start) break; 1136 else lpitem->rect.right = lprect->right; 1137 } 1138 maxY = max( maxY, lpitem->rect.bottom ); 1139 orgX = lpitem->rect.right; 1140 } 1141 1142 /* Finish the line (set all items to the largest height found) */ 1143 while (start < i) lppop->items[start++].rect.bottom = maxY; 1142 1144 } 1143 1145 … … 1152 1154 for (i = lppop->nItems - 1; i >= helpPos; i--, lpitem--) { 1153 1155 if ( (helpPos==-1) || (helpPos>i) ) 1154 break; 1155 if (lpitem->rect.top != orgY) break; 1156 if (lpitem->rect.right >= orgX) break; 1156 break; /* done */ 1157 if (lpitem->rect.top != orgY) break; /* Other line */ 1158 if (lpitem->rect.right >= orgX) break; /* Too far right already */ 1157 1159 lpitem->rect.left += orgX - lpitem->rect.right; 1158 1160 lpitem->rect.right = orgX; … … 1167 1169 */ 1168 1170 static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc, MENUITEM *lpitem, 1169 1171 UINT height, BOOL menuBar, UINT odaction ) 1170 1172 { 1171 1173 RECT rect; … … 1175 1177 if (lpitem->fType & MF_SYSMENU) 1176 1178 { 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1179 if( !IsIconic(hwnd) ) { 1180 if (TWEAK_WineLook > WIN31_LOOK) 1181 NC_DrawSysButton95( hwnd, hdc, 1182 lpitem->fState & 1183 (MF_HILITE | MF_MOUSESELECT) ); 1184 else 1185 NC_DrawSysButton( hwnd, hdc, 1186 lpitem->fState & 1187 (MF_HILITE | MF_MOUSESELECT) ); 1188 } 1189 1190 return; 1189 1191 } 1190 1192 … … 1203 1205 1204 1206 dis.CtlType = ODT_MENU; 1205 1207 dis.CtlID = 0; 1206 1208 dis.itemID = lpitem->wID; 1207 1209 dis.itemData = (DWORD)lpitem->dwItemData; … … 1215 1217 dis.rcItem = lpitem->rect; 1216 1218 TRACE("Ownerdraw: owner=%04x itemID=%d, itemState=%d, itemAction=%d, " 1217 1218 1219 1220 1219 "hwndItem=%04x, hdc=%04x, rcItem={%d,%d,%d,%d}\n", hwndOwner, 1220 dis.itemID, dis.itemState, dis.itemAction, dis.hwndItem, 1221 dis.hDC, dis.rcItem.left, dis.rcItem.top, dis.rcItem.right, 1222 dis.rcItem.bottom); 1221 1223 SendMessageA( hwndOwner, WM_DRAWITEM, 0, (LPARAM)&dis ); 1222 1224 /* Fall through to draw popup-menu arrow */ … … 1224 1226 1225 1227 TRACE("rect={%d,%d,%d,%d}\n", lpitem->rect.left, lpitem->rect.top, 1226 1228 lpitem->rect.right,lpitem->rect.bottom); 1227 1229 1228 1230 if (menuBar && (lpitem->fType & MF_SEPARATOR)) return; … … 1232 1234 if (!(lpitem->fType & MF_OWNERDRAW)) 1233 1235 { 1234 1235 1236 if (lpitem->fState & MF_HILITE) 1237 { 1236 1238 #ifdef __WIN32OS2__ 1237 if(!fOS2Look) 1239 if(!fOS2Look) 1238 1240 #else 1239 1241 if(TWEAK_WineLook == WIN98_LOOK) 1240 1242 #endif 1241 1242 1243 1244 1245 1246 1247 1248 1249 1243 { 1244 if(menuBar) 1245 DrawEdge(hdc, &rect, BDR_SUNKENOUTER, BF_RECT); 1246 else 1247 FillRect(hdc, &rect, GetSysColorBrush(COLOR_HIGHLIGHT)); 1248 } 1249 else /* Not Win98 Look */ 1250 { 1251 if(!IS_BITMAP_ITEM(lpitem->fType)) 1250 1252 #ifdef __WIN32OS2__ 1251 1253 FillRect(hdc, &rect, GetOS2ColorBrush(PMSYSCLR_MENUHILITEBGND)); 1252 1254 #else 1253 1255 FillRect(hdc, &rect, GetSysColorBrush(COLOR_HIGHLIGHT)); 1254 1256 #endif 1255 1256 1257 } 1258 } 1257 1259 else 1258 1260 FillRect( hdc, &rect, GetSysColorBrush(COLOR_MENU) ); 1259 1261 } 1260 1262 … … 1266 1268 if (!menuBar && (lpitem->fType & MF_MENUBARBREAK)) 1267 1269 { 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1270 if (TWEAK_WineLook > WIN31_LOOK) 1271 { 1272 RECT rc = rect; 1273 rc.top = 3; 1274 rc.bottom = height - 3; 1275 DrawEdge (hdc, &rc, EDGE_ETCHED, BF_LEFT); 1276 } 1277 else 1278 { 1279 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) ); 1280 MoveToEx( hdc, rect.left, 0, NULL ); 1281 LineTo( hdc, rect.left, height ); 1282 } 1281 1283 } 1282 1284 … … 1284 1286 if (lpitem->fType & MF_SEPARATOR) 1285 1287 { 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1288 if (TWEAK_WineLook > WIN31_LOOK) 1289 { 1290 RECT rc = rect; 1291 rc.left++; 1292 rc.right--; 1293 rc.top += SEPARATOR_HEIGHT / 2; 1294 DrawEdge (hdc, &rc, EDGE_ETCHED, BF_TOP); 1295 } 1296 else 1297 { 1298 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) ); 1299 MoveToEx( hdc, rect.left, rect.top + SEPARATOR_HEIGHT/2, NULL ); 1300 LineTo( hdc, rect.right, rect.top + SEPARATOR_HEIGHT/2 ); 1301 } 1302 return; 1301 1303 } 1302 1304 } … … 1307 1309 { 1308 1310 #ifdef __WIN32OS2__ 1309 if(!fOS2Look) 1311 if(!fOS2Look) 1310 1312 #else 1311 1313 if(TWEAK_WineLook == WIN98_LOOK) 1312 1314 #endif 1313 1315 { 1314 1316 if(menuBar) { 1315 1317 SetTextColor(hdc, GetSysColor(COLOR_MENUTEXT)); 1316 1318 SetBkColor(hdc, GetSysColor(COLOR_MENU)); 1317 1318 1319 1320 1321 1319 } else { 1320 if(lpitem->fState & MF_GRAYED) 1321 SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT)); 1322 else 1323 SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT)); 1322 1324 SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT)); 1323 1324 1325 1326 1327 1328 1325 } 1326 } 1327 else /* Not Win98 Look */ 1328 { 1329 SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT)); 1330 if(!IS_BITMAP_ITEM(lpitem->fType)) 1329 1331 #ifdef __WIN32OS2__ 1330 1332 SetBkColor(hdc, GetOS2Color(PMSYSCLR_MENUHILITEBGND)); 1331 1333 #else 1332 1334 SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT)); 1333 1335 #endif 1334 1336 } 1335 1337 } 1336 1338 else 1337 1339 { 1338 1339 1340 1341 1342 1343 } 1344 1345 1346 /* 1347 1348 1349 1340 if (lpitem->fState & MF_GRAYED) 1341 SetTextColor( hdc, GetSysColor( COLOR_GRAYTEXT ) ); 1342 else 1343 SetTextColor( hdc, GetSysColor( COLOR_MENUTEXT ) ); 1344 SetBkColor( hdc, GetSysColor( COLOR_MENU ) ); 1345 } 1346 1347 /* helper lines for debugging */ 1348 /* FrameRect(hdc, &rect, GetStockObject(BLACK_BRUSH)); 1349 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) ); 1350 MoveToEx( hdc, rect.left, (rect.top + rect.bottom)/2, NULL ); 1351 LineTo( hdc, rect.right, (rect.top + rect.bottom)/2 ); 1350 1352 */ 1351 1353 1352 1354 if (!menuBar) 1353 1355 { 1354 INTy = rect.top + rect.bottom;1356 INT y = rect.top + rect.bottom; 1355 1357 UINT check_bitmap_width = GetSystemMetrics( SM_CXMENUCHECK ); 1356 1358 UINT check_bitmap_height = GetSystemMetrics( SM_CYMENUCHECK ); … … 1358 1360 if (!(lpitem->fType & MF_OWNERDRAW)) 1359 1361 { 1360 1361 1362 1363 1364 1362 /* Draw the check mark 1363 * 1364 * FIXME: 1365 * Custom checkmark bitmaps are monochrome but not always 1bpp. 1366 */ 1365 1367 HBITMAP bm = (lpitem->fState & MF_CHECKED) ? lpitem->hCheckBit : lpitem->hUnCheckBit; 1366 1368 if (bm) /* we have a custom bitmap */ … … 1390 1392 } 1391 1393 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1394 /* Draw the popup-menu arrow */ 1395 if (lpitem->fType & MF_POPUP) 1396 { 1397 HDC hdcMem = CreateCompatibleDC( hdc ); 1398 HBITMAP hOrigBitmap; 1399 1400 hOrigBitmap = SelectObject( hdcMem, hStdMnArrow ); 1401 BitBlt( hdc, rect.right - arrow_bitmap_width - 1, 1402 (y - arrow_bitmap_height) / 2, 1403 arrow_bitmap_width, arrow_bitmap_height, 1404 hdcMem, 0, 0, SRCCOPY ); 1403 1405 SelectObject( hdcMem, hOrigBitmap ); 1404 1405 1406 1407 1408 1406 DeleteDC( hdcMem ); 1407 } 1408 1409 rect.left += check_bitmap_width; 1410 rect.right -= arrow_bitmap_width; 1409 1411 } 1410 1412 … … 1417 1419 { 1418 1420 MENU_DrawBitmapItem( hdc, lpitem, &rect, menuBar ); 1419 1421 return; 1420 1422 1421 1423 } … … 1423 1425 else if (IS_STRING_ITEM(lpitem->fType)) 1424 1426 { 1425 1426 1427 1428 1429 1430 1427 register int i; 1428 HFONT hfontOld = 0; 1429 1430 UINT uFormat = (menuBar) ? 1431 DT_CENTER | DT_VCENTER | DT_SINGLELINE : 1432 DT_LEFT | DT_VCENTER | DT_SINGLELINE; 1431 1433 1432 1434 #ifdef __WIN32OS2__ 1433 1435 if ( lpitem->fState & MFS_DEFAULT && !fOS2Look) 1434 1436 #else 1435 1437 if ( lpitem->fState & MFS_DEFAULT ) 1436 1438 #endif 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1439 { 1440 hfontOld = SelectObject( hdc, hMenuFontBold); 1441 } 1442 1443 if (menuBar) 1444 { 1445 rect.left += MENU_BAR_ITEMS_SPACE / 2; 1446 rect.right -= MENU_BAR_ITEMS_SPACE / 2; 1447 } 1448 1449 for (i = 0; lpitem->text[i]; i++) 1450 if ((lpitem->text[i] == '\t') || (lpitem->text[i] == '\b')) 1451 break; 1452 1453 if( (TWEAK_WineLook != WIN31_LOOK) && (lpitem->fState & MF_GRAYED)) 1454 { 1455 if (!(lpitem->fState & MF_HILITE) ) 1456 { 1457 ++rect.left; ++rect.top; ++rect.right; ++rect.bottom; 1458 SetTextColor(hdc, RGB(0xff, 0xff, 0xff)); 1459 DrawTextW( hdc, lpitem->text, i, &rect, uFormat ); 1460 --rect.left; --rect.top; --rect.right; --rect.bottom; 1461 } 1462 SetTextColor(hdc, RGB(0x80, 0x80, 0x80)); 1463 } 1464 1465 DrawTextW( hdc, lpitem->text, i, &rect, uFormat); 1466 1467 /* paint the shortcut text */ 1468 if (!menuBar && lpitem->text[i]) /* There's a tab or flush-right char */ 1469 { 1470 if (lpitem->text[i] == '\t') 1471 { 1472 rect.left = lpitem->xTab; 1473 uFormat = DT_LEFT | DT_VCENTER | DT_SINGLELINE; 1474 } 1475 else 1476 { 1477 uFormat = DT_RIGHT | DT_VCENTER | DT_SINGLELINE; 1478 } 1479 1480 if( !(TWEAK_WineLook == WIN31_LOOK) && (lpitem->fState & MF_GRAYED)) 1481 { 1482 if (!(lpitem->fState & MF_HILITE) ) 1483 { 1484 ++rect.left; ++rect.top; ++rect.right; ++rect.bottom; 1485 SetTextColor(hdc, RGB(0xff, 0xff, 0xff)); 1486 DrawTextW( hdc, lpitem->text + i + 1, -1, &rect, uFormat ); 1487 --rect.left; --rect.top; --rect.right; --rect.bottom; 1488 } 1489 SetTextColor(hdc, RGB(0x80, 0x80, 0x80)); 1490 } 1491 DrawTextW( hdc, lpitem->text + i + 1, -1, &rect, uFormat ); 1492 } 1493 1494 if (hfontOld) 1495 SelectObject (hdc, hfontOld); 1494 1496 } 1495 1497 } … … 1512 1514 if(TWEAK_WineLook == WIN31_LOOK) 1513 1515 { 1514 1515 1516 rect.bottom -= POPUP_YSHADE * GetSystemMetrics(SM_CYBORDER); 1517 rect.right -= POPUP_XSHADE * GetSystemMetrics(SM_CXBORDER); 1516 1518 } 1517 1519 … … 1519 1521 && (SelectObject( hdc, hMenuFont))) 1520 1522 { 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 i = rect.right;/* why SetBrushOrg() doesn't? */1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1523 HPEN hPrevPen; 1524 1525 Rectangle( hdc, rect.left, rect.top, rect.right, rect.bottom ); 1526 1527 hPrevPen = SelectObject( hdc, GetStockObject( NULL_PEN ) ); 1528 if( hPrevPen ) 1529 { 1530 INT ropPrev, i; 1531 POPUPMENU *menu; 1532 1533 /* draw 3-d shade */ 1534 if(TWEAK_WineLook == WIN31_LOOK) { 1535 SelectObject( hdc, hShadeBrush ); 1536 SetBkMode( hdc, TRANSPARENT ); 1537 ropPrev = SetROP2( hdc, R2_MASKPEN ); 1538 1539 i = rect.right; /* why SetBrushOrg() doesn't? */ 1540 PatBlt( hdc, i & 0xfffffffe, 1541 rect.top + POPUP_YSHADE*GetSystemMetrics(SM_CYBORDER), 1542 i%2 + POPUP_XSHADE*GetSystemMetrics(SM_CXBORDER), 1543 rect.bottom - rect.top, 0x00a000c9 ); 1544 i = rect.bottom; 1545 PatBlt( hdc, rect.left + POPUP_XSHADE*GetSystemMetrics(SM_CXBORDER), 1546 i & 0xfffffffe,rect.right - rect.left, 1547 i%2 + POPUP_YSHADE*GetSystemMetrics(SM_CYBORDER), 0x00a000c9 ); 1548 SelectObject( hdc, hPrevPen ); 1549 SelectObject( hdc, hPrevBrush ); 1550 SetROP2( hdc, ropPrev ); 1551 } 1552 else 1553 DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT); 1554 1555 /* draw menu items */ 1556 1557 menu = MENU_GetMenu( hmenu ); 1558 if (menu && menu->nItems) 1559 { 1560 MENUITEM *item; 1561 UINT u; 1562 1563 for (u = menu->nItems, item = menu->items; u > 0; u--, item++) 1564 MENU_DrawMenuItem( hwnd, hmenu, menu->hwndOwner, hdc, item, 1565 menu->Height, FALSE, ODA_DRAWENTIRE ); 1566 1567 } 1568 } else 1569 { 1570 SelectObject( hdc, hPrevBrush ); 1571 } 1570 1572 } 1571 1573 } … … 1611 1613 if (TWEAK_WineLook == WIN31_LOOK) 1612 1614 { 1613 1614 1615 1615 SelectObject( hDC, GetSysColorPen(COLOR_WINDOWFRAME) ); 1616 MoveToEx( hDC, lprect->left, lprect->bottom, NULL ); 1617 LineTo( hDC, lprect->right, lprect->bottom ); 1616 1618 } 1617 1619 else 1618 1620 { 1619 1620 1621 1621 SelectObject( hDC, GetSysColorPen(COLOR_3DFACE)); 1622 MoveToEx( hDC, lprect->left, lprect->bottom, NULL ); 1623 LineTo( hDC, lprect->right, lprect->bottom ); 1622 1624 } 1623 1625 … … 1658 1660 if (menu->FocusedItem != NO_SELECTED_ITEM) 1659 1661 { 1660 1661 1662 menu->items[menu->FocusedItem].fState &= ~(MF_HILITE|MF_MOUSESELECT); 1663 menu->FocusedItem = NO_SELECTED_ITEM; 1662 1664 } 1663 1665 … … 1737 1739 if (lppop->FocusedItem != NO_SELECTED_ITEM) 1738 1740 { 1739 1740 1741 lppop->items[lppop->FocusedItem].fState &= ~(MF_HILITE|MF_MOUSESELECT); 1742 MENU_DrawMenuItem(lppop->hWnd, hmenu, hwndOwner, hdc,&lppop->items[lppop->FocusedItem], 1741 1743 lppop->Height, !(lppop->wFlags & MF_POPUP), 1742 1744 ODA_SELECT ); 1743 1745 } 1744 1746 … … 1756 1758 { 1757 1759 MENUITEM *ip = &lppop->items[lppop->FocusedItem]; 1758 1760 SendMessageA( hwndOwner, WM_MENUSELECT, 1759 1761 MAKELONG(ip->fType & MF_POPUP ? wIndex: ip->wID, 1760 1762 ip->fType | ip->fState | MF_MOUSESELECT | … … 1797 1799 if ( menu->FocusedItem != NO_SELECTED_ITEM ) 1798 1800 { 1799 1800 1801 1802 1803 1804 1805 1806 1801 if( menu->nItems == 1 ) return; else 1802 for (i = menu->FocusedItem + offset ; i >= 0 && i < menu->nItems 1803 ; i += offset) 1804 if (!(menu->items[i].fType & MF_SEPARATOR)) 1805 { 1806 MENU_SelectItem( hwndOwner, hmenu, i, TRUE, 0 ); 1807 return; 1808 } 1807 1809 } 1808 1810 1809 1811 for ( i = (offset > 0) ? 0 : menu->nItems - 1; 1810 1811 1812 1813 1814 1815 1812 i >= 0 && i < menu->nItems ; i += offset) 1813 if (!(menu->items[i].fType & MF_SEPARATOR)) 1814 { 1815 MENU_SelectItem( hwndOwner, hmenu, i, TRUE, 0 ); 1816 return; 1817 } 1816 1818 } 1817 1819 … … 1863 1865 1864 1866 if ((item->fType & MF_POPUP) && (flags & MF_POPUP) && (item->hSubMenu != id) ) 1865 1867 DestroyMenu( item->hSubMenu ); /* ModifyMenu() spec */ 1866 1868 1867 1869 if (flags & MF_POPUP) 1868 1870 { 1869 1871 POPUPMENU *menu = MENU_GetMenu((UINT16)id); 1870 1872 if (menu) menu->wFlags |= MF_POPUP; 1871 1873 else 1872 1874 { 1873 1875 item->wID = 0; … … 1875 1877 item->fType = 0; 1876 1878 item->fState = 0; 1877 1879 return FALSE; 1878 1880 } 1879 1881 } … … 1929 1931 1930 1932 /* Create new items array */ 1931 1932 1933 newItems = HeapAlloc( GetProcessHeap(), 0, sizeof(MENUITEM) * (menu->nItems+1) ); 1933 1934 if (!newItems) … … 1938 1939 if (menu->nItems > 0) 1939 1940 { 1940 1941 1942 1943 1941 /* Copy the old array into the new one */ 1942 if (pos > 0) memcpy( newItems, menu->items, pos * sizeof(MENUITEM) ); 1943 if (pos < menu->nItems) memcpy( &newItems[pos+1], &menu->items[pos], 1944 (menu->nItems-pos)*sizeof(MENUITEM) ); 1944 1945 HeapFree( GetProcessHeap(), 0, menu->items ); 1945 1946 } … … 2005 2006 WORD resinfo; 2006 2007 do { 2007 2008 2009 2010 2011 2008 MENUITEMINFOW mii; 2009 2010 mii.cbSize = sizeof(mii); 2011 mii.fMask = MIIM_STATE | MIIM_ID | MIIM_TYPE; 2012 mii.fType = GET_DWORD(res); 2012 2013 res += sizeof(DWORD); 2013 2014 mii.fState = GET_DWORD(res); 2014 2015 res += sizeof(DWORD); 2015 2016 mii.wID = GET_DWORD(res); 2016 2017 res += sizeof(DWORD); 2017 2018 resinfo = GET_WORD(res); /* FIXME: for 16-bit apps this is a byte. */ 2018 2019 res += sizeof(WORD); 2019 2020 2021 2022 2023 2024 2020 /* Align the text on a word boundary. */ 2021 res += (~((int)res - 1)) & 1; 2022 mii.dwTypeData = (LPWSTR) res; 2023 res += (1 + strlenW(mii.dwTypeData)) * sizeof(WCHAR); 2024 /* Align the following fields on a dword boundary. */ 2025 res += (~((int)res - 1)) & 3; 2025 2026 2026 2027 TRACE("Menu item: [%08x,%08x,%04x,%04x,%s]\n", 2027 2028 mii.fType, mii.fState, mii.wID, resinfo, debugstr_w(mii.dwTypeData)); 2028 2029 2029 if (resinfo & 1) {/* Pop-up? */2030 2031 2032 2033 2034 2035 2036 2030 if (resinfo & 1) { /* Pop-up? */ 2031 /* DWORD helpid = GET_DWORD(res); FIXME: use this. */ 2032 res += sizeof(DWORD); 2033 mii.hSubMenu = CreatePopupMenu(); 2034 if (!mii.hSubMenu) 2035 return NULL; 2036 if (!(res = MENUEX_ParseResource(res, mii.hSubMenu))) { 2037 DestroyMenu(mii.hSubMenu); 2037 2038 return NULL; 2038 2039 } 2039 2040 2041 } 2042 2043 2044 2045 2046 2047 2048 2040 mii.fMask |= MIIM_SUBMENU; 2041 mii.fType |= MF_POPUP; 2042 } 2043 else if(!*mii.dwTypeData && !(mii.fType & MF_SEPARATOR)) 2044 { 2045 WARN("Converting NULL menu item %04x, type %04x to SEPARATOR\n", 2046 mii.wID, mii.fType); 2047 mii.fType |= MF_SEPARATOR; 2048 } 2049 InsertMenuItemW(hMenu, -1, MF_BYPOSITION, &mii); 2049 2050 } while (!(resinfo & MF_END)); 2050 2051 return res; … … 2087 2088 if (menu && top_popup) 2088 2089 { 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2090 HMENU hsubmenu; 2091 POPUPMENU *submenu; 2092 MENUITEM *item; 2093 2094 if (menu->FocusedItem != NO_SELECTED_ITEM) 2095 { 2096 item = &menu->items[menu->FocusedItem]; 2097 if (!(item->fType & MF_POPUP) || 2098 !(item->fState & MF_MOUSESELECT)) return; 2099 item->fState &= ~MF_MOUSESELECT; 2100 hsubmenu = item->hSubMenu; 2101 } else return; 2102 2103 submenu = MENU_GetMenu( hsubmenu ); 2104 MENU_HideSubPopups( hwndOwner, hsubmenu, FALSE ); 2105 MENU_SelectItem( hwndOwner, hsubmenu, NO_SELECTED_ITEM, sendMenuSelect, 0 ); 2105 2106 DestroyWindow( submenu->hWnd ); 2106 2107 submenu->hWnd = 0; … … 2139 2140 if (!(wFlags & TPM_NONOTIFY)) 2140 2141 SendMessageA( hwndOwner, WM_INITMENUPOPUP, item->hSubMenu, 2141 2142 MAKELONG( menu->FocusedItem, IS_SYSTEM_MENU(menu) )); 2142 2143 2143 2144 item = &menu->items[menu->FocusedItem]; … … 2154 2155 item->fState |= MF_HILITE; 2155 2156 MENU_DrawMenuItem( menu->hWnd, hmenu, hwndOwner, hdc, item, menu->Height, !(menu->wFlags & MF_POPUP), ODA_DRAWENTIRE ); 2156 2157 ReleaseDC( menu->hWnd, hdc ); 2157 2158 } 2158 2159 if (!item->rect.top && !item->rect.left && !item->rect.bottom && !item->rect.right) … … 2163 2164 if (IS_SYSTEM_MENU(menu)) 2164 2165 { 2165 2166 MENU_InitSysMenuPopup(item->hSubMenu, 2166 2167 GetWindowLongA( menu->hWnd, GWL_STYLE ), 2167 2168 GetClassLongA( menu->hWnd, GCL_STYLE)); 2168 2169 2169 2170 2171 2170 NC_GetSysPopupPos( menu->hWnd, &rect ); 2171 rect.top = rect.bottom; 2172 rect.right = GetSystemMetrics(SM_CXSIZE); 2172 2173 rect.bottom = GetSystemMetrics(SM_CYSIZE); 2173 2174 } … … 2175 2176 { 2176 2177 GetWindowRect( menu->hWnd, &rect ); 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2178 if (menu->wFlags & MF_POPUP) 2179 { 2180 rect.left += item->rect.right - GetSystemMetrics(SM_CXBORDER); 2181 rect.top += item->rect.top; 2182 rect.right = item->rect.left - item->rect.right + GetSystemMetrics(SM_CXBORDER); 2183 rect.bottom = item->rect.top - item->rect.bottom; 2184 } 2185 else 2186 { 2187 rect.left += item->rect.left; 2188 rect.top += item->rect.bottom; 2189 rect.right = item->rect.right - item->rect.left; 2190 rect.bottom = item->rect.bottom - item->rect.top; 2191 } 2191 2192 } 2192 2193 2193 2194 MENU_ShowPopup( hwndOwner, item->hSubMenu, menu->FocusedItem, 2194 2195 rect.left, rect.top, rect.right, rect.bottom ); 2195 2196 if (selectFirst) 2196 2197 MENU_MoveSelection( hwndOwner, item->hSubMenu, ITEM_NEXT ); … … 2258 2259 2259 2260 if (!menu || !menu->nItems || 2260 2261 (menu->FocusedItem == NO_SELECTED_ITEM)) return -1; 2261 2262 2262 2263 item = &menu->items[menu->FocusedItem]; … … 2267 2268 if (!(item->fType & MF_POPUP)) 2268 2269 { 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2270 if (!(item->fState & (MF_GRAYED | MF_DISABLED)) && !(item->fType & MF_SEPARATOR)) 2271 { 2272 /* If TPM_RETURNCMD is set you return the id, but 2273 do not send a message to the owner */ 2274 if(!(wFlags & TPM_RETURNCMD)) 2275 { 2276 if( menu->wFlags & MF_SYSMENU ) 2277 PostMessageA( pmt->hOwnerWnd, WM_SYSCOMMAND, item->wID, 2278 MAKELPARAM((INT16)pmt->pt.x, (INT16)pmt->pt.y) ); 2279 else 2280 PostMessageA( pmt->hOwnerWnd, WM_COMMAND, item->wID, 0 ); 2281 } 2282 return item->wID; 2283 } 2283 2284 } 2284 2285 else 2285 2286 pmt->hCurrentMenu = MENU_ShowSubPopup(pmt->hOwnerWnd, hMenu, TRUE, wFlags); 2286 2287 2287 2288 return -1; … … 2301 2302 2302 2303 if( pmt->hTopMenu != hPtMenu && 2303 2304 { 2305 2306 2307 2304 !((ptmenu->wFlags | topmenu->wFlags) & MF_POPUP) ) 2305 { 2306 /* both are top level menus (system and menu-bar) */ 2307 MENU_HideSubPopups( pmt->hOwnerWnd, pmt->hTopMenu, FALSE ); 2308 MENU_SelectItem( pmt->hOwnerWnd, pmt->hTopMenu, NO_SELECTED_ITEM, FALSE, 0 ); 2308 2309 pmt->hTopMenu = hPtMenu; 2309 2310 } … … 2324 2325 if (hPtMenu) 2325 2326 { 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2327 UINT id = 0; 2328 POPUPMENU *ptmenu = MENU_GetMenu( hPtMenu ); 2329 MENUITEM *item; 2330 2331 if( IS_SYSTEM_MENU(ptmenu) ) 2332 item = ptmenu->items; 2333 else 2334 item = MENU_FindItemByCoords( ptmenu, pmt->pt, &id ); 2335 2336 if( item ) 2337 { 2338 if( ptmenu->FocusedItem != id ) 2339 MENU_SwitchTracking( pmt, hPtMenu, id ); 2340 2341 /* If the popup menu is not already "popped" */ 2342 if(!(item->fState & MF_MOUSESELECT )) 2343 { 2344 pmt->hCurrentMenu = MENU_ShowSubPopup( pmt->hOwnerWnd, hPtMenu, FALSE, wFlags ); 2345 2346 /* In win31, a newly popped menu always remains opened for the next buttonup */ 2346 2347 #ifdef __WIN32OS2__ 2347 2348 ptmenu->bTimeToHide = FALSE; 2348 if(fOS2Look) 2349 ptmenu->bTimeToHide = FALSE; 2349 2350 #endif 2350 2351 2352 2353 2354 2355 2356 2351 if(TWEAK_WineLook == WIN31_LOOK) 2352 ptmenu->bTimeToHide = FALSE; 2353 } 2354 2355 return TRUE; 2356 } 2357 /* Else the click was on the menu bar, finish the tracking */ 2357 2358 } 2358 2359 return FALSE; … … 2373 2374 if (hPtMenu) 2374 2375 { 2375 2376 2377 2376 UINT id = 0; 2377 POPUPMENU *ptmenu = MENU_GetMenu( hPtMenu ); 2378 MENUITEM *item; 2378 2379 2379 2380 if( IS_SYSTEM_MENU(ptmenu) ) … … 2382 2383 item = MENU_FindItemByCoords( ptmenu, pmt->pt, &id ); 2383 2384 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2385 if( item && (ptmenu->FocusedItem == id )) 2386 { 2387 if( !(item->fType & MF_POPUP) ) 2388 return MENU_ExecFocusedItem( pmt, hPtMenu, wFlags); 2389 2390 /* If we are dealing with the top-level menu */ 2391 /* and this is a click on an already "popped" item: */ 2392 /* Stop the menu tracking and close the opened submenus */ 2393 if((pmt->hTopMenu == hPtMenu) && (ptmenu->bTimeToHide == TRUE)) 2394 return 0; 2395 } 2396 ptmenu->bTimeToHide = TRUE; 2396 2397 } 2397 2398 return -1; … … 2411 2412 if( hPtMenu ) 2412 2413 { 2413 2414 ptmenu = MENU_GetMenu( hPtMenu ); 2414 2415 if( IS_SYSTEM_MENU(ptmenu) ) 2415 2416 id = 0; 2416 2417 else 2417 2418 MENU_FindItemByCoords( ptmenu, pmt->pt, &id ); … … 2420 2421 if( id == NO_SELECTED_ITEM ) 2421 2422 { 2422 2423 2423 MENU_SelectItem( pmt->hOwnerWnd, pmt->hCurrentMenu, 2424 NO_SELECTED_ITEM, TRUE, pmt->hTopMenu); 2424 2425 2425 2426 } 2426 2427 else if( ptmenu->FocusedItem != id ) 2427 2428 { 2428 2429 2429 MENU_SwitchTracking( pmt, hPtMenu, id ); 2430 pmt->hCurrentMenu = MENU_ShowSubPopup(pmt->hOwnerWnd, hPtMenu, FALSE, wFlags); 2430 2431 } 2431 2432 return TRUE; … … 2446 2447 { 2447 2448 MDINEXTMENU next_menu; 2448 2449 2450 2449 HMENU hNewMenu; 2450 HWND hNewWnd; 2451 UINT id = 0; 2451 2452 2452 2453 next_menu.hmenuIn = (IS_SYSTEM_MENU(menu)) ? GetSubMenu(pmt->hTopMenu,0) : pmt->hTopMenu; … … 2455 2456 SendMessageW( pmt->hOwnerWnd, WM_NEXTMENU, vk, (LPARAM)&next_menu ); 2456 2457 2457 2458 TRACE("%04x [%04x] -> %04x [%04x]\n", 2458 2459 pmt->hCurrentMenu, pmt->hOwnerWnd, next_menu.hmenuNext, next_menu.hwndNext ); 2459 2460 2460 2461 2461 if (!next_menu.hmenuNext || !next_menu.hwndNext) 2462 { 2462 2463 DWORD style = GetWindowLongA( pmt->hOwnerWnd, GWL_STYLE ); 2463 2464 2465 2466 2464 hNewWnd = pmt->hOwnerWnd; 2465 if( IS_SYSTEM_MENU(menu) ) 2466 { 2467 /* switch to the menu bar */ 2467 2468 2468 2469 if(style & WS_CHILD || !(hNewMenu = GetMenu(hNewWnd))) return FALSE; 2469 2470 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2471 if( vk == VK_LEFT ) 2472 { 2473 menu = MENU_GetMenu( hNewMenu ); 2474 id = menu->nItems - 1; 2475 } 2476 } 2477 else if (style & WS_SYSMENU ) 2478 { 2479 /* switch to the system menu */ 2480 hNewMenu = get_win_sys_menu( hNewWnd ); 2481 } 2481 2482 else return FALSE; 2482 2483 2484 2483 } 2484 else /* application returned a new menu to switch to */ 2485 { 2485 2486 hNewMenu = next_menu.hmenuNext; 2486 2487 hNewWnd = WIN_GetFullHandle( next_menu.hwndNext ); 2487 2488 2488 2489 2489 if( IsMenu(hNewMenu) && IsWindow(hNewWnd) ) 2490 { 2490 2491 DWORD style = GetWindowLongA( hNewWnd, GWL_STYLE ); 2491 2492 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2493 if (style & WS_SYSMENU && 2494 GetSubMenu(get_win_sys_menu(hNewWnd), 0) == hNewMenu ) 2495 { 2496 /* get the real system menu */ 2497 hNewMenu = get_win_sys_menu(hNewWnd); 2498 } 2499 else if (style & WS_CHILD || GetMenu(hNewWnd) != hNewMenu ) 2500 { 2501 /* FIXME: Not sure what to do here; 2502 * perhaps try to track hNewMenu as a popup? */ 2503 2504 TRACE(" -- got confused.\n"); 2505 return FALSE; 2506 } 2507 } 2508 else return FALSE; 2509 } 2510 2511 if( hNewMenu != pmt->hTopMenu ) 2512 { 2513 MENU_SelectItem( pmt->hOwnerWnd, pmt->hTopMenu, NO_SELECTED_ITEM, 2513 2514 FALSE, 0 ); 2514 2515 2516 2517 2518 2519 2520 2521 2515 if( pmt->hCurrentMenu != pmt->hTopMenu ) 2516 MENU_HideSubPopups( pmt->hOwnerWnd, pmt->hTopMenu, FALSE ); 2517 } 2518 2519 if( hNewWnd != pmt->hOwnerWnd ) 2520 { 2521 ReleaseCapture(); 2522 pmt->hOwnerWnd = hNewWnd; 2522 2523 #ifdef __WIN32OS2__ 2523 2524 SetCapture(pmt->hOwnerWnd); //SvL: Don't know if this is good enough 2524 2525 #else 2525 2526 EVENT_Capture( pmt->hOwnerWnd, HTMENU ); 2526 2527 #endif 2527 2528 2529 2530 2531 2532 2528 } 2529 2530 pmt->hTopMenu = pmt->hCurrentMenu = hNewMenu; /* all subpopups are hidden */ 2531 MENU_SelectItem( pmt->hOwnerWnd, pmt->hTopMenu, id, TRUE, 0 ); 2532 2533 return TRUE; 2533 2534 } 2534 2535 return FALSE; … … 2552 2553 switch( uMsg ) 2553 2554 { 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2555 case WM_KEYDOWN: 2556 PeekMessageA( &msg, 0, 0, 0, PM_NOYIELD | PM_NOREMOVE); 2557 if( msg.message == WM_KEYUP || msg.message == WM_PAINT ) 2558 { 2559 PeekMessageA( &msg, 0, 0, 0, PM_NOYIELD | PM_REMOVE); 2560 PeekMessageA( &msg, 0, 0, 0, PM_NOYIELD | PM_NOREMOVE); 2561 if( msg.message == WM_KEYDOWN && 2562 (msg.wParam == VK_LEFT || msg.wParam == VK_RIGHT)) 2563 { 2564 pmt->trackFlags |= TF_SUSPENDPOPUP; 2565 return TRUE; 2566 } 2567 } 2568 break; 2568 2569 } 2569 2570 … … 2624 2625 /* Try to move 1 column left (if possible) */ 2625 2626 if( (prevcol = MENU_GetStartOfPrevColumn( pmt->hCurrentMenu )) != 2626 2627 2628 2629 2630 2627 NO_SELECTED_ITEM ) { 2628 2629 MENU_SelectItem( pmt->hOwnerWnd, pmt->hCurrentMenu, 2630 prevcol, TRUE, 0 ); 2631 return; 2631 2632 } 2632 2633 … … 2634 2635 while (hmenutmp != pmt->hCurrentMenu) 2635 2636 { 2636 2637 2637 hmenuprev = hmenutmp; 2638 hmenutmp = MENU_GetSubPopup( hmenuprev ); 2638 2639 } 2639 2640 … … 2643 2644 if ( (hmenuprev == pmt->hTopMenu) && !(menu->wFlags & MF_POPUP) ) 2644 2645 { 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2646 /* move menu bar selection if no more popups are left */ 2647 2648 if( !MENU_DoNextMenu( pmt, VK_LEFT) ) 2649 MENU_MoveSelection( pmt->hOwnerWnd, pmt->hTopMenu, ITEM_PREV ); 2650 2651 if ( hmenuprev != hmenutmp || pmt->trackFlags & TF_SUSPENDPOPUP ) 2652 { 2653 /* A sublevel menu was displayed - display the next one 2654 * unless there is another displacement coming up */ 2655 2656 if( !MENU_SuspendPopup( pmt, WM_KEYDOWN ) ) 2657 pmt->hCurrentMenu = MENU_ShowSubPopup(pmt->hOwnerWnd, 2658 pmt->hTopMenu, TRUE, wFlags); 2659 } 2659 2660 } 2660 2661 } … … 2673 2674 2674 2675 TRACE("MENU_KeyRight called, cur %x (%s), top %x (%s).\n", 2675 2676 2677 2678 2676 pmt->hCurrentMenu, 2677 debugstr_w((MENU_GetMenu(pmt->hCurrentMenu))-> 2678 items[0].text), 2679 pmt->hTopMenu, debugstr_w(menu->items[0].text) ); 2679 2680 2680 2681 if ( (menu->wFlags & MF_POPUP) || (pmt->hCurrentMenu != pmt->hTopMenu)) 2681 2682 { 2682 2683 2684 2685 2686 2687 2688 2683 /* If already displaying a popup, try to display sub-popup */ 2684 2685 hmenutmp = pmt->hCurrentMenu; 2686 pmt->hCurrentMenu = MENU_ShowSubPopup(pmt->hOwnerWnd, hmenutmp, TRUE, wFlags); 2687 2688 /* if subpopup was displayed then we are done */ 2689 if (hmenutmp != pmt->hCurrentMenu) return; 2689 2690 } 2690 2691 2691 2692 /* Check to see if there's another column */ 2692 2693 if( (nextcol = MENU_GetStartOfNextColumn( pmt->hCurrentMenu )) != 2693 2694 2695 2696 2697 2698 } 2699 2700 if (!(menu->wFlags & MF_POPUP)) 2701 { 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2694 NO_SELECTED_ITEM ) { 2695 TRACE("Going to %d.\n", nextcol ); 2696 MENU_SelectItem( pmt->hOwnerWnd, pmt->hCurrentMenu, 2697 nextcol, TRUE, 0 ); 2698 return; 2699 } 2700 2701 if (!(menu->wFlags & MF_POPUP)) /* menu bar tracking */ 2702 { 2703 if( pmt->hCurrentMenu != pmt->hTopMenu ) 2704 { 2705 MENU_HideSubPopups( pmt->hOwnerWnd, pmt->hTopMenu, FALSE ); 2706 hmenutmp = pmt->hCurrentMenu = pmt->hTopMenu; 2707 } else hmenutmp = 0; 2708 2709 /* try to move to the next item */ 2710 if( !MENU_DoNextMenu( pmt, VK_RIGHT) ) 2711 MENU_MoveSelection( pmt->hOwnerWnd, pmt->hTopMenu, ITEM_NEXT ); 2712 2713 if( hmenutmp || pmt->trackFlags & TF_SUSPENDPOPUP ) 2714 if( !MENU_SuspendPopup(pmt, WM_KEYDOWN) ) 2715 pmt->hCurrentMenu = MENU_ShowSubPopup(pmt->hOwnerWnd, 2716 pmt->hTopMenu, TRUE, wFlags); 2716 2717 } 2717 2718 } … … 2743 2744 2744 2745 TRACE("hmenu=0x%04x flags=0x%08x (%d,%d) hwnd=0x%04x (%d,%d)-(%d,%d)\n", 2745 2746 2746 hmenu, wFlags, x, y, hwnd, (lprect) ? lprect->left : 0, (lprect) ? lprect->top : 0, 2747 (lprect) ? lprect->right : 0, (lprect) ? lprect->bottom : 0); 2747 2748 2748 2749 fEndMenu = FALSE; … … 2751 2752 if (wFlags & TPM_BUTTONDOWN) 2752 2753 { 2753 2754 2755 2754 /* Get the result in order to start the tracking or not */ 2755 fRemove = MENU_ButtonDown( &mt, hmenu, wFlags ); 2756 fEndMenu = !fRemove; 2756 2757 } 2757 2758 … … 2769 2770 while (!fEndMenu) 2770 2771 { 2771 2772 2773 2774 2775 2776 2772 menu = MENU_GetMenu( mt.hCurrentMenu ); 2773 if (!menu) /* sometimes happens if I do a window manager close */ 2774 break; 2775 2776 /* we have to keep the message in the queue until it's 2777 * clear that menu loop is not over yet. */ 2777 2778 2778 2779 for (;;) … … 2803 2804 } 2804 2805 2805 2806 /* check if EndMenu() tried to cancel us, by posting this message */ 2806 2807 if(msg.message == WM_CANCELMODE) 2807 2808 2809 2808 { 2809 /* we are now out of the loop */ 2810 fEndMenu = TRUE; 2810 2811 2811 2812 #ifdef __WIN32OS2__ 2812 2813 2813 /* remove the message from the queue */ 2814 PeekMessageA( &msg, 0, msg.message, msg.message, PM_REMOVE ); 2814 2815 #endif 2815 2816 2817 2816 /* break out of internal loop, ala ESCAPE */ 2817 break; 2818 } 2818 2819 2819 2820 TranslateMessage( &msg ); 2820 2821 mt.pt = msg.pt; 2821 2822 2822 2823 2823 if ( (msg.hwnd==menu->hWnd) || (msg.message!=WM_TIMER) ) 2824 enterIdleSent=FALSE; 2824 2825 2825 2826 fRemove = FALSE; 2826 2827 2827 if ((msg.message >= WM_MOUSEFIRST) && (msg.message <= WM_MOUSELAST)) 2828 { 2828 2829 /* 2829 2830 * use the mouse coordinates in lParam instead of those in the MSG … … 2839 2840 ClientToScreen(msg.hwnd,&mt.pt); 2840 2841 2841 2842 2843 2844 2845 2846 2847 2848 2849 2842 /* Find a menu for this mouse event */ 2843 hmenu = MENU_PtMenu( mt.hTopMenu, mt.pt ); 2844 2845 switch(msg.message) 2846 { 2847 /* no WM_NC... messages in captured state */ 2848 2849 case WM_RBUTTONDBLCLK: 2850 case WM_RBUTTONDOWN: 2850 2851 #ifdef __WIN32OS2__ 2851 2852 if (!(wFlags & TPM_RIGHTBUTTON)) { 2852 2853 MENUITEM *item; 2853 2854 2854 UINT id = 0; 2855 2855 2856 if( IS_SYSTEM_MENU(menu) ) 2856 2857 item = menu->items; 2857 2858 else 2858 2859 item = MENU_FindItemByCoords( menu, mt.pt, &id ); 2859 2860 if (item) break; 2861 2860 //@@PF If our pointer is over the menu - do nothing 2861 if (item) break; 2862 //@@PF Time to close menu - win2k&98 checked 2862 2863 fEndMenu = 1; 2863 2864 break; … … 2865 2866 goto buttondown; 2866 2867 #else 2867 2868 if (!(wFlags & TPM_RIGHTBUTTON)) break; 2868 2869 #endif 2869 2870 2870 /* fall through */ 2871 case WM_LBUTTONDBLCLK: 2871 2872 #ifdef __WIN32OS2__ 2872 2873 if (bSysMenu && (hmenu == mt.hTopMenu)) … … 2889 2890 2890 2891 #endif 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2892 case WM_LBUTTONDOWN: 2893 /* If the message belongs to the menu, removes it from the queue */ 2894 /* Else, end menu tracking */ 2895 fRemove = MENU_ButtonDown( &mt, hmenu, wFlags ); 2896 fEndMenu = !fRemove; 2897 break; 2898 2899 case WM_RBUTTONUP: 2900 if (!(wFlags & TPM_RIGHTBUTTON)) break; 2901 /* fall through */ 2902 case WM_LBUTTONUP: 2903 /* Check if a menu was selected by the mouse */ 2904 if (hmenu) 2905 { 2905 2906 executedMenuId = MENU_ButtonUp( &mt, hmenu, wFlags); 2906 2907 2907 2908 2908 /* End the loop if executedMenuId is an item ID */ 2909 /* or if the job was done (executedMenuId = 0). */ 2909 2910 fEndMenu = fRemove = (executedMenuId != -1); 2910 2911 } 2911 2912 /* No menu was selected by the mouse */ 2912 2913 /* if the function was called by TrackPopupMenu, continue … … 2915 2916 fEndMenu = ((wFlags & TPM_POPUPMENU) ? FALSE : TRUE); 2916 2917 2917 2918 2919 2918 break; 2919 2920 case WM_MOUSEMOVE: 2920 2921 /* In win95 winelook, the selected menu item must be changed every time the 2921 2922 mouse moves. In Win31 winelook, the mouse button has to be held down */ … … 2924 2925 //PF Win32 eats first mousemove to prevent auto-select of item 2925 2926 //on TrackMenuPopup pressed button - verified in Win2k 2926 if (bFirstMouseMove) 2927 { 2928 bFirstMouseMove = FALSE; 2927 if (bFirstMouseMove) 2928 { 2929 bFirstMouseMove = FALSE; 2929 2930 break; 2930 2931 } … … 2937 2938 ((wFlags & TPM_RIGHTBUTTON) && (msg.wParam & MK_RBUTTON))) ) 2938 2939 2939 2940 2941 2942 2943 2944 2940 fEndMenu |= !MENU_MouseMove( &mt, hmenu, wFlags ); 2941 2942 } /* switch(msg.message) - mouse */ 2943 } 2944 else if ((msg.message >= WM_KEYFIRST) && (msg.message <= WM_KEYLAST)) 2945 { 2945 2946 fRemove = TRUE; /* Keyboard messages are always removed */ 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2947 switch(msg.message) 2948 { 2949 case WM_KEYDOWN: 2950 switch(msg.wParam) 2951 { 2952 case VK_HOME: 2953 case VK_END: 2954 MENU_SelectItem( mt.hOwnerWnd, mt.hCurrentMenu, 2955 NO_SELECTED_ITEM, FALSE, 0 ); 2956 /* fall through */ 2957 case VK_UP: 2958 MENU_MoveSelection( mt.hOwnerWnd, mt.hCurrentMenu, 2959 (msg.wParam == VK_HOME)? ITEM_NEXT : ITEM_PREV ); 2960 break; 2961 2962 case VK_DOWN: /* If on menu bar, pull-down the menu */ 2963 2964 menu = MENU_GetMenu( mt.hCurrentMenu ); 2965 if (!(menu->wFlags & MF_POPUP)) 2966 mt.hCurrentMenu = MENU_ShowSubPopup(mt.hOwnerWnd, mt.hTopMenu, TRUE, wFlags); 2967 else /* otherwise try to move selection */ 2968 MENU_MoveSelection( mt.hOwnerWnd, mt.hCurrentMenu, ITEM_NEXT ); 2969 break; 2970 2971 case VK_LEFT: 2972 MENU_KeyLeft( &mt, wFlags ); 2973 break; 2974 2975 case VK_RIGHT: 2976 MENU_KeyRight( &mt, wFlags ); 2977 break; 2978 2979 case VK_ESCAPE: 2979 2980 fEndMenu = MENU_KeyEscape(&mt, wFlags); 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 UINTpos;3016 3017 3018 2981 break; 2982 2983 case VK_F1: 2984 { 2985 HELPINFO hi; 2986 hi.cbSize = sizeof(HELPINFO); 2987 hi.iContextType = HELPINFO_MENUITEM; 2988 if (menu->FocusedItem == NO_SELECTED_ITEM) 2989 hi.iCtrlId = 0; 2990 else 2991 hi.iCtrlId = menu->items[menu->FocusedItem].wID; 2992 hi.hItemHandle = hmenu; 2993 hi.dwContextId = menu->dwContextHelpID; 2994 hi.MousePos = msg.pt; 2995 SendMessageA(hwnd, WM_HELP, 0, (LPARAM)&hi); 2996 break; 2997 } 2998 2999 default: 3000 break; 3001 } 3002 break; /* WM_KEYDOWN */ 3003 3004 case WM_SYSKEYDOWN: 3005 switch(msg.wParam) 3006 { 3007 case VK_MENU: 3008 fEndMenu = TRUE; 3009 break; 3010 3011 } 3012 break; /* WM_SYSKEYDOWN */ 3013 3014 case WM_CHAR: 3015 { 3016 UINT pos; 3017 3018 if (msg.wParam == '\r' || msg.wParam == ' ') 3019 { 3019 3020 executedMenuId = MENU_ExecFocusedItem(&mt,mt.hCurrentMenu, wFlags); 3020 3021 fEndMenu = (executedMenuId != -1); 3021 3022 3022 3023 3024 3025 3026 3027 3028 3029 3023 break; 3024 } 3025 3026 /* Hack to avoid control chars. */ 3027 /* We will find a better way real soon... */ 3028 if ((msg.wParam <= 32) || (msg.wParam >= 127)) break; 3029 3030 pos = MENU_FindItemByKey( mt.hOwnerWnd, mt.hCurrentMenu, 3030 3031 LOWORD(msg.wParam), FALSE ); 3031 3032 3033 3034 3035 3032 if (pos == (UINT)-2) fEndMenu = TRUE; 3033 else if (pos == (UINT)-1) MessageBeep(0); 3034 else 3035 { 3036 MENU_SelectItem( mt.hOwnerWnd, mt.hCurrentMenu, pos, 3036 3037 TRUE, 0 ); 3037 3038 executedMenuId = MENU_ExecFocusedItem(&mt,mt.hCurrentMenu, wFlags); 3038 3039 fEndMenu = (executedMenuId != -1); 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3040 } 3041 } 3042 break; 3043 } /* switch(msg.message) - kbd */ 3044 } 3045 else 3046 { 3047 DispatchMessageA( &msg ); 3048 } 3049 3050 if (!fEndMenu) fRemove = TRUE; 3051 3052 /* finally remove message from the queue */ 3052 3053 3053 3054 if (fRemove && !(mt.trackFlags & TF_SKIPREMOVE) ) 3054 #ifdef __WIN32OS2__ 3055 #ifdef __WIN32OS2__ 3055 3056 ; 3056 3057 #else 3057 3058 PeekMessageA( &msg, 0, msg.message, msg.message, PM_REMOVE ); 3058 3059 #endif 3059 3060 else mt.trackFlags &= ~TF_SKIPREMOVE; 3060 3061 } 3061 3062 … … 3071 3072 if( IsMenu( mt.hTopMenu ) ) 3072 3073 { 3073 3074 menu = MENU_GetMenu( mt.hTopMenu ); 3074 3075 3075 3076 if( IsWindow( mt.hOwnerWnd ) ) 3076 3077 { 3077 3078 3079 3080 3078 MENU_HideSubPopups( mt.hOwnerWnd, mt.hTopMenu, FALSE ); 3079 3080 if (menu && menu->wFlags & MF_POPUP) 3081 { 3081 3082 DestroyWindow( menu->hWnd ); 3082 3083 menu->hWnd = 0; 3083 3084 3085 3084 } 3085 MENU_SelectItem( mt.hOwnerWnd, mt.hTopMenu, NO_SELECTED_ITEM, FALSE, 0 ); 3086 SendMessageA( mt.hOwnerWnd, WM_MENUSELECT, MAKELONG(0,0xffff), 0 ); 3086 3087 } 3087 3088 … … 3153 3154 if (parent != GetDesktopWindow()) ScreenToClient( parent, &pt ); 3154 3155 3155 3156 3157 3156 MENU_InitTracking( hWnd, hMenu, FALSE, wFlags ); 3157 MENU_TrackMenu( hMenu, wFlags, pt.x, pt.y, hWnd, NULL ); 3158 MENU_ExitTracking(hWnd); 3158 3159 } 3159 3160 } … … 3241 3242 3242 3243 if (MENU_ShowPopup( hWnd, hMenu, 0, x, y, 0, 0 )) 3243 3244 ret = MENU_TrackMenu( hMenu, wFlags | TPM_POPUPMENU, 0, 0, hWnd, lpRect ); 3244 3245 MENU_ExitTracking(hWnd); 3245 3246 3246 3247 if( (!(wFlags & TPM_RETURNCMD)) && (ret != FALSE) ) 3247 3248 ret = 1; 3248 3249 3249 3250 return ret; … … 3274 3275 { 3275 3276 case WM_CREATE: 3276 3277 3278 3277 { 3278 CREATESTRUCTW *cs = (CREATESTRUCTW*)lParam; 3279 SetWindowLongW( hwnd, 0, (LONG)cs->lpCreateParams ); 3279 3280 return 0; 3280 3281 } 3281 3282 3282 3283 case WM_MOUSEACTIVATE: /* We don't want to be activated */ … … 3284 3285 3285 3286 case WM_PAINT: 3286 3287 3288 3289 3287 { 3288 PAINTSTRUCT ps; 3289 BeginPaint( hwnd, &ps ); 3290 MENU_DrawPopupMenu( hwnd, ps.hdc, 3290 3291 (HMENU)GetWindowLongA( hwnd, 0 ) ); 3291 3292 EndPaint( hwnd, &ps ); 3292 3293 return 0; 3293 3294 } 3294 3295 case WM_ERASEBKGND: 3295 3296 return 1; … … 3302 3303 case WM_SHOWWINDOW: 3303 3304 3304 3305 3305 if( wParam ) 3306 { 3306 3307 if (!GetWindowLongW( hwnd, 0 )) ERR("no menu to display\n"); 3307 3308 3308 } 3309 else 3309 3310 SetWindowLongW( hwnd, 0, 0 ); 3310 3311 break; 3311 3312 3312 3313 case MM_SETMENUHANDLE: … … 3419 3420 3420 3421 TRACE("(%04x, %04X, %04X) !\n", 3421 3422 hMenu, wItemID, wFlags); 3422 3423 3423 3424 /* Get the Popupmenu to access the owner menu */ 3424 3425 if (!(menu = MENU_GetMenu(hMenu))) 3425 3426 return (UINT)-1; 3426 3427 3427 3428 if (!(item = MENU_FindItem( &hMenu, &wItemID, wFlags ))) 3428 3429 return (UINT)-1; 3429 3430 3430 3431 oldflags = item->fState & (MF_GRAYED | MF_DISABLED); … … 3433 3434 /* In win95 if the close item in the system menu change update the close button */ 3434 3435 if (TWEAK_WineLook == WIN95_LOOK) 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3436 if((item->wID == SC_CLOSE) && (oldflags != wFlags)) 3437 { 3438 if (menu->hSysMenuOwner != 0) 3439 { 3440 POPUPMENU* parentMenu; 3441 3442 /* Get the parent menu to access*/ 3443 if (!(parentMenu = MENU_GetMenu(menu->hSysMenuOwner))) 3444 return (UINT)-1; 3445 3446 /* Refresh the frame to reflect the change*/ 3447 SetWindowPos(parentMenu->hWnd, 0, 0, 0, 0, 0, 3448 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER); 3449 } 3450 } 3450 3451 3451 3452 return oldflags; … … 3457 3458 */ 3458 3459 INT WINAPI GetMenuStringA( 3459 HMENU hMenu,/* [in] menuhandle */3460 UINT wItemID,/* [in] menu item (dep. on wFlags) */3461 LPSTR str,/* [out] outbuffer. If NULL, func returns entry length*/3462 INT nMaxSiz,/* [in] length of buffer. if 0, func returns entry len*/3463 UINT wFlags/* [in] MF_ flags */3460 HMENU hMenu, /* [in] menuhandle */ 3461 UINT wItemID, /* [in] menu item (dep. on wFlags) */ 3462 LPSTR str, /* [out] outbuffer. If NULL, func returns entry length*/ 3463 INT nMaxSiz, /* [in] length of buffer. if 0, func returns entry len*/ 3464 UINT wFlags /* [in] MF_ flags */ 3464 3465 ) { 3465 3466 MENUITEM *item; … … 3472 3473 str[0] = '\0'; 3473 3474 if (!WideCharToMultiByte( CP_ACP, 0, item->text, -1, str, nMaxSiz, NULL, NULL )) 3475 #ifdef __WIN32OS2__ 3476 lstrtrunc( str, nMaxSiz ); 3477 #else 3474 3478 str[nMaxSiz-1] = 0; 3479 #endif 3475 3480 TRACE("returning '%s'\n", str ); 3476 3481 return strlen(str); … … 3522 3527 MENUITEM *item; 3523 3528 TRACE("(menu=%04x, id=%04x, flags=%04x);\n", 3524 3529 hMenu, wItemID, wFlags); 3525 3530 if (!(item = MENU_FindItem( &hMenu, &wItemID, wFlags ))) return -1; 3526 3531 debug_print_menuitem (" item: ", item, ""); 3527 3532 if (item->fType & MF_POPUP) 3528 3533 { 3529 3530 3531 3534 POPUPMENU *menu = MENU_GetMenu( item->hSubMenu ); 3535 if (!menu) return -1; 3536 else return (menu->nItems << 8) | ((item->fState|item->fType) & 0xff); 3532 3537 } 3533 3538 else 3534 3539 { 3535 3536 3537 3538 3540 /* We used to (from way back then) mask the result to 0xff. */ 3541 /* I don't know why and it seems wrong as the documented */ 3542 /* return flag MF_SEPARATOR is outside that mask. */ 3543 return (item->fType | item->fState); 3539 3544 } 3540 3545 } … … 3546 3551 INT WINAPI GetMenuItemCount( HMENU hMenu ) 3547 3552 { 3548 LPPOPUPMENU 3553 LPPOPUPMENU menu = MENU_GetMenu(hMenu); 3549 3554 if (!menu) return -1; 3550 3555 TRACE("(%04x) returning %d\n", … … 3585 3590 if (IS_STRING_ITEM(flags) && str) 3586 3591 TRACE("hMenu %04x, pos %d, flags %08x, " 3587 3592 "id %04x, str %s\n", 3588 3593 hMenu, pos, flags, id, debugstr_w(str) ); 3589 3594 else TRACE("hMenu %04x, pos %d, flags %08x, " 3590 3595 "id %04x, str %08lx (not a string)\n", 3591 3596 hMenu, pos, flags, id, (DWORD)str ); 3592 3597 … … 3600 3605 3601 3606 if (flags & MF_POPUP) /* Set the MF_POPUP flag on the popup-menu */ 3602 3607 (MENU_GetMenu((HMENU16)id))->wFlags |= MF_POPUP; 3603 3608 3604 3609 item->hCheckBit = item->hUnCheckBit = 0; … … 3656 3661 BOOL WINAPI RemoveMenu( HMENU hMenu, UINT nPos, UINT wFlags ) 3657 3662 { 3658 LPPOPUPMENU 3663 LPPOPUPMENU menu; 3659 3664 MENUITEM *item; 3660 3665 … … 3674 3679 else 3675 3680 { 3676 3677 3678 3679 3680 3681 3681 while(nPos < menu->nItems) 3682 { 3683 *item = *(item+1); 3684 item++; 3685 nPos++; 3686 } 3682 3687 menu->items = HeapReAlloc( GetProcessHeap(), 0, menu->items, 3683 3688 menu->nItems * sizeof(MENUITEM) ); … … 3711 3716 if (IS_STRING_ITEM(flags)) 3712 3717 { 3713 3718 TRACE("%04x %d %04x %04x %s\n", 3714 3719 hMenu, pos, flags, id, debugstr_w(str) ); 3715 3720 if (!str) return FALSE; … … 3717 3722 else 3718 3723 { 3719 3724 TRACE("%04x %d %04x %04x %08lx\n", 3720 3725 hMenu, pos, flags, id, (DWORD)str ); 3721 3726 } … … 3789 3794 if (!hNewCheck && !hNewUnCheck) 3790 3795 { 3791 3796 item->fState &= ~MF_USECHECKBITMAPS; 3792 3797 } 3793 3798 else /* Install new bitmaps */ 3794 3799 { 3795 3796 3797 3800 item->hCheckBit = hNewCheck; 3801 item->hUnCheckBit = hNewUnCheck; 3802 item->fState |= MF_USECHECKBITMAPS; 3798 3803 } 3799 3804 return TRUE; … … 3880 3885 HMENU retvalue = 0; 3881 3886 3882 if(IsWindow(hWnd)) 3887 if(IsWindow(hWnd)) 3883 3888 { 3884 3889 HMENU hSysMenu = getSysMenu(hWnd); … … 3934 3939 if (wndPtr) 3935 3940 { 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3941 if( wndPtr->hSysMenu ) 3942 { 3943 if( bRevert ) 3944 { 3945 DestroyMenu(wndPtr->hSysMenu); 3946 wndPtr->hSysMenu = 0; 3947 } 3948 else 3949 { 3950 POPUPMENU *menu = MENU_GetMenu( wndPtr->hSysMenu ); 3951 if( menu ) 3947 3952 { 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 { 3965 3966 3967 3968 3969 3970 3971 3972 3953 if( menu->nItems > 0 && menu->items[0].hSubMenu == MENU_DefSysPopup ) 3954 menu->items[0].hSubMenu = MENU_CopySysPopup(); 3955 } 3956 else 3957 { 3958 WARN("Current sys-menu (%04x) of wnd %04x is broken\n", 3959 wndPtr->hSysMenu, hWnd); 3960 wndPtr->hSysMenu = 0; 3961 } 3962 } 3963 } 3964 3965 if(!wndPtr->hSysMenu && (wndPtr->dwStyle & WS_SYSMENU) ) 3966 wndPtr->hSysMenu = MENU_GetSysMenu( hWnd, (HMENU)(-1) ); 3967 3968 if( wndPtr->hSysMenu ) 3969 { 3970 POPUPMENU *menu; 3971 retvalue = GetSubMenu(wndPtr->hSysMenu, 0); 3972 3973 /* Store the dummy sysmenu handle to facilitate the refresh */ 3974 /* of the close button if the SC_CLOSE item change */ 3975 menu = MENU_GetMenu(retvalue); 3976 if ( menu ) 3977 menu->hSysMenuOwner = wndPtr->hSysMenu; 3973 3978 } 3974 3979 WIN_ReleaseWndPtr(wndPtr); … … 3999 4004 if (wndPtr) 4000 4005 { 4001 4002 4006 if (wndPtr->hSysMenu) DestroyMenu( wndPtr->hSysMenu ); 4007 wndPtr->hSysMenu = MENU_GetSysMenu( hwnd, hMenu ); 4003 4008 WIN_ReleaseWndPtr(wndPtr); 4004 4009 return TRUE; 4005 4010 } 4006 4011 return FALSE; … … 4126 4131 if (!fEndMenu && top_popup) 4127 4132 { 4128 4133 /* terminate the menu handling code */ 4129 4134 fEndMenu = TRUE; 4130 4135 4131 4132 4133 4134 4136 /* needs to be posted to wakeup the internal menu handler */ 4137 /* which will now terminate the menu, in the event that */ 4138 /* the main window was minimized, or lost focus, so we */ 4139 /* don't end up with an orphaned menu */ 4135 4140 PostMessageA( top_popup, WM_CANCELMODE, 0, 0); 4136 4141 } … … 4152 4157 #ifndef __WIN32OS2__ 4153 4158 /********************************************************************** 4154 * 4159 * LoadMenu (USER.150) 4155 4160 */ 4156 4161 HMENU16 WINAPI LoadMenu16( HINSTANCE16 instance, LPCSTR name ) … … 4204 4209 4205 4210 /********************************************************************** 4206 * 4211 * LoadMenuIndirect (USER.220) 4207 4212 */ 4208 4213 HMENU16 WINAPI LoadMenuIndirect16( LPCVOID template ) … … 4233 4238 4234 4239 /********************************************************************** 4235 * 4240 * LoadMenuIndirectA (USER32.@) 4236 4241 */ 4237 4242 HMENU WINAPI LoadMenuIndirectA( LPCVOID template ) … … 4247 4252 { 4248 4253 case 0: 4249 4250 4251 4252 4253 4254 4255 4256 4257 4254 offset = GET_WORD(p); 4255 p += sizeof(WORD) + offset; 4256 if (!(hMenu = CreateMenu())) return 0; 4257 if (!MENU_ParseResource( p, hMenu, TRUE )) 4258 { 4259 DestroyMenu( hMenu ); 4260 return 0; 4261 } 4262 return hMenu; 4258 4263 case 1: 4259 4260 4261 4262 4263 4264 4265 4266 4267 4264 offset = GET_WORD(p); 4265 p += sizeof(WORD) + offset; 4266 if (!(hMenu = CreateMenu())) return 0; 4267 if (!MENUEX_ParseResource( p, hMenu)) 4268 { 4269 DestroyMenu( hMenu ); 4270 return 0; 4271 } 4272 return hMenu; 4268 4273 default: 4269 4274 ERR("version %d not supported.\n", version); … … 4274 4279 4275 4280 /********************************************************************** 4276 * 4281 * LoadMenuIndirectW (USER32.@) 4277 4282 */ 4278 4283 HMENU WINAPI LoadMenuIndirectW( LPCVOID template ) … … 4284 4289 4285 4290 /********************************************************************** 4286 * 4291 * IsMenu (USER32.@) 4287 4292 */ 4288 4293 BOOL WINAPI IsMenu(HMENU hmenu) … … 4293 4298 4294 4299 /********************************************************************** 4295 * 4300 * GetMenuItemInfo_common 4296 4301 */ 4297 4302 4298 4303 static BOOL GetMenuItemInfo_common ( HMENU hmenu, UINT item, BOOL bypos, 4299 4304 LPMENUITEMINFOW lpmii, BOOL unicode) 4300 4305 { 4301 4306 MENUITEM *menu = MENU_FindItem (&hmenu, &item, bypos? MF_BYPOSITION : 0); … … 4304 4309 4305 4310 if (!menu) 4306 4311 return FALSE; 4307 4312 4308 4313 if (lpmii->fMask & MIIM_TYPE) { 4309 4310 4311 4314 lpmii->fType = menu->fType; 4315 switch (MENU_ITEM_TYPE(menu->fType)) { 4316 case MF_STRING: 4312 4317 break; /* will be done below */ 4313 4314 4315 4316 4317 4318 4319 4318 case MF_OWNERDRAW: 4319 case MF_BITMAP: 4320 lpmii->dwTypeData = menu->text; 4321 /* fall through */ 4322 default: 4323 lpmii->cch = 0; 4324 } 4320 4325 } 4321 4326 … … 4337 4342 if (!WideCharToMultiByte( CP_ACP, 0, menu->text, -1, 4338 4343 (LPSTR)lpmii->dwTypeData, lpmii->cch, NULL, NULL )) 4344 #ifdef __WIN32OS2__ 4345 lstrtrunc((LPSTR)lpmii->dwTypeData, lpmii->cch ); 4346 #else 4339 4347 ((LPSTR)lpmii->dwTypeData)[lpmii->cch-1] = 0; 4348 #endif 4340 4349 } 4341 4350 /* if we've copied a substring we return its length */ … … 4349 4358 4350 4359 if (lpmii->fMask & MIIM_FTYPE) 4351 4360 lpmii->fType = menu->fType; 4352 4361 4353 4362 if (lpmii->fMask & MIIM_BITMAP) 4354 4363 lpmii->hbmpItem = menu->hbmpItem; 4355 4364 4356 4365 if (lpmii->fMask & MIIM_STATE) 4357 4366 lpmii->fState = menu->fState; 4358 4367 4359 4368 if (lpmii->fMask & MIIM_ID) 4360 4369 lpmii->wID = menu->wID; 4361 4370 4362 4371 if (lpmii->fMask & MIIM_SUBMENU) 4363 4372 lpmii->hSubMenu = menu->hSubMenu; 4364 4373 4365 4374 if (lpmii->fMask & MIIM_CHECKMARKS) { 4366 4367 4375 lpmii->hbmpChecked = menu->hCheckBit; 4376 lpmii->hbmpUnchecked = menu->hUnCheckBit; 4368 4377 } 4369 4378 if (lpmii->fMask & MIIM_DATA) 4370 4379 lpmii->dwItemData = menu->dwItemData; 4371 4380 4372 4381 return TRUE; … … 4374 4383 4375 4384 /********************************************************************** 4376 * 4385 * GetMenuItemInfoA (USER32.@) 4377 4386 */ 4378 4387 BOOL WINAPI GetMenuItemInfoA( HMENU hmenu, UINT item, BOOL bypos, … … 4384 4393 4385 4394 /********************************************************************** 4386 * 4395 * GetMenuItemInfoW (USER32.@) 4387 4396 */ 4388 4397 BOOL WINAPI GetMenuItemInfoW( HMENU hmenu, UINT item, BOOL bypos, … … 4418 4427 4419 4428 /********************************************************************** 4420 * 4429 * SetMenuItemInfo_common 4421 4430 */ 4422 4431 4423 4432 static BOOL SetMenuItemInfo_common(MENUITEM * menu, 4424 4425 4433 const MENUITEMINFOW *lpmii, 4434 BOOL unicode) 4426 4435 { 4427 4436 if (!menu) return FALSE; … … 4430 4439 4431 4440 if (lpmii->fMask & MIIM_TYPE ) { 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4441 /* Get rid of old string. */ 4442 if ( IS_STRING_ITEM(menu->fType) && menu->text) { 4443 HeapFree(GetProcessHeap(), 0, menu->text); 4444 menu->text = NULL; 4445 } 4446 4447 /* make only MENU_ITEM_TYPE bits in menu->fType equal lpmii->fType */ 4448 menu->fType &= ~MENU_ITEM_TYPE(menu->fType); 4449 menu->fType |= MENU_ITEM_TYPE(lpmii->fType); 4450 4451 menu->text = lpmii->dwTypeData; 4443 4452 4444 4453 if (IS_STRING_ITEM(menu->fType)) … … 4447 4456 4448 4457 if (lpmii->fMask & MIIM_FTYPE ) { 4449 4450 4451 4452 4453 4454 4455 4458 /* free the string when the type is changing */ 4459 if ( (!IS_STRING_ITEM(lpmii->fType)) && IS_STRING_ITEM(menu->fType) && menu->text) { 4460 HeapFree(GetProcessHeap(), 0, menu->text); 4461 menu->text = NULL; 4462 } 4463 menu->fType &= ~MENU_ITEM_TYPE(menu->fType); 4464 menu->fType |= MENU_ITEM_TYPE(lpmii->fType); 4456 4465 if ( IS_STRING_ITEM(menu->fType) && !menu->text ) 4457 4466 menu->fType |= MF_SEPARATOR; … … 4459 4468 4460 4469 if (lpmii->fMask & MIIM_STRING ) { 4461 4462 4463 4470 /* free the string when used */ 4471 if ( IS_STRING_ITEM(menu->fType) && menu->text) { 4472 HeapFree(GetProcessHeap(), 0, menu->text); 4464 4473 set_menu_item_text( menu, lpmii->dwTypeData, unicode ); 4465 4474 } 4466 4475 } 4467 4476 4468 4477 if (lpmii->fMask & MIIM_STATE) 4469 4478 { 4470 4471 4479 /* FIXME: MFS_DEFAULT do we have to reset the other menu items? */ 4480 menu->fState = lpmii->fState; 4472 4481 } 4473 4482 4474 4483 if (lpmii->fMask & MIIM_ID) 4475 4484 menu->wID = lpmii->wID; 4476 4485 4477 4486 if (lpmii->fMask & MIIM_SUBMENU) { 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4487 menu->hSubMenu = lpmii->hSubMenu; 4488 if (menu->hSubMenu) { 4489 POPUPMENU *subMenu = MENU_GetMenu((UINT16)menu->hSubMenu); 4490 if (subMenu) { 4491 subMenu->wFlags |= MF_POPUP; 4492 menu->fType |= MF_POPUP; 4493 } 4494 else 4495 /* FIXME: Return an error ? */ 4496 menu->fType &= ~MF_POPUP; 4497 } 4498 else 4499 menu->fType &= ~MF_POPUP; 4491 4500 } 4492 4501 … … 4496 4505 menu->fType |= MFT_RADIOCHECK; 4497 4506 4498 4499 4507 menu->hCheckBit = lpmii->hbmpChecked; 4508 menu->hUnCheckBit = lpmii->hbmpUnchecked; 4500 4509 } 4501 4510 if (lpmii->fMask & MIIM_DATA) 4502 4511 menu->dwItemData = lpmii->dwItemData; 4503 4512 4504 4513 debug_print_menuitem("SetMenuItemInfo_common to : ", menu, ""); … … 4507 4516 4508 4517 /********************************************************************** 4509 * 4518 * SetMenuItemInfoA (USER32.@) 4510 4519 */ 4511 4520 BOOL WINAPI SetMenuItemInfoA(HMENU hmenu, UINT item, BOOL bypos, … … 4513 4522 { 4514 4523 if ((lpmii->fType & (MF_HILITE|MF_POPUP)) || (lpmii->fState)) { 4515 4516 4517 4524 /* QuickTime does pass invalid data into SetMenuItemInfo. 4525 * do some of the checks Windows does. 4526 */ 4518 4527 WARN("Bad masks for type (0x%08x) or state (0x%08x)\n", 4519 4528 lpmii->fType,lpmii->fState ); 4520 4529 return FALSE; 4521 4530 } 4522 4531 4523 4532 return SetMenuItemInfo_common(MENU_FindItem(&hmenu, &item, bypos? MF_BYPOSITION : 0), 4524 4533 (const MENUITEMINFOW *)lpmii, FALSE); 4525 4534 } 4526 4535 4527 4536 /********************************************************************** 4528 * 4537 * SetMenuItemInfoW (USER32.@) 4529 4538 */ 4530 4539 BOOL WINAPI SetMenuItemInfoW(HMENU hmenu, UINT item, BOOL bypos, … … 4532 4541 { 4533 4542 return SetMenuItemInfo_common(MENU_FindItem(&hmenu, &item, bypos? MF_BYPOSITION : 0), 4534 4543 lpmii, TRUE); 4535 4544 } 4536 4545 4537 4546 /********************************************************************** 4538 * 4547 * SetMenuDefaultItem (USER32.@) 4539 4548 * 4540 4549 */ 4541 4550 BOOL WINAPI SetMenuDefaultItem(HMENU hmenu, UINT uItem, UINT bypos) 4542 4551 { 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4552 UINT i; 4553 POPUPMENU *menu; 4554 MENUITEM *item; 4555 4556 TRACE("(0x%x,%d,%d)\n", hmenu, uItem, bypos); 4557 4558 if (!(menu = MENU_GetMenu(hmenu))) return FALSE; 4559 4560 /* reset all default-item flags */ 4561 item = menu->items; 4562 for (i = 0; i < menu->nItems; i++, item++) 4563 { 4564 item->fState &= ~MFS_DEFAULT; 4565 } 4566 4567 /* no default item */ 4568 if ( -1 == uItem) 4569 { 4570 return TRUE; 4571 } 4572 4573 item = menu->items; 4574 if ( bypos ) 4575 { 4576 if ( uItem >= menu->nItems ) return FALSE; 4577 item[uItem].fState |= MFS_DEFAULT; 4578 return TRUE; 4579 } 4580 else 4581 { 4582 for (i = 0; i < menu->nItems; i++, item++) 4583 { 4584 if (item->wID == uItem) 4585 { 4586 item->fState |= MFS_DEFAULT; 4587 return TRUE; 4588 } 4589 } 4590 4591 } 4592 return FALSE; 4584 4593 } 4585 4594 4586 4595 /********************************************************************** 4587 * 4596 * GetMenuDefaultItem (USER32.@) 4588 4597 */ 4589 4598 UINT WINAPI GetMenuDefaultItem(HMENU hmenu, UINT bypos, UINT flags) 4590 4599 { 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4600 POPUPMENU *menu; 4601 MENUITEM * item; 4602 UINT i = 0; 4603 4604 TRACE("(0x%x,%d,%d)\n", hmenu, bypos, flags); 4605 4606 if (!(menu = MENU_GetMenu(hmenu))) return -1; 4607 4608 /* find default item */ 4609 item = menu->items; 4610 4611 /* empty menu */ 4612 if (! item) return -1; 4613 4614 while ( !( item->fState & MFS_DEFAULT ) ) 4615 { 4616 i++; item++; 4617 if (i >= menu->nItems ) return -1; 4618 } 4619 4620 /* default: don't return disabled items */ 4621 if ( (!(GMDI_USEDISABLED & flags)) && (item->fState & MFS_DISABLED )) return -1; 4622 4623 /* search rekursiv when needed */ 4624 if ( (item->fType & MF_POPUP) && (flags & GMDI_GOINTOPOPUPS) ) 4625 { 4626 UINT ret; 4627 ret = GetMenuDefaultItem( item->hSubMenu, bypos, flags ); 4628 if ( -1 != ret ) return ret; 4629 4630 /* when item not found in submenu, return the popup item */ 4631 } 4632 return ( bypos ) ? i : item->wID; 4624 4633 4625 4634 } … … 4627 4636 4628 4637 /********************************************************************** 4629 * 4638 * InsertMenuItemA (USER32.@) 4630 4639 */ 4631 4640 BOOL WINAPI InsertMenuItemA(HMENU hMenu, UINT uItem, BOOL bypos, … … 4638 4647 4639 4648 /********************************************************************** 4640 * 4649 * InsertMenuItemW (USER32.@) 4641 4650 */ 4642 4651 BOOL WINAPI InsertMenuItemW(HMENU hMenu, UINT uItem, BOOL bypos, … … 4648 4657 4649 4658 /********************************************************************** 4650 * 4659 * CheckMenuRadioItem (USER32.@) 4651 4660 */ 4652 4661 4653 4662 BOOL WINAPI CheckMenuRadioItem(HMENU hMenu, 4654 4655 4663 UINT first, UINT last, UINT check, 4664 UINT bypos) 4656 4665 { 4657 4666 MENUITEM *mifirst, *milast, *micheck; … … 4659 4668 4660 4669 TRACE("ox%x: %d-%d, check %d, bypos=%d\n", 4661 4670 hMenu, first, last, check, bypos); 4662 4671 4663 4672 mifirst = MENU_FindItem (&mfirst, &first, bypos); … … 4666 4675 4667 4676 if (mifirst == NULL || milast == NULL || micheck == NULL || 4668 4669 4670 4677 mifirst > milast || mfirst != mlast || mfirst != mcheck || 4678 micheck > milast || micheck < mifirst) 4679 return FALSE; 4671 4680 4672 4681 while (mifirst <= milast) 4673 4682 { 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 if (mifirst == micheck) 4684 { 4685 mifirst->fType |= MFT_RADIOCHECK; 4686 mifirst->fState |= MFS_CHECKED; 4687 } else { 4688 mifirst->fType &= ~MFT_RADIOCHECK; 4689 mifirst->fState &= ~MFS_CHECKED; 4690 } 4691 mifirst++; 4683 4692 } 4684 4693 … … 4687 4696 4688 4697 /********************************************************************** 4689 * 4698 * GetMenuItemRect (USER32.@) 4690 4699 * 4691 4700 * ATTENTION: Here, the returned values in rect are the screen … … 4695 4704 */ 4696 4705 BOOL WINAPI GetMenuItemRect (HWND hwnd, HMENU hMenu, UINT uItem, 4697 4706 LPRECT rect) 4698 4707 { 4699 4708 POPUPMENU *itemMenu; … … 4708 4717 if(!hwnd) 4709 4718 { 4710 4711 4712 4713 4714 4715 4716 4719 itemMenu = MENU_GetMenu(hMenu); 4720 if (itemMenu == NULL) 4721 return FALSE; 4722 4723 if(itemMenu->hWnd == 0) 4724 return FALSE; 4725 referenceHwnd = itemMenu->hWnd; 4717 4726 } 4718 4727 4719 4728 if ((rect == NULL) || (item == NULL)) 4720 4729 return FALSE; 4721 4730 4722 4731 *rect = item->rect; … … 4729 4738 4730 4739 /********************************************************************** 4731 * 4740 * SetMenuInfo (USER32.@) 4732 4741 * 4733 4742 * FIXME 4734 * 4735 * 4743 * MIM_APPLYTOSUBMENUS 4744 * actually use the items to draw the menu 4736 4745 */ 4737 4746 BOOL WINAPI SetMenuInfo (HMENU hMenu, LPCMENUINFO lpmi) … … 4744 4753 { 4745 4754 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4755 if (lpmi->fMask & MIM_BACKGROUND) 4756 menu->hbrBack = lpmi->hbrBack; 4757 4758 if (lpmi->fMask & MIM_HELPID) 4759 menu->dwContextHelpID = lpmi->dwContextHelpID; 4760 4761 if (lpmi->fMask & MIM_MAXHEIGHT) 4762 menu->cyMax = lpmi->cyMax; 4763 4764 if (lpmi->fMask & MIM_MENUDATA) 4765 menu->dwMenuData = lpmi->dwMenuData; 4766 4767 if (lpmi->fMask & MIM_STYLE) 4768 menu->dwStyle = lpmi->dwStyle; 4769 4770 return TRUE; 4762 4771 } 4763 4772 return FALSE; … … 4765 4774 4766 4775 /********************************************************************** 4767 * 4776 * GetMenuInfo (USER32.@) 4768 4777 * 4769 4778 * NOTES 4770 * 4779 * win98/NT5.0 4771 4780 * 4772 4781 */ … … 4779 4788 { 4780 4789 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4790 if (lpmi->fMask & MIM_BACKGROUND) 4791 lpmi->hbrBack = menu->hbrBack; 4792 4793 if (lpmi->fMask & MIM_HELPID) 4794 lpmi->dwContextHelpID = menu->dwContextHelpID; 4795 4796 if (lpmi->fMask & MIM_MAXHEIGHT) 4797 lpmi->cyMax = menu->cyMax; 4798 4799 if (lpmi->fMask & MIM_MENUDATA) 4800 lpmi->dwMenuData = menu->dwMenuData; 4801 4802 if (lpmi->fMask & MIM_STYLE) 4803 lpmi->dwStyle = menu->dwStyle; 4804 4805 return TRUE; 4797 4806 } 4798 4807 return FALSE; … … 4810 4819 if ((menu = MENU_GetMenu(hMenu))) 4811 4820 { 4812 4813 4821 menu->dwContextHelpID = dwContextHelpID; 4822 return TRUE; 4814 4823 } 4815 4824 return FALSE; … … 4827 4836 if ((menu = MENU_GetMenu(hMenu))) 4828 4837 { 4829 4838 return menu->dwContextHelpID; 4830 4839 } 4831 4840 return 0; … … 4847 4856 } 4848 4857 4849 #ifdef __WIN32OS2__ 4858 #ifdef __WIN32OS2__ 4850 4859 //****************************************************************************** 4851 4860 //****************************************************************************** … … 4853 4862 { 4854 4863 fDisableOdinSysMenuItems = TRUE; 4864 } 4865 /********************************************************************** 4866 * KBD_translate_accelerator 4867 * 4868 * FIXME: should send some WM_INITMENU or/and WM_INITMENUPOPUP -messages 4869 */ 4870 static BOOL KBD_translate_accelerator(HWND hWnd,LPMSG msg, 4871 BYTE fVirt,WORD key,WORD cmd) 4872 { 4873 BOOL sendmsg = FALSE; 4874 4875 if(msg->wParam == key) 4876 { 4877 if (msg->message == WM_CHAR) { 4878 if ( !(fVirt & FALT) && !(fVirt & FVIRTKEY) ) 4879 { 4880 dprintf(("TranslateAccelerator: found accel for WM_CHAR: ('%c')\n", msg->wParam&0xff)); 4881 sendmsg=TRUE; 4882 } 4883 } 4884 else 4885 { 4886 if(fVirt & FVIRTKEY) { 4887 INT mask = 0; 4888 if(GetKeyState(VK_SHIFT) & 0x8000) mask |= FSHIFT; 4889 if(GetKeyState(VK_CONTROL) & 0x8000) mask |= FCONTROL; 4890 if(GetKeyState(VK_MENU) & 0x8000) mask |= FALT; 4891 4892 if(mask == (fVirt & (FSHIFT | FCONTROL | FALT))) 4893 sendmsg=TRUE; 4894 else dprintf(("TranslateAccelerator: but incorrect SHIFT/CTRL/ALT-state %x != %x", mask, fVirt)); 4895 } 4896 else 4897 { 4898 if (!(msg->lParam & 0x01000000)) /* no special_key */ 4899 { 4900 if ((fVirt & FALT) && (msg->lParam & 0x20000000)) 4901 { /* ^^ ALT pressed */ 4902 dprintf(("TranslateAccelerator: found accel for Alt-%c\n", msg->wParam&0xff)); 4903 sendmsg=TRUE; 4904 } 4905 } 4906 } 4907 } 4908 4909 dprintf(("TranslateAccelerator: not match for %x %x %x", fVirt, key, cmd)); 4910 } 4911 4912 else if( key >= 1 && key <= 26 && !( fVirt & FVIRTKEY )) // Ctrl-A to Ctrl-Z 4913 { 4914 int ctrlCh; 4915 4916 if( msg->message == WM_CHAR ) 4917 ctrlCh = toupper( msg->wParam ) - 'A' + 1; 4918 else 4919 ctrlCh = msg->wParam - VK_A + 1; 4920 4921 if( ctrlCh == key ) 4922 { 4923 INT mask = 0; 4924 if(GetKeyState(VK_SHIFT) & 0x8000) mask |= FSHIFT; 4925 if(GetKeyState(VK_CONTROL) & 0x8000) mask |= FCONTROL; 4926 if(GetKeyState(VK_MENU) & 0x8000) mask |= FALT; 4927 4928 if(mask == FCONTROL) 4929 { 4930 sendmsg=TRUE; 4931 } 4932 } 4933 } 4934 4935 if (sendmsg) /* found an accelerator, but send a message... ? */ 4936 { 4937 INT iSysStat = -1,iStat = -1,mesg=0; 4938 HMENU hSysMenu, hMenu, hSubMenu; 4939 UINT nPos; 4940 4941 if (msg->message == WM_KEYUP || msg->message == WM_SYSKEYUP) { 4942 mesg=1; 4943 } 4944 else 4945 if (GetCapture()) 4946 mesg=2; 4947 else 4948 if (!IsWindowEnabled(hWnd)) 4949 mesg=3; 4950 else 4951 { 4952 hMenu = (GetWindowLongA(hWnd, GWL_STYLE) & WS_CHILD) ? NULL : GetMenu(hWnd); 4953 hSysMenu = getSysMenu(hWnd); 4954 4955 hSubMenu = hSysMenu; 4956 nPos = cmd; 4957 if(MENU_FindItem(&hSubMenu, &nPos, MF_BYCOMMAND)) 4958 { 4959 SendMessageA(hWnd, WM_INITMENU, (WPARAM)hSysMenu, 0L); 4960 if(hSubMenu != hSysMenu) 4961 { 4962 nPos = MENU_FindSubMenu(&hSysMenu, hSubMenu); 4963 dprintf(("hSysMenu = %04x, hSubMenu = %04x, nPos = %d\n", hSysMenu, hSubMenu, nPos)); 4964 SendMessageA(hWnd, WM_INITMENUPOPUP, (WPARAM)hSubMenu, MAKELPARAM(nPos, TRUE)); 4965 } 4966 iSysStat = GetMenuState(GetSubMenu(hSysMenu, 0), cmd, MF_BYCOMMAND); 4967 } 4968 else 4969 { 4970 hSubMenu = hMenu; 4971 nPos = cmd; 4972 if(MENU_FindItem(&hSubMenu, &nPos, MF_BYCOMMAND)) 4973 { 4974 SendMessageA(hWnd, WM_INITMENU, (WPARAM)hMenu, 0L); 4975 if(hSubMenu != hMenu) 4976 { 4977 nPos = MENU_FindSubMenu(&hMenu, hSubMenu); 4978 dprintf(("hMenu = %04x, hSubMenu = %04x, nPos = %d\n", hMenu, hSubMenu, nPos)); 4979 SendMessageA(hWnd, WM_INITMENUPOPUP, (WPARAM)hSubMenu, MAKELPARAM(nPos, FALSE)); 4980 } 4981 iStat = GetMenuState(hMenu, cmd, MF_BYCOMMAND); 4982 } 4983 } 4984 4985 if (iSysStat!=-1) 4986 { 4987 if (iSysStat & (MF_DISABLED|MF_GRAYED)) 4988 mesg=4; 4989 else 4990 mesg=WM_SYSCOMMAND; 4991 } 4992 else 4993 { 4994 if (iStat!=-1) 4995 { 4996 if (IsIconic(hWnd)) { 4997 mesg=5; 4998 } 4999 else 5000 { 5001 if (iStat & (MF_DISABLED|MF_GRAYED)) 5002 mesg=6; 5003 else 5004 mesg=WM_COMMAND; 5005 } 5006 } 5007 else 5008 mesg=WM_COMMAND; 5009 } 5010 } 5011 if ( mesg==WM_COMMAND ) 5012 SendMessageA(hWnd, mesg, MAKEWPARAM( cmd, 1 ), NULL); 5013 else if( mesg==WM_SYSCOMMAND ) 5014 SendMessageA( hWnd, mesg, cmd, MAKELPARAM( 0, 1 )); 5015 else 5016 { 5017 /* some reasons for NOT sending the WM_{SYS}COMMAND message: 5018 * #0: unknown (please report!) 5019 * #1: for WM_KEYUP,WM_SYSKEYUP 5020 * #2: mouse is captured 5021 * #3: window is disabled 5022 * #4: it's a disabled system menu option 5023 * #5: it's a menu option, but window is iconic 5024 * #6: it's a menu option, but disabled 5025 */ 5026 if(mesg==0) 5027 dprintf(("ERROR: unknown reason - please report!")); 5028 else dprintf(("but won't send WM_{SYS}COMMAND, reason is #%d\n",mesg)); 5029 5030 } 5031 return TRUE; 5032 } 5033 5034 return FALSE; 5035 } 5036 /***************************************************************************** 5037 * Name : int WIN32API TranslateAcceleratorA 5038 * Purpose : Translate WM_*KEYDOWN messages to WM_COMMAND messages 5039 * according to Accelerator table 5040 * Parameters: HWND hwnd, HACCEL haccel, LPMSG lpmsg 5041 * Variables : 5042 * Result : int FALSE (no accelerator found) TRUE (accelerator found) 5043 * Remark : if a accelerator is found it is not neccesarely executed 5044 * depends on window stat 5045 * 5046 *****************************************************************************/ 5047 INT WINAPI TranslateAcceleratorA(HWND hWnd, HACCEL hAccel, LPMSG msg) 5048 { 5049 /* YES, Accel16! */ 5050 LPACCEL lpAccelTbl; 5051 int i; 5052 5053 SetLastError(ERROR_SUCCESS); 5054 if (msg == NULL) 5055 { 5056 dprintf(("TranslateAcceleratorAmsg null; should hang here to be win compatible")); 5057 SetLastError(ERROR_INVALID_PARAMETER); 5058 return 0; 5059 } 5060 if (!hAccel || !(lpAccelTbl = (LPACCEL)GlobalLock(hAccel))) 5061 { 5062 dprintf(("TranslateAcceleratorA: invalid accel handle=%x", hAccel)); 5063 SetLastError(ERROR_INVALID_PARAMETER); 5064 return 0; 5065 } 5066 if(!IsWindow(hWnd)) { 5067 dprintf(("TranslateAccelerator, window %x not found", hWnd)); 5068 SetLastError(ERROR_INVALID_WINDOW_HANDLE); 5069 return 0; 5070 } 5071 if ((msg->message != WM_KEYDOWN && 5072 msg->message != WM_KEYUP && 5073 msg->message != WM_SYSKEYDOWN && 5074 msg->message != WM_SYSKEYUP && 5075 msg->message != WM_CHAR)) 5076 { 5077 return 0; 5078 } 5079 5080 /* TRACE_(accel)("TranslateAccelerators hAccel=%04x, hWnd=%04x," 5081 "msg->hwnd=%04x, msg->message=%04x, wParam=%08x, lParam=%lx\n", 5082 hAccel,hWnd,msg->hwnd,msg->message,msg->wParam,msg->lParam); */ 5083 5084 i = 0; 5085 do 5086 { 5087 if (KBD_translate_accelerator(hWnd,msg,lpAccelTbl[i].fVirt, 5088 lpAccelTbl[i].key,lpAccelTbl[i].cmd)) 5089 { 5090 return 1; 5091 } 5092 } 5093 while ((lpAccelTbl[i++].fVirt & 0x80) == 0); 5094 5095 // WARN_(accel)("couldn't translate accelerator key\n"); 5096 return 0; 4855 5097 } 4856 5098 //****************************************************************************** … … 5046 5288 } 5047 5289 #endif 5290 5291
Note:
See TracChangeset
for help on using the changeset viewer.