tWin32 widgets in tab pages are now made children of an embedded dialog box. Th… | |
git clone git://src.adamsgaard.dk/vaccinewars | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit c93e1368ae9043a09ee189fc468a024fba9036c4 | |
parent a0ab9bd376c839eb5048870043f82a510691bddb | |
Author: Ben Webb <[email protected]> | |
Date: Wed, 11 Sep 2002 10:23:03 +0000 | |
Win32 widgets in tab pages are now made children of an embedded dialog box. | |
This means that pages can now be easily shown/hidden by just showing/hiding | |
tthe parent dialog box. In addition, this appears to be the only way under | |
Windows XP of getting the right background texture in tab controls. Functions | |
have been added to a) check that we're using version 6 or later of | |
comctl32.dll (as shipped with XP) and b) call the EnableThemeDialogTexture in | |
uxtheme.dll (if present) to set the background texture. | |
Diffstat: | |
M ChangeLog | 1 + | |
M src/dopewars.rc | 5 +++++ | |
M src/gtkport/clist.c | 7 +++++-- | |
M src/gtkport/gtkport.c | 148 +++++++++++++++++++++++++----… | |
M src/gtkport/gtkport.h | 2 ++ | |
5 files changed, 132 insertions(+), 31 deletions(-) | |
--- | |
diff --git a/ChangeLog b/ChangeLog | |
t@@ -17,6 +17,7 @@ cvs | |
- Spanish translation added by Quique | |
- The Windows build of dopewars should now use Unicode throughout, on | |
platforms with Unicode support (i.e. NT/2000/XP) | |
+ - Under Windows XP, the "pretty" new common controls are now used | |
1.5.7 25-06-2002 | |
- Sound support; Windows multimedia, ESD and SDL outputs are supported; | |
diff --git a/src/dopewars.rc b/src/dopewars.rc | |
t@@ -9,3 +9,8 @@ STYLE WS_POPUP | WS_CAPTION | WS_THICKFRAME | DS_MODALFRAME | … | |
CAPTION "" | |
BEGIN | |
END | |
+ | |
+tabpage DIALOG 40, 40, 40, 40 | |
+STYLE DS_CONTROL | WS_CHILD | DS_3DLOOK | WS_VISIBLE | |
+BEGIN | |
+END | |
diff --git a/src/gtkport/clist.c b/src/gtkport/clist.c | |
t@@ -132,8 +132,11 @@ void gtk_clist_set_size(GtkWidget *widget, GtkAllocation … | |
gtk_container_set_size(widget, allocation); | |
if (clist->header) { | |
- SetWindowPos(clist->header, HWND_TOP, | |
- allocation->x, allocation->y, | |
+ POINT pt; | |
+ pt.x = allocation->x; | |
+ pt.y = allocation->y; | |
+ MapWidgetOrigin(widget, &pt); | |
+ SetWindowPos(clist->header, HWND_TOP, pt.x, pt.y, | |
allocation->width, clist->header_size, SWP_NOZORDER); | |
allocation->y += clist->header_size - 1; | |
allocation->height -= clist->header_size - 1; | |
diff --git a/src/gtkport/gtkport.c b/src/gtkport/gtkport.c | |
t@@ -58,6 +58,7 @@ const gchar *GTK_STOCK_HELP = N_("_Help"); | |
#include <winsock.h> | |
#include <commctrl.h> | |
#include <richedit.h> | |
+#include <shlwapi.h> | |
#define LISTITEMVPACK 0 | |
t@@ -67,6 +68,7 @@ HICON mainIcon = NULL; | |
static WNDPROC customWndProc = NULL; | |
static gboolean HaveRichEdit = FALSE; | |
static gchar *RichEditClass = NULL; | |
+static gboolean HaveXPControls = FALSE; | |
static guint RecurseLevel = 0; | |
t@@ -76,6 +78,11 @@ static const gchar *WC_GTKHPANED = "WC_GTKHPANED"; | |
static const gchar *WC_GTKDIALOG = "WC_GTKDIALOG"; | |
static const gchar *WC_GTKURL = "WC_GTKURL"; | |
+static const int ETDT_DISABLE = 0x1; | |
+static const int ETDT_ENABLE = 0x2; | |
+static const int ETDT_USETABTEXTURE = 0x4; | |
+static const int ETDT_ENABLETAB = 0x6; | |
+ | |
static void gtk_button_size_request(GtkWidget *widget, | |
GtkRequisition *requisition); | |
static void gtk_entry_size_request(GtkWidget *widget, | |
t@@ -691,7 +698,7 @@ static void DispatchTimeoutEvent(UINT id) | |
} | |
} | |
-HWND gtk_get_parent_hwnd(GtkWidget *widget) | |
+static HWND gtk_get_window_hwnd(GtkWidget *widget) | |
{ | |
widget = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW); | |
if (widget) { | |
t@@ -701,20 +708,34 @@ HWND gtk_get_parent_hwnd(GtkWidget *widget) | |
} | |
} | |
-static HWND gtk_get_window_or_notebook(GtkWidget *widget) | |
+HWND gtk_get_parent_hwnd(GtkWidget *widget) | |
{ | |
+ GtkWidget *child = NULL; | |
while (widget && GTK_OBJECT(widget)->klass != GTK_TYPE_WINDOW | |
&& GTK_OBJECT(widget)->klass != GTK_TYPE_NOTEBOOK) { | |
+ child = widget; | |
widget = widget->parent; | |
} | |
if (widget) { | |
- return widget->hWnd; | |
+ if (GTK_OBJECT(widget)->klass == GTK_TYPE_NOTEBOOK) { | |
+ GSList *children; | |
+ for (children = GTK_NOTEBOOK(widget)->children; children; | |
+ children = g_slist_next(children)) { | |
+ GtkNotebookChild *note_child; | |
+ note_child = (GtkNotebookChild *)(children->data); | |
+ if (note_child && note_child->child == child) { | |
+ return note_child->tabpage; | |
+ } | |
+ } | |
+ return NULL; | |
+ } else { | |
+ return widget->hWnd; | |
+ } | |
} else { | |
return NULL; | |
} | |
} | |
- | |
static void UpdatePanedGhostRect(GtkPaned *paned, RECT *OldRect, | |
RECT *NewRect, gint x, gint y) | |
{ | |
t@@ -1016,17 +1037,6 @@ static BOOL HandleWinMessage(HWND hwnd, UINT msg, WPARA… | |
} | |
switch (msg) { | |
- case WM_CTLCOLORSTATIC: | |
- widget = GTK_WIDGET(myGetWindowLong((HWND)lParam, GWL_USERDATA)); | |
- if (widget && gtk_widget_get_ancestor(widget, GTK_TYPE_NOTEBOOK)) { | |
- hDC = (HDC)wParam; | |
- if (GTK_OBJECT(widget)->klass == &GtkLabelClass) { | |
- SetBkMode(hDC, TRANSPARENT); | |
- *dodef = FALSE; | |
- return (gboolean)GetStockObject(NULL_BRUSH); | |
- } | |
- } | |
- break; | |
case WM_DRAWITEM: | |
if ((lpdis = (LPDRAWITEMSTRUCT)lParam) | |
&& (widget = GTK_WIDGET(myGetWindowLong(lpdis->hwndItem, GWL_USERDATA)… | |
t@@ -1153,6 +1163,59 @@ void SetCustomWndProc(WNDPROC wndproc) | |
customWndProc = wndproc; | |
} | |
+/* | |
+ * Returns TRUE if we are using version 6 of the Common Controls library | |
+ * (as shipped with Windows XP) and thus need to worry about visual themes | |
+ */ | |
+static gboolean CheckForXPControls(void) | |
+{ | |
+ HINSTANCE hDll; | |
+ BOOL retval = FALSE; | |
+ | |
+ hDll = LoadLibrary("COMCTL32.DLL"); | |
+ if (hDll) { | |
+ DLLGETVERSIONPROC getverproc; | |
+ getverproc = (DLLGETVERSIONPROC)GetProcAddress(hDll, "DllGetVersion"); | |
+ if (getverproc) { | |
+ DLLVERSIONINFO dvi; | |
+ HRESULT hr; | |
+ ZeroMemory(&dvi, sizeof(dvi)); | |
+ dvi.cbSize = sizeof(dvi); | |
+ hr = getverproc(&dvi); | |
+ if (SUCCEEDED(hr) && dvi.dwMajorVersion >= 6) { | |
+ retval = TRUE; | |
+ } | |
+ } | |
+ FreeLibrary(hDll); | |
+ } | |
+ return retval; | |
+} | |
+ | |
+/* | |
+ * On systems with suitable DLLs, sets the background texture of the | |
+ * given dialog. dwFlags can be one or more of the ETDT_ constants. | |
+ */ | |
+static void myEnableThemeDialogTexture(HWND hWnd, DWORD dwFlags) | |
+{ | |
+ typedef HRESULT (*ENABLETHEMEDIALOGTEXTUREPROC)(HWND hWnd, DWORD dwFlags); | |
+ HINSTANCE module; | |
+ | |
+ /* Dialog textures are only worth setting when using XP common controls */ | |
+ if (!HaveXPControls) return; | |
+ | |
+ module = LoadLibrary("UXTHEME.DLL"); | |
+ if (module) { | |
+ ENABLETHEMEDIALOGTEXTUREPROC func; | |
+ HRESULT result; | |
+ func = (ENABLETHEMEDIALOGTEXTUREPROC) | |
+ GetProcAddress(module, "EnableThemeDialogTexture"); | |
+ if (func) { | |
+ result = func(hWnd, dwFlags); | |
+ } | |
+ FreeLibrary(module); | |
+ } | |
+} | |
+ | |
void win32_init(HINSTANCE hInstance, HINSTANCE hPrevInstance, | |
char *MainIcon) | |
{ | |
t@@ -1186,6 +1249,8 @@ void win32_init(HINSTANCE hInstance, HINSTANCE hPrevInst… | |
} | |
HaveRichEdit = GetClassInfo(hInstance, RichEditClass, &wc); | |
+ HaveXPControls = CheckForXPControls(); | |
+ | |
if (!hPrevInstance) { | |
wc.style = 0; | |
wc.lpfnWndProc = MainWndProc; | |
t@@ -1529,21 +1594,27 @@ void gtk_widget_size_request(GtkWidget *widget, | |
} | |
} | |
+void MapWidgetOrigin(GtkWidget *widget, POINT *pt) | |
+{ | |
+ HWND imm_parent, window_parent; | |
+ | |
+ imm_parent = GetParent(widget->hWnd); | |
+ window_parent = gtk_get_window_hwnd(widget); | |
+ if (imm_parent && window_parent && imm_parent != window_parent) { | |
+ MapWindowPoints(window_parent, imm_parent, pt, 1); | |
+ } | |
+} | |
+ | |
void gtk_widget_set_size(GtkWidget *widget, GtkAllocation *allocation) | |
{ | |
gtk_signal_emit(GTK_OBJECT(widget), "set_size", allocation); | |
memcpy(&widget->allocation, allocation, sizeof(GtkAllocation)); | |
if (widget->hWnd) { | |
- HWND imm_parent, window_parent; | |
POINT pt; | |
pt.x = allocation->x; | |
pt.y = allocation->y; | |
- imm_parent = GetParent(widget->hWnd); | |
- window_parent = gtk_get_parent_hwnd(widget); | |
- if (imm_parent && window_parent && imm_parent != window_parent) { | |
- MapWindowPoints(window_parent, imm_parent, &pt, 1); | |
- } | |
+ MapWidgetOrigin(widget, &pt); | |
SetWindowPos(widget->hWnd, HWND_TOP, pt.x, pt.y, | |
allocation->width, allocation->height, | |
SWP_NOZORDER | | |
t@@ -2553,7 +2624,7 @@ void gtk_frame_realize(GtkWidget *widget) | |
HWND Parent; | |
GtkFrame *frame = GTK_FRAME(widget); | |
- Parent = gtk_get_window_or_notebook(widget); | |
+ Parent = gtk_get_parent_hwnd(widget); | |
widget->hWnd = myCreateWindow("BUTTON", frame->text, | |
WS_CHILD | BS_GROUPBOX, | |
widget->allocation.x, widget->allocation.y, | |
t@@ -4065,10 +4136,16 @@ void gtk_notebook_insert_page(GtkNotebook *notebook, G… | |
GtkWidget *tab_label, gint position) | |
{ | |
GtkNotebookChild *note_child; | |
+ GtkWidget *widget = GTK_WIDGET(notebook); | |
+ | |
note_child = g_new0(GtkNotebookChild, 1); | |
note_child->child = child; | |
note_child->tab_label = tab_label; | |
+ note_child->tabpage = myCreateDialog(hInst, "tabpage", | |
+ gtk_get_parent_hwnd(widget->parent), | |
+ MainDlgProc); | |
+ myEnableThemeDialogTexture(note_child->tabpage, ETDT_ENABLETAB); | |
notebook->children = | |
g_slist_insert(notebook->children, note_child, position); | |
child->parent = GTK_WIDGET(notebook); | |
t@@ -4092,10 +4169,11 @@ void gtk_notebook_set_page(GtkNotebook *notebook, gint… | |
children = g_slist_next(children)) { | |
note_child = (GtkNotebookChild *)(children->data); | |
if (note_child && note_child->child) { | |
- if (pos == page_num) | |
- gtk_widget_show_all_full(note_child->child, TRUE); | |
- else | |
- gtk_widget_hide_all_full(note_child->child, TRUE); | |
+ if (pos == page_num) { | |
+ ShowWindow(note_child->tabpage, SW_SHOW); | |
+ } else { | |
+ ShowWindow(note_child->tabpage, SW_HIDE); | |
+ } | |
pos++; | |
} | |
} | |
t@@ -4115,7 +4193,7 @@ void gtk_notebook_realize(GtkWidget *widget) | |
gint tab_pos = 0; | |
TC_ITEM tie; | |
- Parent = gtk_get_parent_hwnd(widget); | |
+ Parent = gtk_get_parent_hwnd(widget->parent); | |
GTK_WIDGET_SET_FLAGS(widget, GTK_CAN_FOCUS); | |
widget->hWnd = myCreateWindow(WC_TABCONTROL, "", | |
WS_CHILD | WS_TABSTOP, 0, 0, 0, 0, | |
t@@ -4136,6 +4214,10 @@ void gtk_notebook_realize(GtkWidget *widget) | |
else | |
tie.pszText = "No label"; | |
myTabCtrl_InsertItem(widget->hWnd, tab_pos++, &tie); | |
+ note_child->tabpage = myCreateDialog(hInst, "tabpage", | |
+ gtk_get_parent_hwnd(widget->parent), | |
+ MainDlgProc); | |
+ myEnableThemeDialogTexture(note_child->tabpage, ETDT_ENABLETAB); | |
if (note_child->child) { | |
gtk_widget_realize(note_child->child); | |
} | |
t@@ -4171,6 +4253,7 @@ void gtk_notebook_hide_all(GtkWidget *widget, gboolean h… | |
note_child = (GtkNotebookChild *)(children->data); | |
if (note_child && note_child->child) | |
gtk_widget_hide_all_full(note_child->child, hWndOnly); | |
+ ShowWindow(note_child->tabpage, SW_HIDE); | |
} | |
} | |
t@@ -4185,6 +4268,7 @@ void gtk_notebook_destroy(GtkWidget *widget) | |
if (note_child) { | |
gtk_widget_destroy(note_child->child); | |
gtk_widget_destroy(note_child->tab_label); | |
+ DestroyWindow(note_child->tabpage); | |
} | |
g_free(note_child); | |
} | |
t@@ -4215,6 +4299,9 @@ void gtk_notebook_set_size(GtkWidget *widget, GtkAllocat… | |
children = g_slist_next(children)) { | |
note_child = (GtkNotebookChild *)(children->data); | |
if (note_child && note_child->child) { | |
+ SetWindowPos(note_child->tabpage, HWND_TOP, | |
+ rect.left, rect.top, rect.right - rect.left, | |
+ rect.bottom - rect.top, SWP_NOZORDER); | |
gtk_widget_set_size(note_child->child, &child_alloc); | |
} | |
} | |
t@@ -4299,8 +4386,11 @@ void gtk_spin_button_set_size(GtkWidget *widget, GtkAll… | |
updown = GTK_SPIN_BUTTON(widget)->updown; | |
if (updown) { | |
- SetWindowPos(updown, HWND_TOP, | |
- allocation->x + allocation->width, allocation->y, | |
+ POINT pt; | |
+ pt.x = allocation->x; | |
+ pt.y = allocation->y; | |
+ MapWidgetOrigin(widget, &pt); | |
+ SetWindowPos(updown, HWND_TOP, pt.x + allocation->width, pt.y, | |
udwidth, allocation->height, SWP_NOZORDER); | |
} | |
} | |
diff --git a/src/gtkport/gtkport.h b/src/gtkport/gtkport.h | |
t@@ -343,6 +343,7 @@ struct _GtkVBox { | |
struct _GtkNotebookChild { | |
GtkWidget *child, *tab_label; | |
+ HWND tabpage; | |
}; | |
struct _GtkNotebook { | |
t@@ -717,6 +718,7 @@ void gtk_marshal_VOID__GINT_GINT_EVENT(GtkObject *object, … | |
/* Private functions */ | |
void gtk_container_set_size(GtkWidget *widget, GtkAllocation *allocation); | |
+void MapWidgetOrigin(GtkWidget *widget, POINT *pt); | |
#else /* CYGWIN */ | |