diff options
Diffstat (limited to 'win/tkWinDialog.c')
-rw-r--r-- | win/tkWinDialog.c | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/win/tkWinDialog.c b/win/tkWinDialog.c index 2b18d45..af512ad 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.30.2.2 2004/02/13 01:26:41 hobbs Exp $ + * RCS: @(#) $Id: tkWinDialog.c,v 1.30.2.3 2004/08/20 00:40:32 hobbs Exp $ * */ @@ -62,6 +62,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; @@ -172,6 +175,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); /* @@ -2487,6 +2491,8 @@ Tk_MessageBoxObjCmd(clientData, interp, objc, objv) MSG_DEFAULT, MSG_ICON, MSG_MESSAGE, MSG_PARENT, MSG_TITLE, MSG_TYPE }; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); tkwin = (Tk_Window) clientData; @@ -2594,12 +2600,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); /* @@ -2616,6 +2632,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) { |