[gtk/gtk-3-24: 1/2] Win32: Fix print dialog custom widget measurement
- From: Luca Bacci <lbacci src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/gtk-3-24: 1/2] Win32: Fix print dialog custom widget measurement
- Date: Thu, 18 Nov 2021 19:03:01 +0000 (UTC)
commit 1650b4b205191609b5e79393ca07257fa6aa8bca
Author: Luca Bacci <luca bacci982 gmail com>
Date: Mon Nov 15 11:51:43 2021 +0100
Win32: Fix print dialog custom widget measurement
gtk/gtkprintoperation-win32.c | 142 ++++++++++++++++++++++++++++++++----------
gtk/gtkwin32embedwidget.c | 1 +
2 files changed, 109 insertions(+), 34 deletions(-)
---
diff --git a/gtk/gtkprintoperation-win32.c b/gtk/gtkprintoperation-win32.c
index b3f9a21cb2..abd4f7de95 100644
--- a/gtk/gtkprintoperation-win32.c
+++ b/gtk/gtkprintoperation-win32.c
@@ -47,6 +47,29 @@
#include "gtkwin32embedwidget.h"
#include "gtkprivate.h"
+#include <pshpack1.h>
+typedef struct {
+ WORD dlgVer;
+ WORD signature;
+ DWORD helpID;
+ DWORD exStyle;
+ DWORD style;
+ WORD cDlgItems;
+ short x;
+ short y;
+ short cx;
+ short cy;
+ short menu;
+ short windowClass;
+ WCHAR title;
+ WORD pointsize;
+ WORD weight;
+ BYTE italic;
+ BYTE charset;
+ WCHAR typeface[LF_FACESIZE];
+} DLGTEMPLATEEX;
+#include <poppack.h>
+
#define MAX_PAGE_RANGES 20
#define STATUS_POLLING_TIME 2000
@@ -1461,7 +1484,12 @@ pageDlgProc (HWND wnd, UINT message, WPARAM wparam, LPARAM lparam)
}
else
{
- op = GTK_PRINT_OPERATION (GetWindowLongPtrW (wnd, GWLP_USERDATA));
+ gpointer user_data = GetWindowLongPtrW (wnd, GWLP_USERDATA);
+
+ if (!user_data)
+ return FALSE;
+
+ op = GTK_PRINT_OPERATION (user_data);
op_win32 = op->priv->platform_data;
return _gtk_win32_embed_widget_dialog_procedure (GTK_WIN32_EMBED_WIDGET (op_win32->embed_widget),
@@ -1471,43 +1499,83 @@ pageDlgProc (HWND wnd, UINT message, WPARAM wparam, LPARAM lparam)
return FALSE;
}
+static INT_PTR CALLBACK
+measure_dialog_procedure (HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ return FALSE;
+}
+
static HPROPSHEETPAGE
-create_application_page (GtkPrintOperation *op)
+create_application_page (GtkPrintOperation *op,
+ HWND hwndOwner,
+ int scale)
{
- HPROPSHEETPAGE hpage;
- PROPSHEETPAGEW page;
- DLGTEMPLATE *template;
+ const LONG DBU_DEFAULT = GetDialogBaseUnits ();
+ int dbu_x = LOWORD (DBU_DEFAULT);
+ int dbu_y = HIWORD (DBU_DEFAULT);
+ HWND measure_dialog = NULL;
HGLOBAL htemplate;
- LONG base_units;
- WORD baseunitX, baseunitY;
- WORD *array;
+ DLGTEMPLATEEX *template;
+ PROPSHEETPAGEW page;
+ HPROPSHEETPAGE hpage;
GtkRequisition requisition;
- const char *tab_label;
+ const char *tab_label = NULL;
- /* Make the template the size of the custom widget size request */
- gtk_widget_get_preferred_size (op->priv->custom_widget,
- &requisition, NULL);
+ /* Widget must be visible to measure its size */
+ gtk_widget_show (op->priv->custom_widget);
+ gtk_widget_get_preferred_size (op->priv->custom_widget, &requisition, NULL);
- base_units = GetDialogBaseUnits ();
- baseunitX = LOWORD (base_units);
- baseunitY = HIWORD (base_units);
-
- htemplate = GlobalAlloc (GMEM_MOVEABLE,
- sizeof (DLGTEMPLATE) + sizeof (WORD) * 3);
+ htemplate = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof (DLGTEMPLATEEX));
template = GlobalLock (htemplate);
- template->style = WS_CHILDWINDOW | DS_CONTROL;
- template->dwExtendedStyle = WS_EX_CONTROLPARENT;
- template->cdit = 0;
- template->x = MulDiv (0, 4, baseunitX);
- template->y = MulDiv (0, 8, baseunitY);
- template->cx = MulDiv (requisition.width, 4, baseunitX);
- template->cy = MulDiv (requisition.height, 8, baseunitY);
-
- array = (WORD *) (template+1);
- *array++ = 0; /* menu */
- *array++ = 0; /* class */
- *array++ = 0; /* title */
-
+ template->dlgVer = 1;
+ template->signature = 0xFFFF;
+ template->helpID = 0;
+ template->exStyle = 0;
+ template->style = DS_SHELLFONT;
+ template->cDlgItems = 0;
+ template->x = 0;
+ template->y = 0;
+ template->cx = 10;
+ template->cy = 10;
+ template->menu = 0;
+ template->windowClass = 0;
+ template->title = 0;
+ template->pointsize = 8;
+ template->weight = FW_NORMAL;
+ template->italic = FALSE;
+ template->charset = DEFAULT_CHARSET;
+ wcscpy_s (template->typeface, LF_FACESIZE, L"MS Shell Dlg");
+
+ /* Create an invisible dialog to measure dialog base units */
+ measure_dialog = CreateDialogIndirectW (NULL, template, hwndOwner, measure_dialog_procedure);
+ if (!measure_dialog)
+ g_warning ("CreateDialogIndirectW failed");
+ else
+ {
+ RECT rect;
+
+ SetRect (&rect, 0, 0, 4, 8);
+ if (!MapDialogRect (measure_dialog, &rect))
+ g_warning ("MapDialogRect failed");
+ else
+ {
+ dbu_x = rect.right - rect.left;
+ dbu_y = rect.bottom - rect.top;
+ }
+
+ DestroyWindow (measure_dialog);
+ measure_dialog = NULL;
+ }
+
+ /* Make the template the size of the custom widget size request */
+ template->exStyle |= WS_EX_CONTROLPARENT;
+ template->style |= WS_CHILD | DS_CONTROL;
+ template->cx = (requisition.width * scale * 4.0) / dbu_x + 1;
+ template->cy = (requisition.height * scale * 8.0) / dbu_y + 1;
+
memset (&page, 0, sizeof (page));
page.dwSize = sizeof (page);
page.dwFlags = PSP_DLGINDIRECT | PSP_USETITLE | PSP_PREMATURE;
@@ -1731,6 +1799,7 @@ gtk_print_operation_run_with_dialog (GtkPrintOperation *op,
GtkPrintOperationPrivate *priv;
IPrintDialogCallback *callback;
HPROPSHEETPAGE prop_page;
+ int scale = 1;
static volatile gsize common_controls_initialized = 0;
if (g_once_init_enter (&common_controls_initialized))
@@ -1762,10 +1831,15 @@ gtk_print_operation_run_with_dialog (GtkPrintOperation *op,
if (parent == NULL)
{
invisible = gtk_invisible_new ();
+
parentHWnd = get_parent_hwnd (invisible);
+ scale = gtk_widget_get_scale_factor (invisible);
+ }
+ else
+ {
+ parentHWnd = get_parent_hwnd (GTK_WIDGET (parent));
+ scale = gtk_widget_get_scale_factor (GTK_WIDGET (parent));
}
- else
- parentHWnd = get_parent_hwnd (GTK_WIDGET (parent));
printdlgex = (LPPRINTDLGEXW)GlobalAlloc (GPTR, sizeof (PRINTDLGEXW));
if (!printdlgex)
@@ -1817,7 +1891,7 @@ gtk_print_operation_run_with_dialog (GtkPrintOperation *op,
g_signal_emit_by_name (op, "create-custom-widget",
&op->priv->custom_widget);
if (op->priv->custom_widget) {
- prop_page = create_application_page (op);
+ prop_page = create_application_page (op, parentHWnd, scale);
printdlgex->nPropertyPages = 1;
printdlgex->lphPropertyPages = &prop_page;
} else {
diff --git a/gtk/gtkwin32embedwidget.c b/gtk/gtkwin32embedwidget.c
index c4e6aff897..619a459c94 100644
--- a/gtk/gtkwin32embedwidget.c
+++ b/gtk/gtkwin32embedwidget.c
@@ -85,6 +85,7 @@ gtk_win32_embed_widget_init (GtkWin32EmbedWidget *embed_widget)
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
gtk_container_set_resize_mode (GTK_CONTAINER (embed_widget), GTK_RESIZE_QUEUE);
G_GNUC_END_IGNORE_DEPRECATIONS;
+ gtk_window_set_decorated (GTK_WINDOW (embed_widget), FALSE);
}
GtkWidget*
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]