summaryrefslogtreecommitdiffstats
path: root/win/tkWinDialog.c
diff options
context:
space:
mode:
Diffstat (limited to 'win/tkWinDialog.c')
-rw-r--r--win/tkWinDialog.c49
1 files changed, 48 insertions, 1 deletions
diff --git a/win/tkWinDialog.c b/win/tkWinDialog.c
index 61799dc..4a18942 100644
--- a/win/tkWinDialog.c
+++ b/win/tkWinDialog.c
@@ -8,7 +8,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkWinDialog.c,v 1.35 2004/05/24 21:23:23 dkf Exp $
+ * RCS: @(#) $Id: tkWinDialog.c,v 1.36 2004/08/20 00:58:52 hobbs Exp $
*
*/
@@ -68,6 +68,9 @@ typedef struct ThreadSpecificData {
UINT WM_LBSELCHANGED; /* Holds a registered windows event used for
* communicating between the Directory
* Chooser dialog and its hook proc. */
+ HHOOK hMsgBoxHook; /* Hook proc for tk_messageBox and the */
+ HICON hSmallIcon; /* icons used by a parent to be used in */
+ HICON hBigIcon; /* the message box */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
@@ -178,6 +181,7 @@ static UINT APIENTRY OFNHookProc(HWND hdlg, UINT uMsg, WPARAM wParam,
LPARAM lParam);
static UINT APIENTRY OFNHookProcW(HWND hdlg, UINT uMsg, WPARAM wParam,
LPARAM lParam);
+static LRESULT CALLBACK MsgBoxCBTProc(int nCode, WPARAM wParam, LPARAM lParam);
static void SetTkDialog(ClientData clientData);
/*
@@ -2540,6 +2544,8 @@ Tk_MessageBoxObjCmd(clientData, interp, objc, objv)
MSG_DEFAULT, MSG_DETAIL, MSG_ICON, MSG_MESSAGE,
MSG_PARENT, MSG_TITLE, MSG_TYPE
};
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
tkwin = (Tk_Window) clientData;
@@ -2668,12 +2674,22 @@ Tk_MessageBoxObjCmd(clientData, interp, objc, objv)
Tcl_UtfToExternalDString(unicodeEncoding, title, -1, &titleString);
oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
+
/*
* MessageBoxW exists for all platforms. Use it to allow unicode
* error message to be displayed correctly where possible by the OS.
+ *
+ * In order to have the parent window icon reflected in a MessageBox,
+ * we have to create a hook that will trigger when the MessageBox is
+ * being created.
*/
+ tsdPtr->hSmallIcon = TkWinGetIcon(parent, ICON_SMALL);
+ tsdPtr->hBigIcon = TkWinGetIcon(parent, ICON_BIG);
+ tsdPtr->hMsgBoxHook = SetWindowsHookEx(WH_CBT, MsgBoxCBTProc, NULL,
+ GetCurrentThreadId());
winCode = MessageBoxW(hWnd, (WCHAR *) Tcl_DStringValue(&messageString),
(WCHAR *) Tcl_DStringValue(&titleString), flags);
+ UnhookWindowsHookEx(tsdPtr->hMsgBoxHook);
(void) Tcl_SetServiceMode(oldMode);
/*
@@ -2690,6 +2706,37 @@ Tk_MessageBoxObjCmd(clientData, interp, objc, objv)
return TCL_OK;
}
+static LRESULT CALLBACK
+MsgBoxCBTProc(int nCode, WPARAM wParam, LPARAM lParam)
+{
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+
+ if (nCode == HCBT_CREATEWND) {
+ /*
+ * Window owned by our task is being created. Since the hook is
+ * installed just before the MessageBox call and removed after the
+ * MessageBox call, the window being created is either the message
+ * box or one of its controls. Check that the class is WC_DIALOG
+ * to ensure that it's the one we want.
+ */
+ LPCBT_CREATEWND lpcbtcreate = (LPCBT_CREATEWND)lParam;
+
+ if (WC_DIALOG == lpcbtcreate->lpcs->lpszClass) {
+ HWND hwnd = (HWND) wParam;
+ SendMessage(hwnd, WM_SETICON, ICON_SMALL,
+ (LPARAM) tsdPtr->hSmallIcon);
+ SendMessage(hwnd, WM_SETICON, ICON_BIG,
+ (LPARAM) tsdPtr->hBigIcon);
+ }
+ }
+
+ /*
+ * Call the next hook proc, if there is one
+ */
+ return CallNextHookEx(tsdPtr->hMsgBoxHook, nCode, wParam, lParam);
+}
+
static void
SetTkDialog(ClientData clientData)
{