- Timestamp:
- Jul 31, 2003, 5:58:58 PM (22 years ago)
- Location:
- trunk/src/user32
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/user32/dbgwrap.cpp
r9701 r10190 312 312 DEBUGWRAP8(GetMenuInfo) 313 313 DEBUGWRAP8(SetMenuInfo) 314 DEBUGWRAP_LVL2_12(TranslateAcceleratorA) 314 315 315 316 #undef DBG_LOCALLOG … … 448 449 449 450 #undef DBG_LOCALLOG 450 #define DBG_LOCALLOG 451 #define DBG_LOCALLOG DBG_display 451 452 DEBUGWRAP8(GetMonitorInfoW) 452 453 DEBUGWRAP8(GetMonitorInfoA) … … 479 480 480 481 #undef DBG_LOCALLOG 481 #define DBG_LOCALLOG 482 #define DBG_LOCALLOG DBG_hook 482 483 DEBUGWRAP16(CallNextHookEx) 483 484 DEBUGWRAP8(SetWindowsHookA) … … 489 490 490 491 #undef DBG_LOCALLOG 491 #define DBG_LOCALLOG 492 #define DBG_LOCALLOG DBG_windowmsg 492 493 DEBUGWRAP20(MsgWaitForMultipleObjects) 493 494 DEBUGWRAP20(BroadcastSystemMessage) … … 547 548 548 549 #undef DBG_LOCALLOG 549 #define DBG_LOCALLOG 550 #define DBG_LOCALLOG DBG_defwndproc 550 551 551 552 DEBUGWRAP_LVL2_16(DefDlgProcA) … … 560 561 561 562 #undef DBG_LOCALLOG 562 #define DBG_LOCALLOG 563 #define DBG_LOCALLOG DBG_windlg 563 564 DEBUGWRAP16(SetDlgItemInt) 564 565 DEBUGWRAP12(SetDlgItemTextA) … … 609 610 610 611 #undef DBG_LOCALLOG 611 #define DBG_LOCALLOG 612 #define DBG_LOCALLOG DBG_winmouse 612 613 DEBUGWRAP4(GetCursorPos) 613 614 DEBUGWRAP8(SetCursorPos) … … 623 624 624 625 #undef DBG_LOCALLOG 625 #define DBG_LOCALLOG 626 #define DBG_LOCALLOG DBG_caret 626 627 DEBUGWRAP16(CreateCaret) 627 628 DEBUGWRAP0(DestroyCaret) … … 662 663 663 664 #undef DBG_LOCALLOG 664 #define DBG_LOCALLOG 665 #define DBG_LOCALLOG DBG_timer 665 666 DEBUGWRAP8(KillTimer) 666 667 DEBUGWRAP16(SetTimer) … … 784 785 DEBUGWRAP8(CreateAcceleratorTableW) 785 786 DEBUGWRAP4(DestroyAcceleratorTable) 786 DEBUGWRAP12(TranslateAcceleratorA)787 787 DEBUGWRAP8(TranslateMDISysAccel) 788 788 DEBUGWRAP8(LoadAcceleratorsA) -
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 -
trunk/src/user32/msgbox.c
r10076 r10190 1 /* $Id: msgbox.c,v 1. 7 2003-05-06 13:50:36sandervl Exp $ */1 /* $Id: msgbox.c,v 1.8 2003-07-31 15:56:43 sandervl Exp $ */ 2 2 /* 3 3 * Message boxes (based on Wine code) … … 360 360 { 361 361 MSGBOXPARAMSA msgboxa; 362 #ifdef __WIN32OS2__ 363 int ret; 364 #endif 362 365 363 366 memcpy(&msgboxa,msgbox,sizeof(msgboxa)); 367 #ifdef __WIN32OS2__ 368 if (msgbox->lpszCaption) 369 msgboxa.lpszCaption = HEAP_strdupWtoA( GetProcessHeap(), 0, msgbox->lpszCaption ); 370 if (msgbox->lpszText) 371 msgboxa.lpszText = HEAP_strdupWtoA( GetProcessHeap(), 0, msgbox->lpszText ); 372 if( msgbox->lpszIcon && HIWORD( msgbox->lpszIcon )) 373 msgboxa.lpszIcon = HEAP_strdupWtoA( GetProcessHeap(), 0, msgbox->lpszIcon ); 374 375 ret = MessageBoxIndirectA(&msgboxa); 376 377 if (msgbox->lpszCaption) 378 HeapFree( GetProcessHeap(), 0, ( LPVOID )msgboxa.lpszCaption ); 379 if (msgbox->lpszText) 380 HeapFree( GetProcessHeap(), 0, ( LPVOID )msgboxa.lpszText ); 381 if( msgbox->lpszIcon && HIWORD( msgbox->lpszIcon )) 382 HeapFree( GetProcessHeap(), 0, ( LPVOID )msgboxa.lpszIcon ); 383 384 return ret; 385 #else 364 386 if (msgbox->lpszCaption) 365 387 lstrcpyWtoA((LPSTR)msgboxa.lpszCaption,msgbox->lpszCaption); … … 368 390 369 391 return MessageBoxIndirectA(&msgboxa); 392 #endif 393 370 394 } 371 395 -
trunk/src/user32/oslibmsg.cpp
r10185 r10190 1 /* $Id: oslibmsg.cpp,v 1.7 1 2003-07-28 11:27:45sandervl Exp $ */1 /* $Id: oslibmsg.cpp,v 1.72 2003-07-31 15:56:43 sandervl Exp $ */ 2 2 /* 3 3 * Window message translation functions for OS/2 … … 226 226 else {//is this allowed? 227 227 // dprintf(("WARNING: OSLibWinDispatchMsg: called with own message!")); 228 return SendMessageA(msg->hwnd, msg->message, msg->wParam, msg->lParam); 228 return isUnicode ? SendMessageW(msg->hwnd, msg->message, msg->wParam, msg->lParam) : 229 SendMessageA(msg->hwnd, msg->message, msg->wParam, msg->lParam); 229 230 } 230 231 } -
trunk/src/user32/oslibmsgtranslate.cpp
r10189 r10190 1 /* $Id: oslibmsgtranslate.cpp,v 1.11 2 2003-07-31 12:25:57sandervl Exp $ */1 /* $Id: oslibmsgtranslate.cpp,v 1.113 2003-07-31 15:56:44 sandervl Exp $ */ 2 2 /* 3 3 * Window message translation functions for OS/2 … … 38 38 #include <winkeyboard.h> 39 39 #include <winnls.h> 40 #include <heapstring.h> 40 41 #include "hook.h" 41 42 #include "user32api.h" … … 732 733 WORD wWinScan; 733 734 734 if (scanCode==0) goto dummymessage; 735 736 KeyTranslatePMScanToWinVKey(usPMScanCode, 737 FALSE, 738 &bWinVKey, 739 &wWinScan, 740 &fWinExtended); 741 winMsg->wParam = bWinVKey; 735 if ( (!IsDBCSEnv() && scanCode == 0) || 736 (scanCode==0 ) && !( flags & KC_CHAR ) ) 737 { 738 goto dummymessage; 739 } 740 741 if( scanCode != 0 ) 742 { 743 KeyTranslatePMScanToWinVKey(usPMScanCode, 744 FALSE, 745 &bWinVKey, 746 &wWinScan, 747 &fWinExtended); 748 winMsg->wParam = bWinVKey; 749 } 750 else 751 { 752 dprintf(("PM: WM_CHAR: DBCS processing ")); 753 754 winMsg->wParam = CHAR1FROMMP( os2Msg->mp2 ); 755 756 wWinScan = 0; 757 fWinExtended = 0; 758 759 if( CHAR2FROMMP( os2Msg->mp2 )) // DBCS character 760 { 761 if( isUnicode ) 762 { 763 char dbcsCh[] = { CHAR1FROMMP( os2Msg->mp2 ), CHAR2FROMMP( os2Msg->mp2 ), 0 }; 764 WCHAR uniChar[ 2 ]; 765 766 lstrcpynAtoW(( LPWSTR )&uniChar, ( LPCSTR )&dbcsCh, 2 ); 767 winMsg->wParam = ( WPARAM )uniChar[ 0 ]; 768 } 769 // insert DBCS trail byte for Non-Unicode window 770 else if(fMsgRemoved && !(teb->o.odin.fTranslated)) 771 { 772 MSG extramsg; 773 memcpy(&extramsg, winMsg, sizeof(MSG)); 774 775 //After SetFocus(0), all keystrokes are converted in WM_SYS* 776 extramsg.message = (fIgnoreKeystrokes) ? WINWM_SYSCHAR : WINWM_CHAR; 777 778 extramsg.wParam = CHAR2FROMMP( os2Msg->mp2 ); 779 extramsg.lParam = 0; 780 781 setThreadQueueExtraCharMessage(teb, &extramsg); 782 } 783 } 784 } 742 785 winMsg->lParam = repeatCount & 0x0FFFF; // bit 0-15, repeatcount 743 786 winMsg->lParam |= (wWinScan & 0x1FF) << 16; // bit 16-23, scancode + bit 15 extended … … 797 840 winMsg->lParam |= WIN_KEY_PREVSTATE; // bit 30, previous state, always 1 for a WM_KEYUP message 798 841 winMsg->lParam |= 1 << 31; // bit 31, transition state, always 1 for WM_KEYUP 842 } 843 else if( scanCode == 0 ) 844 { 845 //After SetFocus(0), all keystrokes are converted in WM_SYS* 846 winMsg->message = (fIgnoreKeystrokes) ? WINWM_SYSCHAR : WINWM_CHAR; 799 847 } 800 848 else -
trunk/src/user32/pmwindow.cpp
r10185 r10190 1 /* $Id: pmwindow.cpp,v 1.21 7 2003-07-28 11:27:47sandervl Exp $ */1 /* $Id: pmwindow.cpp,v 1.218 2003-07-31 15:56:44 sandervl Exp $ */ 2 2 /* 3 3 * Win32 Window Managment Code for OS/2 … … 514 514 // - thread must not be suspended in WaitMessage 515 515 if(!teb || (msg != WM_CREATE && win32wnd == NULL) || teb->o.odin.fWaitMessageSuspend) { 516 if(teb ->o.odin.fWaitMessageSuspend)516 if(teb && teb->o.odin.fWaitMessageSuspend) 517 517 dprintf(("OS2: fWaitMessageSuspend window %x msg %x -> run default frame proc", hwnd, msg)); 518 518 else dprintf(("OS2: Invalid win32wnd pointer for window %x msg %x", hwnd, msg)); … … 1182 1182 // - thread must not be suspended in WaitMessage 1183 1183 if(!teb || (msg != WM_CREATE && win32wnd == NULL) || teb->o.odin.fWaitMessageSuspend) { 1184 if(teb ->o.odin.fWaitMessageSuspend)1184 if(teb && teb->o.odin.fWaitMessageSuspend) 1185 1185 dprintf(("PMFRAME: fWaitMessageSuspend window %x msg %x -> run default frame proc", hwnd, msg)); 1186 1186 else dprintf(("PMFRAME: Invalid win32wnd pointer for window %x msg %x", hwnd, msg)); -
trunk/src/user32/resources/user32_Ko.orc
r9491 r10190 7 7 MENUITEM "Å©±â º¯°æ(&S)", 61440 8 8 MENUITEM "ŸÆÀÌÄÜ Ç¥œÃ(&N)", 61472 9 MENUITEM "ÀüÃŒ Èžé Ç¥œÃ(& M)", 614889 MENUITEM "ÀüÃŒ Èžé Ç¥œÃ(&F)", 61488 10 10 MENUITEM SEPARATOR 11 11 MENUITEM "ŽÝ±â(&C)\tAlt-F4", 61536 … … 16 16 SYSMENUWARP MENU LOADONCALL MOVEABLE DISCARDABLE 17 17 { 18 MENUITEM "º¹ Í(&R)\tAlt-F5", 6172819 MENUITEM "ÀÌ ¿(&M)\tAlt-F7", 6145620 MENUITEM "Å â º¯°æ(&S)\tAlt-F8", 6144021 MENUITEM " ÆÀÌÄÜ ÇÃ(&N)\tAlt-F9", 6147222 MENUITEM "Àüà Ȟé ÇÃ(&M)\tAlt-F10", 6148818 MENUITEM "º¹±Í(&R)\tAlt-F5", 61728 19 MENUITEM "À̵¿(&M)\tAlt-F7", 61456 20 MENUITEM "Å©±â º¯°æ(&S)\tAlt-F8", 61440 21 MENUITEM "ŸÆÀÌÄÜ Ç¥œÃ(&N)\tAlt-F9", 61472 22 MENUITEM "ÀüÃŒ Èžé Ç¥œÃ(&F)\tAlt-F10", 61488 23 23 MENUITEM SEPARATOR 24 MENUITEM " Ýâ(&C)\tAlt-F4", 6153624 MENUITEM "ŽÝ±â(&C)\tAlt-F4", 61536 25 25 MENUITEM SEPARATOR 26 MENUITEM "ÀÛ ÷ Àüȯ(&W) ...\tCtrl-Esc", 6174426 MENUITEM "ÀÛŸ÷ Àüȯ(&W) ...\tCtrl-Esc", 61744 27 27 } 28 28 -
trunk/src/user32/win32wbase.cpp
r10134 r10190 1 /* $Id: win32wbase.cpp,v 1.37 5 2003-06-03 09:51:05 sandervl Exp $ */1 /* $Id: win32wbase.cpp,v 1.376 2003-07-31 15:56:45 sandervl Exp $ */ 2 2 /* 3 3 * Win32 Window Base Class for OS/2 … … 86 86 //****************************************************************************** 87 87 //****************************************************************************** 88 Win32BaseWindow::Win32BaseWindow() 88 Win32BaseWindow::Win32BaseWindow() 89 89 : GenericObject(&windows, &critsect), ChildWindow(&critsect) 90 90 { … … 126 126 windowNameA = NULL; 127 127 windowNameW = NULL; 128 windowNameLength = 0; 129 128 windowNameLengthA = 0; 129 windowNameLengthW = 0; 130 130 131 userWindowBytes = NULL;; 131 132 nrUserWindowBytes= 0; … … 228 229 { 229 230 //if we're the last child that's being destroyed and our 230 //parent window was also destroyed, then we 231 //parent window was also destroyed, then we 231 232 if(getParent()->IsWindowDestroyed()) 232 233 { … … 236 237 } 237 238 } 238 else 239 else 239 240 { 240 241 Win32BaseWindow *wndparent = (Win32BaseWindow *)ChildWindow::getParentOfChild(); … … 340 341 } 341 342 if (window->getExStyle() & WS_EX_TOPMOST) 342 cs->dwExStyle |= WS_EX_TOPMOST; 343 cs->dwExStyle |= WS_EX_TOPMOST; 343 344 344 345 RELEASE_WNDOBJ(window); … … 389 390 cs->lpszClass = buffer; 390 391 } 391 392 392 /* Fix the coordinates */ 393 393 fXDefault = FALSE; … … 446 446 RELEASE_WNDOBJ(wndparent); 447 447 } 448 else owner = NULL; 448 else owner = NULL; 449 449 450 450 if(owner == NULL) … … 582 582 vertScrollInfo->flags = ESB_ENABLE_BOTH; 583 583 } 584 584 585 585 // initially allocate the window name fields 586 586 if(HIWORD(cs->lpszName)) … … 588 588 if (!isUnicode) 589 589 { 590 windowNameLength = strlen(cs->lpszName);591 windowNameA = (LPSTR)_smalloc(windowNameLength +1);592 memcpy(windowNameA,cs->lpszName,windowNameLength+1);593 windowNameW = (LPWSTR)_smalloc((windowNameLength+1)*sizeof(WCHAR)); 594 lstrcpynAtoW(windowNameW,windowNameA,windowNameLength+1);595 windowName A[windowNameLength] = 0;596 windowNameW[windowNameLength] = 0;590 windowNameLengthA = strlen(cs->lpszName); 591 windowNameA = (LPSTR)_smalloc(windowNameLengthA+1); 592 strcpy(windowNameA,cs->lpszName); 593 594 windowNameLengthW = lstrlenAtoW( windowNameA, -1 ); 595 windowNameW = (LPWSTR)_smalloc(( windowNameLengthW + 1 ) * sizeof( WCHAR ) ); 596 lstrcpyAtoW( windowNameW, windowNameA ); 597 597 } 598 598 else 599 599 { 600 600 // Wide 601 windowNameLength = lstrlenW((LPWSTR)cs->lpszName);602 windowNameW = (LPWSTR)_smalloc( (windowNameLength+1)*sizeof(WCHAR));603 memcpy(windowNameW,(LPWSTR)cs->lpszName, (windowNameLength+1)*sizeof(WCHAR));604 601 windowNameLengthW = lstrlenW((LPWSTR)cs->lpszName); 602 windowNameW = (LPWSTR)_smalloc((windowNameLengthW+1)*sizeof(WCHAR)); 603 strcpyW(windowNameW,(LPWSTR)cs->lpszName); 604 605 605 // windowNameW[lstrlenW((LPWSTR)cs->lpszName)] = 0; // need ? 606 606 607 607 // Ascii 608 windowNameA = (LPSTR)_smalloc(windowNameLength+1); 609 WideCharToMultiByte(CP_ACP, 610 0, 611 windowNameW, 612 windowNameLength, 613 windowNameA, 614 windowNameLength + 1, 615 0, 616 NULL); 617 windowNameA[windowNameLength] = 0; 618 } 619 608 windowNameLengthA = lstrlenWtoA( windowNameW, -1 ); 609 windowNameA = (LPSTR)_smalloc( windowNameLengthA + 1 ); 610 lstrcpyWtoA( windowNameA, windowNameW ); 611 } 612 613 dprintf(("windowNameA 0x%lx to 0x%lx windowNameW : 0x%lx to 0x%lx", 614 windowNameA, windowNameA + windowNameLengthA, 615 windowNameW, windowNameW + windowNameLengthW )); 616 620 617 if(fOS2Look) { 621 618 OSLibWinSetTitleBarText(OS2HwndFrame, windowNameA); … … 752 749 //@@PF Popup children of inactive windows can thus bring inactive window 753 750 //on top, this is not correct, popup windows can be on top only if their owner 754 //is in foreground, otherwise they are linked after owner. 751 //is in foreground, otherwise they are linked after owner. 755 752 if (((dwStyle & (WS_CHILD|WS_POPUP)) == WS_POPUP) && getOwner() && (getOwner()->getWindowHandle() != GetForegroundWindow())) 756 753 { … … 1066 1063 1067 1064 dprintf(("MsgButton %d at (%d,%d)", msg->message, msg->pt.x, msg->pt.y)); 1068 switch(msg->message) 1065 switch(msg->message) 1069 1066 { 1070 1067 case WM_LBUTTONDBLCLK: … … 1132 1129 SendMessageA(getWindowHandle(),WM_SETCURSOR, getWindowHandle(), MAKELONG(lastHitTestVal, msg->message)); 1133 1130 1134 switch(msg->message) 1131 switch(msg->message) 1135 1132 { 1136 1133 case WM_LBUTTONDOWN: … … 1155 1152 } 1156 1153 //****************************************************************************** 1157 // 1154 // 1158 1155 // Win32BaseWindow::saveAndValidateUpdateRegion 1159 1156 // 1160 // If an application doesn't validate the update region while processing 1157 // If an application doesn't validate the update region while processing 1161 1158 // WM_PAINT, then we must remember it for the next time. Also validates 1162 1159 // the current update region. … … 1192 1189 } 1193 1190 //****************************************************************************** 1194 // 1191 // 1195 1192 // Win32BaseWindow::checkForDirtyUpdateRegion 1196 1193 // 1197 // If an application doesn't validate the update region while processing 1194 // If an application doesn't validate the update region while processing 1198 1195 // WM_PAINT, then we must remember it for the next time. If the window has 1199 1196 // a dirty update region, then invalidate that region. … … 1250 1247 ULONG Win32BaseWindow::MsgChar(MSG *msg) 1251 1248 { 1252 return DispatchMsgA(msg);1249 return IsWindowUnicode() ? DispatchMsgW( msg ) : DispatchMsgA( msg ); 1253 1250 } 1254 1251 //****************************************************************************** … … 1276 1273 //Send WM_PAINTICON here if minimized, because client window will 1277 1274 //not receive a (valid) WM_PAINT message 1278 if (getStyle() & WS_MINIMIZE) 1275 if (getStyle() & WS_MINIMIZE) 1279 1276 { 1280 1277 rc = SendMessageA(getWindowHandle(),WM_PAINTICON, 1, 0); … … 1347 1344 #endif 1348 1345 //WS_EX_TOOLWINDOW is incompatible with the OS2Look (titlebar thinner + smaller font) 1349 if(fOS2Look && ((dwStyle & WS_CAPTION) == WS_CAPTION) && !(dwExStyle & WS_EX_TOOLWINDOW)) 1346 if(fOS2Look && ((dwStyle & WS_CAPTION) == WS_CAPTION) && !(dwExStyle & WS_EX_TOOLWINDOW)) 1350 1347 { 1351 1348 RECT rect = {0}; … … 1362 1359 rect.top = rect.bottom - rect.top; 1363 1360 rect.right = rectWindow.right - rectWindow.left - rect.right; 1364 1361 1365 1362 rectOS2.xLeft = rect.left; 1366 1363 rectOS2.xRight = rect.right; … … 1368 1365 rectOS2.yTop = height - rect.bottom; 1369 1366 1370 //@@PF Disable close button as well when needed by application 1367 //@@PF Disable close button as well when needed by application 1371 1368 OSLibChangeCloseButtonState(getOS2FrameWindowHandle(), fCloseButton); 1372 1369 OSLibWinPositionFrameControls(getOS2FrameWindowHandle(), &rectOS2, 1373 1370 dwStyle, dwExStyle, IconForWindow(ICON_SMALL), 1374 1371 fCloseButton, windowClass->getIcon() != NULL); 1375 1372 } 1376 1373 return rc; … … 1562 1559 1563 1560 case WM_GETTEXTLENGTH: 1564 return windowNameLength ;1561 return windowNameLengthA; 1565 1562 1566 1563 case WM_GETTEXT: 1567 if (!lParam || !wParam) 1564 if (!lParam || !wParam) 1568 1565 return 0; 1569 if (!windowNameA) 1566 if (!windowNameA) 1570 1567 ((LPSTR)lParam)[0] = 0; 1571 else 1572 memcpy((LPSTR)lParam, windowNameA, min(windowNameLength+1, wParam));1573 return min(windowNameLength, wParam);1568 else 1569 lstrcpynA(( LPSTR )lParam, windowNameA, wParam ); 1570 return strlen(( LPSTR )lParam ); 1574 1571 1575 1572 case WM_SETTEXT: 1576 1573 { 1577 1574 LPCSTR lpsz = (LPCSTR)lParam; 1578 1575 1579 1576 // reallocate if new buffer is larger 1580 1577 if (!lParam) … … 1582 1579 free(windowNameA); 1583 1580 free(windowNameW); 1584 windowNameLength = 0; 1581 windowNameLengthA = 0; 1582 windowNameLengthW = 0; 1585 1583 windowNameA = NULL; 1586 1584 windowNameW = NULL; … … 1590 1588 // determine length of new text 1591 1589 int iTextLength = strlen(lpsz); 1592 1593 if (windowNameLength < iTextLength)1590 1591 if (windowNameLengthA < iTextLength) 1594 1592 { 1595 1593 if (windowNameA) … … 1598 1596 windowNameA = NULL; 1599 1597 } 1600 1598 1601 1599 if (windowNameW) 1602 1600 { … … 1605 1603 } 1606 1604 } 1607 1608 windowNameLength = iTextLength;1605 1606 windowNameLengthA = iTextLength; 1609 1607 if(!windowNameA) 1610 windowNameA = (LPSTR)_smalloc(windowNameLength+1); 1611 memcpy(windowNameA, lpsz, windowNameLength+1); 1608 windowNameA = (LPSTR)_smalloc(windowNameLengthA+1); 1609 strcpy(windowNameA, lpsz); 1610 windowNameLengthW = lstrlenAtoW( windowNameA, -1 ); 1612 1611 if(!windowNameW) 1613 windowNameW = (LPWSTR)_smalloc(( windowNameLength+1)*sizeof(WCHAR));1614 lstrcpy nAtoW(windowNameW, windowNameA, windowNameLength+1);1615 } 1616 1612 windowNameW = (LPWSTR)_smalloc(( windowNameLengthW + 1 )*sizeof(WCHAR)); 1613 lstrcpyAtoW( windowNameW, windowNameA ); 1614 } 1615 1617 1616 dprintf(("WM_SETTEXT of %x to %s\n", Win32Hwnd, lParam)); 1618 1617 if ((dwStyle & WS_CAPTION) == WS_CAPTION) … … 1675 1674 dprintf(("DefWndProc: WM_MOUSEACTIVATE for %x Msg %s", Win32Hwnd, GetMsgText(HIWORD(lParam)))); 1676 1675 if (::GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD) 1677 1678 1679 1680 1681 1682 1676 { 1677 LONG ret = ::SendMessageW( ::GetParent(hwnd), WM_MOUSEACTIVATE, wParam, lParam ); 1678 if (ret) return ret; 1679 } 1680 1681 /* Caption clicks are handled by the NC_HandleNCLButtonDown() */ 1683 1682 return (LOWORD(lParam) >= HTCLIENT) ? MA_ACTIVATE : MA_NOACTIVATE; 1684 1683 } … … 1754 1753 if (::GetWindowLongA( getWindowHandle(), GWL_STYLE ) & WS_CHILD) 1755 1754 return ::SendMessageA( ::GetParent(getWindowHandle()), WM_MOUSEWHEEL, wParam, lParam ); 1756 1755 break; 1757 1756 1758 1757 case WM_WINDOWPOSCHANGED: … … 1789 1788 RECT rect; 1790 1789 int rc; 1791 1792 if (!windowClass || (!windowClass->getBackgroundBrush() 1790 1791 if (!windowClass || (!windowClass->getBackgroundBrush() 1793 1792 && !(getStyle() & WS_MINIMIZE))) return 0; 1794 1793 … … 1804 1803 hBrush = GetSysColorBrush(hBrush-1); 1805 1804 } 1806 1805 1807 1806 1808 1807 rc = GetClipBox( (HDC)wParam, &rect ); … … 1905 1904 1906 1905 case WM_KEYDOWN: 1907 1908 1906 if(wParam == VK_F10) iF10Key = VK_F10; 1907 break; 1909 1908 1910 1909 case WM_SYSKEYDOWN: 1911 1910 { 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 if( wParam == VK_F4 )/* try to close the window */1923 1911 if( HIWORD(lParam) & KEYDATA_ALT ) 1912 { 1913 /* if( HIWORD(lParam) & ~KEYDATA_PREVSTATE ) */ 1914 if( wParam == VK_MENU && !iMenuSysKey ) 1915 iMenuSysKey = 1; 1916 else 1917 iMenuSysKey = 0; 1918 1919 iF10Key = 0; 1920 1921 if( wParam == VK_F4 ) /* try to close the window */ 1922 { 1924 1923 HWND top = GetTopParent(); 1925 1924 if (!(GetClassLongW( top, GCL_STYLE ) & CS_NOCLOSE)) 1926 1925 PostMessageW( top, WM_SYSCOMMAND, SC_CLOSE, 0 ); 1927 1926 } 1928 1927 1929 1928 //Default OS/2 app behaviour for system keys 1930 1929 if(fOS2Look) 1931 1930 { 1932 if( wParam == VK_F5 )/* try to restore the window */1933 1934 1931 if( wParam == VK_F5 ) /* try to restore the window */ 1932 { 1933 HWND top = GetTopParent(); 1935 1934 /* No checks needed SC_RESTORE handler does them */ 1936 1937 1938 1939 if( wParam == VK_F7 )/* size the window */1940 1941 1942 1943 1944 1945 if( wParam == VK_F8 )/* move the window */1946 1947 1948 1949 1950 1951 1952 if( wParam == VK_F9 )/* try to minimize the window */1953 1954 1955 1956 1957 1958 1959 if( wParam == VK_F10 )/* try to maximize the window */1960 1961 1962 1963 1964 1965 } 1966 1967 } 1968 1969 1970 1971 1935 PostMessageW( top, WM_SYSCOMMAND, SC_RESTORE, 0 ); 1936 } 1937 1938 if( wParam == VK_F7 ) /* size the window */ 1939 { 1940 HWND top = GetTopParent(); 1941 PostMessageW( top, WM_SYSCOMMAND, SC_MOVE, 0 ); 1942 } 1943 1944 if( wParam == VK_F8 ) /* move the window */ 1945 { 1946 HWND top = GetTopParent(); 1947 if ( GetWindowLongA(top, GWL_STYLE) & WS_SIZEBOX) 1948 PostMessageW( top, WM_SYSCOMMAND, SC_SIZE, 0 ); 1949 } 1950 1951 if( wParam == VK_F9 ) /* try to minimize the window */ 1952 { 1953 HWND top = GetTopParent(); 1954 if ( GetWindowLongA(top, GWL_STYLE) & WS_MINIMIZEBOX) 1955 PostMessageW( top, WM_SYSCOMMAND, SC_MINIMIZE, 0 ); 1956 } 1957 1958 if( wParam == VK_F10 ) /* try to maximize the window */ 1959 { 1960 HWND top = GetTopParent(); 1961 if ( GetWindowLongA(top, GWL_STYLE) & WS_MAXIMIZEBOX) 1962 PostMessageW( top, WM_SYSCOMMAND, SC_MAXIMIZE, 0 ); 1963 } 1964 } 1965 1966 } 1967 else if( wParam == VK_F10 ) 1968 iF10Key = 1; 1969 else 1970 if( wParam == VK_ESCAPE && (GetKeyState(VK_SHIFT) & 0x8000)) 1972 1971 SendMessageW(getWindowHandle(), WM_SYSCOMMAND, SC_KEYMENU, VK_SPACE ); 1973 1972 return 0; … … 1979 1978 // no break; 1980 1979 case WM_SYSKEYUP: 1981 1982 1980 /* Press and release F10 or ALT */ 1981 if (((wParam == VK_MENU) && iMenuSysKey) || 1983 1982 ((wParam == VK_F10) && iF10Key)) 1984 1983 ::SendMessageW( GetTopParent(), WM_SYSCOMMAND, SC_KEYMENU, 0L ); 1985 1984 iMenuSysKey = iF10Key = 0; 1986 1985 break; 1987 1986 … … 2020 2019 case WM_RBUTTONUP: 2021 2020 { 2022 2023 2024 2025 2021 POINT pt; 2022 pt.x = SLOWORD(lParam); 2023 pt.y = SHIWORD(lParam); 2024 ClientToScreen(getWindowHandle(), &pt); 2026 2025 SendMessageA( getWindowHandle(), WM_CONTEXTMENU, getWindowHandle(),MAKELPARAM(pt.x, pt.y) ); 2027 2026 } … … 2136 2135 { 2137 2136 case WM_GETTEXTLENGTH: 2138 return windowNameLength ;2137 return windowNameLengthW; 2139 2138 2140 2139 case WM_GETTEXT: 2141 if (!lParam || !wParam) 2140 if (!lParam || !wParam) 2142 2141 return 0; 2143 2142 if (!windowNameW) 2144 2143 ((LPWSTR)lParam)[0] = 0; 2145 else 2146 memcpy((LPSTR)lParam, windowNameW, min( sizeof(WCHAR) * (windowNameLength+1), wParam) ); 2147 return min(windowNameLength, wParam); 2144 else 2145 lstrcpynW(( LPWSTR )lParam, windowNameW, wParam ); 2146 2147 return strlenW(( LPWSTR )lParam ); 2148 2148 2149 2149 case WM_SETTEXT: 2150 2150 { 2151 2151 LPWSTR lpsz = (LPWSTR)lParam; 2152 2152 2153 2153 // reallocate if new buffer is larger 2154 2154 if (!lParam) … … 2156 2156 free(windowNameA); 2157 2157 free(windowNameW); 2158 windowNameLength = 0; 2158 windowNameLengthA = 0; 2159 windowNameLengthW = 0; 2159 2160 windowNameA = NULL; 2160 2161 windowNameW = NULL; … … 2164 2165 // determine length of new text 2165 2166 int iTextLength = lstrlenW(lpsz); 2166 2167 if (windowNameLength < iTextLength)2167 2168 if (windowNameLengthW < iTextLength) 2168 2169 { 2169 2170 if (windowNameA) … … 2172 2173 windowNameA = NULL; 2173 2174 } 2174 2175 2175 2176 if (windowNameW) 2176 2177 { … … 2179 2180 } 2180 2181 } 2181 2182 windowNameLength = iTextLength;2182 2183 windowNameLengthW = iTextLength; 2183 2184 if(!windowNameW) 2184 windowNameW = (LPWSTR)_smalloc((windowNameLength+1)*sizeof(WCHAR)); 2185 memcpy(windowNameW, lpsz, (windowNameLength+1) * sizeof(WCHAR)); 2185 windowNameW = (LPWSTR)_smalloc((windowNameLengthW+1)*sizeof(WCHAR)); 2186 strcpyW(windowNameW, lpsz); 2187 windowNameLengthA = lstrlenWtoA( windowNameW, -1 ); 2186 2188 if(!windowNameA) 2187 windowNameA = (LPSTR)_smalloc( windowNameLength+1);2188 lstrcpy nWtoA(windowNameA, windowNameW, windowNameLength+1);2189 } 2190 2191 dprintf(("WM_SETTEXT of %x \n",Win32Hwnd));2189 windowNameA = (LPSTR)_smalloc( windowNameLengthA + 1 ); 2190 lstrcpyWtoA( windowNameA, windowNameW ); 2191 } 2192 2193 dprintf(("WM_SETTEXT of %x to %s\n", Win32Hwnd, windowNameA)); 2192 2194 if ((dwStyle & WS_CAPTION) == WS_CAPTION) 2193 2195 { … … 2259 2261 hWndIcon = windowClass->getIcon(); 2260 2262 else 2261 if (!(dwStyle & DS_MODALFRAME)) 2263 if (!(dwStyle & DS_MODALFRAME)) 2262 2264 {//SvL: load it as shared or else we'll leak icons 2263 2265 hWndIcon = LoadImageA(0,MAKEINTRESOURCEA(OIC_ODINICON),IMAGE_ICON,0,0,LR_DEFAULTCOLOR|LR_SHARED); … … 2279 2281 hWndIcon = windowClass->getIcon(); 2280 2282 else 2281 if (!(dwStyle & DS_MODALFRAME)) 2283 if (!(dwStyle & DS_MODALFRAME)) 2282 2284 {//SvL: load it as shared or else we'll leak icons 2283 2285 hWndIcon = LoadImageA(0,MAKEINTRESOURCEA(OIC_ODINICON),IMAGE_ICON,0,0,LR_DEFAULTCOLOR|LR_SHARED); … … 2310 2312 dprintf(("ShowWindow: GetProcessDword(0, GPD_STARTF_SHOWWINDOW) -> %x", nCmdShow)); 2311 2313 } 2312 2314 2313 2315 2314 2316 switch(nCmdShow) … … 2433 2435 //****************************************************************************** 2434 2436 //****************************************************************************** 2435 BOOL Win32BaseWindow::SetWindowPos(HWND hwndInsertAfter, int x, int y, int cx, 2437 BOOL Win32BaseWindow::SetWindowPos(HWND hwndInsertAfter, int x, int y, int cx, 2436 2438 int cy, UINT fuFlags, BOOL fShowWindow) 2437 2439 { … … 2538 2540 OSLibWinQueryWindowPos(OS2HwndFrame, &swpOld); 2539 2541 } 2540 if((dwOldStyle & WS_MINIMIZE) && (getStyle() & WS_MINIMIZE)) 2542 if((dwOldStyle & WS_MINIMIZE) && (getStyle() & WS_MINIMIZE)) 2541 2543 {//don't allow size changes if the window is minimized 2542 2544 //we will update the restore position at the end of this method … … 2589 2591 //SvL: Must also deactivate the window when hiding it or else focus won't 2590 2592 // change. (NOTE: make sure this doesn't cause regressions (01-02-2003) 2591 if((swp.fl & (SWPOS_HIDE|SWPOS_DEACTIVATE)) == (SWPOS_HIDE|SWPOS_DEACTIVATE)) 2593 if((swp.fl & (SWPOS_HIDE|SWPOS_DEACTIVATE)) == (SWPOS_HIDE|SWPOS_DEACTIVATE)) 2592 2594 { 2593 2595 //we must make sure the owner is not disabled or else the focus will … … 2687 2689 wpos->y = rectWindow.top; 2688 2690 } 2689 2691 2690 2692 WINDOWPOS wpOld = *wpos; 2691 2693 if(!(wpos->flags & SWP_NOSENDCHANGING)) … … 2823 2825 return FALSE; 2824 2826 } 2825 2827 2826 2828 if(!(getStyle() & WS_CHILD) && getOwner() == NULL) 2827 2829 { … … 2854 2856 } 2855 2857 dprintf(("DestroyWindow %x -> HIDDEN", hwnd)); 2856 2858 2857 2859 // check the handle for the last active popup window 2858 2860 Win32BaseWindow* owner = getOwner(); … … 2870 2872 // (MFC created modeless dialog) 2871 2873 //TODO: This might be the wrong place to do it. EndDialog is called, 2872 // so perhaps it should be done there. (although Wine only 2874 // so perhaps it should be done there. (although Wine only 2873 2875 // enables the owner if the dialog is modal) 2874 2876 ::EnableWindow(owner->getWindowHandle(), 1); 2875 2877 } 2876 2878 2877 2879 fDestroyWindowCalled = TRUE; 2878 2880 … … 2929 2931 Win32BaseWindow *wndparent = (Win32BaseWindow *)ChildWindow::getParentOfChild(); 2930 2932 2931 if(getStyle() & WS_CHILD) 2933 if(getStyle() & WS_CHILD) 2932 2934 { 2933 2935 if(wndparent) { … … 2938 2940 return 0; 2939 2941 } 2940 else 2942 else 2941 2943 if(getStyle() & WS_POPUP) 2942 2944 return (getOwner()) ? getOwner()->getWindowHandle() : 0; … … 3027 3029 // in release build. 3028 3030 Win32BaseWindow *_parent = getParent(); 3029 3030 if(_parent) 3031 3032 if(_parent) 3031 3033 { 3032 3034 if(_parent->getWindowHandle() == hwndParent) 3033 3035 return TRUE; 3034 3036 3035 3037 return _parent->IsChild(hwndParent); 3036 3038 } 3037 else 3039 else 3038 3040 return 0; 3039 3041 } … … 3208 3210 dprintf(("EnumWindows %x %x", lpfn, lParam)); 3209 3211 3210 for(int i=0;i<MAX_WINDOW_HANDLES;i++) 3212 for(int i=0;i<MAX_WINDOW_HANDLES;i++) 3211 3213 { 3212 3214 window = Win32BaseWindow::GetWindowFromHandle(hwnd); … … 3440 3442 if(window->state >= STATE_POST_WMNCCREATE) { 3441 3443 hwndRelated = window->getWindowHandle(); 3442 RELEASE_WNDOBJ(window); 3444 RELEASE_WNDOBJ(window); 3443 3445 } 3444 3446 else { 3445 3447 hwndRelated = window->GetWindow(GW_HWNDNEXT); 3446 RELEASE_WNDOBJ(window); 3448 RELEASE_WNDOBJ(window); 3447 3449 } 3448 3450 } … … 3497 3499 //****************************************************************************** 3498 3500 PRECT Win32BaseWindow::getWindowRect() 3499 { 3500 return &rectWindow; 3501 { 3502 return &rectWindow; 3501 3503 } 3502 3504 //****************************************************************************** … … 3668 3670 { 3669 3671 //if the destination window is created by this process, send message 3670 if(dwProcessId == currentProcessId) 3672 if(dwProcessId == currentProcessId) 3671 3673 { 3672 3674 if(fUnicode) { … … 3677 3679 //else get data directory from window structure 3678 3680 //TODO: must lock window structure.... (TODO) 3679 return windowNameLength;3681 return fUnicode ? windowNameLengthW : windowNameLengthA; 3680 3682 } 3681 3683 //****************************************************************************** … … 3689 3691 return SendMessageA(getWindowHandle(),WM_GETTEXT,(WPARAM)cch,(LPARAM)lpsz); 3690 3692 } 3691 3693 3692 3694 //else get data directory from window structure 3693 3695 if (!lpsz || !cch) return 0; 3694 3696 if (!windowNameA) lpsz[0] = 0; 3695 else memcpy(lpsz, windowNameA, min(windowNameLength + 1, cch));3696 return min(windowNameLength, cch);3697 else lstrcpynA( lpsz, windowNameA, cch ); 3698 return strlen( lpsz ); 3697 3699 } 3698 3700 //****************************************************************************** … … 3707 3709 } 3708 3710 //else get data directory from window structure 3709 if (!lpsz || !cch) 3711 if (!lpsz || !cch) 3710 3712 return 0; 3711 if (!windowNameW) 3713 if (!windowNameW) 3712 3714 lpsz[0] = 0; 3713 else 3714 memcpy(lpsz, windowNameW, min( sizeof(WCHAR) * (windowNameLength+1), cch));3715 3716 return min(windowNameLength, cch);3715 else 3716 lstrcpynW( lpsz, windowNameW, cch ); 3717 3718 return strlenW( lpsz ); 3717 3719 } 3718 3720 //****************************************************************************** … … 3751 3753 SendMessageA(getWindowHandle(),WM_STYLECHANGED,GWL_EXSTYLE,(LPARAM)&ss); 3752 3754 3753 OSLibSetWindowStyle(getOS2FrameWindowHandle(), getOS2WindowHandle(), 3755 OSLibSetWindowStyle(getOS2FrameWindowHandle(), getOS2WindowHandle(), 3754 3756 getStyle(), getExStyle(),ss.styleOld); 3755 3757 … … 3760 3762 { 3761 3763 STYLESTRUCT ss; 3762 3764 3763 3765 //SvL: TODO: Can you change minimize or maximize status here too? 3764 3766 … … 3768 3770 } 3769 3771 dprintf(("SetWindowLong GWL_STYLE %x old %x new style %x (%x)", getWindowHandle(), dwStyle, value)); 3770 3772 3771 3773 //Changing WS_CHILD style is allowed 3772 3774 ss.styleOld = getStyle(); … … 3776 3778 SendMessageA(getWindowHandle(),WM_STYLECHANGED,GWL_STYLE,(LPARAM)&ss); 3777 3779 3778 OSLibSetWindowStyle(getOS2FrameWindowHandle(), getOS2WindowHandle(), 3780 OSLibSetWindowStyle(getOS2FrameWindowHandle(), getOS2WindowHandle(), 3779 3781 getStyle(), getExStyle(),ss.styleOld); 3780 3782 … … 3941 3943 switch(index) 3942 3944 { 3943 case GWW_ID: 3944 3945 case GWW_ID: 3946 if(HIWORD(getWindowId())) 3945 3947 dprintf(("WARNING: GWW_ID: discards high bits of 0x%08x!\n", getWindowId())); 3946 3948 return (WORD)getWindowId(); 3947 3949 3948 case GWW_HWNDPARENT: 3950 case GWW_HWNDPARENT: 3949 3951 dprintf(("WARNING: GWW_HWNDPARENT: discards high bits of 0x%08x!\n", GetParent())); 3950 3951 3952 case GWW_HINSTANCE: 3953 3952 return (WORD) GetParent(); 3953 3954 case GWW_HINSTANCE: 3955 if (HIWORD(hInstance)) 3954 3956 dprintf(("WARNING: GWW_HINSTANCE: discards high bits of 0x%08x!\n", hInstance)); 3955 3957 return (WORD)hInstance; … … 3969 3971 // VISRGN_NOTIFY_PROC lpNotifyProc - notification handler 3970 3972 // DWORD dwUserData - caller supplied parameter for handler invocations 3971 // 3973 // 3972 3974 // Returns: 3973 3975 // TRUE - Success … … 3989 3991 // Parameters: 3990 3992 // BOOL fDrawingAllowed - drawing is allowed or not 3991 // 3993 // 3992 3994 // Returns: 3993 3995 // TRUE - Success … … 3995 3997 // 3996 3998 //****************************************************************************** 3997 void Win32BaseWindow::callVisibleRgnNotifyProc(BOOL fDrawingAllowed) 3999 void Win32BaseWindow::callVisibleRgnNotifyProc(BOOL fDrawingAllowed) 3998 4000 { 3999 4001 if(fDrawingAllowed) { … … 4016 4018 // int chdcWindow - size of HDC array (IN) 4017 4019 // int *pnrdcs - number of HDCs returned (OUT) 4018 // 4020 // 4019 4021 // Returns: 4020 4022 // TRUE - Success … … 4050 4052 // Parameters: 4051 4053 // HDC hdc - HDC to be added to our list of open DCs 4052 // 4054 // 4053 4055 // Returns: 4054 4056 // … … 4083 4085 // Parameters: 4084 4086 // HDC hdc - HDC to be removed from our list of open DCs 4085 // 4087 // 4086 4088 // Returns: 4087 4089 // … … 4141 4143 { 4142 4144 DWORD magic; 4143 HWND hwnd; 4145 HWND hwnd; 4144 4146 4145 4147 if(hwndOS2 == OSLIB_HWND_DESKTOP) … … 4157 4159 // dprintf2(("Win32BaseWindow::GetWindowFromOS2Handle: not an Odin os2 window %x", hwndOS2)); 4158 4160 4159 //Now check if it's a fake window 4161 //Now check if it's a fake window 4160 4162 Win32FakeWindow *window = Win32FakeWindow::GetWindowFromOS2Handle(hwndOS2); 4161 4163 if(window) { -
trunk/src/user32/win32wbase.h
r10091 r10190 1 /* $Id: win32wbase.h,v 1.15 4 2003-05-15 12:40:20sandervl Exp $ */1 /* $Id: win32wbase.h,v 1.155 2003-07-31 15:56:47 sandervl Exp $ */ 2 2 /* 3 3 * Win32 Window Base Class for OS/2 … … 31 31 #define NROF_WIN32WNDBYTES 16 32 32 33 #define WINDOWFLAG_ACTIVE 33 #define WINDOWFLAG_ACTIVE 1 34 34 35 35 #define WIN32PM_MAGIC 0x12345678 … … 38 38 #define MAX_OPENDCS 8 39 39 40 #define TYPE_ASCII 41 #define TYPE_UNICODE 40 #define TYPE_ASCII 0 41 #define TYPE_UNICODE 1 42 42 43 43 #define GW_HWNDNEXTCHILD (0x10000 | GW_HWNDNEXT) … … 101 101 #define HAS_MENU() (!(getStyle() & WS_CHILD) && (getWindowId() != 0)) 102 102 103 #define STATE_INIT 103 #define STATE_INIT 0 //initial state 104 104 #define STATE_PRE_WMNCCREATE 1 //before WM_NCCREATE 105 105 #define STATE_POST_WMNCCREATE 2 //after WM_NCCREATE … … 234 234 235 235 void saveAndValidateUpdateRegion(); 236 void checkForDirtyUpdateRegion(); 236 void checkForDirtyUpdateRegion(); 237 237 BOOL hasDirtUpdateRegion() { return fDirtyUpdateRegion; }; 238 238 … … 276 276 //hack alert (see DestroyWindow) 277 277 BOOL IsChildDestructionInProgress() { return fChildDestructionInProgress; }; 278 void SetChildDestructionInProgress(BOOL fDestuctionInProgress) 279 { 278 void SetChildDestructionInProgress(BOOL fDestuctionInProgress) 279 { 280 280 fChildDestructionInProgress = fDestuctionInProgress; 281 281 }; … … 310 310 CHAR *getWindowNameA() { return windowNameA; }; //only for MDI windows! 311 311 WCHAR *getWindowNameW() { return windowNameW; }; //only for MDI windows! 312 int getWindowNameLength() { return windowNameLength; }; 312 int getWindowNameLengthA() { return windowNameLengthA; }; 313 int getWindowNameLengthW() { return windowNameLengthW; }; 313 314 Win32WndClass *getClass() { return windowClass; }; 314 315 Win32BaseWindow *getOwner() { return owner; }; … … 338 339 339 340 340 BOOL isComingToTop(){ return fComingToTop; };341 void setComingToTop(BOOL fTop){ fComingToTop = fTop; };341 BOOL isComingToTop() { return fComingToTop; }; 342 void setComingToTop(BOOL fTop) { fComingToTop = fTop; }; 342 343 BOOL isInTasklist() { return fTaskList; }; 343 344 344 345 //window property methods 345 346 HANDLE getProp(LPCSTR str); 346 347 348 349 347 BOOL setProp(LPCSTR str, HANDLE handle); 348 HANDLE removeProp(LPCSTR str); 349 INT enumPropsExA(PROPENUMPROCEXA func, LPARAM lParam); 350 INT enumPropsExW(PROPENUMPROCEXW func, LPARAM lParam); 350 351 351 352 #ifdef DEBUG … … 391 392 ULONG userData; //GWL_USERDATA 392 393 HWND hwndLastActive; // last active popup handle 393 394 394 395 ULONG cbExtra; 395 396 PVOID pExtra; … … 414 415 fCXDefault:1, 415 416 fParentDC:1, 416 417 fComingToTop:1, 417 418 isUnicode:1, 418 419 fMinMaxChange:1, //set when switching between min/max/restored state … … 440 441 char *windowNameA; 441 442 WCHAR *windowNameW; 442 int windowNameLength; 443 443 int windowNameLengthA; 444 int windowNameLengthW; 445 444 446 char *userWindowBytes; 445 447 ULONG nrUserWindowBytes; … … 455 457 VISRGN_NOTIFY_PROC lpVisRgnNotifyProc; 456 458 DWORD dwVisRgnNotifyParam; 457 459 458 460 HANDLE hTaskList; //PM specific (switchentry handle) 459 461 -
trunk/src/user32/winaccel.cpp
r9974 r10190 1 /* $Id: winaccel.cpp,v 1.1 1 2003-04-02 12:58:02sandervl Exp $ */1 /* $Id: winaccel.cpp,v 1.12 2003-07-31 15:56:47 sandervl Exp $ */ 2 2 /* 3 3 * Win32 accelerator key functions for OS/2 … … 18 18 #include <misc.h> 19 19 #include <heapstring.h> 20 #include "win32wbase.h"21 20 #include <win\winnls.h> 22 21 … … 24 23 #include "dbglocal.h" 25 24 26 /**********************************************************************27 * KBD_translate_accelerator28 *29 * FIXME: should send some WM_INITMENU or/and WM_INITMENUPOPUP -messages30 */31 static BOOL KBD_translate_accelerator(HWND hWnd,LPMSG msg,32 BYTE fVirt,WORD key,WORD cmd)33 {34 BOOL sendmsg = FALSE;35 36 if(msg->wParam == key)37 {38 if (msg->message == WM_CHAR) {39 if ( !(fVirt & FALT) && !(fVirt & FVIRTKEY) )40 {41 dprintf(("TranslateAccelerator: found accel for WM_CHAR: ('%c')\n", msg->wParam&0xff));42 sendmsg=TRUE;43 }44 }45 else46 {47 if(fVirt & FVIRTKEY) {48 INT mask = 0;49 if(GetKeyState(VK_SHIFT) & 0x8000) mask |= FSHIFT;50 if(GetKeyState(VK_CONTROL) & 0x8000) mask |= FCONTROL;51 if(GetKeyState(VK_MENU) & 0x8000) mask |= FALT;52 53 if(mask == (fVirt & (FSHIFT | FCONTROL | FALT)))54 sendmsg=TRUE;55 else dprintf(("TranslateAccelerator: but incorrect SHIFT/CTRL/ALT-state %x != %x", mask, fVirt));56 }57 else58 {59 if (!(msg->lParam & 0x01000000)) /* no special_key */60 {61 if ((fVirt & FALT) && (msg->lParam & 0x20000000))62 { /* ^^ ALT pressed */63 dprintf(("TranslateAccelerator: found accel for Alt-%c\n", msg->wParam&0xff));64 sendmsg=TRUE;65 }66 }67 }68 }69 70 if (sendmsg) /* found an accelerator, but send a message... ? */71 {72 INT iSysStat,iStat,mesg=0;73 HMENU hMenu;74 75 if (msg->message == WM_KEYUP || msg->message == WM_SYSKEYUP) {76 mesg=1;77 }78 else79 if (GetCapture())80 mesg=2;81 else82 if (!IsWindowEnabled(hWnd))83 mesg=3;84 else85 {86 Win32BaseWindow *window;87 88 window = Win32BaseWindow::GetWindowFromHandle(hWnd);89 if(!window) {90 return FALSE; //should never happen! (already checked)91 }92 93 hMenu = GetMenu(hWnd);94 95 iSysStat = (window->GetSysMenu()) ? GetMenuState(GetSubMenu(window->GetSysMenu(), 0),96 cmd, MF_BYCOMMAND) : -1 ;97 iStat = (hMenu) ? GetMenuState(hMenu, cmd, MF_BYCOMMAND) : -1 ;98 99 if (iSysStat!=-1)100 {101 if (iSysStat & (MF_DISABLED|MF_GRAYED))102 mesg=4;103 else104 mesg=WM_SYSCOMMAND;105 }106 else107 {108 if (iStat!=-1)109 {110 if (IsIconic(hWnd)) {111 mesg=5;112 }113 else114 {115 if (iStat & (MF_DISABLED|MF_GRAYED))116 mesg=6;117 else118 mesg=WM_COMMAND;119 }120 }121 else122 mesg=WM_COMMAND;123 }124 RELEASE_WNDOBJ(window);125 }126 if ( mesg==WM_COMMAND || mesg==WM_SYSCOMMAND )127 {128 SendMessageA(hWnd, mesg, cmd, 0x00010000L);129 }130 else131 {132 /* some reasons for NOT sending the WM_{SYS}COMMAND message:133 * #0: unknown (please report!)134 * #1: for WM_KEYUP,WM_SYSKEYUP135 * #2: mouse is captured136 * #3: window is disabled137 * #4: it's a disabled system menu option138 * #5: it's a menu option, but window is iconic139 * #6: it's a menu option, but disabled140 */141 if(mesg==0)142 dprintf(("ERROR: unknown reason - please report!"));143 else dprintf(("but won't send WM_{SYS}COMMAND, reason is #%d\n",mesg));144 145 }146 return TRUE;147 }148 dprintf(("TranslateAccelerator: not match for %x %x %x", fVirt, key, cmd));149 }150 return FALSE;151 }152 /*****************************************************************************153 * Name : int WIN32API TranslateAcceleratorA154 * Purpose : Translate WM_*KEYDOWN messages to WM_COMMAND messages155 * according to Accelerator table156 * Parameters: HWND hwnd, HACCEL haccel, LPMSG lpmsg157 * Variables :158 * Result : int FALSE (no accelerator found) TRUE (accelerator found)159 * Remark : if a accelerator is found it is not neccesarely executed160 * depends on window stat161 *162 *****************************************************************************/163 INT WINAPI TranslateAcceleratorA(HWND hWnd, HACCEL hAccel, LPMSG msg)164 {165 /* YES, Accel16! */166 LPACCEL lpAccelTbl;167 int i;168 169 SetLastError(ERROR_SUCCESS);170 if (msg == NULL)171 {172 dprintf(("TranslateAcceleratorAmsg null; should hang here to be win compatible"));173 SetLastError(ERROR_INVALID_PARAMETER);174 return 0;175 }176 if (!hAccel || !(lpAccelTbl = (LPACCEL)GlobalLock(hAccel)))177 {178 dprintf(("TranslateAcceleratorA: invalid accel handle=%x", hAccel));179 SetLastError(ERROR_INVALID_PARAMETER);180 return 0;181 }182 if(!IsWindow(hWnd)) {183 dprintf(("TranslateAccelerator, window %x not found", hWnd));184 SetLastError(ERROR_INVALID_WINDOW_HANDLE);185 return 0;186 }187 if ((msg->message != WM_KEYDOWN &&188 msg->message != WM_KEYUP &&189 msg->message != WM_SYSKEYDOWN &&190 msg->message != WM_SYSKEYUP &&191 msg->message != WM_CHAR))192 {193 return 0;194 }195 196 /* TRACE_(accel)("TranslateAccelerators hAccel=%04x, hWnd=%04x,"197 "msg->hwnd=%04x, msg->message=%04x, wParam=%08x, lParam=%lx\n",198 hAccel,hWnd,msg->hwnd,msg->message,msg->wParam,msg->lParam); */199 200 i = 0;201 do202 {203 if (KBD_translate_accelerator(hWnd,msg,lpAccelTbl[i].fVirt,204 lpAccelTbl[i].key,lpAccelTbl[i].cmd))205 {206 return 1;207 }208 }209 while ((lpAccelTbl[i++].fVirt & 0x80) == 0);210 211 // WARN_(accel)("couldn't translate accelerator key\n");212 return 0;213 }214 25 /********************************************************************** 215 26 * LoadAccelerators32W [USER.177] -
trunk/src/user32/windowmsg.cpp
r10185 r10190 1 /* $Id: windowmsg.cpp,v 1.4 3 2003-07-28 11:27:50sandervl Exp $ */1 /* $Id: windowmsg.cpp,v 1.44 2003-07-31 15:56:47 sandervl Exp $ */ 2 2 /* 3 3 * Win32 window message APIs for OS/2 … … 86 86 return 0; /* invalid winproc */ 87 87 88 return CallWindowProc A( (WNDPROC)msg->lParam, msg->hwnd,88 return CallWindowProcW( (WNDPROC)msg->lParam, msg->hwnd, 89 89 msg->message, msg->wParam, GetTickCount() ); 90 90 } … … 319 319 { 320 320 case WM_GETTEXT: 321 case WM_ASKCBFORMATNAME: 321 322 { 322 323 LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0, … … 330 331 case WM_SETTEXT: 331 332 case WM_WININICHANGE: 333 case WM_DEVMODECHANGE: 332 334 case CB_DIR: 333 335 case LB_DIR: … … 431 433 return 1; 432 434 433 /* kso 2003-07-03: to make password field work, I took this from latest wine code. (winproc.c) */ 435 case WM_CHARTOITEM: 436 case WM_MENUCHAR: 437 case WM_CHAR: 438 case WM_DEADCHAR: 439 case WM_SYSCHAR: 440 case WM_SYSDEADCHAR: 434 441 case EM_SETPASSWORDCHAR: 435 442 { 436 BYTEch = LOWORD(*pwparam);437 WCHAR wch = 0;438 MultiByteToWideChar(CP_ACP, 0, (LPCSTR)&ch, 1, &wch, 1);443 char ch = LOWORD(*pwparam); 444 WCHAR wch; 445 MultiByteToWideChar(CP_ACP, 0, &ch, 1, &wch, 1); 439 446 *pwparam = MAKEWPARAM( wch, HIWORD(*pwparam) ); 440 447 } 441 448 return 0; 442 449 443 case WM_ASKCBFORMATNAME:444 case WM_DEVMODECHANGE:445 450 case WM_PAINTCLIPBOARD: 446 451 case WM_SIZECLIPBOARD: … … 463 468 { 464 469 case WM_GETTEXT: 470 case WM_ASKCBFORMATNAME: 465 471 { 466 472 LPARAM *ptr = (LPARAM *)lParam - 1; … … 495 501 case WM_SETTEXT: 496 502 case WM_WININICHANGE: 503 case WM_DEVMODECHANGE: 497 504 case CB_DIR: 498 505 case LB_DIR: … … 569 576 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed. 570 577 */ 571 INT WINPROC_MapMsg32WTo32A( HWND hwnd, UINT msg, WPARAM wParam, LPARAM *plparam)578 INT WINPROC_MapMsg32WTo32A( HWND hwnd, UINT msg, WPARAM *pwparam, LPARAM *plparam) 572 579 { switch(msg) 573 580 { 574 581 case WM_GETTEXT: 575 { 582 case WM_ASKCBFORMATNAME: 583 { 584 #ifdef __WIN32OS2__ 585 *pwparam = *pwparam * sizeof( WCHAR ); //DBCS 586 #endif 576 587 LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0, 577 wParam + sizeof(LPARAM) );588 *pwparam + sizeof(LPARAM) ); 578 589 if (!ptr) return -1; 579 590 *ptr++ = *plparam; /* Store previous lParam */ … … 584 595 case WM_SETTEXT: 585 596 case WM_WININICHANGE: 597 case WM_DEVMODECHANGE: 586 598 case CB_DIR: 587 599 case LB_DIR: … … 681 693 if (!ptr) return -1; 682 694 *ptr++ = *plparam; /* Store previous lParam */ 695 #ifdef __WIN32OS2__ 696 *((WORD *) ptr) = len * sizeof(WCHAR); /* Store the length */ 697 #else 683 698 *((WORD *) ptr) = len; /* Store the length */ 699 #endif 684 700 *plparam = (LPARAM)ptr; 685 701 } 686 702 return 1; 687 703 688 case WM_ASKCBFORMATNAME: 689 case WM_DEVMODECHANGE: 704 case WM_CHARTOITEM: 705 case WM_MENUCHAR: 706 case WM_CHAR: 707 case WM_DEADCHAR: 708 case WM_SYSCHAR: 709 case WM_SYSDEADCHAR: 710 case EM_SETPASSWORDCHAR: 711 { 712 WCHAR wch = LOWORD(*pwparam); 713 char ch; 714 WideCharToMultiByte( CP_ACP, 0, &wch, 1, &ch, 1, NULL, NULL ); 715 *pwparam = MAKEWPARAM( ch, HIWORD(*pwparam) ); 716 } 717 return 0; 718 690 719 case WM_PAINTCLIPBOARD: 691 720 case WM_SIZECLIPBOARD: 692 case EM_SETPASSWORDCHAR:693 721 // FIXME_(msg)("message %s (%04x) needs translation, please report\n",SPY_GetMsgName(msg),msg ); 694 722 return -1; … … 709 737 { 710 738 case WM_GETTEXT: 739 case WM_ASKCBFORMATNAME: 711 740 { 712 741 LPARAM *ptr = (LPARAM *)lParam - 1; 742 743 #ifdef __WIN32OS2__ 744 wParam = wParam / sizeof( WCHAR ); 745 #endif 713 746 lstrcpynAtoW( (LPWSTR)*ptr, (LPSTR)lParam, wParam ); 714 747 HeapFree( GetProcessHeap(), 0, ptr ); … … 718 751 case WM_SETTEXT: 719 752 case WM_WININICHANGE: 753 case WM_DEVMODECHANGE: 720 754 case CB_DIR: 721 755 case LB_DIR: … … 800 834 case EM_GETLINE: 801 835 { LPARAM * ptr = (LPARAM *)lParam - 1; /* get the old lparam */ 836 #ifdef __WIN32OS2__ 837 WORD len = *(WORD *)ptr/sizeof(WCHAR); 838 #else 802 839 WORD len = *(WORD *)ptr; 840 #endif 803 841 lstrcpynAtoW( (LPWSTR) *ptr, (LPSTR)lParam, len ); 804 842 HeapFree( GetProcessHeap(), 0, ptr ); … … 819 857 LRESULT result; 820 858 859 #ifdef __WIN32OS2__ 860 if( IsDBCSEnv() && msg == WM_CHAR ) 861 { 862 static BYTE dbcsLead = 0; 863 WCHAR charA = wParam; 864 int size = dbcsLead ? 2 : 1; 865 866 if( dbcsLead ) 867 charA = ( charA << 8 ) | dbcsLead; 868 else if( IsDBCSLeadByte( wParam )) 869 { 870 dbcsLead = wParam; 871 return 0; 872 } 873 MultiByteToWideChar( CP_ACP, 0, ( LPSTR )&charA, size, ( LPWSTR )&wParam, 1 ); 874 875 dbcsLead = 0; 876 } 877 else 878 #endif 821 879 if (WINPROC_MapMsg32ATo32W( hwnd, msg, &wParam, &lParam ) == -1) return 0; 880 822 881 result = func( hwnd, msg, wParam, lParam ); 823 882 WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam ); 883 884 #ifdef __WIN32OS2__ 885 if(IsDBCSEnv()) 886 { 887 switch( msg ) 888 { 889 case WM_GETTEXTLENGTH : 890 { 891 LPWSTR ustr = ( LPWSTR )HeapAlloc( GetProcessHeap(), 0, ( result + 1 ) * sizeof( WCHAR )); 892 result = func( hwnd, WM_GETTEXT, ( WPARAM )( result + 1 ), ( LPARAM )ustr ); 893 result = lstrlenWtoA( ustr, result ); 894 HeapFree( GetProcessHeap(), 0, ustr ); 895 break; 896 } 897 898 case LB_GETTEXTLEN : 899 { 900 LPWSTR ustr = ( LPWSTR )HeapAlloc( GetProcessHeap(), 0, ( result + 1 ) * sizeof( WCHAR )); 901 result = func( hwnd, LB_GETTEXT, wParam, ( LPARAM )ustr ); 902 if( result != LB_ERR ) 903 result = lstrlenWtoA( ustr, result ); 904 905 HeapFree( GetProcessHeap(), 0, ustr ); 906 break; 907 } 908 909 910 case CB_GETLBTEXTLEN : 911 { 912 LPWSTR ustr = ( LPWSTR )HeapAlloc( GetProcessHeap(), 0, ( result + 1 ) * sizeof( WCHAR )); 913 result = func( hwnd, CB_GETLBTEXT, wParam, ( LPARAM )ustr ); 914 if( result != CB_ERR ) 915 result = lstrlenWtoA( ustr, result ); 916 917 HeapFree( GetProcessHeap(), 0, ustr ); 918 break; 919 } 920 } 921 } 922 #endif 824 923 return result; 825 924 } … … 836 935 LRESULT result; 837 936 838 if (WINPROC_MapMsg32WTo32A( hwnd, msg, wParam, &lParam ) == -1) return 0; 937 #ifdef __WIN32OS2__ 938 if( IsDBCSEnv() && msg == WM_CHAR ) 939 { 940 char charA[ 2 ]; 941 942 if( WideCharToMultiByte( CP_ACP, 0, ( LPWSTR )&wParam, 1, ( LPSTR )charA, 2, 0, 0 ) > 1 ) 943 { 944 func( hwnd, msg, ( WPARAM )charA[ 0 ], lParam ); 945 wParam = charA[ 1 ]; 946 } 947 else 948 wParam = charA[ 0 ]; 949 } 950 else 951 #endif 952 if (WINPROC_MapMsg32WTo32A( hwnd, msg, &wParam, &lParam ) == -1) return 0; 839 953 840 954 result = func( hwnd, msg, wParam, lParam ); 841 955 WINPROC_UnmapMsg32WTo32A( hwnd, msg, wParam, lParam ); 956 957 #ifdef __WIN32OS2__ 958 if( IsDBCSEnv() ) 959 { 960 switch( msg ) 961 { 962 case WM_GETTEXTLENGTH : 963 { 964 LPSTR astr = ( LPSTR )HeapAlloc( GetProcessHeap(), 0, result + 1 ); 965 result = func( hwnd, WM_GETTEXT, ( WPARAM )( result + 1 ), ( LPARAM )astr ); 966 result = lstrlenAtoW( astr, result ); 967 HeapFree( GetProcessHeap(), 0, astr ); 968 break; 969 } 970 971 case LB_GETTEXTLEN : 972 { 973 LPSTR astr = ( LPSTR )HeapAlloc( GetProcessHeap(), 0, result + 1 ); 974 result = func( hwnd, LB_GETTEXT, wParam, ( LPARAM )astr ); 975 if( result != LB_ERR ) 976 result = lstrlenAtoW( astr, result ); 977 978 HeapFree( GetProcessHeap(), 0, astr ); 979 break; 980 } 981 982 983 case CB_GETLBTEXTLEN : 984 { 985 LPSTR astr = ( LPSTR )HeapAlloc( GetProcessHeap(), 0, result + 1 ); 986 result = func( hwnd, CB_GETLBTEXT, wParam, ( LPARAM )astr ); 987 if( result != CB_ERR ) 988 result = lstrlenAtoW( astr, result ); 989 990 HeapFree( GetProcessHeap(), 0, astr ); 991 break; 992 } 993 } 994 } 995 #endif 842 996 return result; 843 997 } -
trunk/src/user32/winkeyboard.cpp
r9974 r10190 1 /* $Id: winkeyboard.cpp,v 1.4 2 2003-04-02 12:58:02sandervl Exp $ */1 /* $Id: winkeyboard.cpp,v 1.43 2003-07-31 15:56:48 sandervl Exp $ */ 2 2 /* 3 3 * Win32 <-> PM key translation … … 1056 1056 BOOL WIN32API SetKeyboardState(PBYTE lpKeyState) 1057 1057 { 1058 dprintf(("USER32: SetKeyboardState %x not implemented", lpKeyState)); 1059 return(TRUE); 1058 dprintf(("USER32: SetKeyboardState %x not implemented", lpKeyState)); 1059 1060 return(TRUE); 1060 1061 } 1061 1062 /*********************************************************************** … … 1204 1205 if(lpbKeyState[VK_LSHIFT] & 0x80) shiftstate |= TCF_LSHIFT; 1205 1206 if(lpbKeyState[VK_RSHIFT] & 0x80) shiftstate |= TCF_RSHIFT; 1207 else 1208 if(lpbKeyState[VK_SHIFT] & 0x80) shiftstate |= TCF_LSHIFT; 1209 1206 1210 if(lpbKeyState[VK_LCONTROL] & 0x80) shiftstate |= TCF_LCONTROL; 1207 1211 if(lpbKeyState[VK_RCONTROL] & 0x80) shiftstate |= TCF_RCONTROL; 1212 else 1213 if(lpbKeyState[VK_CONTROL] & 0x80) shiftstate |= TCF_LCONTROL; 1214 1208 1215 if(lpbKeyState[VK_LMENU] & 0x80) shiftstate |= TCF_ALT; 1209 1216 if(lpbKeyState[VK_RMENU] & 0x80) shiftstate |= TCF_ALTGR; 1217 else 1218 if(lpbKeyState[VK_MENU] & 0x80) shiftstate |= TCF_ALT; 1219 1210 1220 if(lpbKeyState[VK_CAPITAL] & 1) shiftstate |= TCF_CAPSLOCK; 1211 1221 if(lpbKeyState[VK_NUMLOCK] & 1) shiftstate |= TCF_NUMLOCK; … … 1615 1625 break; 1616 1626 1627 case 0: 1628 { 1629 UINT ret; 1630 if( uCode >= VK_A && uCode <= VK_Z) { 1631 ret = OSLibWinTranslateChar('A' + uCode - VK_A, TC_CHARTOSCANCODE, 0); 1632 dprintf(("MapVirtualKeyA %x (%c) -> %x", uCode, 'A' + uCode - VK_A, ret)); 1633 return ret; 1634 } 1635 else 1636 if( uCode >= VK_0 && uCode <= VK_0) { 1637 ret = OSLibWinTranslateChar('0' + uCode - VK_0, TC_CHARTOSCANCODE, 0); 1638 dprintf(("MapVirtualKeyA %x (%c) -> %x", uCode, '0' + uCode - VK_0, ret)); 1639 return ret; 1640 } 1641 break; 1642 } 1643 1617 1644 case 1: 1618 1645 case 3:
Note:
See TracChangeset
for help on using the changeset viewer.