Mercurial > dwindows
comparison win/dw.c @ 466:c3dfa117b080
Added new code to make the menu handlers window local instead of global.
According to the docs this will only work on Win2k/98 and above, so I
added a WINNT_COMPAT define to allow Dynamic Windows to work on WinNT and
Win95 without the new menu code. Also improved on this same fix for OS/2.
author | bsmith@81767d24-ef19-dc11-ae90-00e081727c95 |
---|---|
date | Wed, 08 Oct 2003 09:36:10 +0000 |
parents | 12ba7e744560 |
children | ecf1df2edcee |
comparison
equal
deleted
inserted
replaced
465:4ff2c7210973 | 466:c3dfa117b080 |
---|---|
6 * (C) 2000-2003 Brian Smith <dbsoft@technologist.com> | 6 * (C) 2000-2003 Brian Smith <dbsoft@technologist.com> |
7 * (C) 2003 Mark Hessling <m.hessling@qut.edu.au> | 7 * (C) 2003 Mark Hessling <m.hessling@qut.edu.au> |
8 * | 8 * |
9 */ | 9 */ |
10 #define _WIN32_IE 0x0500 | 10 #define _WIN32_IE 0x0500 |
11 #ifdef WINNT_COMPAT | |
11 #define WINVER 0x400 | 12 #define WINVER 0x400 |
13 #else | |
14 #define WINVER 0x500 | |
15 #endif | |
12 #include <windows.h> | 16 #include <windows.h> |
13 #include <windowsx.h> | 17 #include <windowsx.h> |
14 #include <commctrl.h> | 18 #include <commctrl.h> |
15 #include <shlwapi.h> | 19 #include <shlwapi.h> |
16 #include <shlobj.h> | 20 #include <shlobj.h> |
202 | 206 |
203 /* Ok this is a really big hack but what the hell ;) */ | 207 /* Ok this is a really big hack but what the hell ;) */ |
204 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) | 208 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) |
205 { | 209 { |
206 char **argv; | 210 char **argv; |
207 int argc; | 211 int argc; |
208 | 212 |
209 DWInstance = hInstance; | 213 DWInstance = hInstance; |
210 | 214 |
211 argv = _convertargs(&argc, lpCmdLine); | 215 argv = _convertargs(&argc, lpCmdLine); |
212 | 216 |
273 */ | 277 */ |
274 void _new_signal(ULONG message, HWND window, int id, void *signalfunction, void *data) | 278 void _new_signal(ULONG message, HWND window, int id, void *signalfunction, void *data) |
275 { | 279 { |
276 SignalHandler *new = malloc(sizeof(SignalHandler)); | 280 SignalHandler *new = malloc(sizeof(SignalHandler)); |
277 | 281 |
278 if(message == WM_COMMAND) | |
279 dw_signal_disconnect_by_window(window); | |
280 | |
281 new->message = message; | 282 new->message = message; |
282 new->window = window; | 283 new->window = window; |
283 new->id = id; | 284 new->id = id; |
284 new->signalfunction = signalfunction; | 285 new->signalfunction = signalfunction; |
285 new->data = data; | 286 new->data = data; |
292 SignalHandler *prev = NULL, *tmp = Root; | 293 SignalHandler *prev = NULL, *tmp = Root; |
293 while(tmp) | 294 while(tmp) |
294 { | 295 { |
295 if(tmp->message == message && | 296 if(tmp->message == message && |
296 tmp->window == window && | 297 tmp->window == window && |
298 tmp->id == id && | |
297 tmp->signalfunction == signalfunction) | 299 tmp->signalfunction == signalfunction) |
298 { | 300 { |
299 tmp->data = data; | 301 tmp->data = data; |
300 free(new); | 302 free(new); |
301 return; | 303 return; |
1340 return pos; | 1342 return pos; |
1341 } | 1343 } |
1342 return -1; | 1344 return -1; |
1343 } | 1345 } |
1344 | 1346 |
1347 #ifndef WINNT_COMPAT | |
1348 HMENU _get_owner(HMENU menu) | |
1349 { | |
1350 MENUINFO mi; | |
1351 | |
1352 mi.cbSize = sizeof(MENUINFO); | |
1353 mi.fMask = MIM_MENUDATA; | |
1354 | |
1355 if(GetMenuInfo(menu, &mi)) | |
1356 return (HMENU)mi.dwMenuData; | |
1357 return (HMENU)0; | |
1358 } | |
1359 | |
1360 /* Find the desktop window handle */ | |
1361 HMENU _menu_owner(HMENU handle) | |
1362 { | |
1363 HMENU menuowner = 0, lastowner = _get_owner(handle); | |
1364 | |
1365 /* Find the toplevel menu */ | |
1366 while((menuowner = _get_owner(lastowner)) != 0) | |
1367 { | |
1368 if(menuowner == (HMENU)1) | |
1369 return lastowner; | |
1370 lastowner = menuowner; | |
1371 } | |
1372 return (HMENU)0; | |
1373 } | |
1374 #endif | |
1375 | |
1345 /* The main window procedure for Dynamic Windows, all the resizing code is done here. */ | 1376 /* The main window procedure for Dynamic Windows, all the resizing code is done here. */ |
1346 BOOL CALLBACK _wndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2) | 1377 BOOL CALLBACK _wndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2) |
1347 { | 1378 { |
1348 int result = -1; | 1379 int result = -1; |
1349 static int command_active = 0; | 1380 static int command_active = 0; |
1662 if(tmp->message == LBN_SELCHANGE && tmp->window == (HWND)mp2) | 1693 if(tmp->message == LBN_SELCHANGE && tmp->window == (HWND)mp2) |
1663 { | 1694 { |
1664 result = listboxselectfunc(tmp->window, dw_listbox_selected(tmp->window), tmp->data); | 1695 result = listboxselectfunc(tmp->window, dw_listbox_selected(tmp->window), tmp->data); |
1665 tmp = NULL; | 1696 tmp = NULL; |
1666 } | 1697 } |
1698 } | |
1699 #ifndef WINNT_COMPAT | |
1700 else if(tmp->id && passthru == tmp->id) | |
1701 { | |
1702 HMENU hwndmenu = GetMenu(hWnd), menuowner = _menu_owner((HMENU)tmp->window); | |
1703 | |
1704 if(menuowner == hwndmenu || !menuowner) | |
1705 { | |
1706 result = clickfunc(tmp->window, tmp->data); | |
1707 tmp = NULL; | |
1708 } | |
1667 } /* Make sure it's the right window, and the right ID */ | 1709 } /* Make sure it's the right window, and the right ID */ |
1710 #endif | |
1668 else if(tmp->window < (HWND)65536 && command == tmp->window) | 1711 else if(tmp->window < (HWND)65536 && command == tmp->window) |
1669 { | 1712 { |
1670 result = clickfunc(popup ? popup : tmp->window, tmp->data); | 1713 result = clickfunc(popup ? popup : tmp->window, tmp->data); |
1671 tmp = NULL; | 1714 tmp = NULL; |
1672 } | 1715 } |
3833 { | 3876 { |
3834 HMENUI tmp; | 3877 HMENUI tmp; |
3835 | 3878 |
3836 tmp = (HMENUI)CreateMenu(); | 3879 tmp = (HMENUI)CreateMenu(); |
3837 | 3880 |
3881 #ifndef WINNT_COMPAT | |
3882 { | |
3883 MENUINFO mi; | |
3884 | |
3885 mi.cbSize = sizeof(MENUINFO); | |
3886 mi.fMask = MIM_MENUDATA; | |
3887 mi.dwMenuData = (ULONG_PTR)1; | |
3888 | |
3889 SetMenuInfo((HMENU)tmp, &mi); | |
3890 } | |
3891 #endif | |
3892 | |
3838 dw_window_set_data(location, "_dw_menu", (void *)tmp); | 3893 dw_window_set_data(location, "_dw_menu", (void *)tmp); |
3839 | 3894 |
3840 SetMenu(location, (HMENU)tmp); | 3895 SetMenu(location, (HMENU)tmp); |
3841 return location; | 3896 return location; |
3842 } | 3897 } |
3872 */ | 3927 */ |
3873 HWND API dw_menu_append_item(HMENUI menux, char *title, ULONG id, ULONG flags, int end, int check, HMENUI submenu) | 3928 HWND API dw_menu_append_item(HMENUI menux, char *title, ULONG id, ULONG flags, int end, int check, HMENUI submenu) |
3874 { | 3929 { |
3875 MENUITEMINFO mii; | 3930 MENUITEMINFO mii; |
3876 HMENU mymenu = (HMENU)menux; | 3931 HMENU mymenu = (HMENU)menux; |
3932 #ifndef WINNT_COMPAT | |
3933 char buffer[15]; | |
3934 #endif | |
3877 | 3935 |
3878 if(IsWindow(menux) && !IsMenu(mymenu)) | 3936 if(IsWindow(menux) && !IsMenu(mymenu)) |
3879 mymenu = (HMENU)dw_window_get_data(menux, "_dw_menu"); | 3937 mymenu = (HMENU)dw_window_get_data(menux, "_dw_menu"); |
3880 | 3938 |
3881 mii.cbSize = sizeof(MENUITEMINFO); | 3939 mii.cbSize = sizeof(MENUITEMINFO); |
3906 mii.hSubMenu = 0; | 3964 mii.hSubMenu = 0; |
3907 mii.dwTypeData = title; | 3965 mii.dwTypeData = title; |
3908 mii.cch = strlen(title); | 3966 mii.cch = strlen(title); |
3909 | 3967 |
3910 InsertMenuItem(mymenu, 65535, TRUE, &mii); | 3968 InsertMenuItem(mymenu, 65535, TRUE, &mii); |
3969 | |
3970 #ifndef WINNT_COMPAT | |
3971 sprintf(buffer, "_dw_id%d", id); | |
3972 dw_window_set_data(DW_HWND_OBJECT, buffer, (void *)mymenu); | |
3973 | |
3974 /* According to the docs this will only work on Win2k/98 and above */ | |
3975 if(submenu) | |
3976 { | |
3977 MENUINFO mi; | |
3978 | |
3979 mi.cbSize = sizeof(MENUINFO); | |
3980 mi.fMask = MIM_MENUDATA; | |
3981 mi.dwMenuData = (ULONG_PTR)mymenu; | |
3982 | |
3983 SetMenuInfo((HMENU)submenu, &mi); | |
3984 } | |
3985 #endif | |
3986 | |
3911 if(IsWindow(menux) && !IsMenu((HMENU)menux)) | 3987 if(IsWindow(menux) && !IsMenu((HMENU)menux)) |
3912 DrawMenuBar(menux); | 3988 DrawMenuBar(menux); |
3913 return (HWND)id; | 3989 return (HWND)id; |
3914 } | 3990 } |
3915 | 3991 |
8126 * sigfunc: The pointer to the function to be used as the callback. | 8202 * sigfunc: The pointer to the function to be used as the callback. |
8127 * data: User data to be passed to the handler function. | 8203 * data: User data to be passed to the handler function. |
8128 */ | 8204 */ |
8129 void API dw_signal_connect(HWND window, char *signame, void *sigfunc, void *data) | 8205 void API dw_signal_connect(HWND window, char *signame, void *sigfunc, void *data) |
8130 { | 8206 { |
8131 ULONG message = 0L; | 8207 ULONG message = 0, id = 0; |
8132 | 8208 |
8133 if(window && signame && sigfunc) | 8209 if(window && signame && sigfunc) |
8134 { | 8210 { |
8135 if(stricmp(signame, DW_SIGNAL_SET_FOCUS) == 0) | 8211 if(stricmp(signame, DW_SIGNAL_SET_FOCUS) == 0) |
8136 window = _normalize_handle(window); | 8212 window = _normalize_handle(window); |
8137 | 8213 |
8138 if((message = _findsigmessage(signame)) != 0) | 8214 if((message = _findsigmessage(signame)) != 0) |
8139 _new_signal(message, window, 0, sigfunc, data); | 8215 { |
8216 /* Handle special case of the menu item */ | |
8217 if(message == WM_COMMAND && window < (HWND)65536) | |
8218 { | |
8219 char buffer[15]; | |
8220 HWND owner; | |
8221 | |
8222 sprintf(buffer, "_dw_id%d", (int)window); | |
8223 owner = (HWND)dw_window_get_data(DW_HWND_OBJECT, buffer); | |
8224 | |
8225 if(owner) | |
8226 { | |
8227 id = (ULONG)window; | |
8228 window = owner; | |
8229 dw_window_set_data(DW_HWND_OBJECT, buffer, 0); | |
8230 } | |
8231 else | |
8232 { | |
8233 /* If it is a popup menu clear all entries */ | |
8234 dw_signal_disconnect_by_window(window); | |
8235 } | |
8236 } | |
8237 _new_signal(message, window, id, sigfunc, data); | |
8238 } | |
8140 } | 8239 } |
8141 } | 8240 } |
8142 | 8241 |
8143 /* | 8242 /* |
8144 * Removes callbacks for a given window with given name. | 8243 * Removes callbacks for a given window with given name. |