[PATCH 2/6] comdlg32: Implement Show and Close for the Item Dialog.

David Hedberg david.hedberg at gmail.com
Wed Mar 30 22:55:23 CDT 2011


---
 dlls/comdlg32/itemdlg.c       |  293 ++++++++++++++++++++++++++++++++++++++++-
 dlls/comdlg32/tests/itemdlg.c |    3 -
 2 files changed, 289 insertions(+), 7 deletions(-)

diff --git a/dlls/comdlg32/itemdlg.c b/dlls/comdlg32/itemdlg.c
index 61dcc99..7343d70 100644
--- a/dlls/comdlg32/itemdlg.c
+++ b/dlls/comdlg32/itemdlg.c
@@ -33,6 +33,7 @@
 
 #include "commdlg.h"
 #include "cdlg.h"
+#include "filedlgbrowser.h"
 
 #include "wine/debug.h"
 #include "wine/list.h"
@@ -72,9 +73,286 @@ typedef struct FileDialogImpl {
     IShellItem *psi_defaultfolder;
     IShellItem *psi_setfolder;
     IShellItem *psi_folder;
+
+    HWND dlg_hwnd;
 } FileDialogImpl;
 
 /**************************************************************************
+ * Window related functions.
+ */
+static SIZE update_layout(FileDialogImpl *This)
+{
+    HDWP hdwp;
+    HWND hwnd;
+    RECT dialog_rc;
+    RECT cancel_rc, open_rc;
+    RECT filetype_rc, filename_rc, filenamelabel_rc;
+    int missing_width, missing_height;
+    static const UINT vspacing = 4, hspacing = 4;
+    SIZE ret;
+
+    GetClientRect(This->dlg_hwnd, &dialog_rc);
+
+    missing_width = max(0, 320 - dialog_rc.right);
+    missing_height = max(0, 200 - dialog_rc.bottom);
+
+    if(missing_width || missing_height)
+    {
+        TRACE("Missing (%d, %d)\n", missing_width, missing_height);
+        ret.cx = missing_width;
+        ret.cy = missing_height;
+        return ret;
+    }
+
+    /****
+     * Calculate the size of the dialog and all the parts.
+     */
+
+    /* Cancel button */
+    hwnd = GetDlgItem(This->dlg_hwnd, IDCANCEL);
+    if(hwnd)
+    {
+        int cancel_width, cancel_height;
+        GetWindowRect(hwnd, &cancel_rc);
+        cancel_width = cancel_rc.right - cancel_rc.left;
+        cancel_height = cancel_rc.bottom - cancel_rc.top;
+
+        cancel_rc.left = dialog_rc.right - cancel_width - hspacing;
+        cancel_rc.top = dialog_rc.bottom - cancel_height - vspacing;
+        cancel_rc.right = cancel_rc.left + cancel_width;
+        cancel_rc.bottom = cancel_rc.top + cancel_height;
+    }
+
+    /* Open/Save button */
+    if(hwnd)
+    {
+        int open_width, open_height;
+        GetWindowRect(hwnd, &open_rc);
+        open_width = open_rc.right - open_rc.left;
+        open_height = open_rc.bottom - open_rc.top;
+
+        open_rc.left = cancel_rc.left - open_width - hspacing;
+        open_rc.top = cancel_rc.top;
+        open_rc.right = open_rc.left + open_width;
+        open_rc.bottom = open_rc.top + open_height;
+    }
+
+    /* The filetype combobox. */
+    hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILETYPE);
+    if(hwnd)
+    {
+        int filetype_width, filetype_height;
+        GetWindowRect(hwnd, &filetype_rc);
+
+        filetype_width = filetype_rc.right - filetype_rc.left;
+        filetype_height = filetype_rc.bottom - filetype_rc.top;
+
+        filetype_rc.right = cancel_rc.right;
+
+        filetype_rc.left = filetype_rc.right - filetype_width;
+        filetype_rc.top = cancel_rc.top - filetype_height - vspacing;
+        filetype_rc.bottom = filetype_rc.top + filetype_height;
+
+        if(!This->filterspec_count)
+            filetype_rc.left = filetype_rc.right;
+    }
+
+    /* Filename label. */
+    hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILENAMESTATIC);
+    if(hwnd)
+    {
+        int filetypelabel_width, filetypelabel_height;
+        GetWindowRect(hwnd, &filenamelabel_rc);
+
+        filetypelabel_width = filenamelabel_rc.right - filenamelabel_rc.left;
+        filetypelabel_height = filenamelabel_rc.bottom - filenamelabel_rc.top;
+
+        filenamelabel_rc.left = 160; /* FIXME */
+        filenamelabel_rc.top = filetype_rc.top;
+        filenamelabel_rc.right = filenamelabel_rc.left + filetypelabel_width;
+        filenamelabel_rc.bottom = filenamelabel_rc.top + filetypelabel_height;
+    }
+
+    /* Filename edit box. */
+    hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILENAME);
+    if(hwnd)
+    {
+        int filename_width, filename_height;
+        GetWindowRect(hwnd, &filename_rc);
+
+        filename_width = filetype_rc.left - filenamelabel_rc.right - hspacing*2;
+        filename_height = filename_rc.bottom - filename_rc.top;
+
+        filename_rc.left = filenamelabel_rc.right + hspacing;
+        filename_rc.top = filetype_rc.top;
+        filename_rc.right = filename_rc.left + filename_width;
+        filename_rc.bottom = filename_rc.top + filename_height;
+    }
+
+    /****
+     * Move everything to the right place.
+     */
+
+    /* FIXME: The Save Dialog uses a slightly different layout. */
+    hdwp = BeginDeferWindowPos(5);
+
+    /* The default controls */
+    if(hdwp && (hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILETYPE)) )
+        DeferWindowPos(hdwp, hwnd, NULL, filetype_rc.left, filetype_rc.top, 0, 0,
+                       SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
+
+    if(hdwp && (hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILENAME)) )
+        DeferWindowPos(hdwp, hwnd, NULL, filename_rc.left, filename_rc.top,
+                       filename_rc.right - filename_rc.left, filename_rc.bottom - filename_rc.top,
+                       SWP_NOZORDER | SWP_NOACTIVATE);
+
+    if(hdwp && (hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILENAMESTATIC)) )
+        DeferWindowPos(hdwp, hwnd, NULL, filenamelabel_rc.left, filenamelabel_rc.top, 0, 0,
+                       SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
+
+    if(hdwp && (hwnd = GetDlgItem(This->dlg_hwnd, IDOK)) )
+        DeferWindowPos(hdwp, hwnd, NULL, open_rc.left, open_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);
+
+    if(hdwp)
+        EndDeferWindowPos(hdwp);
+    else
+        ERR("Failed to position dialog controls.\n");
+
+    ret.cx = 0; ret.cy = 0;
+    return ret;
+}
+
+static LRESULT on_wm_initdialog(HWND hwnd, LPARAM lParam)
+{
+    FileDialogImpl *This = (FileDialogImpl*)lParam;
+    HWND hitem;
+
+    TRACE("(%p, %p)\n", This, hwnd);
+
+    SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LPARAM)This);
+    This->dlg_hwnd = hwnd;
+
+    hitem = GetDlgItem(This->dlg_hwnd, pshHelp);
+    if(hitem) ShowWindow(hitem, SW_HIDE);
+
+    hitem = GetDlgItem(This->dlg_hwnd, IDC_FILETYPESTATIC);
+    if(hitem) ShowWindow(hitem, SW_HIDE);
+
+    /* Fill filetypes combobox, or hide it. */
+    hitem = GetDlgItem(This->dlg_hwnd, IDC_FILETYPE);
+    if(This->filterspec_count)
+    {
+        UINT i;
+        for(i = 0; i < This->filterspec_count; i++)
+            SendMessageW(hitem, CB_ADDSTRING, 0, (LPARAM)This->filterspecs[i].pszName);
+
+        SendMessageW(hitem, CB_SETCURSEL, This->filetypeindex, 0);
+    }
+    else
+        ShowWindow(hitem, SW_HIDE);
+
+    update_layout(This);
+
+    return TRUE;
+}
+
+static LRESULT on_wm_size(FileDialogImpl *This)
+{
+    update_layout(This);
+    return FALSE;
+}
+
+static LRESULT on_wm_getminmaxinfo(FileDialogImpl *This, LPARAM lparam)
+{
+    MINMAXINFO *mmi = (MINMAXINFO*)lparam;
+    TRACE("%p (%p)\n", This, mmi);
+
+    /* FIXME */
+    mmi->ptMinTrackSize.x = 640;
+    mmi->ptMinTrackSize.y = 480;
+
+    return FALSE;
+}
+
+static LRESULT on_wm_destroy(FileDialogImpl *This)
+{
+    TRACE("%p\n", This);
+
+    This->dlg_hwnd = NULL;
+
+    return TRUE;
+}
+
+static LRESULT on_idok(FileDialogImpl *This)
+{
+    TRACE("%p\n", This);
+
+    EndDialog(This->dlg_hwnd, S_OK);
+
+    return FALSE;
+}
+
+static LRESULT on_idcancel(FileDialogImpl *This)
+{
+    TRACE("%p\n", This);
+
+    EndDialog(This->dlg_hwnd, HRESULT_FROM_WIN32(ERROR_CANCELLED));
+
+    return FALSE;
+}
+
+static LRESULT on_wm_command(FileDialogImpl *This, WPARAM wparam, LPARAM lparam)
+{
+    switch(wparam)
+    {
+    case IDOK:                return on_idok(This);
+    case IDCANCEL:            return on_idcancel(This);
+    default:                  TRACE("Unknown command.\n");
+    }
+    return FALSE;
+}
+
+static LRESULT CALLBACK itemdlg_dlgproc(HWND hwnd, UINT umessage, WPARAM wparam, LPARAM lparam)
+{
+    FileDialogImpl *This = (FileDialogImpl*)GetWindowLongPtrW(hwnd, GWLP_USERDATA);
+
+    switch(umessage)
+    {
+    case WM_INITDIALOG:       return on_wm_initdialog(hwnd, lparam);
+    case WM_COMMAND:          return on_wm_command(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);
+    }
+
+    return FALSE;
+}
+
+static HRESULT create_dialog(FileDialogImpl *This, HWND parent)
+{
+    INT_PTR res;
+
+    SetLastError(0);
+    res = DialogBoxParamW(COMDLG32_hInstance,
+                          MAKEINTRESOURCEW(NEWFILEOPENV3ORD),
+                          parent, itemdlg_dlgproc, (LPARAM)This);
+    This->dlg_hwnd = NULL;
+    if(res == -1)
+    {
+        ERR("Failed to show dialog (LastError: %d)\n", GetLastError());
+        return E_FAIL;
+    }
+
+    TRACE("Returning 0x%08x\n", (HRESULT)res);
+    return (HRESULT)res;
+}
+
+/**************************************************************************
  * IFileDialog implementation
  */
 static inline FileDialogImpl *impl_from_IFileDialog2(IFileDialog2 *iface)
@@ -156,8 +434,9 @@ static ULONG WINAPI IFileDialog2_fnRelease(IFileDialog2 *iface)
 static HRESULT WINAPI IFileDialog2_fnShow(IFileDialog2 *iface, HWND hwndOwner)
 {
     FileDialogImpl *This = impl_from_IFileDialog2(iface);
-    FIXME("stub - %p (%p)\n", This, hwndOwner);
-    return E_NOTIMPL;
+    TRACE("%p (%p)\n", iface, hwndOwner);
+
+    return create_dialog(This, hwndOwner);
 }
 
 static HRESULT WINAPI IFileDialog2_fnSetFileTypes(IFileDialog2 *iface, UINT cFileTypes,
@@ -442,8 +721,12 @@ static HRESULT WINAPI IFileDialog2_fnSetDefaultExtension(IFileDialog2 *iface, LP
 static HRESULT WINAPI IFileDialog2_fnClose(IFileDialog2 *iface, HRESULT hr)
 {
     FileDialogImpl *This = impl_from_IFileDialog2(iface);
-    FIXME("stub - %p (0x%08x)\n", This, hr);
-    return E_NOTIMPL;
+    TRACE("%p (0x%08x)\n", This, hr);
+
+    if(This->dlg_hwnd)
+        EndDialog(This->dlg_hwnd, hr);
+
+    return S_OK;
 }
 
 static HRESULT WINAPI IFileDialog2_fnSetClientGuid(IFileDialog2 *iface, REFGUID guid)
@@ -1043,6 +1326,8 @@ static HRESULT FileDialog_constructor(IUnknown *pUnkOuter, REFIID riid, void **p
     list_init(&fdimpl->events_clients);
     fdimpl->events_next_cookie = 0;
 
+    fdimpl->dlg_hwnd = NULL;
+
     /* FIXME: The default folder setting should be restored for the
      * application if it was previously set. */
     SHGetDesktopFolder(&psf);
diff --git a/dlls/comdlg32/tests/itemdlg.c b/dlls/comdlg32/tests/itemdlg.c
index 2e26186..b0661b4 100644
--- a/dlls/comdlg32/tests/itemdlg.c
+++ b/dlls/comdlg32/tests/itemdlg.c
@@ -574,13 +574,10 @@ static void test_basics(void)
     }
 
     /* Close */
-    todo_wine
-    {
     hr = IFileOpenDialog_Close(pfod, S_FALSE);
     ok(hr == S_OK, "got 0x%08x\n", hr);
     hr = IFileSaveDialog_Close(pfsd, S_FALSE);
     ok(hr == S_OK, "got 0x%08x\n", hr);
-    }
 
     /* SetOkButtonLabel */
     todo_wine
-- 
1.7.4.1




More information about the wine-patches mailing list