# HG changeset patch # User bsmith@81767d24-ef19-dc11-ae90-00e081727c95 # Date 1065081086 0 # Node ID 4ff2c721097395ee8e5280e07c4921c14553f922 # Parent 3251fbca6fb3946aee2a86da90f111d4c5a7da78 Menu item handlers are now window local, ID is still used but it is local to the menubar or popup menu it is associated with. diff -r 3251fbca6fb3 -r 4ff2c7210973 os2/dw.c --- a/os2/dw.c Fri Aug 08 23:09:44 2003 +0000 +++ b/os2/dw.c Thu Oct 02 07:51:26 2003 +0000 @@ -46,7 +46,7 @@ DWTID _dwtid = 0; LONG _foreground = 0xAAAAAA, _background = DW_CLR_DEFAULT; -HWND hwndBubble = NULLHANDLE, hwndBubbleLast = NULLHANDLE, hwndEmph = NULLHANDLE; +HWND hwndApp = NULLHANDLE, hwndBubble = NULLHANDLE, hwndBubbleLast = NULLHANDLE, hwndEmph = NULLHANDLE; PRECORDCORE pCore = NULL, pCoreEmph = NULL; ULONG aulBuffer[4]; HWND lasthcnr = 0, lastitem = 0, popup = 0, desktop; @@ -123,9 +123,6 @@ { SignalHandler *new = malloc(sizeof(SignalHandler)); - if(message == WM_COMMAND) - dw_signal_disconnect_by_window(window); - new->message = message; new->window = window; new->id = id; @@ -142,6 +139,7 @@ { if(tmp->message == message && tmp->window == window && + tmp->id == id && tmp->signalfunction == signalfunction) { tmp->data = data; @@ -1936,6 +1934,27 @@ pCoreEmph = NULL; } +/* Find the desktop window handle */ +HWND _menu_owner(HWND handle) +{ + HWND menuowner = NULLHANDLE, lastowner = (HWND)dw_window_get_data(handle, "_dw_owner"); + int menubar = (int)dw_window_get_data(handle, "_dw_menubar"); + + /* Find the toplevel window */ + while(!menubar && (menuowner = (HWND)dw_window_get_data(lastowner, "_dw_owner")) != NULLHANDLE) + { + menubar = (int)dw_window_get_data(lastowner, "_dw_menubar"); + lastowner = menuowner; + } + if(menuowner && menubar) + { + HWND client = WinWindowFromID(menuowner, FID_CLIENT); + + return client ? client : menuowner; + } + return NULLHANDLE; +} + MRESULT EXPENTRY _run_event(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { int result = -1; @@ -2138,7 +2157,17 @@ int (* API clickfunc)(HWND, void *) = (int (* API)(HWND, void *))tmp->signalfunction; ULONG command = COMMANDMSG(&msg)->cmd; - if(tmp->window < 65536 && command == tmp->window) + if(tmp->id) + { + HWND menuowner = _menu_owner(tmp->window); + + if((menuowner == hWnd || menuowner == NULLHANDLE) && command == tmp->id) + { + result = clickfunc(tmp->window, tmp->data); + tmp = NULL; + } + } + else if(tmp->window < 65536 && command == tmp->window) { result = clickfunc(popup ? popup : tmp->window, tmp->data); tmp = NULL; @@ -3206,7 +3235,13 @@ desktop = WinQueryDesktopWindow(dwhab, NULLHANDLE); if(!IS_WARP4()) - DefaultFont = "8.Helv"; + DefaultFont = "8.Helv"; + + /* This is a window that hangs around as long as the + * application does and handles menu messages. + */ + hwndApp = dw_window_new(HWND_OBJECT, "", 0); + return rc; } @@ -3938,6 +3973,8 @@ FID_MENU, NULL, NULL); + dw_window_set_data(tmp, "_dw_owner", (void *)location); + dw_window_set_data(tmp, "_dw_menubar", (void *)location); return tmp; } @@ -3966,8 +4003,9 @@ HWND API dw_menu_append_item(HMENUI menux, char *title, ULONG id, ULONG flags, int end, int check, HMENUI submenu) { MENUITEM miSubMenu; - - if(!menux) + char buffer[15]; + + if(!menux || id > 65536) return NULLHANDLE; if(end) @@ -3988,6 +4026,12 @@ MM_INSERTITEM, MPFROMP(&miSubMenu), MPFROMP(title)); + + sprintf(buffer, "_dw_id%d", id); + dw_window_set_data(hwndApp, buffer, (void *)menux); + + if(submenu) + dw_window_set_data(submenu, "_dw_owner", (void *)menux); return (HWND)id; } @@ -7542,6 +7586,9 @@ */ void API dw_exit(int exitcode) { + /* Destroy the menu message window */ + dw_window_destroy(hwndApp); + /* In case we are in a signal handler, don't * try to free memory that could possibly be * free()'d by the runtime already. @@ -8297,12 +8344,35 @@ */ void API dw_signal_connect(HWND window, char *signame, void *sigfunc, void *data) { - ULONG message = 0L; + ULONG message = 0, id = 0; if(window && signame && sigfunc) { if((message = _findsigmessage(signame)) != 0) - _new_signal(message, window, 0, sigfunc, data); + { + /* Handle special case of the menu item */ + if(message == WM_COMMAND && window < 65536) + { + char buffer[15]; + HWND owner; + + sprintf(buffer, "_dw_id%d", (int)window); + owner = (HWND)dw_window_get_data(hwndApp, buffer); + + if(owner) + { + id = window; + window = owner; + dw_window_set_data(hwndApp, buffer, 0); + } + else + { + /* If it is a popup menu clear all entries */ + dw_signal_disconnect_by_window(window); + } + } + _new_signal(message, window, id, sigfunc, data); + } } }