comparison os2/dw.c @ 465:4ff2c7210973

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.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Thu, 02 Oct 2003 07:51:26 +0000
parents 9d874ce0124a
children c3dfa117b080
comparison
equal deleted inserted replaced
464:3251fbca6fb3 465:4ff2c7210973
44 HAB dwhab = 0; 44 HAB dwhab = 0;
45 HMQ dwhmq = 0; 45 HMQ dwhmq = 0;
46 DWTID _dwtid = 0; 46 DWTID _dwtid = 0;
47 LONG _foreground = 0xAAAAAA, _background = DW_CLR_DEFAULT; 47 LONG _foreground = 0xAAAAAA, _background = DW_CLR_DEFAULT;
48 48
49 HWND hwndBubble = NULLHANDLE, hwndBubbleLast = NULLHANDLE, hwndEmph = NULLHANDLE; 49 HWND hwndApp = NULLHANDLE, hwndBubble = NULLHANDLE, hwndBubbleLast = NULLHANDLE, hwndEmph = NULLHANDLE;
50 PRECORDCORE pCore = NULL, pCoreEmph = NULL; 50 PRECORDCORE pCore = NULL, pCoreEmph = NULL;
51 ULONG aulBuffer[4]; 51 ULONG aulBuffer[4];
52 HWND lasthcnr = 0, lastitem = 0, popup = 0, desktop; 52 HWND lasthcnr = 0, lastitem = 0, popup = 0, desktop;
53 53
54 unsigned long _colors[] = { 54 unsigned long _colors[] = {
121 */ 121 */
122 void _new_signal(ULONG message, HWND window, int id, void *signalfunction, void *data) 122 void _new_signal(ULONG message, HWND window, int id, void *signalfunction, void *data)
123 { 123 {
124 SignalHandler *new = malloc(sizeof(SignalHandler)); 124 SignalHandler *new = malloc(sizeof(SignalHandler));
125 125
126 if(message == WM_COMMAND)
127 dw_signal_disconnect_by_window(window);
128
129 new->message = message; 126 new->message = message;
130 new->window = window; 127 new->window = window;
131 new->id = id; 128 new->id = id;
132 new->signalfunction = signalfunction; 129 new->signalfunction = signalfunction;
133 new->data = data; 130 new->data = data;
140 SignalHandler *prev = NULL, *tmp = Root; 137 SignalHandler *prev = NULL, *tmp = Root;
141 while(tmp) 138 while(tmp)
142 { 139 {
143 if(tmp->message == message && 140 if(tmp->message == message &&
144 tmp->window == window && 141 tmp->window == window &&
142 tmp->id == id &&
145 tmp->signalfunction == signalfunction) 143 tmp->signalfunction == signalfunction)
146 { 144 {
147 tmp->data = data; 145 tmp->data = data;
148 free(new); 146 free(new);
149 return; 147 return;
1934 WinSendMsg(hwndEmph, CM_SETRECORDEMPHASIS, pCoreEmph, MPFROM2SHORT(FALSE, CRA_SOURCE)); 1932 WinSendMsg(hwndEmph, CM_SETRECORDEMPHASIS, pCoreEmph, MPFROM2SHORT(FALSE, CRA_SOURCE));
1935 hwndEmph = NULLHANDLE; 1933 hwndEmph = NULLHANDLE;
1936 pCoreEmph = NULL; 1934 pCoreEmph = NULL;
1937 } 1935 }
1938 1936
1937 /* Find the desktop window handle */
1938 HWND _menu_owner(HWND handle)
1939 {
1940 HWND menuowner = NULLHANDLE, lastowner = (HWND)dw_window_get_data(handle, "_dw_owner");
1941 int menubar = (int)dw_window_get_data(handle, "_dw_menubar");
1942
1943 /* Find the toplevel window */
1944 while(!menubar && (menuowner = (HWND)dw_window_get_data(lastowner, "_dw_owner")) != NULLHANDLE)
1945 {
1946 menubar = (int)dw_window_get_data(lastowner, "_dw_menubar");
1947 lastowner = menuowner;
1948 }
1949 if(menuowner && menubar)
1950 {
1951 HWND client = WinWindowFromID(menuowner, FID_CLIENT);
1952
1953 return client ? client : menuowner;
1954 }
1955 return NULLHANDLE;
1956 }
1957
1939 MRESULT EXPENTRY _run_event(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) 1958 MRESULT EXPENTRY _run_event(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1940 { 1959 {
1941 int result = -1; 1960 int result = -1;
1942 SignalHandler *tmp = Root; 1961 SignalHandler *tmp = Root;
1943 ULONG origmsg = msg; 1962 ULONG origmsg = msg;
2136 case WM_COMMAND: 2155 case WM_COMMAND:
2137 { 2156 {
2138 int (* API clickfunc)(HWND, void *) = (int (* API)(HWND, void *))tmp->signalfunction; 2157 int (* API clickfunc)(HWND, void *) = (int (* API)(HWND, void *))tmp->signalfunction;
2139 ULONG command = COMMANDMSG(&msg)->cmd; 2158 ULONG command = COMMANDMSG(&msg)->cmd;
2140 2159
2141 if(tmp->window < 65536 && command == tmp->window) 2160 if(tmp->id)
2161 {
2162 HWND menuowner = _menu_owner(tmp->window);
2163
2164 if((menuowner == hWnd || menuowner == NULLHANDLE) && command == tmp->id)
2165 {
2166 result = clickfunc(tmp->window, tmp->data);
2167 tmp = NULL;
2168 }
2169 }
2170 else if(tmp->window < 65536 && command == tmp->window)
2142 { 2171 {
2143 result = clickfunc(popup ? popup : tmp->window, tmp->data); 2172 result = clickfunc(popup ? popup : tmp->window, tmp->data);
2144 tmp = NULL; 2173 tmp = NULL;
2145 } 2174 }
2146 } 2175 }
3204 DosQuerySysInfo(QSV_VERSION_MAJOR, QSV_MS_COUNT,(void *)aulBuffer, 4*sizeof(ULONG)); 3233 DosQuerySysInfo(QSV_VERSION_MAJOR, QSV_MS_COUNT,(void *)aulBuffer, 4*sizeof(ULONG));
3205 3234
3206 desktop = WinQueryDesktopWindow(dwhab, NULLHANDLE); 3235 desktop = WinQueryDesktopWindow(dwhab, NULLHANDLE);
3207 3236
3208 if(!IS_WARP4()) 3237 if(!IS_WARP4())
3209 DefaultFont = "8.Helv"; 3238 DefaultFont = "8.Helv";
3239
3240 /* This is a window that hangs around as long as the
3241 * application does and handles menu messages.
3242 */
3243 hwndApp = dw_window_new(HWND_OBJECT, "", 0);
3244
3210 return rc; 3245 return rc;
3211 } 3246 }
3212 3247
3213 /* 3248 /*
3214 * Runs a message loop for Dynamic Windows. 3249 * Runs a message loop for Dynamic Windows.
3936 location, 3971 location,
3937 HWND_TOP, 3972 HWND_TOP,
3938 FID_MENU, 3973 FID_MENU,
3939 NULL, 3974 NULL,
3940 NULL); 3975 NULL);
3976 dw_window_set_data(tmp, "_dw_owner", (void *)location);
3977 dw_window_set_data(tmp, "_dw_menubar", (void *)location);
3941 return tmp; 3978 return tmp;
3942 } 3979 }
3943 3980
3944 /* 3981 /*
3945 * Destroys a menu created with dw_menubar_new or dw_menu_new. 3982 * Destroys a menu created with dw_menubar_new or dw_menu_new.
3964 * submenu: Handle to an existing menu to be a submenu or NULL. 4001 * submenu: Handle to an existing menu to be a submenu or NULL.
3965 */ 4002 */
3966 HWND API dw_menu_append_item(HMENUI menux, char *title, ULONG id, ULONG flags, int end, int check, HMENUI submenu) 4003 HWND API dw_menu_append_item(HMENUI menux, char *title, ULONG id, ULONG flags, int end, int check, HMENUI submenu)
3967 { 4004 {
3968 MENUITEM miSubMenu; 4005 MENUITEM miSubMenu;
3969 4006 char buffer[15];
3970 if(!menux) 4007
4008 if(!menux || id > 65536)
3971 return NULLHANDLE; 4009 return NULLHANDLE;
3972 4010
3973 if(end) 4011 if(end)
3974 miSubMenu.iPosition=MIT_END; 4012 miSubMenu.iPosition=MIT_END;
3975 else 4013 else
3986 4024
3987 WinSendMsg(menux, 4025 WinSendMsg(menux,
3988 MM_INSERTITEM, 4026 MM_INSERTITEM,
3989 MPFROMP(&miSubMenu), 4027 MPFROMP(&miSubMenu),
3990 MPFROMP(title)); 4028 MPFROMP(title));
4029
4030 sprintf(buffer, "_dw_id%d", id);
4031 dw_window_set_data(hwndApp, buffer, (void *)menux);
4032
4033 if(submenu)
4034 dw_window_set_data(submenu, "_dw_owner", (void *)menux);
3991 return (HWND)id; 4035 return (HWND)id;
3992 } 4036 }
3993 4037
3994 /* 4038 /*
3995 * Sets the state of a menu item check. 4039 * Sets the state of a menu item check.
7540 * Parameters: 7584 * Parameters:
7541 * exitcode: Exit code reported to the operating system. 7585 * exitcode: Exit code reported to the operating system.
7542 */ 7586 */
7543 void API dw_exit(int exitcode) 7587 void API dw_exit(int exitcode)
7544 { 7588 {
7589 /* Destroy the menu message window */
7590 dw_window_destroy(hwndApp);
7591
7545 /* In case we are in a signal handler, don't 7592 /* In case we are in a signal handler, don't
7546 * try to free memory that could possibly be 7593 * try to free memory that could possibly be
7547 * free()'d by the runtime already. 7594 * free()'d by the runtime already.
7548 */ 7595 */
7549 Root = NULL; 7596 Root = NULL;
8295 * sigfunc: The pointer to the function to be used as the callback. 8342 * sigfunc: The pointer to the function to be used as the callback.
8296 * data: User data to be passed to the handler function. 8343 * data: User data to be passed to the handler function.
8297 */ 8344 */
8298 void API dw_signal_connect(HWND window, char *signame, void *sigfunc, void *data) 8345 void API dw_signal_connect(HWND window, char *signame, void *sigfunc, void *data)
8299 { 8346 {
8300 ULONG message = 0L; 8347 ULONG message = 0, id = 0;
8301 8348
8302 if(window && signame && sigfunc) 8349 if(window && signame && sigfunc)
8303 { 8350 {
8304 if((message = _findsigmessage(signame)) != 0) 8351 if((message = _findsigmessage(signame)) != 0)
8305 _new_signal(message, window, 0, sigfunc, data); 8352 {
8353 /* Handle special case of the menu item */
8354 if(message == WM_COMMAND && window < 65536)
8355 {
8356 char buffer[15];
8357 HWND owner;
8358
8359 sprintf(buffer, "_dw_id%d", (int)window);
8360 owner = (HWND)dw_window_get_data(hwndApp, buffer);
8361
8362 if(owner)
8363 {
8364 id = window;
8365 window = owner;
8366 dw_window_set_data(hwndApp, buffer, 0);
8367 }
8368 else
8369 {
8370 /* If it is a popup menu clear all entries */
8371 dw_signal_disconnect_by_window(window);
8372 }
8373 }
8374 _new_signal(message, window, id, sigfunc, data);
8375 }
8306 } 8376 }
8307 } 8377 }
8308 8378
8309 /* 8379 /*
8310 * Removes callbacks for a given window with given name. 8380 * Removes callbacks for a given window with given name.