From 2ce90e00efa9c970e2e47cb0f002037a582e98cc Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Tue, 25 Aug 2015 14:16:55 -0500 Subject: [PATCH 6/6] comdlg32: Use a real split button in the item dialog. --- dlls/comdlg32/comdlg32.rc | 7 +-- dlls/comdlg32/itemdlg.c | 139 ++++++++-------------------------------------- include/commctrl.h | 1 + 3 files changed, 24 insertions(+), 123 deletions(-) diff --git a/dlls/comdlg32/comdlg32.rc b/dlls/comdlg32/comdlg32.rc index 240972e..fba1373 100644 --- a/dlls/comdlg32/comdlg32.rc +++ b/dlls/comdlg32/comdlg32.rc @@ -490,12 +490,7 @@ FONT 8, "MS Shell Dlg" COMBOBOX IDC_FILETYPE, 226, 256, 100, 12, WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | WS_CLIPSIBLINGS | CBS_HASSTRINGS | CBS_DROPDOWNLIST - DEFPUSHBUTTON "&Open", IDOK, 350, 240, 32, 14, WS_GROUP | WS_CLIPSIBLINGS - - /* drop-down menu for open button */ - CONTROL "6", psh1, "Button", WS_CHILD | WS_CLIPSIBLINGS | WS_GROUP | WS_TABSTOP | - BS_CHECKBOX | BS_PUSHLIKE, 342, 240, 8, 14 - + DEFPUSHBUTTON "&Open", IDOK, 350, 240, 40, 14, WS_GROUP | WS_CLIPSIBLINGS PUSHBUTTON "Cancel", IDCANCEL, 395, 240, 40, 14, WS_CLIPSIBLINGS PUSHBUTTON "&Help", pshHelp, 350, 272, 40, 14, WS_CLIPSIBLINGS } diff --git a/dlls/comdlg32/itemdlg.c b/dlls/comdlg32/itemdlg.c index aba4fc4..803e9b2 100644 --- a/dlls/comdlg32/itemdlg.c +++ b/dlls/comdlg32/itemdlg.c @@ -1446,7 +1446,8 @@ static BOOL update_open_dropdown(FileDialogImpl *This) { /* Show or hide the open dropdown button as appropriate */ BOOL show=FALSE, showing; - HWND open_hwnd, dropdown_hwnd; + HWND open_hwnd; + LONG_PTR style; if (This->hmenu_opendropdown) { @@ -1468,33 +1469,19 @@ static BOOL update_open_dropdown(FileDialogImpl *This) } open_hwnd = GetDlgItem(This->dlg_hwnd, IDOK); - dropdown_hwnd = GetDlgItem(This->dlg_hwnd, psh1); - showing = (GetWindowLongPtrW(dropdown_hwnd, GWL_STYLE) & WS_VISIBLE) != 0; + style = GetWindowLongPtrW(open_hwnd, GWL_STYLE); + showing = (style & BS_SPLITBUTTON) != 0; if (showing != show) { - RECT open_rc, dropdown_rc; - - GetWindowRect(open_hwnd, &open_rc); - GetWindowRect(dropdown_hwnd, &dropdown_rc); - if (show) - { - ShowWindow(dropdown_hwnd, SW_SHOW); - - SetWindowPos(open_hwnd, NULL, 0, 0, - (open_rc.right - open_rc.left) - (dropdown_rc.right - dropdown_rc.left), - open_rc.bottom - open_rc.top, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); - } + style |= BS_SPLITBUTTON; else - { - ShowWindow(dropdown_hwnd, SW_HIDE); + style &= ~BS_SPLITBUTTON; - SetWindowPos(open_hwnd, NULL, 0, 0, - (open_rc.right - open_rc.left) + (dropdown_rc.right - dropdown_rc.left), - open_rc.bottom - open_rc.top, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); - } + SetWindowLongPtrW(open_hwnd, GWL_STYLE, style); + InvalidateRect(open_hwnd, NULL, TRUE); } return show; @@ -1505,12 +1492,11 @@ static void update_layout(FileDialogImpl *This) HDWP hdwp; HWND hwnd; RECT dialog_rc; - RECT cancel_rc, dropdown_rc, open_rc; + RECT cancel_rc, open_rc; RECT filetype_rc, filename_rc, filenamelabel_rc; RECT toolbar_rc, ebrowser_rc, customctrls_rc; static const UINT vspacing = 4, hspacing = 4; static const UINT min_width = 320, min_height = 200; - BOOL show_dropdown; if (!GetClientRect(This->dlg_hwnd, &dialog_rc)) { @@ -1543,31 +1529,9 @@ static void update_layout(FileDialogImpl *This) cancel_rc.bottom = cancel_rc.top + cancel_height; } - /* Open/Save dropdown */ - show_dropdown = update_open_dropdown(This); - - if(show_dropdown) - { - int dropdown_width, dropdown_height; - hwnd = GetDlgItem(This->dlg_hwnd, psh1); - - GetWindowRect(hwnd, &dropdown_rc); - dropdown_width = dropdown_rc.right - dropdown_rc.left; - dropdown_height = dropdown_rc.bottom - dropdown_rc.top; - - dropdown_rc.left = cancel_rc.left - dropdown_width - hspacing; - dropdown_rc.top = cancel_rc.top; - dropdown_rc.right = dropdown_rc.left + dropdown_width; - dropdown_rc.bottom = dropdown_rc.top + dropdown_height; - } - else - { - dropdown_rc.left = dropdown_rc.right = cancel_rc.left - hspacing; - dropdown_rc.top = cancel_rc.top; - dropdown_rc.bottom = cancel_rc.bottom; - } - /* Open/Save button */ + update_open_dropdown(This); + hwnd = GetDlgItem(This->dlg_hwnd, IDOK); if(hwnd) { @@ -1576,8 +1540,8 @@ static void update_layout(FileDialogImpl *This) open_width = open_rc.right - open_rc.left; open_height = open_rc.bottom - open_rc.top; - open_rc.left = dropdown_rc.left - open_width; - open_rc.top = dropdown_rc.top; + open_rc.left = cancel_rc.left - open_width; + open_rc.top = cancel_rc.top; open_rc.right = open_rc.left + open_width; open_rc.bottom = open_rc.top + open_height; } @@ -1688,10 +1652,6 @@ static void update_layout(FileDialogImpl *This) DeferWindowPos(hdwp, hwnd, NULL, open_rc.left, open_rc.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE); - if(hdwp && This->hmenu_opendropdown && (hwnd = GetDlgItem(This->dlg_hwnd, psh1))) - DeferWindowPos(hdwp, hwnd, NULL, dropdown_rc.left, dropdown_rc.top, 0, 0, - SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE); - if(hdwp && (hwnd = GetDlgItem(This->dlg_hwnd, IDCANCEL)) ) DeferWindowPos(hdwp, hwnd, NULL, cancel_rc.left, cancel_rc.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE); @@ -1829,25 +1789,6 @@ static void update_control_text(FileDialogImpl *This) } } -static LRESULT CALLBACK dropdown_subclass_proc(HWND hwnd, UINT umessage, WPARAM wparam, LPARAM lparam) -{ - static const WCHAR prop_this[] = {'i','t','e','m','d','l','g','_','T','h','i','s',0}; - static const WCHAR prop_oldwndproc[] = {'i','t','e','m','d','l','g','_','o','l','d','w','n','d','p','r','o','c',0}; - - if (umessage == WM_LBUTTONDOWN) - { - FileDialogImpl *This = (FileDialogImpl*)GetPropW(hwnd, prop_this); - - SendMessageW(hwnd, BM_SETCHECK, BST_CHECKED, 0); - show_opendropdown(This); - SendMessageW(hwnd, BM_SETCHECK, BST_UNCHECKED, 0); - - return 0; - } - - return CallWindowProcW((WNDPROC)GetPropW(hwnd, prop_oldwndproc), hwnd, umessage, wparam, lparam); -} - static LRESULT on_wm_initdialog(HWND hwnd, LPARAM lParam) { FileDialogImpl *This = (FileDialogImpl*)lParam; @@ -1909,37 +1850,6 @@ static LRESULT on_wm_initdialog(HWND hwnd, LPARAM lParam) (hitem = GetDlgItem(This->dlg_hwnd, IDC_FILENAME)) ) SendMessageW(hitem, WM_SETTEXT, 0, (LPARAM)This->set_filename); - if(This->hmenu_opendropdown) - { - HWND dropdown_hwnd; - LOGFONTW lfw, lfw_marlett; - HFONT dialog_font; - static const WCHAR marlett[] = {'M','a','r','l','e','t','t',0}; - static const WCHAR prop_this[] = {'i','t','e','m','d','l','g','_','T','h','i','s',0}; - static const WCHAR prop_oldwndproc[] = {'i','t','e','m','d','l','g','_','o','l','d','w','n','d','p','r','o','c',0}; - - dropdown_hwnd = GetDlgItem(This->dlg_hwnd, psh1); - - /* Change dropdown button font to Marlett */ - dialog_font = (HFONT)SendMessageW(dropdown_hwnd, WM_GETFONT, 0, 0); - - GetObjectW(dialog_font, sizeof(lfw), &lfw); - - memset(&lfw_marlett, 0, sizeof(lfw_marlett)); - lstrcpyW(lfw_marlett.lfFaceName, marlett); - lfw_marlett.lfHeight = lfw.lfHeight; - lfw_marlett.lfCharSet = SYMBOL_CHARSET; - - This->hfont_opendropdown = CreateFontIndirectW(&lfw_marlett); - - SendMessageW(dropdown_hwnd, WM_SETFONT, (LPARAM)This->hfont_opendropdown, 0); - - /* Subclass button so we can handle LBUTTONDOWN */ - SetPropW(dropdown_hwnd, prop_this, (HANDLE)This); - SetPropW(dropdown_hwnd, prop_oldwndproc, - (HANDLE)SetWindowLongPtrW(dropdown_hwnd, GWLP_WNDPROC, (LONG_PTR)dropdown_subclass_proc)); - } - ctrl_container_reparent(This, This->dlg_hwnd); init_explorerbrowser(This); init_toolbar(This, hwnd); @@ -2009,19 +1919,6 @@ static LRESULT on_idcancel(FileDialogImpl *This) return FALSE; } -static LRESULT on_command_opendropdown(FileDialogImpl *This, WPARAM wparam, LPARAM lparam) -{ - if(HIWORD(wparam) == BN_CLICKED) - { - HWND hwnd = (HWND)lparam; - SendMessageW(hwnd, BM_SETCHECK, BST_CHECKED, 0); - show_opendropdown(This); - SendMessageW(hwnd, BM_SETCHECK, BST_UNCHECKED, 0); - } - - return FALSE; -} - static LRESULT on_browse_back(FileDialogImpl *This) { TRACE("%p\n", This); @@ -2091,7 +1988,6 @@ static LRESULT on_wm_command(FileDialogImpl *This, WPARAM wparam, LPARAM lparam) { case IDOK: return on_idok(This); case IDCANCEL: return on_idcancel(This); - case psh1: return on_command_opendropdown(This, wparam, lparam); case IDC_NAVBACK: return on_browse_back(This); case IDC_NAVFORWARD: return on_browse_forward(This); case IDC_FILETYPE: return on_command_filetype(This, wparam, lparam); @@ -2100,6 +1996,14 @@ static LRESULT on_wm_command(FileDialogImpl *This, WPARAM wparam, LPARAM lparam) return FALSE; } +static LRESULT on_wm_notify(FileDialogImpl *This, WPARAM wparam, LPARAM lparam) +{ + NMHDR* nmhdr = (NMHDR*)lparam; + if (nmhdr->idFrom == IDOK && nmhdr->code == BCN_DROPDOWN) + show_opendropdown(This); + return FALSE; +} + static LRESULT CALLBACK itemdlg_dlgproc(HWND hwnd, UINT umessage, WPARAM wparam, LPARAM lparam) { FileDialogImpl *This = (FileDialogImpl*)GetWindowLongPtrW(hwnd, GWLP_USERDATA); @@ -2108,6 +2012,7 @@ static LRESULT CALLBACK itemdlg_dlgproc(HWND hwnd, UINT umessage, WPARAM wparam, { case WM_INITDIALOG: return on_wm_initdialog(hwnd, lparam); case WM_COMMAND: return on_wm_command(This, wparam, lparam); + case WM_NOTIFY: return on_wm_notify(This, wparam, lparam); case WM_SIZE: return on_wm_size(This); case WM_GETMINMAXINFO: return on_wm_getminmaxinfo(This, lparam); case WM_DESTROY: return on_wm_destroy(This); diff --git a/include/commctrl.h b/include/commctrl.h index 0bcaeb6..1c79aec 100644 --- a/include/commctrl.h +++ b/include/commctrl.h @@ -1018,6 +1018,7 @@ static const WCHAR WC_BUTTONW[] = { 'B','u','t','t','o','n',0 }; #define BCN_LAST (0U-1350U) #define BCN_HOTITEMCHANGE (BCN_FIRST + 0x0001) +#define BCN_DROPDOWN (BCN_FIRST + 0x0002) typedef struct tagNMBCHOTITEM { -- 2.1.4