From f82a6ef646a08bece15a3a9cd666440490f8ff53 Mon Sep 17 00:00:00 2001 From: chengyemao Date: Tue, 28 Dec 2004 08:45:31 +0000 Subject: Modified to support embedded menu widget --- win/tkWin.h | 3 ++- win/tkWinEmbed.c | 47 +++++++++++++++++++++++++++++++++++-- win/tkWinMenu.c | 32 +++++++++++++++++++++++++- win/tkWinWm.c | 70 ++++++++++++++++++++++++++++++++------------------------ win/tkWinX.c | 3 ++- 5 files changed, 120 insertions(+), 35 deletions(-) diff --git a/win/tkWin.h b/win/tkWin.h index ce4cbc1..c8eca7f 100644 --- a/win/tkWin.h +++ b/win/tkWin.h @@ -9,7 +9,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkWin.h,v 1.10 2004/12/20 15:30:43 chengyemao Exp $ + * RCS: @(#) $Id: tkWin.h,v 1.11 2004/12/28 08:45:31 chengyemao Exp $ */ #ifndef _TKWIN @@ -48,6 +48,7 @@ #define TK_WITHDRAW (WM_USER+8) /* an embedded window requests to withdraw */ #define TK_GETFRAMEWID (WM_USER+9) /* an embedded window requests a frame window id */ #define TK_OVERRIDEREDIRECT (WM_USER+10) /* an embedded window requests to overrideredirect */ +#define TK_SETMENU (WM_USER+11) /* an embedded window requests to setup menu */ /* *-------------------------------------------------------------- diff --git a/win/tkWinEmbed.c b/win/tkWinEmbed.c index 1aca63f..371d5c3 100644 --- a/win/tkWinEmbed.c +++ b/win/tkWinEmbed.c @@ -11,7 +11,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkWinEmbed.c,v 1.15 2004/12/20 15:30:43 chengyemao Exp $ + * RCS: @(#) $Id: tkWinEmbed.c,v 1.16 2004/12/28 08:45:31 chengyemao Exp $ */ #include "tkWinInt.h" @@ -33,6 +33,7 @@ typedef struct Container { * window, or NULL if the * embedded application isn't in * this process. */ + HWND embeddedMenuHWnd; /* Tk's embedded menu window handler */ struct Container *nextPtr; /* Next in list of all containers in * this process. */ } Container; @@ -416,6 +417,7 @@ TkWinEmbeddedEventProc(hwnd, message, wParam, lParam) break; case TK_DETACHWINDOW: + containerPtr->embeddedMenuHWnd = NULL; containerPtr->embeddedHWnd = NULL; containerPtr->parentPtr->flags &= ~TK_BOTH_HALVES; break; @@ -475,7 +477,13 @@ TkWinEmbeddedEventProc(hwnd, message, wParam, lParam) result = TkpWinToplevelOverrideRedirect(containerPtr->parentPtr, wParam); break; - /* + case TK_SETMENU: + containerPtr->embeddedMenuHWnd = (HWND)lParam; + TkWinSetMenu((Tk_Window)containerPtr->parentPtr, (HMENU)wParam); + result = 1; + break; + + /* * Return 0 since the current Tk container implementation * is unable to provide following services. * @@ -653,6 +661,41 @@ Tk_GetEmbeddedHWnd(winPtr) } return NULL; } + +/* + *---------------------------------------------------------------------- + * + * Tk_GetEmbeddedMenuHWND -- + * + * This function returns the embedded menu window id. + * + * Results: + * If winPtr is a container, the return value is the HWND for the + * embedded menu window. Otherwise it returns NULL. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +HWND +Tk_GetEmbeddedMenuHWND(tkwin) + Tk_Window tkwin; +{ + TkWindow *winPtr = (TkWindow*)tkwin; + Container *containerPtr; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + + for (containerPtr = tsdPtr->firstContainerPtr; containerPtr != NULL; + containerPtr = containerPtr->nextPtr) { + if (containerPtr->parentPtr == winPtr) { + return containerPtr->embeddedMenuHWnd; + } + } + return NULL; +} /* *---------------------------------------------------------------------- diff --git a/win/tkWinMenu.c b/win/tkWinMenu.c index 677b090..7daa307 100644 --- a/win/tkWinMenu.c +++ b/win/tkWinMenu.c @@ -9,7 +9,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkWinMenu.c,v 1.36 2004/09/21 19:13:58 mdejong Exp $ + * RCS: @(#) $Id: tkWinMenu.c,v 1.37 2004/12/28 08:45:31 chengyemao Exp $ */ #define OEMRESOURCE @@ -3082,6 +3082,36 @@ TkpMenuInit() TkCreateExitHandler(MenuExitHandler, (ClientData) NULL); SetDefaults(1); } + +/* + *---------------------------------------------------------------------- + * + * Tk_GetMenuHWND -- + * + * This function returns the HWND of a hidden menu Window that + * processes messages of a popup menu. This hidden menu window + * is used to handle either a dynamic popup menu in the same + * process or a pull-down menu of an embedded window in a + * different process. + * + * Results: + * Returns the HWND of the hidden menu Window. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +HWND +Tk_GetMenuHWND(tkwin) + Tk_Window tkwin; +{ + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + TkMenuInit(); + return tsdPtr->menuHWND; +} /* *---------------------------------------------------------------------- diff --git a/win/tkWinWm.c b/win/tkWinWm.c index 4e3e059..e9263ab 100644 --- a/win/tkWinWm.c +++ b/win/tkWinWm.c @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkWinWm.c,v 1.84 2004/12/21 05:58:20 chengyemao Exp $ + * RCS: @(#) $Id: tkWinWm.c,v 1.85 2004/12/28 08:45:31 chengyemao Exp $ */ #include "tkWinInt.h" @@ -5549,22 +5549,6 @@ UpdateGeometryInfo(clientData) } /* - * If this window is embedded and the container is also in this - * process, we don't need to do anything special about the - * geometry, except to make sure that the desired size is known - * by the container. Also, zero out any position information, - * since embedded windows are not allowed to move. - */ - - if (winPtr->flags & TK_BOTH_HALVES) { - wmPtr->x = wmPtr->y = 0; - wmPtr->flags &= ~(WM_NEGATIVE_X|WM_NEGATIVE_Y); - Tk_GeometryRequest((Tk_Window) TkpGetOtherWindow(winPtr), - width, height); - return; - } - - /* * Reconfigure the window if it isn't already configured correctly. Base * the size check on what we *asked for* last time, not what we got. * Return immediately if there have been no changes in the requested @@ -6517,21 +6501,23 @@ TkWinSetMenu(tkwin, hMenu) WmInfo *wmPtr = winPtr->wmInfoPtr; wmPtr->hMenu = hMenu; + if (!(wmPtr->flags & WM_NEVER_MAPPED)) { + int syncPending = wmPtr->flags & WM_SYNC_PENDING; - if (!(wmPtr->flags & TK_EMBEDDED)) { - if (!(wmPtr->flags & WM_NEVER_MAPPED)) { - int syncPending = wmPtr->flags & WM_SYNC_PENDING; - - wmPtr->flags |= WM_SYNC_PENDING; - SetMenu(wmPtr->wrapper, hMenu); - if (!syncPending) { - wmPtr->flags &= ~WM_SYNC_PENDING; - } + wmPtr->flags |= WM_SYNC_PENDING; + SetMenu(wmPtr->wrapper, hMenu); + if (!syncPending) { + wmPtr->flags &= ~WM_SYNC_PENDING; } + } + if (!(winPtr->flags & TK_EMBEDDED)) { if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) { Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr); wmPtr->flags |= WM_UPDATE_PENDING|WM_MOVE_PENDING; } + } else { + SendMessage(wmPtr->wrapper, TK_SETMENU, + (WPARAM)hMenu, (LPARAM)Tk_GetMenuHWND(tkwin)); } } @@ -7291,10 +7277,6 @@ WmProc(hwnd, message, wParam, lParam) LRESULT result; TkWindow *winPtr = NULL; - if (TkWinHandleMenuEvent(&hwnd, &message, &wParam, &lParam, &result)) { - goto done; - } - switch (message) { case WM_KILLFOCUS: case WM_ERASEBKGND: @@ -7437,6 +7419,34 @@ WmProc(hwnd, message, wParam, lParam) } winPtr = GetTopLevel(hwnd); + switch(message) { + case WM_SYSCOMMAND: + if (TkWinHandleMenuEvent(&hwnd, &message, &wParam, &lParam, &result)) { + goto done; + } + break; + + case WM_INITMENU: + case WM_COMMAND: + case WM_MENUCHAR: + case WM_MEASUREITEM: + case WM_DRAWITEM: + case WM_MENUSELECT: + case WM_ENTERIDLE: + { + HWND hMenuHWnd = Tk_GetEmbeddedMenuHWND((Tk_Window)winPtr); + if(hMenuHWnd) { + SendMessage(hMenuHWnd, message, wParam, lParam); + goto done; + } else { + if (TkWinHandleMenuEvent(&hwnd, &message, &wParam, &lParam, &result)) { + goto done; + } + } + } + break; + } + if (winPtr && winPtr->window) { HWND child = Tk_GetHWND(winPtr->window); if (message == WM_SETFOCUS) { diff --git a/win/tkWinX.c b/win/tkWinX.c index 3285ec4..2da11fa 100644 --- a/win/tkWinX.c +++ b/win/tkWinX.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkWinX.c,v 1.39 2004/12/20 15:30:44 chengyemao Exp $ + * RCS: @(#) $Id: tkWinX.c,v 1.40 2004/12/28 08:45:32 chengyemao Exp $ */ #include "tkWinInt.h" @@ -821,6 +821,7 @@ TkWinChildProc(hwnd, message, wParam, lParam) case TK_RAISEWINDOW: case TK_GETFRAMEWID: case TK_OVERRIDEREDIRECT: + case TK_SETMENU: result = TkWinEmbeddedEventProc(hwnd, message, wParam, lParam); break; -- cgit v0.12