comparison win/dw.c @ 506:f1998a89a4d5

Load the Win2K/98 functions dynamically so the same DW.DLL binary will work on Windows 95 and NT with the enhanced menu functionality automatically disabled.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Wed, 21 Jan 2004 06:31:41 +0000
parents 2ecbb7963011
children c607eb385e58
comparison
equal deleted inserted replaced
505:2ecbb7963011 506:f1998a89a4d5
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
12 #define WINVER 0x400
13 #else
14 #define WINVER 0x500 11 #define WINVER 0x500
15 #endif
16 #include <windows.h> 12 #include <windows.h>
17 #include <windowsx.h> 13 #include <windowsx.h>
18 #include <commctrl.h> 14 #include <commctrl.h>
19 #include <shlwapi.h> 15 #include <shlwapi.h>
20 #include <shlobj.h> 16 #include <shlobj.h>
33 DWTID _dwtid = -1; 29 DWTID _dwtid = -1;
34 30
35 #define PACKVERSION(major,minor) MAKELONG(minor,major) 31 #define PACKVERSION(major,minor) MAKELONG(minor,major)
36 32
37 #define IS_IE5PLUS (dwComctlVer >= PACKVERSION(5,80)) 33 #define IS_IE5PLUS (dwComctlVer >= PACKVERSION(5,80))
34 #define IS_WINNTOR95 (((LOBYTE(LOWORD(dwVersion))) < 5) && (HIBYTE(LOWORD(dwVersion)) < 10))
38 35
39 #ifndef MIN 36 #ifndef MIN
40 #define MIN(a, b) (((a) < (b)) ? (a) : (b)) 37 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
41 #endif 38 #endif
39
40 static BOOL (WINAPI* MyGetMenuInfo)(HMENU, LPCMENUINFO) = 0;
41 static BOOL (WINAPI* MySetMenuInfo)(HMENU, LPCMENUINFO) = 0;
42 42
43 int main(int argc, char *argv[]); 43 int main(int argc, char *argv[]);
44 44
45 #define ICON_INDEX_LIMIT 200 45 #define ICON_INDEX_LIMIT 200
46 HICON lookup[200]; 46 HICON lookup[200];
418 return TRUE; 418 return TRUE;
419 } 419 }
420 420
421 void _free_menu_data(HMENU menu) 421 void _free_menu_data(HMENU menu)
422 { 422 {
423 #ifndef WINNT_COMPAT 423 if(!IS_WINNTOR95)
424 int i, count = GetMenuItemCount(menu); 424 {
425 425 int i, count = GetMenuItemCount(menu);
426 for(i=0;i<count;i++) 426
427 { 427 for(i=0;i<count;i++)
428 MENUITEMINFO mii; 428 {
429 429 MENUITEMINFO mii;
430 mii.cbSize = sizeof(MENUITEMINFO); 430
431 mii.fMask = MIIM_SUBMENU; 431 mii.cbSize = sizeof(MENUITEMINFO);
432 432 mii.fMask = MIIM_SUBMENU;
433 if(GetMenuItemInfo(menu, i, TRUE, &mii) 433
434 && mii.hSubMenu) 434 if(GetMenuItemInfo(menu, i, TRUE, &mii)
435 _free_menu_data(mii.hSubMenu); 435 && mii.hSubMenu)
436 } 436 _free_menu_data(mii.hSubMenu);
437 #endif 437 }
438 }
438 dw_signal_disconnect_by_name((HWND)menu, DW_SIGNAL_CLICKED); 439 dw_signal_disconnect_by_name((HWND)menu, DW_SIGNAL_CLICKED);
439 } 440 }
440 441
441 /* Convert to our internal color scheme */ 442 /* Convert to our internal color scheme */
442 ULONG _internal_color(ULONG color) 443 ULONG _internal_color(ULONG color)
1363 return pos; 1364 return pos;
1364 } 1365 }
1365 return -1; 1366 return -1;
1366 } 1367 }
1367 1368
1368 #ifndef WINNT_COMPAT
1369 HMENU _get_owner(HMENU menu) 1369 HMENU _get_owner(HMENU menu)
1370 { 1370 {
1371 MENUINFO mi; 1371 MENUINFO mi;
1372 1372
1373 mi.cbSize = sizeof(MENUINFO); 1373 mi.cbSize = sizeof(MENUINFO);
1374 mi.fMask = MIM_MENUDATA; 1374 mi.fMask = MIM_MENUDATA;
1375 1375
1376 if(GetMenuInfo(menu, &mi)) 1376 if(MyGetMenuInfo(menu, &mi))
1377 return (HMENU)mi.dwMenuData; 1377 return (HMENU)mi.dwMenuData;
1378 return (HMENU)0; 1378 return (HMENU)0;
1379 } 1379 }
1380 1380
1381 /* Find the desktop window handle */ 1381 /* Find the desktop window handle */
1390 return lastowner; 1390 return lastowner;
1391 lastowner = menuowner; 1391 lastowner = menuowner;
1392 } 1392 }
1393 return (HMENU)0; 1393 return (HMENU)0;
1394 } 1394 }
1395 #endif
1396 1395
1397 /* The main window procedure for Dynamic Windows, all the resizing code is done here. */ 1396 /* The main window procedure for Dynamic Windows, all the resizing code is done here. */
1398 BOOL CALLBACK _wndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2) 1397 BOOL CALLBACK _wndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2)
1399 { 1398 {
1400 int result = -1, taskbar = FALSE; 1399 int result = -1, taskbar = FALSE;
1761 { 1760 {
1762 result = listboxselectfunc(tmp->window, dw_listbox_selected(tmp->window), tmp->data); 1761 result = listboxselectfunc(tmp->window, dw_listbox_selected(tmp->window), tmp->data);
1763 tmp = NULL; 1762 tmp = NULL;
1764 } 1763 }
1765 } 1764 }
1766 #ifndef WINNT_COMPAT 1765 else if(!IS_WINNTOR95 && tmp->id && passthru == tmp->id)
1767 else if(tmp->id && passthru == tmp->id)
1768 { 1766 {
1769 HMENU hwndmenu = GetMenu(hWnd), menuowner = _menu_owner((HMENU)tmp->window); 1767 HMENU hwndmenu = GetMenu(hWnd), menuowner = _menu_owner((HMENU)tmp->window);
1770 1768
1771 if(menuowner == hwndmenu || !menuowner) 1769 if(menuowner == hwndmenu || !menuowner)
1772 { 1770 {
1773 result = clickfunc(tmp->window, tmp->data); 1771 result = clickfunc(tmp->window, tmp->data);
1774 tmp = NULL; 1772 tmp = NULL;
1775 } 1773 }
1776 } /* Make sure it's the right window, and the right ID */ 1774 } /* Make sure it's the right window, and the right ID */
1777 #endif
1778 else if(tmp->window < (HWND)65536 && command == tmp->window) 1775 else if(tmp->window < (HWND)65536 && command == tmp->window)
1779 { 1776 {
1780 result = clickfunc(popup ? popup : tmp->window, tmp->data); 1777 result = clickfunc(popup ? popup : tmp->window, tmp->data);
1781 tmp = NULL; 1778 tmp = NULL;
1782 } 1779 }
3240 _background[z] = DW_RGB_TRANSPARENT; 3237 _background[z] = DW_RGB_TRANSPARENT;
3241 _hPen[z] = CreatePen(PS_SOLID, 1, _foreground[z]); 3238 _hPen[z] = CreatePen(PS_SOLID, 1, _foreground[z]);
3242 _hBrush[z] = CreateSolidBrush(_foreground[z]); 3239 _hBrush[z] = CreateSolidBrush(_foreground[z]);
3243 } 3240 }
3244 3241
3242 if(!IS_WINNTOR95)
3243 {
3244 /* Get function pointers for the Win2k/98 menu functions */
3245 HANDLE huser = LoadLibrary("user32");
3246
3247 MyGetMenuInfo = (void*)GetProcAddress(huser, "GetMenuInfo");
3248 MySetMenuInfo = (void*)GetProcAddress(huser, "SetMenuInfo");
3249 FreeLibrary(huser);
3250 }
3251
3245 return 0; 3252 return 0;
3246 } 3253 }
3247 3254
3248 /* 3255 /*
3249 * Runs a message loop for Dynamic Windows. 3256 * Runs a message loop for Dynamic Windows.
3459 */ 3466 */
3460 int API dw_window_destroy(HWND handle) 3467 int API dw_window_destroy(HWND handle)
3461 { 3468 {
3462 HWND parent = GetParent(handle); 3469 HWND parent = GetParent(handle);
3463 Box *thisbox = (Box *)GetWindowLongPtr(parent, GWLP_USERDATA); 3470 Box *thisbox = (Box *)GetWindowLongPtr(parent, GWLP_USERDATA);
3464 #ifndef WINNT_COMPAT 3471
3465 HMENU menu = GetMenu(handle); 3472 if(!IS_WINNTOR95)
3466 3473 {
3467 if(menu) 3474 HMENU menu = GetMenu(handle);
3468 _free_menu_data(menu); 3475
3469 #endif 3476 if(menu)
3477 _free_menu_data(menu);
3478 }
3470 3479
3471 if(parent != HWND_DESKTOP && thisbox && thisbox->count) 3480 if(parent != HWND_DESKTOP && thisbox && thisbox->count)
3472 { 3481 {
3473 int z, index = -1; 3482 int z, index = -1;
3474 Item *tmpitem, *thisitem = thisbox->items; 3483 Item *tmpitem, *thisitem = thisbox->items;
3960 { 3969 {
3961 HMENUI tmp; 3970 HMENUI tmp;
3962 3971
3963 tmp = (HMENUI)CreateMenu(); 3972 tmp = (HMENUI)CreateMenu();
3964 3973
3965 #ifndef WINNT_COMPAT 3974 if(!IS_WINNTOR95)
3966 { 3975 {
3967 MENUINFO mi; 3976 MENUINFO mi;
3968 3977
3969 mi.cbSize = sizeof(MENUINFO); 3978 mi.cbSize = sizeof(MENUINFO);
3970 mi.fMask = MIM_MENUDATA; 3979 mi.fMask = MIM_MENUDATA;
3971 mi.dwMenuData = (ULONG_PTR)1; 3980 mi.dwMenuData = (ULONG_PTR)1;
3972 3981
3973 SetMenuInfo((HMENU)tmp, &mi); 3982 MySetMenuInfo((HMENU)tmp, &mi);
3974 } 3983 }
3975 #endif
3976 3984
3977 dw_window_set_data(location, "_dw_menu", (void *)tmp); 3985 dw_window_set_data(location, "_dw_menu", (void *)tmp);
3978 3986
3979 SetMenu(location, (HMENU)tmp); 3987 SetMenu(location, (HMENU)tmp);
3980 return location; 3988 return location;
4011 */ 4019 */
4012 HWND API dw_menu_append_item(HMENUI menux, char *title, ULONG id, ULONG flags, int end, int check, HMENUI submenu) 4020 HWND API dw_menu_append_item(HMENUI menux, char *title, ULONG id, ULONG flags, int end, int check, HMENUI submenu)
4013 { 4021 {
4014 MENUITEMINFO mii; 4022 MENUITEMINFO mii;
4015 HMENU mymenu = (HMENU)menux; 4023 HMENU mymenu = (HMENU)menux;
4016 #ifndef WINNT_COMPAT
4017 char buffer[15]; 4024 char buffer[15];
4018 #endif
4019 4025
4020 if(IsWindow(menux) && !IsMenu(mymenu)) 4026 if(IsWindow(menux) && !IsMenu(mymenu))
4021 mymenu = (HMENU)dw_window_get_data(menux, "_dw_menu"); 4027 mymenu = (HMENU)dw_window_get_data(menux, "_dw_menu");
4022 4028
4023 mii.cbSize = sizeof(MENUITEMINFO); 4029 mii.cbSize = sizeof(MENUITEMINFO);
4049 mii.dwTypeData = title; 4055 mii.dwTypeData = title;
4050 mii.cch = strlen(title); 4056 mii.cch = strlen(title);
4051 4057
4052 InsertMenuItem(mymenu, 65535, TRUE, &mii); 4058 InsertMenuItem(mymenu, 65535, TRUE, &mii);
4053 4059
4054 #ifndef WINNT_COMPAT 4060 if(!IS_WINNTOR95)
4055 sprintf(buffer, "_dw_id%d", id); 4061 {
4056 dw_window_set_data(DW_HWND_OBJECT, buffer, (void *)mymenu); 4062 sprintf(buffer, "_dw_id%d", id);
4057 4063 dw_window_set_data(DW_HWND_OBJECT, buffer, (void *)mymenu);
4058 /* According to the docs this will only work on Win2k/98 and above */ 4064
4059 if(submenu) 4065 /* According to the docs this will only work on Win2k/98 and above */
4060 { 4066 if(submenu)
4061 MENUINFO mi; 4067 {
4062 4068 MENUINFO mi;
4063 mi.cbSize = sizeof(MENUINFO); 4069
4064 mi.fMask = MIM_MENUDATA; 4070 mi.cbSize = sizeof(MENUINFO);
4065 mi.dwMenuData = (ULONG_PTR)mymenu; 4071 mi.fMask = MIM_MENUDATA;
4066 4072 mi.dwMenuData = (ULONG_PTR)mymenu;
4067 SetMenuInfo((HMENU)submenu, &mi); 4073
4068 } 4074 MySetMenuInfo((HMENU)submenu, &mi);
4069 #endif 4075 }
4076 }
4070 4077
4071 if(IsWindow(menux) && !IsMenu((HMENU)menux)) 4078 if(IsWindow(menux) && !IsMenu((HMENU)menux))
4072 DrawMenuBar(menux); 4079 DrawMenuBar(menux);
4073 return (HWND)id; 4080 return (HWND)id;
4074 } 4081 }