David Hedberg : comdlg32: Layout the customized controls.

Alexandre Julliard julliard at winehq.org
Fri May 27 11:03:40 CDT 2011


Module: wine
Branch: master
Commit: bb2230f0e8a287a70f56ff582d410b93f44d081b
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=bb2230f0e8a287a70f56ff582d410b93f44d081b

Author: David Hedberg <david.hedberg at gmail.com>
Date:   Fri May 27 04:05:52 2011 +0200

comdlg32: Layout the customized controls.

---

 dlls/comdlg32/itemdlg.c |  158 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 157 insertions(+), 1 deletions(-)

diff --git a/dlls/comdlg32/itemdlg.c b/dlls/comdlg32/itemdlg.c
index 40e785c..5acf3d2 100644
--- a/dlls/comdlg32/itemdlg.c
+++ b/dlls/comdlg32/itemdlg.c
@@ -536,6 +536,29 @@ static void ctrl_resize(HWND hctrl, UINT min_width, UINT max_width)
     HeapFree(GetProcessHeap(), 0, text);
 }
 
+static void customctrl_resize(FileDialogImpl *This, customctrl *ctrl)
+{
+    RECT rc;
+
+    switch(ctrl->type)
+    {
+    case IDLG_CCTRL_PUSHBUTTON:
+    case IDLG_CCTRL_COMBOBOX:
+    case IDLG_CCTRL_CHECKBUTTON:
+    case IDLG_CCTRL_TEXT:
+        ctrl_resize(ctrl->hwnd, 160, 160);
+        GetWindowRect(ctrl->hwnd, &rc);
+        SetWindowPos(ctrl->wrapper_hwnd, NULL, 0, 0, rc.right-rc.left, rc.bottom-rc.top,
+                     SWP_NOZORDER|SWP_NOMOVE|SWP_NOZORDER);
+    case IDLG_CCTRL_RADIOBUTTONLIST:
+    case IDLG_CCTRL_EDITBOX:
+    case IDLG_CCTRL_SEPARATOR:
+    case IDLG_CCTRL_MENU:
+        /* Nothing */
+        break;
+    }
+}
+
 static LRESULT notifysink_on_create(HWND hwnd, CREATESTRUCTW *crs)
 {
     FileDialogImpl *This = crs->lpCreateParams;
@@ -613,7 +636,126 @@ static HRESULT cctrl_create_new(FileDialogImpl *This, DWORD id,
  */
 static UINT ctrl_container_resize(FileDialogImpl *This, UINT container_width)
 {
-    return 0;
+    UINT container_height;
+    UINT column_width;
+    UINT nr_of_cols;
+    UINT max_control_height, total_height = 0;
+    UINT cur_col_pos, cur_row_pos;
+    customctrl *ctrl;
+    BOOL fits_height;
+    static const UINT col_indent = 100; /* The first column is indented 100px */
+    static const UINT cspacing = 90;    /* Columns are spaced with 90px */
+    static const UINT rspacing = 4;     /* Rows are spaced with 4 px. */
+
+    /* Given the new width of the container, this function determines the
+     * needed height of the container and places the controls according to
+     * the new layout. Returns the new height.
+     */
+
+    TRACE("%p\n", This);
+
+    column_width = This->cctrl_width + cspacing;
+    nr_of_cols = (container_width - col_indent + cspacing) / column_width;
+
+    /* We don't need to do anything unless the number of visible columns has changed. */
+    if(nr_of_cols == This->cctrls_cols)
+    {
+        RECT rc;
+        GetWindowRect(This->cctrls_hwnd, &rc);
+        return rc.bottom - rc.top;
+    }
+
+   This->cctrls_cols = nr_of_cols;
+
+    /* Get the size of the tallest control, and the total size of
+     * all the controls to figure out the number of slots we need.
+     */
+    max_control_height = 0;
+    LIST_FOR_EACH_ENTRY(ctrl, &This->cctrls, customctrl, entry)
+    {
+        if(ctrl->cdcstate & CDCS_VISIBLE)
+        {
+            RECT rc;
+            UINT control_height;
+            GetWindowRect(ctrl->wrapper_hwnd, &rc);
+            control_height = rc.bottom - rc.top;
+            max_control_height = max(max_control_height, control_height);
+
+            total_height +=  control_height + rspacing;
+        }
+    }
+
+    if(!total_height)
+        return 0;
+
+    container_height = max(total_height / nr_of_cols, max_control_height + rspacing);
+    TRACE("Guess: container_height: %d\n",container_height);
+
+    /* Incrementally increase container_height until all the controls
+     * fit.
+     */
+    do {
+        UINT columns_needed = 1;
+        cur_row_pos = 0;
+
+        fits_height = TRUE;
+        LIST_FOR_EACH_ENTRY(ctrl, &This->cctrls, customctrl, entry)
+        {
+            if(ctrl->cdcstate & CDCS_VISIBLE)
+            {
+                RECT rc;
+                UINT control_height;
+                GetWindowRect(ctrl->wrapper_hwnd, &rc);
+                control_height = rc.bottom - rc.top;
+
+                if(cur_row_pos + control_height > container_height)
+                {
+                    if(++columns_needed > nr_of_cols)
+                    {
+                        container_height += 1;
+                        fits_height = FALSE;
+                        break;
+                    }
+                    cur_row_pos = 0;
+                }
+
+                cur_row_pos += control_height + rspacing;
+            }
+        }
+    } while(!fits_height);
+
+    TRACE("Final container height: %d\n", container_height);
+
+    /* Move the controls to their final destination
+     */
+    cur_col_pos = col_indent, cur_row_pos = 0;
+    LIST_FOR_EACH_ENTRY(ctrl, &This->cctrls, customctrl, entry)
+    {
+        if(ctrl->cdcstate & CDCS_VISIBLE)
+        {
+            RECT rc;
+            UINT control_height;
+            GetWindowRect(ctrl->wrapper_hwnd, &rc);
+            control_height = rc.bottom - rc.top;
+
+            if(cur_row_pos + control_height > container_height)
+            {
+                cur_row_pos = 0;
+                cur_col_pos += This->cctrl_width + cspacing;
+            }
+
+            SetWindowPos(ctrl->wrapper_hwnd, NULL, cur_col_pos, cur_row_pos, 0, 0,
+                         SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER);
+
+            cur_row_pos += control_height + rspacing;
+        }
+    }
+
+    /* Sanity check */
+    if(cur_row_pos + This->cctrl_width > container_width)
+        ERR("-- Failed to place controls properly.\n");
+
+    return container_height;
 }
 
 static void ctrl_container_reparent(FileDialogImpl *This, HWND parent)
@@ -622,6 +764,9 @@ static void ctrl_container_reparent(FileDialogImpl *This, HWND parent)
 
     if(parent)
     {
+        customctrl *ctrl;
+        HFONT font;
+
         wndstyle = GetWindowLongW(This->cctrls_hwnd, GWL_STYLE);
         wndstyle &= ~(WS_POPUP);
         wndstyle |= WS_CHILD;
@@ -629,6 +774,17 @@ static void ctrl_container_reparent(FileDialogImpl *This, HWND parent)
 
         SetParent(This->cctrls_hwnd, parent);
         ShowWindow(This->cctrls_hwnd, TRUE);
+
+        /* Set the fonts to match the dialog font. */
+        font = (HFONT)SendMessageW(parent, WM_GETFONT, 0, 0);
+        if(!font)
+            ERR("Failed to get font handle from dialog.\n");
+
+        LIST_FOR_EACH_ENTRY(ctrl, &This->cctrls, customctrl, entry)
+        {
+            if(font) SendMessageW(ctrl->hwnd, WM_SETFONT, (WPARAM)font, TRUE);
+            customctrl_resize(This, ctrl);
+        }
     }
     else
     {




More information about the wine-cvs mailing list