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 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) { |