From dd16b91a87c91de56a93d5e3dae4de78e3e6f411 Mon Sep 17 00:00:00 2001 From: Rein Klazes Date: Thu, 30 Apr 2009 08:06:50 +0200 Subject: [PATCH] comdlg32: Implement OFN_ENABLESIZING flag for GetOpenFileName and friends. --- dlls/comdlg32/filedlg.c | 161 ++++++++++++++++++++++++++++++++- dlls/comdlg32/filedlgbrowser.h | 3 + 2 files changed, 162 insertions(+), 2 deletions(-) diff --git a/dlls/comdlg32/filedlg.c b/dlls/comdlg32/filedlg.c index 8c8e230ea68..b4239425a76 100644 --- a/dlls/comdlg32/filedlg.c +++ b/dlls/comdlg32/filedlg.c @@ -37,7 +37,6 @@ * FIXME: add to recent docs * * FIXME: flags not implemented: OFN_DONTADDTORECENT, - * OFN_ENABLESIZING, * OFN_NODEREFERENCELINKS, OFN_NOREADONLYRETURN, * OFN_NOTESTFILECREATE, OFN_USEMONIKERS * @@ -82,7 +81,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(commdlg); #define UNIMPLEMENTED_FLAGS \ -(OFN_DONTADDTORECENT | OFN_ENABLESIZING |\ +(OFN_DONTADDTORECENT |\ OFN_NODEREFERENCELINKS | OFN_NOREADONLYRETURN |\ OFN_NOTESTFILECREATE /*| OFN_USEMONIKERS*/) @@ -271,6 +270,13 @@ static BOOL GetFileName95(FileOpenDlgInfos *fodInfos) return FALSE; } + if (fodInfos->ofnInfos->Flags & OFN_ENABLESIZING) + { + ((LPDLGTEMPLATEW)template)->style |= WS_SIZEBOX; + fodInfos->sizedlg.cx = fodInfos->sizedlg.cy = 0; + fodInfos->initial_size.x = fodInfos->initial_size.y = 0; + } + /* old style hook messages */ if (IsHooked(fodInfos)) { @@ -978,6 +984,125 @@ static INT_PTR FILEDLG95_HandleCustomDialogMessages(HWND hwnd, UINT uMsg, WPARAM return TRUE; } +/*********************************************************************** + * FILEDLG95_OnWMGetMMI + * + * WM_GETMINMAXINFO message handler for resizable dialogs + */ +static LRESULT FILEDLG95_OnWMGetMMI( HWND hwnd, LPMINMAXINFO mmiptr) +{ + FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr); + if( !(fodInfos->ofnInfos->Flags & OFN_ENABLESIZING)) return FALSE; + if( fodInfos->initial_size.x || fodInfos->initial_size.y) + { + mmiptr->ptMinTrackSize = fodInfos->initial_size; + } + return TRUE; +} + +/*********************************************************************** + * FILEDLG95_OnWMSize + * + * WM_SIZE message handler, resize the dialog. Re-arrange controls. + * + * FIXME: this could be made more elaborate. Now use a simple scheme + * where the file view is enlarged and the controls are either moved + * vertically or horizontally to get out of the way. Only the "grip" + * is moved in both directions to stay in the corner. + */ +static LRESULT FILEDLG95_OnWMSize(HWND hwnd, WPARAM wParam, LPARAM lParam) +{ + RECT rc, rcview; + int chgx, chgy; + HWND ctrl; + HDWP hdwp; + FileOpenDlgInfos *fodInfos; + + if( wParam != SIZE_RESTORED) return FALSE; + fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr); + if( !(fodInfos->ofnInfos->Flags & OFN_ENABLESIZING)) return FALSE; + /* get the new dialog rectangle */ + GetWindowRect( hwnd, &rc); + /* not initialized yet */ + if( (fodInfos->sizedlg.cx == 0 && fodInfos->sizedlg.cy == 0) || + ((fodInfos->sizedlg.cx == rc.right -rc.left) && /* no change */ + (fodInfos->sizedlg.cy == rc.bottom -rc.top))) + return FALSE; + chgx = rc.right - rc.left - fodInfos->sizedlg.cx; + chgy = rc.bottom - rc.top - fodInfos->sizedlg.cy; + fodInfos->sizedlg.cx = rc.right - rc.left; + fodInfos->sizedlg.cy = rc.bottom - rc.top; + /* change the size of the view window */ + GetWindowRect( fodInfos->ShellInfos.hwndView, &rcview); + MapWindowPoints( NULL, hwnd, (LPPOINT) &rcview, 2); + hdwp = BeginDeferWindowPos( 10); + DeferWindowPos( hdwp, fodInfos->ShellInfos.hwndView, NULL, 0, 0, + rcview.right - rcview.left + chgx, + rcview.bottom - rcview.top + chgy, + SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER); + /* change position and sizes of the controls */ + for( ctrl = GetWindow( hwnd, GW_CHILD); ctrl ; ctrl = GetWindow( ctrl, GW_HWNDNEXT)) + { + GetWindowRect( ctrl, &rc); + MapWindowPoints( NULL, hwnd, (LPPOINT) &rc, 2); + if( ctrl == fodInfos->DlgInfos.hwndGrip) + { + DeferWindowPos( hdwp, ctrl, NULL, rc.left + chgx, rc.top + chgy, + 0, 0, + SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER); + } + else if( rc.top > rcview.bottom) + { + /* if it was below the shell view + * move to bottom */ + DeferWindowPos( hdwp, ctrl, NULL, rc.left, rc.top + chgy, + rc.right - rc.left, rc.bottom - rc.top, + SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER); + } + else if( rc.left > rcview.right) + { + /* if it was to the right of the shell view + * move to right */ + DeferWindowPos( hdwp, ctrl, NULL, rc.left + chgx, rc.top, + rc.right - rc.left, rc.bottom - rc.top, + SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER); + } + } + if(fodInfos->DlgInfos.hwndCustomDlg && + (fodInfos->ofnInfos->Flags & (OFN_ENABLETEMPLATE | OFN_ENABLETEMPLATEHANDLE))) + { + GetClientRect(hwnd, &rc); + DeferWindowPos( hdwp,fodInfos->DlgInfos.hwndCustomDlg, NULL, + 0, 0, rc.right, rc.bottom, SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER); + for( ctrl = GetWindow( fodInfos->DlgInfos.hwndCustomDlg, GW_CHILD); + ctrl ; ctrl = GetWindow( ctrl, GW_HWNDNEXT)) + { + GetWindowRect( ctrl, &rc); + MapWindowPoints( NULL, hwnd, (LPPOINT) &rc, 2); + if( rc.top > rcview.bottom) + { + /* if it was below the shell view + * move to bottom */ + DeferWindowPos( hdwp, ctrl, NULL, rc.left, rc.top + chgy, + rc.right - rc.left, rc.bottom - rc.top, + SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER); + } + else if( rc.left > rcview.right) + { + /* if it was to the right of the shell view + * move to right */ + DeferWindowPos( hdwp, ctrl, NULL, rc.left + chgx, rc.top, + rc.right - rc.left, rc.bottom - rc.top, + SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER); + } + } + } + EndDeferWindowPos( hdwp); + /* should not be needed */ + RedrawWindow( hwnd, NULL, 0, RDW_ALLCHILDREN | RDW_INVALIDATE ); + return TRUE; +} + /*********************************************************************** * FileOpenDlgProc95 * @@ -994,6 +1119,9 @@ INT_PTR CALLBACK FileOpenDlgProc95(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l case WM_INITDIALOG: { FileOpenDlgInfos * fodInfos = (FileOpenDlgInfos *)lParam; + RECT rc; + int gripx = GetSystemMetrics( SM_CYHSCROLL); + int gripy = GetSystemMetrics( SM_CYVSCROLL); /* Adds the FileOpenDlgInfos in the property list of the dialog so it will be easily accessible through a GetPropA(...) */ @@ -1001,17 +1129,46 @@ INT_PTR CALLBACK FileOpenDlgProc95(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l FILEDLG95_InitControls(hwnd); + if (fodInfos->ofnInfos->Flags & OFN_ENABLESIZING) + { + GetWindowRect( hwnd, &rc); + fodInfos->DlgInfos.hwndGrip = + CreateWindowExA( 0, "SCROLLBAR", NULL, + WS_CHILD | WS_GROUP | WS_VISIBLE | WS_CLIPSIBLINGS | + SBS_SIZEGRIP | SBS_SIZEBOXBOTTOMRIGHTALIGN, + rc.right - gripx, rc.bottom - gripy, + gripx, gripy, hwnd, (HMENU) -1, COMDLG32_hInstance, NULL); + } + fodInfos->DlgInfos.hwndCustomDlg = CreateTemplateDialog((FileOpenDlgInfos *)lParam, hwnd); FILEDLG95_ResizeControls(hwnd, wParam, lParam); FILEDLG95_FillControls(hwnd, wParam, lParam); + if (fodInfos->ofnInfos->Flags & OFN_ENABLESIZING) + { + GetWindowRect( hwnd, &rc); + /* FIXME: should remember sizes of last invocation */ + fodInfos->sizedlg.cx = rc.right - rc.left; + fodInfos->sizedlg.cy = rc.bottom - rc.top; + fodInfos->initial_size.x = fodInfos->sizedlg.cx; + fodInfos->initial_size.y = fodInfos->sizedlg.cy; + GetClientRect( hwnd, &rc); + SetWindowPos( fodInfos->DlgInfos.hwndGrip, NULL, + rc.right - gripx, rc.bottom - gripy, + 0, 0, SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER); + } + SendCustomDlgNotificationMessage(hwnd,CDN_INITDONE); SendCustomDlgNotificationMessage(hwnd,CDN_FOLDERCHANGE); SendCustomDlgNotificationMessage(hwnd,CDN_SELCHANGE); return 0; } + case WM_SIZE: + return FILEDLG95_OnWMSize(hwnd, wParam, lParam); + case WM_GETMINMAXINFO: + return FILEDLG95_OnWMGetMMI( hwnd, (LPMINMAXINFO)lParam); case WM_COMMAND: return FILEDLG95_OnWMCommand(hwnd, wParam, lParam); case WM_DRAWITEM: diff --git a/dlls/comdlg32/filedlgbrowser.h b/dlls/comdlg32/filedlgbrowser.h index f8da75eddf7..ca332ec5f8e 100644 --- a/dlls/comdlg32/filedlgbrowser.h +++ b/dlls/comdlg32/filedlgbrowser.h @@ -58,6 +58,8 @@ typedef struct LPCWSTR defext; LPCWSTR filter; LPCWSTR customfilter; + SIZE sizedlg; /* remember the size of the dialog */ + POINT initial_size; /* remember the initial size of the dialog */ struct { IShellBrowser *FOIShellBrowser; IShellFolder *FOIShellFolder; @@ -78,6 +80,7 @@ typedef struct HWND hwndLookInCB; HWND hwndFileName; HWND hwndTB; + HWND hwndGrip; HWND hwndCustomDlg; DWORD dwDlgProp; } DlgInfos;