Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3732 lines
95 KiB

  1. /*-----------------------------------------------------------------------
  2. |
  3. | CTL3D
  4. |
  5. | Copyright Microsoft Corporation 1992. All Rights Reserved.
  6. |
  7. |
  8. | This module contains the functions to give windows controls a 3d effect
  9. |
  10. | This source is made public for your edification and debugging pleasure
  11. |
  12. | PLEASE do not make any changes or release private versions of this DLL
  13. | send e-mail to me (wesc) if you have feature requests or bug fixes.
  14. |
  15. | Thanks -- Wes.
  16. |
  17. |
  18. | History:
  19. | 1-Jan-92 : Added OOM handling on GetDC (not really necessary but
  20. | XL4 OOM failure testing made GetDC return NULL)
  21. |
  22. | 1-Jan-92 : Check wasn't getting redrawn when state changed in
  23. | the default button proc.
  24. |
  25. | 29-Jan-92: If button has the focus and app is switched in, we weren't
  26. | redrawing the entire button check & text. Force redraw
  27. | of these on WM_SETFOCUS message.
  28. |
  29. | 3-Feb-92: Fixed switch in via task manager by erasing the buttons
  30. | backgound on WM_SETFOCUS (detect this when wParam == NULL)
  31. |
  32. | 4-Apr-92: Make it work with OWNERDRAW buttons
  33. |
  34. | 22-Apr-92: Removed Excel specific code
  35. |
  36. | 19-May-92: Turn it into a DLL
  37. |
  38. | May-Jun92: Lots o' fixes & enhancements
  39. |
  40. | 23-Jun-92: Added support for hiding, sizing & moving
  41. |
  42. | 24-Jun-92: Make checks & radio button circles draw w/ window
  43. | text color 'cause they are drawn on window bkgnd
  44. |
  45. | 30-Jun-92: (0.984) Fix bug where EnableWindow of StaticText doesn't
  46. | redraw properly. Also disable ctl3d when verWindows > 3.1
  47. |
  48. | 1-Jul-92: Added WIN32 support (davegi) (not in this source)
  49. |
  50. | 2-Jul-92: (0.984) Disable when verWindows >= 4.0
  51. |
  52. | 20-Jul-92: (0.985) Draw focus rects of checks/radios properly on non
  53. | default sized controls.
  54. |
  55. | 21-Jul-92: (0.990) Ctl3dAutoSubclass
  56. |
  57. | 21-Jul-92: (0.991) ported DaveGi's WIN32 support
  58. |
  59. | 22-Jul-92: (0.991) fixed Ctl3dCtlColor returning fFalse bug
  60. |
  61. | 4-Aug-92: (0.992) Graphic designers bug fixes...Now subclass
  62. | regular buttons + disabled states for checks & radios
  63. |
  64. | 6-Aug-92: (0.993) Fix bug where activate via taskman & group
  65. | box has focus, & not centering text in buttons
  66. |
  67. | 6-Aug-92: (0.993) Tweek drawing next to scroll bars.
  68. |
  69. | 13-Aug-92: (0.994) Fix button focus rect bug drawing due to
  70. | Win 3.0 DrawText bug.
  71. |
  72. | 14-Aug-92: (1.0) Release of version 1.0
  73. | Don't draw default button border on BS_DEFPUSHBUTTON
  74. | pushbuttons
  75. | Fix bogus bug where Windows hangs when in a AUTORADIOBUTTON
  76. | hold down space bar and hit arrow key.
  77. |
  78. | 23-Sep-92: (1.01) Made Ctl3dCtlColor call DefWindowProc so it works when
  79. | called in a windproc.
  80. |
  81. | 28-Sep-92: (1.02) Added MyGetTextExtent so '&''s not considered in
  82. | text extents.
  83. |
  84. | 08-Dec-92: (1.03) minor tweeks to the button text centering code
  85. | for Publisher
  86. |
  87. | 11-Dec-92: (1.04) added 3d frames to dialogs
  88. |
  89. | 15-Dec-92: (1.05) fixed bug where group boxes redraw wrong when
  90. | Window text is changed to something shorter
  91. |
  92. | ??-Dec-92: (1.06) added 3d borders
  93. |
  94. | 21-Dec-92: (1.07) added WM_DLGBORDER to disable borders
  95. |
  96. | 4-Jan-93: (1.08) fixed WM_SETTEXT bug w/ DLG frames & checks/checkboxes
  97. | Also, WM_DLGSUBCLASS
  98. |
  99. | 22-Feb-93: (1.12) disabled it under Chicago
  100. |
  101. | 25-Feb-93: (1.13) re-add fix which allows dialog procs to
  102. | handle WM_CTLCOLOR messages
  103. |
  104. | 26-April-93 (2.0) Changed to allow for second subclass. Now uses class instead of
  105. | wndproc for subclass determination.
  106. | store next wndproc in properties with global atoms
  107. |
  108. | 06-Jun-93 (2.0) Make a static linked library version.
  109. |
  110. |
  111. -----------------------------------------------------------------------*/
  112. #define NO_STRICT
  113. #include <windows.h>
  114. #ifdef _BORLAND
  115. #include <mem.h>
  116. #else
  117. #include <memory.h>
  118. #endif
  119. #include <malloc.h>
  120. #include "ctl3d.h"
  121. #include "stdio.h"
  122. /*-----------------------------------------------------------------------
  123. |CTL3D Types
  124. -----------------------------------------------------------------------*/
  125. #ifdef WIN32
  126. #define Win32Only(e) e
  127. #define Win16Only(e)
  128. #define Win32Or16(e32, e16) e32
  129. #define Win16Or32(e16, e32) e32
  130. #define _loadds
  131. #define __export
  132. #define FValidLibHandle(hlib) ((hlib) != NULL)
  133. //
  134. // No concept of far in Win32.
  135. //
  136. #define MEMCMP memcmp
  137. #define NPTSTR LPTSTR
  138. //
  139. // Control IDs are LONG in Win32.
  140. //
  141. typedef LONG CTLID;
  142. #define GetControlId(hwnd) GetWindowLong(hwnd, GWL_ID)
  143. //
  144. // Send a color button message.
  145. //
  146. #define SEND_COLOR_BUTTON_MESSAGE( hwndParent, hwnd, hdc ) \
  147. ((HBRUSH) SendMessage(hwndParent, WM_CTLCOLORBTN, (WPARAM) hdc, (LPARAM) hwnd))
  148. //
  149. // Send a color static message.
  150. //
  151. #define SEND_COLOR_STATIC_MESSAGE( hwndParent, hwnd, hdc ) \
  152. ((HBRUSH) SendMessage(hwndParent, WM_CTLCOLORSTATIC, (WPARAM) hdc, (LPARAM) hwnd))
  153. #else
  154. #define CallWindowProcA CallWindowProc
  155. #define DefWindowProcA DefWindowProc
  156. #define MessageBoxA MessageBox
  157. #define TEXT(a) a
  158. #define TCHAR char
  159. #ifndef LPTSTR
  160. #define LPTSTR LPSTR
  161. #endif
  162. #define LPCTSTR LPCSTR
  163. #define NPTSTR NPSTR
  164. #define Win32Only(e)
  165. #define Win16Only(e) e
  166. #define Win32Or16(e32, e16) e16
  167. #define Win16Or32(e16, e32) e16
  168. #define FValidLibHandle(hlib) (( hlib ) > 32 )
  169. #define MEMCMP _fmemcmp
  170. typedef WORD CTLID;
  171. #define GetControlId(h) GetWindowWord(h, GWW_ID)
  172. #define SEND_COLOR_BUTTON_MESSAGE( hwndParent, hwnd, hdc ) \
  173. ((HBRUSH) SendMessage(hwndParent, WM_CTLCOLOR, (WORD) hdc, MAKELONG(hwnd, CTLCOLOR_BTN)))
  174. #define SEND_COLOR_STATIC_MESSAGE( hwndParent, hwnd, hdc ) \
  175. ((HBRUSH) SendMessage(hwndParent, WM_CTLCOLOR, (WORD) hdc, MAKELONG(hwnd, CTLCOLOR_STATIC)))
  176. typedef struct
  177. {
  178. LPARAM lParam;
  179. WPARAM wParam;
  180. UINT message;
  181. HWND hwnd;
  182. } CWPSTRUCT;
  183. #endif // WIN32
  184. // DBCS far east short cut key support
  185. #define cchShortCutModeMax 10
  186. #define chShortCutSbcsPrefix '\036'
  187. #define chShortCutDbcsPrefix '\037'
  188. #define cchClassMax 16 // max class is "combolbox"+NUL rounded up to 16
  189. #define Assert(f)
  190. #define PUBLIC
  191. #define PRIVATE static
  192. #define fFalse 0
  193. #define fTrue 1
  194. #define INCBTHOOK 1
  195. #define OUTCBTHOOK 0
  196. #ifdef _BORLAND
  197. #define CSCONST(type) type const
  198. #define CodeLpszDecl(lpszVar, szLit) TCHAR *lpszVar = szLit
  199. #define CodeLpszDeclA(lpszVar, szLit) char *lpszVar = szLit
  200. #define _alloca alloca
  201. #define _memcmp memcmp
  202. #else
  203. #ifdef WIN32
  204. #define CSCONST(type) type const
  205. #define CodeLpszDecl(lpszVar, szLit) TCHAR *lpszVar = szLit
  206. #define CodeLpszDeclA(lpszVar, szLit) char *lpszVar = szLit
  207. #else
  208. #define CSCONST(type) type _based(_segname("_CODE")) const
  209. #define CodeLpszDecl(lpszVar, szLit) \
  210. static CSCONST(char) lpszVar##Code[] = szLit; \
  211. char far *lpszVar = (char far *)lpszVar##Code
  212. #define CodeLpszDeclA(lpszVar, szLit) \
  213. static CSCONST(char) lpszVar##Code[] = szLit; \
  214. char far *lpszVar = (char far *)lpszVar##Code
  215. #endif
  216. #endif
  217. // isomorphic to windows RECT
  218. typedef struct
  219. {
  220. int xLeft;
  221. int yTop;
  222. int xRight;
  223. int yBot;
  224. } RC;
  225. // Windows Versions (Byte order flipped from GetWindowsVersion)
  226. #define ver30 0x0300
  227. #define ver31 0x030a
  228. #define ver40 0x035F
  229. // Border widths
  230. #define dxBorder 1
  231. #define dyBorder 1
  232. // Index Color Table
  233. // WARNING: change mpicvSysColors if you change the icv order
  234. typedef WORD ICV;
  235. #define icvBtnHilite 0
  236. #define icvBtnFace 1
  237. #define icvBtnShadow 2
  238. #define icvBrushMax 3
  239. #define icvBtnText 3
  240. #define icvWindow 4
  241. #define icvWindowText 5
  242. #define icvGrayText 6
  243. #define icvWindowFrame 7
  244. #define icvMax 8
  245. typedef COLORREF CV;
  246. // CoLoR Table
  247. typedef struct
  248. {
  249. CV rgcv[icvMax];
  250. } CLRT;
  251. // BRush Table
  252. typedef struct
  253. {
  254. HBRUSH mpicvhbr[icvBrushMax];
  255. } BRT;
  256. // DrawRec3d flags
  257. #define dr3Left 0x0001
  258. #define dr3Top 0x0002
  259. #define dr3Right 0x0004
  260. #define dr3Bot 0x0008
  261. #define dr3HackBotRight 0x1000 // code size is more important than aesthetics
  262. #define dr3All 0x000f
  263. typedef WORD DR3;
  264. // Control Types
  265. // Commdlg types are necessary because commdlg.dll subclasses certain
  266. // controls before the app can call Ctl3dSubclassDlg.
  267. #define ctButton 0
  268. #define ctList 1
  269. #define ctEdit 2
  270. #define ctCombo 3
  271. #define ctStatic 4
  272. #define ctComboLBox 5
  273. #define ctMax 6
  274. // ConTroL
  275. typedef struct
  276. {
  277. FARPROC lpfn;
  278. WNDPROC lpfnDefProc;
  279. TCHAR szClassName[cchClassMax];
  280. } CTL;
  281. // Control DEFinition
  282. typedef struct
  283. {
  284. TCHAR sz[20];
  285. WNDPROC lpfnWndProc;
  286. BOOL (* lpfnFCanSubclass)(HWND, LONG, WORD, WORD, HWND);
  287. WORD msk;
  288. } CDEF;
  289. // CLIent HooK
  290. typedef struct
  291. {
  292. HANDLE hinstApp;
  293. HANDLE htask;
  294. HHOOK hhook;
  295. int iCount;
  296. DWORD dwFlags;
  297. } CLIHK;
  298. #ifdef WIN32
  299. #define iclihkMaxBig 1024
  300. #define iclihkMaxSmall 128
  301. #else
  302. #define iclihkMaxBig 32
  303. #define iclihkMaxSmall 4
  304. #endif
  305. #ifdef DLL
  306. #define iclihkMax iclihkMaxBig
  307. #else
  308. #ifdef SDLL
  309. #define iclihkMax iclihkMaxBig
  310. #else
  311. #define iclihkMax iclihkMaxSmall
  312. #define _loadds
  313. #endif
  314. #endif
  315. #ifdef SDLL
  316. extern const HINSTANCE _hModule;
  317. #endif
  318. // special styles
  319. // #define bitFCoolButtons 0x0001
  320. /*-----------------------------------------------------------------------
  321. |CTL3D Function Prototypes
  322. -----------------------------------------------------------------------*/
  323. PRIVATE VOID End3dDialogs(VOID);
  324. PRIVATE BOOL FAR FInit3dDialogs(VOID);
  325. PRIVATE BOOL DoSubclassCtl(HWND hwnd, WORD grbit, WORD wCallFlags, HWND hwndParent);
  326. PRIVATE BOOL InternalCtl3dColorChange(BOOL fForce);
  327. PRIVATE VOID DeleteObjectNull(HANDLE FAR *ph);
  328. PRIVATE VOID DeleteObjects(VOID);
  329. PRIVATE int IclihkFromHinst(HANDLE hinst);
  330. LRESULT __export _loadds WINAPI Ctl3dHook(int code, WPARAM wParam, LPARAM lParam);
  331. LRESULT __export _loadds WINAPI BtnWndProc3d(HWND hwnd, UINT wm, WPARAM wParam, LPARAM lParam);
  332. LRESULT __export _loadds WINAPI EditWndProc3d(HWND hwnd, UINT wm, WPARAM wParam, LPARAM lParam);
  333. LRESULT __export _loadds WINAPI ListWndProc3d(HWND hwnd, UINT wm, WPARAM wParam, LPARAM lParam);
  334. LRESULT __export _loadds WINAPI ComboWndProc3d(HWND hwnd, UINT wm, WPARAM wParam, LPARAM lParam);
  335. LRESULT __export _loadds WINAPI StaticWndProc3d(HWND hwnd, UINT wm, WPARAM wParam, LPARAM lParam);
  336. LRESULT __export _loadds WINAPI CDListWndProc3d(HWND hwnd, UINT wm, WPARAM wParam, LPARAM lParam);
  337. LRESULT __export _loadds WINAPI CDEditWndProc3d(HWND hwnd, UINT wm, WPARAM wParam, LPARAM lParam);
  338. WORD __export _loadds WINAPI Ctl3dSetStyle(HANDLE hinst, LPTSTR lpszName, WORD grbit);
  339. LRESULT __export _loadds WINAPI Ctl3dDlgProc(HWND hwnd, UINT wm, WPARAM wParam, LPARAM lParam);
  340. BOOL FBtn(HWND, LONG, WORD, WORD, HWND);
  341. BOOL FEdit(HWND, LONG, WORD, WORD, HWND);
  342. BOOL FList(HWND, LONG, WORD, WORD, HWND);
  343. BOOL FComboList(HWND, LONG, WORD, WORD, HWND);
  344. BOOL FCombo(HWND, LONG, WORD, WORD, HWND);
  345. BOOL FStatic(HWND, LONG, WORD, WORD, HWND);
  346. HBITMAP PASCAL LoadUIBitmap(HANDLE, LPCTSTR, COLORREF, COLORREF, COLORREF, COLORREF, COLORREF, COLORREF);
  347. #ifdef WIN32
  348. #ifdef DLL
  349. BOOL CALLBACK LibMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved);
  350. #else
  351. #ifdef SDLL
  352. FAR BOOL Ctl3dLibMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved);
  353. #else
  354. FAR BOOL LibMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved);
  355. #endif
  356. #endif
  357. #else
  358. #ifdef DLL
  359. int WINAPI LibMain(HANDLE hModule, WORD wDataSeg, WORD cbHeapSize, LPSTR lpszCmdLine);
  360. #else
  361. #ifdef SDLL
  362. int FAR Ctl3dLibMain(HANDLE hModule, WORD wDataSeg, WORD cbHeapSize, LPSTR lpszCmdLine);
  363. #else
  364. #ifdef _BORLAND
  365. int FAR PASCAL LibMain(HANDLE hModule, WORD wDataSeg, WORD cbHeapSize, LPSTR lpszCmdLine);
  366. #else
  367. int FAR LibMain(HANDLE hModule, WORD wDataSeg, WORD cbHeapSize, LPSTR lpszCmdLine);
  368. #endif
  369. #endif
  370. #endif
  371. #endif
  372. #ifndef _BORLAND
  373. #ifndef WIN32
  374. #pragma alloc_text(INIT_TEXT, Ctl3dSetStyle)
  375. #pragma alloc_text(INIT_TEXT, Ctl3dColorChange)
  376. #pragma alloc_text(INIT_TEXT, Ctl3dGetVer)
  377. #pragma alloc_text(INIT_TEXT, Ctl3dRegister)
  378. #pragma alloc_text(INIT_TEXT, Ctl3dUnregister)
  379. #pragma alloc_text(INIT_TEXT, Ctl3dAutoSubclass)
  380. #pragma alloc_text(INIT_TEXT, Ctl3dEnabled)
  381. #pragma alloc_text(INIT_TEXT, Ctl3dWinIniChange)
  382. #pragma alloc_text(INIT_TEXT, DeleteObjects)
  383. #pragma alloc_text(INIT_TEXT, DeleteObjectNull)
  384. #pragma alloc_text(INIT_TEXT, InternalCtl3dColorChange)
  385. #ifdef SDLL
  386. #pragma alloc_text(INIT_TEXT, Ctl3dLibMain)
  387. #else
  388. #pragma alloc_text(INIT_TEXT, LibMain)
  389. #endif
  390. #pragma alloc_text(INIT_TEXT, FInit3dDialogs)
  391. #pragma alloc_text(INIT_TEXT, End3dDialogs)
  392. #pragma alloc_text(INIT_TEXT, LoadUIBitmap)
  393. #pragma alloc_text(INIT_TEXT, IclihkFromHinst)
  394. #endif
  395. #endif
  396. #ifndef WIN32
  397. #ifdef DLL
  398. int FAR PASCAL WEP(int);
  399. #pragma alloc_text(WEP_TEXT, WEP)
  400. #endif
  401. #endif
  402. /*-----------------------------------------------------------------------
  403. |CTL3D Globals
  404. -----------------------------------------------------------------------*/
  405. //These static varables are only access when running 16 bit Windows or Win32s
  406. //Since this is single threaded access they are OK to be statics and not protected.
  407. //
  408. static HHOOK hhookCallWndProcFilterProc;
  409. static FARPROC lpfnSubclassByHook;
  410. static HWND SubclasshWnd;
  411. #ifdef WIN32
  412. CRITICAL_SECTION g_CriticalSection;
  413. #endif
  414. typedef struct _g3d
  415. {
  416. BOOL f3dDialogs;
  417. int cInited;
  418. ATOM aCtl3dOld;
  419. ATOM aCtl3dHighOld;
  420. ATOM aCtl3dLowOld;
  421. ATOM aCtl3d;
  422. ATOM aCtl3dHigh;
  423. ATOM aCtl3dLow;
  424. ATOM aCtl3dDisable;
  425. // module & windows stuff
  426. HANDLE hinstLib;
  427. HANDLE hmodLib;
  428. WORD verWindows;
  429. WORD verBase;
  430. // drawing globals
  431. CLRT clrt;
  432. BRT brt;
  433. HBITMAP hbmpCheckboxes;
  434. // Hook cache
  435. HANDLE htaskCache;
  436. int iclihkCache;
  437. int iclihkMac;
  438. CLIHK rgclihk[iclihkMax];
  439. // Control info
  440. CTL mpctctl[ctMax];
  441. FARPROC lpfnDefDlgWndProc;
  442. // System Metrics
  443. int dxFrame;
  444. int dyFrame;
  445. int dyCaption;
  446. int dxSysMenu;
  447. // Windows functions
  448. #ifndef WIN32
  449. #ifdef DLL
  450. HHOOK (FAR PASCAL *lpfnSetWindowsHookEx)(int, HOOKPROC, HINSTANCE, HANDLE);
  451. LRESULT (FAR PASCAL *lpfnCallNextHookEx)(HHOOK, int, WPARAM, LPARAM);
  452. BOOL (FAR PASCAL *lpfnUnhookWindowsHookEx)(HHOOK);
  453. #endif
  454. #endif
  455. // DBCS stuff
  456. char chShortCutPrefix;
  457. char fDBCS;
  458. } G3D;
  459. G3D g3d;
  460. CSCONST(CDEF) mpctcdef[ctMax] =
  461. {
  462. { TEXT("Button"), BtnWndProc3d, FBtn, CTL3D_BUTTONS },
  463. { TEXT("ListBox"), ListWndProc3d, FList, CTL3D_LISTBOXES },
  464. { TEXT("Edit"), EditWndProc3d, FEdit, CTL3D_EDITS },
  465. { TEXT("ComboBox"), ComboWndProc3d, FCombo, CTL3D_COMBOS},
  466. { TEXT("Static"), StaticWndProc3d, FStatic, CTL3D_STATICTEXTS|CTL3D_STATICFRAMES },
  467. { TEXT("ComboLBox"), ListWndProc3d, FComboList, CTL3D_LISTBOXES },
  468. };
  469. CSCONST (WORD) mpicvSysColor[] =
  470. {
  471. COLOR_BTNHIGHLIGHT,
  472. COLOR_BTNFACE,
  473. COLOR_BTNSHADOW,
  474. COLOR_BTNTEXT,
  475. COLOR_WINDOW,
  476. COLOR_WINDOWTEXT,
  477. COLOR_GRAYTEXT,
  478. COLOR_WINDOWFRAME
  479. };
  480. #define WM_CHECKSUBCLASS_OLD (WM_USER+5443)
  481. #define WM_CHECKSUBCLASS (WM_USER+5444)
  482. /*-----------------------------------------------------------------------
  483. | CTL3D Utility routines
  484. -----------------------------------------------------------------------*/
  485. PRIVATE FARPROC LpfnGetDefWndProcNull(HWND hwnd)
  486. {
  487. if ( hwnd == NULL )
  488. return NULL;
  489. Win32Only(return (FARPROC) GetProp(hwnd, (LPCTSTR) g3d.aCtl3d));
  490. Win16Only(return (FARPROC) MAKELONG((UINT) GetProp(hwnd, (LPCSTR) g3d.aCtl3dLow),
  491. GetProp(hwnd, (LPCSTR) g3d.aCtl3dHigh)));
  492. }
  493. PRIVATE FARPROC LpfnGetDefWndProc(HWND hwnd, int ct)
  494. {
  495. FARPROC lpfnWndProc;
  496. lpfnWndProc = LpfnGetDefWndProcNull(hwnd);
  497. if ( lpfnWndProc == NULL ) {
  498. if ( ct == ctMax )
  499. {
  500. lpfnWndProc = (FARPROC) g3d.lpfnDefDlgWndProc;
  501. }
  502. else
  503. {
  504. lpfnWndProc = (FARPROC) g3d.mpctctl[ct].lpfnDefProc;
  505. }
  506. Win32Only(SetProp(hwnd, (LPCTSTR) g3d.aCtl3d, (HANDLE)(DWORD)lpfnWndProc));
  507. Win16Only(SetProp(hwnd, (LPCTSTR) g3d.aCtl3dLow, LOWORD(lpfnWndProc)));
  508. Win16Only(SetProp(hwnd, (LPCTSTR) g3d.aCtl3dHigh, HIWORD(lpfnWndProc)));
  509. }
  510. return lpfnWndProc;
  511. }
  512. PRIVATE VOID SubclassWindow(HWND hwnd, FARPROC lpfnSubclassProc)
  513. {
  514. FARPROC lpfnWndProc;
  515. // Make sure we don't double subclass (16 | 32 bit subclass??)
  516. if (GetProp(hwnd, (LPCTSTR) g3d.aCtl3dOld) ||
  517. GetProp(hwnd, (LPCTSTR) g3d.aCtl3d) ||
  518. GetProp(hwnd, (LPCTSTR) g3d.aCtl3dLow) ||
  519. GetProp(hwnd, (LPCTSTR) g3d.aCtl3dLowOld) ||
  520. GetProp(hwnd, (LPCTSTR) g3d.aCtl3dHigh) ||
  521. GetProp(hwnd, (LPCTSTR) g3d.aCtl3dHighOld))
  522. {
  523. return;
  524. }
  525. // Is this already subclassed by CTL3D?
  526. if (LpfnGetDefWndProcNull(hwnd) == (FARPROC) NULL)
  527. {
  528. #ifdef WIN32
  529. if (g3d.fDBCS && !IsWindowUnicode(hwnd))
  530. {
  531. TCHAR szClass[cchClassMax];
  532. GetClassName(hwnd, szClass, cchClassMax);
  533. if (lstrcmpi(szClass, TEXT("edit")) == 0)
  534. {
  535. lpfnWndProc = (FARPROC)SetWindowLongA(hwnd, GWL_WNDPROC,(LONG)lpfnSubclassProc);
  536. goto SetProps;
  537. }
  538. }
  539. #endif
  540. lpfnWndProc = (FARPROC)SetWindowLong((HWND) hwnd, GWL_WNDPROC, (LONG) lpfnSubclassProc);
  541. SetProps:
  542. Win32Only(SetProp(hwnd, (LPCTSTR) g3d.aCtl3d, (HANDLE)(DWORD)lpfnWndProc));
  543. Win16Only(SetProp(hwnd, (LPCTSTR) g3d.aCtl3dLow, LOWORD(lpfnWndProc)));
  544. Win16Only(SetProp(hwnd, (LPCTSTR) g3d.aCtl3dHigh, HIWORD(lpfnWndProc)));
  545. }
  546. }
  547. LRESULT __export _loadds WINAPI CallWndProcFilterProc(int code, WPARAM wParam, LPARAM lParam)
  548. {
  549. CWPSTRUCT FAR *cwpStruct;
  550. LONG l;
  551. cwpStruct = (CWPSTRUCT FAR *) lParam;
  552. l = CallNextHookEx(hhookCallWndProcFilterProc, code, wParam, lParam);
  553. if ( cwpStruct->hwnd == SubclasshWnd )
  554. {
  555. BOOL fSubclass;
  556. UnhookWindowsHookEx(hhookCallWndProcFilterProc);
  557. if (g3d.verWindows >= ver40 && (GetWindowLong(cwpStruct->hwnd, GWL_STYLE) & 0x04))
  558. fSubclass = fFalse;
  559. else
  560. fSubclass = fTrue;
  561. SendMessage(cwpStruct->hwnd, WM_DLGSUBCLASS, 0, (LPARAM)(int FAR *)&fSubclass);
  562. if (fSubclass)
  563. SubclassWindow(cwpStruct->hwnd, lpfnSubclassByHook);
  564. hhookCallWndProcFilterProc = 0L;
  565. lpfnSubclassByHook = NULL;
  566. SubclasshWnd = NULL;
  567. }
  568. return l;
  569. }
  570. PRIVATE VOID HookSubclassWindow(HWND hWnd, FARPROC lpfnSubclass)
  571. {
  572. //
  573. // Windows 3.1 ( 16 bit ) and Win32s can't sublcass in
  574. // WH_CBT hook. Must set up a MSG hook and subclasss at
  575. // WM_GETMINMAXINFO ( for dialogs ) or WM_NCCREATE ( for controls )
  576. // Any other message and we are out of here.
  577. //
  578. // Notes from the inside:
  579. //
  580. // The only reason not to get the WM_GETMINMAXINFO/WM_NCCREATE message
  581. // is if another CBT hook did not allow the window create.
  582. // This code only runs/works on non multithreaded systems. Thus the global
  583. // to hold the Hook Proc and subclass proc is OK.
  584. //
  585. lpfnSubclassByHook = lpfnSubclass;
  586. SubclasshWnd = hWnd;
  587. Win32Only(hhookCallWndProcFilterProc = SetWindowsHookEx(WH_CALLWNDPROC, (FARPROC)CallWndProcFilterProc, g3d.hmodLib, GetCurrentThreadId()));
  588. Win16Only(hhookCallWndProcFilterProc = SetWindowsHookEx(WH_CALLWNDPROC, (FARPROC)CallWndProcFilterProc, g3d.hmodLib, GetCurrentTask()));
  589. }
  590. PRIVATE LRESULT CleanupSubclass(HWND hwnd, UINT wm, WPARAM wParam, LPARAM lParam, int ct)
  591. {
  592. FARPROC lpfnWinProc;
  593. LRESULT lRet;
  594. lpfnWinProc = LpfnGetDefWndProc(hwnd, ct);
  595. lRet = CallWindowProc(lpfnWinProc, hwnd, wm, wParam, lParam);
  596. Win32Only(RemoveProp(hwnd, (LPCTSTR) g3d.aCtl3d));
  597. Win16Only(RemoveProp(hwnd, (LPCTSTR) g3d.aCtl3dLow));
  598. Win16Only(RemoveProp(hwnd, (LPCTSTR) g3d.aCtl3dHigh));
  599. RemoveProp(hwnd, (LPCTSTR) g3d.aCtl3dDisable);
  600. return lRet;
  601. }
  602. PRIVATE VOID DeleteObjectNull(HANDLE FAR *ph)
  603. {
  604. if (*ph != NULL)
  605. {
  606. DeleteObject(*ph);
  607. *ph = NULL;
  608. }
  609. }
  610. PRIVATE VOID DeleteObjects(VOID)
  611. {
  612. int icv;
  613. for(icv = 0; icv < icvBrushMax; icv++)
  614. DeleteObjectNull(&g3d.brt.mpicvhbr[icv]);
  615. DeleteObjectNull(&g3d.hbmpCheckboxes);
  616. }
  617. PRIVATE VOID PatFill(HDC hdc, RC FAR *lprc)
  618. {
  619. PatBlt(hdc, lprc->xLeft, lprc->yTop, lprc->xRight-lprc->xLeft, lprc->yBot-lprc->yTop, PATCOPY);
  620. }
  621. /*-----------------------------------------------------------------------
  622. | DrawRec3d
  623. |
  624. |
  625. | Arguments:
  626. | HDC hdc:
  627. | RC FAR *lprc:
  628. | LONG cvUL:
  629. | LONG cvLR:
  630. | WORD grbit;
  631. |
  632. | Returns:
  633. |
  634. -----------------------------------------------------------------------*/
  635. PRIVATE VOID DrawRec3d(HDC hdc, RC FAR *lprc, ICV icvUL, ICV icvLR, DR3 dr3)
  636. {
  637. COLORREF cvSav;
  638. RC rc;
  639. cvSav = SetBkColor(hdc, g3d.clrt.rgcv[icvUL]);
  640. // top
  641. rc = *lprc;
  642. rc.yBot = rc.yTop+1;
  643. if (dr3 & dr3Top)
  644. ExtTextOut(hdc, 0, 0, ETO_OPAQUE, (LPRECT) &rc,
  645. (LPCTSTR) NULL, 0, (int far *) NULL);
  646. // left
  647. rc.yBot = lprc->yBot;
  648. rc.xRight = rc.xLeft+1;
  649. if (dr3 & dr3Left)
  650. ExtTextOut(hdc, 0, 0, ETO_OPAQUE, (LPRECT) &rc,
  651. (LPCTSTR) NULL, 0, (int far *) NULL);
  652. if (icvUL != icvLR)
  653. SetBkColor(hdc, g3d.clrt.rgcv[icvLR]);
  654. // right
  655. rc.xRight = lprc->xRight;
  656. rc.xLeft = rc.xRight-1;
  657. if (dr3 & dr3Right)
  658. ExtTextOut(hdc, 0, 0, ETO_OPAQUE, (LPRECT) &rc,
  659. (LPCTSTR) NULL, 0, (int far *) NULL);
  660. // bot
  661. if (dr3 & dr3Bot)
  662. {
  663. rc.xLeft = lprc->xLeft;
  664. rc.yTop = rc.yBot-1;
  665. if (dr3 & dr3HackBotRight)
  666. rc.xRight -=2;
  667. ExtTextOut(hdc, 0, 0, ETO_OPAQUE, (LPRECT) &rc,
  668. (LPCTSTR) NULL, 0, (int far *) NULL);
  669. }
  670. SetBkColor(hdc, cvSav);
  671. }
  672. #ifdef CANTUSE
  673. // Windows forces dialog fonts to be BOLD...URRRGH
  674. PRIVATE VOID MyDrawText(HWND hwnd, HDC hdc, LPSTR lpch, int cch, RC FAR *lprc, int dt)
  675. {
  676. TEXTMETRIC tm;
  677. BOOL fChisled;
  678. fChisled = fFalse;
  679. if (!IsWindowEnabled(hwnd))
  680. {
  681. GetTextMetrics(hdc, &tm);
  682. if (tm.tmWeight > 400)
  683. SetTextColor(hdc, g3d.clrt.rgcv[icvGrayText]);
  684. else
  685. {
  686. fChisled = fTrue;
  687. SetTextColor(hdc, g3d.clrt.rgcv[icvBtnHilite]);
  688. OffsetRect((LPRECT) lprc, -1, -1);
  689. }
  690. }
  691. DrawText(hdc, lpch, cch, (LPRECT) lprc, dt);
  692. if (fChisled)
  693. {
  694. SetTextColor(hdc, g3d.clrt.rgcv[icvBtnHilite]);
  695. OffsetRect((LPRECT) lprc, 1, 1);
  696. DrawText(hdc, lpch, cch, (LPRECT) lprc, dt);
  697. }
  698. }
  699. #endif
  700. PRIVATE VOID DrawInsetRect3d(HDC hdc, RC FAR *prc, DR3 dr3)
  701. {
  702. RC rc;
  703. rc = *prc;
  704. DrawRec3d(hdc, &rc, icvWindowFrame, icvBtnFace, (WORD)(dr3 & dr3All));
  705. rc.xLeft--;
  706. rc.yTop--;
  707. rc.xRight++;
  708. rc.yBot++;
  709. DrawRec3d(hdc, &rc, icvBtnShadow, icvBtnHilite, dr3);
  710. }
  711. PRIVATE VOID ClipCtlDc(HWND hwnd, HDC hdc)
  712. {
  713. RC rc;
  714. GetClientRect(hwnd, (LPRECT) &rc);
  715. IntersectClipRect(hdc, rc.xLeft, rc.yTop, rc.xRight, rc.yBot);
  716. }
  717. PRIVATE int IclihkFromHinst(HANDLE hinst)
  718. {
  719. int iclihk;
  720. for (iclihk = 0; iclihk < g3d.iclihkMac; iclihk++)
  721. if (g3d.rgclihk[iclihk].hinstApp == hinst)
  722. return iclihk;
  723. return -1;
  724. }
  725. PRIVATE VOID MyGetTextExtent(HDC hdc, LPTSTR lpsz, int FAR *lpdx, int FAR *lpdy)
  726. {
  727. LPTSTR lpch;
  728. TCHAR szT[256];
  729. lpch = szT;
  730. while(*lpsz != '\000')
  731. {
  732. if (*lpsz == '&')
  733. {
  734. lpsz++;
  735. if (*lpsz == '\000')
  736. break;
  737. }
  738. //begin DBCS: far east short cut key support
  739. else if (g3d.fDBCS)
  740. {
  741. if (*lpsz == g3d.chShortCutPrefix)
  742. { // skip only prefix
  743. lpsz++;
  744. if (*lpsz == '\000')
  745. break;
  746. }
  747. else if (*lpsz == chShortCutSbcsPrefix || *lpsz == chShortCutDbcsPrefix)
  748. { // skip both prefix and short cut key
  749. lpsz++;
  750. if (*lpsz == '\000')
  751. break;
  752. lpsz = Win32Or16(CharNext(lpsz),AnsiNext(lpsz));
  753. continue;
  754. }
  755. }
  756. //end DBCS
  757. *lpch++ = *lpsz++;
  758. }
  759. *lpch = '\000';
  760. #ifdef WIN32
  761. {
  762. SIZE pt;
  763. GetTextExtentPoint(hdc, szT, lstrlen(szT), &pt);
  764. *lpdx = pt.cx;
  765. *lpdy = pt.cy;
  766. }
  767. #else
  768. {
  769. long dwExt;
  770. dwExt = GetTextExtent(hdc, szT, lpch-(char far *)szT);
  771. *lpdx = LOWORD(dwExt);
  772. // Check for Hangeul Windows - JeeP 011194
  773. if ( (g3d.verWindows >= ver31 && GetSystemMetrics(SM_DBCSENABLED)) ||
  774. (IsDBCSLeadByte(0xa1) && !IsDBCSLeadByte(0xa0)) )
  775. *lpdy = HIWORD(dwExt)+1;
  776. else
  777. *lpdy = HIWORD(dwExt);
  778. }
  779. #endif
  780. }
  781. /*-----------------------------------------------------------------------
  782. | CTL3D Publics
  783. -----------------------------------------------------------------------*/
  784. PUBLIC BOOL WINAPI Ctl3dRegister(HANDLE hinstApp)
  785. {
  786. #ifdef WIN32
  787. #ifndef DLL
  788. InitializeCriticalSection(&g_CriticalSection);
  789. #endif
  790. EnterCriticalSection(&g_CriticalSection);
  791. #endif
  792. g3d.cInited++;
  793. Win32Only(LeaveCriticalSection(&g_CriticalSection));
  794. if (g3d.cInited == 1)
  795. {
  796. #ifndef DLL
  797. #ifdef SDLL
  798. Win32Only(Ctl3dLibMain(hinstApp, DLL_PROCESS_ATTACH, (LPVOID) NULL));
  799. Win16Only(Ctl3dLibMain(hinstApp, 0, 0, (LPSTR) NULL));
  800. #else
  801. Win32Only(LibMain(hinstApp, DLL_PROCESS_ATTACH, (LPVOID) NULL));
  802. Win16Only(LibMain(hinstApp, 0, 0, (LPSTR) NULL));
  803. #endif
  804. #endif
  805. FInit3dDialogs();
  806. }
  807. if (Ctl3dIsAutoSubclass())
  808. Ctl3dAutoSubclass(hinstApp);
  809. return g3d.f3dDialogs;
  810. }
  811. PUBLIC BOOL WINAPI Ctl3dUnregister(HANDLE hinstApp)
  812. {
  813. int iclihk;
  814. HANDLE hTask;
  815. //
  816. // Find the task's hook
  817. //
  818. Win32Only(hTask = (HANDLE)GetCurrentThreadId());
  819. Win16Only(hTask = GetCurrentTask());
  820. Win32Only(EnterCriticalSection(&g_CriticalSection));
  821. for (iclihk = 0; iclihk < g3d.iclihkMac; iclihk++)
  822. {
  823. if (g3d.rgclihk[iclihk].htask == hTask)
  824. {
  825. g3d.rgclihk[iclihk].iCount--;
  826. if ( g3d.rgclihk[iclihk].iCount == 0 || hinstApp == g3d.rgclihk[iclihk].hinstApp)
  827. {
  828. Win32Only(UnhookWindowsHookEx(g3d.rgclihk[iclihk].hhook));
  829. #ifdef DLL
  830. Win16Only((*g3d.lpfnUnhookWindowsHookEx)(g3d.rgclihk[iclihk].hhook));
  831. #else
  832. Win16Only(UnhookWindowsHookEx(g3d.rgclihk[iclihk].hhook));
  833. #endif
  834. g3d.iclihkMac--;
  835. while(iclihk < g3d.iclihkMac)
  836. {
  837. g3d.rgclihk[iclihk] = g3d.rgclihk[iclihk+1];
  838. iclihk++;
  839. }
  840. }
  841. }
  842. }
  843. g3d.cInited--;
  844. Win32Only(LeaveCriticalSection(&g_CriticalSection));
  845. if (g3d.cInited == 0)
  846. {
  847. End3dDialogs();
  848. }
  849. return fTrue;
  850. }
  851. /*-----------------------------------------------------------------------
  852. | Ctl3dAutoSubclass
  853. |
  854. | Automatically subclasses all dialogs of the client app.
  855. |
  856. | Note: Due to bugs in Commdlg, an app should still call Ctl3dSubclassDlg
  857. | for the Commdlg OpenFile and PageSetup dialogs.
  858. |
  859. | Arguments:
  860. | HANDLE hinstApp:
  861. |
  862. | Returns:
  863. |
  864. -----------------------------------------------------------------------*/
  865. PUBLIC BOOL WINAPI Ctl3dAutoSubclass(HANDLE hinstApp)
  866. {
  867. return Ctl3dAutoSubclassEx(hinstApp, 0);
  868. }
  869. PUBLIC BOOL WINAPI Ctl3dAutoSubclassEx(HANDLE hinstApp, DWORD dwFlags)
  870. {
  871. HHOOK hhook;
  872. HANDLE htask;
  873. int iclihk;
  874. if (g3d.verWindows < ver31)
  875. return fFalse;
  876. if (!g3d.f3dDialogs)
  877. return fFalse;
  878. #ifdef WIN32
  879. // CTL3D_SUBCLASS_DYNCREATE is considered default in Win32, but
  880. // not Win16 for backward compatibility reasons.
  881. dwFlags |= CTL3D_SUBCLASS_DYNCREATE;
  882. #endif
  883. // CTL3D_NOSUBCLASS_DYNCREATE always overrides CTL3D_SUBCLASS_DYNCREATE
  884. if (dwFlags & CTL3D_NOSUBCLASS_DYNCREATE)
  885. dwFlags &= ~(CTL3D_NOSUBCLASS_DYNCREATE|CTL3D_SUBCLASS_DYNCREATE);
  886. Win32Only(EnterCriticalSection(&g_CriticalSection));
  887. if (g3d.iclihkMac == iclihkMax)
  888. goto Fail;
  889. Win32Only(htask = (HANDLE)GetCurrentThreadId());
  890. Win16Only(htask = GetCurrentTask());
  891. //
  892. // Don't set the hook twice for the same task....
  893. //
  894. for (iclihk = 0; iclihk < g3d.iclihkMac; iclihk++)
  895. {
  896. if (g3d.rgclihk[iclihk].htask == htask)
  897. {
  898. g3d.rgclihk[iclihk].iCount++;
  899. goto Success;
  900. }
  901. }
  902. Win32Only(hhook = SetWindowsHookEx(WH_CBT, (HOOKPROC)Ctl3dHook, g3d.hmodLib, (DWORD)htask));
  903. #ifdef DLL
  904. Win16Only(hhook = (*g3d.lpfnSetWindowsHookEx)(WH_CBT, (HOOKPROC) Ctl3dHook, g3d.hmodLib, hinstApp == NULL ? NULL : htask));
  905. #else
  906. Win16Only(hhook = SetWindowsHookEx(WH_CBT, (HOOKPROC) Ctl3dHook, g3d.hmodLib, hinstApp == NULL ? NULL : htask));
  907. #endif
  908. if (hhook != NULL)
  909. {
  910. g3d.rgclihk[g3d.iclihkMac].hinstApp = hinstApp;
  911. g3d.rgclihk[g3d.iclihkMac].htask = htask;
  912. g3d.rgclihk[g3d.iclihkMac].hhook = hhook;
  913. g3d.rgclihk[g3d.iclihkMac].iCount = 1;
  914. g3d.rgclihk[g3d.iclihkMac].dwFlags = dwFlags;
  915. g3d.htaskCache = htask;
  916. g3d.iclihkCache = g3d.iclihkMac;
  917. g3d.iclihkMac++;
  918. Success:
  919. Win32Only(LeaveCriticalSection(&g_CriticalSection));
  920. return fTrue;
  921. }
  922. Fail:
  923. Win32Only(LeaveCriticalSection(&g_CriticalSection));
  924. return fFalse;
  925. }
  926. /*-----------------------------------------------------------------------
  927. | Ctl3dIsAutoSubclass
  928. |
  929. | Returns:
  930. | Whether this task has Automatic Subclassing Enabled
  931. |
  932. -----------------------------------------------------------------------*/
  933. PUBLIC BOOL WINAPI Ctl3dIsAutoSubclass()
  934. {
  935. int iclihk;
  936. HANDLE hTask;
  937. Win32Only(hTask = (HANDLE)GetCurrentThreadId());
  938. Win16Only(hTask = GetCurrentTask());
  939. for (iclihk = 0; iclihk < g3d.iclihkMac; iclihk++)
  940. {
  941. if (g3d.rgclihk[iclihk].htask == hTask)
  942. {
  943. return TRUE;
  944. }
  945. }
  946. // didn't find task in hook table.
  947. return FALSE;
  948. }
  949. /*-----------------------------------------------------------------------
  950. | Ctl3dUnAutoSubclass
  951. |
  952. -----------------------------------------------------------------------*/
  953. PUBLIC BOOL WINAPI Ctl3dUnAutoSubclass()
  954. {
  955. int iclihk;
  956. HANDLE hTask;
  957. // Find the task's hook
  958. //
  959. //
  960. Win32Only(hTask = (HANDLE)GetCurrentThreadId());
  961. Win16Only(hTask = GetCurrentTask());
  962. Win32Only(EnterCriticalSection(&g_CriticalSection));
  963. for (iclihk = 0; iclihk < g3d.iclihkMac; iclihk++)
  964. {
  965. if (g3d.rgclihk[iclihk].htask == hTask)
  966. {
  967. g3d.rgclihk[iclihk].iCount--;
  968. if ( g3d.rgclihk[iclihk].iCount == 0 )
  969. {
  970. Win32Only(UnhookWindowsHookEx(g3d.rgclihk[iclihk].hhook));
  971. #ifdef DLL
  972. Win16Only((*g3d.lpfnUnhookWindowsHookEx)(g3d.rgclihk[iclihk].hhook));
  973. #else
  974. Win16Only(UnhookWindowsHookEx(g3d.rgclihk[iclihk].hhook));
  975. #endif
  976. g3d.iclihkMac--;
  977. while(iclihk < g3d.iclihkMac)
  978. {
  979. g3d.rgclihk[iclihk] = g3d.rgclihk[iclihk+1];
  980. iclihk++;
  981. }
  982. }
  983. }
  984. }
  985. Win32Only(LeaveCriticalSection(&g_CriticalSection));
  986. return TRUE;
  987. }
  988. WORD __export _loadds WINAPI Ctl3dSetStyle(HANDLE hinst, LPTSTR lpszName, WORD grbit)
  989. {
  990. #ifdef OLD
  991. WORD grbitOld;
  992. if (!g3d.f3dDialogs)
  993. return fFalse;
  994. grbitOld = grbitStyle;
  995. if (grbit != 0)
  996. grbitStyle = grbit;
  997. if (hinst != NULL && lpszName != NULL)
  998. {
  999. HBITMAP hbmpCheckboxesNew;
  1000. hbmpCheckboxesNew = LoadUIBitmap(hinst, (LPCSTR) lpszName,
  1001. g3d.clrt.rgcv[icvWindowText],
  1002. g3d.clrt.rgcv[icvBtnFace],
  1003. g3d.clrt.rgcv[icvBtnShadow],
  1004. g3d.clrt.rgcv[icvBtnHilite],
  1005. g3d.clrt.rgcv[icvWindow],
  1006. g3d.clrt.rgcv[icvWindowFrame]);
  1007. if (hbmpCheckboxesNew != NULL)
  1008. {
  1009. DeleteObjectNull(&g3d.hbmpCheckboxes);
  1010. g3d.hbmpCheckboxes = hbmpCheckboxesNew;
  1011. }
  1012. }
  1013. return grbitOld;
  1014. #endif
  1015. return 0;
  1016. }
  1017. /*-----------------------------------------------------------------------
  1018. | Ctl3dGetVer
  1019. |
  1020. | Returns version of CTL3D library
  1021. |
  1022. | Returns:
  1023. | Major version # in hibyte, minor version # in lobyte
  1024. |
  1025. -----------------------------------------------------------------------*/
  1026. PUBLIC WORD WINAPI Ctl3dGetVer(void)
  1027. {
  1028. return 0x0231;
  1029. }
  1030. /*-----------------------------------------------------------------------
  1031. | Ctl3dEnabled
  1032. |
  1033. | Returns:
  1034. | Whether or not controls will be draw with 3d effects
  1035. -----------------------------------------------------------------------*/
  1036. PUBLIC BOOL WINAPI Ctl3dEnabled(void)
  1037. {
  1038. return g3d.f3dDialogs;
  1039. }
  1040. /*-----------------------------------------------------------------------
  1041. | Ctl3dSubclassCtl
  1042. |
  1043. | Subclasses an individual control
  1044. |
  1045. | Arguments:
  1046. | HWND hwnd:
  1047. |
  1048. | Returns:
  1049. | fTrue if control was successfully subclassed
  1050. |
  1051. -----------------------------------------------------------------------*/
  1052. PUBLIC BOOL WINAPI Ctl3dSubclassCtl(HWND hwnd)
  1053. {
  1054. if (!g3d.f3dDialogs)
  1055. return fFalse;
  1056. return DoSubclassCtl(hwnd, CTL3D_ALL, OUTCBTHOOK, NULL);
  1057. }
  1058. /*-----------------------------------------------------------------------
  1059. | Ctl3dUnsubclassCtl
  1060. |
  1061. | Un-Subclasses an individual control
  1062. |
  1063. | Arguments:
  1064. | HWND hwnd:
  1065. |
  1066. | Returns:
  1067. | fTrue if control was successfully subclassed
  1068. |
  1069. -----------------------------------------------------------------------*/
  1070. PUBLIC BOOL WINAPI Ctl3dUnsubclassCtl(HWND hwnd)
  1071. {
  1072. FARPROC lpfnWinProc;
  1073. HWND hwndKids;
  1074. int ct;
  1075. if (!g3d.f3dDialogs)
  1076. return fFalse;
  1077. lpfnWinProc = (FARPROC) GetWindowLong(hwnd, GWL_WNDPROC);
  1078. // Is it a control
  1079. for (ct = 0; ct < ctMax; ct++)
  1080. {
  1081. if ( lpfnWinProc == g3d.mpctctl[ct].lpfn )
  1082. {
  1083. lpfnWinProc = LpfnGetDefWndProc(hwnd, ct);
  1084. Win32Only(RemoveProp(hwnd, (LPCTSTR) g3d.aCtl3d));
  1085. Win16Only(RemoveProp(hwnd, (LPCTSTR) g3d.aCtl3dLow));
  1086. Win16Only(RemoveProp(hwnd, (LPCTSTR) g3d.aCtl3dHigh));
  1087. SetWindowLong(hwnd, GWL_WNDPROC, (LONG) lpfnWinProc );
  1088. lpfnWinProc = NULL;
  1089. ct = ctMax+10;
  1090. }
  1091. }
  1092. // How about a dlg ?
  1093. if ( ct == ctMax )
  1094. {
  1095. if ( lpfnWinProc == (FARPROC) Ctl3dDlgProc )
  1096. {
  1097. lpfnWinProc = LpfnGetDefWndProc(hwnd, ct);
  1098. Win32Only(RemoveProp(hwnd, (LPCTSTR) g3d.aCtl3d));
  1099. Win16Only(RemoveProp(hwnd, (LPCTSTR) g3d.aCtl3dLow));
  1100. Win16Only(RemoveProp(hwnd, (LPCTSTR) g3d.aCtl3dHigh));
  1101. SetWindowLong(hwnd, GWL_WNDPROC, (LONG) lpfnWinProc );
  1102. lpfnWinProc = NULL;
  1103. }
  1104. else
  1105. {
  1106. // None of the above, add disable property
  1107. if (GetProp(hwnd, (LPCTSTR) g3d.aCtl3d) ||
  1108. GetProp(hwnd, (LPCTSTR) g3d.aCtl3dLow) ||
  1109. GetProp(hwnd, (LPCTSTR) g3d.aCtl3dHigh))
  1110. {
  1111. SetProp(hwnd,(LPCTSTR) g3d.aCtl3dDisable, (HANDLE) 1);
  1112. }
  1113. }
  1114. }
  1115. //
  1116. // Now unsubclass all the kids
  1117. //
  1118. for (hwndKids = GetWindow(hwnd, GW_CHILD); hwndKids != NULL;
  1119. hwndKids = GetWindow(hwndKids, GW_HWNDNEXT))
  1120. {
  1121. Ctl3dUnsubclassCtl(hwndKids);
  1122. }
  1123. return fTrue;
  1124. }
  1125. /*-----------------------------------------------------------------------
  1126. | Ctl3dSubclassCtlEx
  1127. |
  1128. | Actually subclass the control
  1129. |
  1130. |
  1131. -----------------------------------------------------------------------*/
  1132. PUBLIC BOOL WINAPI Ctl3dSubclassCtlEx(HWND hwnd, int ct)
  1133. {
  1134. LONG style;
  1135. BOOL fCan;
  1136. if (!g3d.f3dDialogs)
  1137. return fFalse;
  1138. if (ct < 0 || ct > ctMax)
  1139. return fFalse;
  1140. // Is this already subclassed by CTL3D?
  1141. if (LpfnGetDefWndProcNull(hwnd) != (FARPROC) NULL)
  1142. return fFalse;
  1143. // Only subclass it if it is something that we'd normally subclass
  1144. style = GetWindowLong(hwnd, GWL_STYLE);
  1145. fCan = mpctcdef[ct].lpfnFCanSubclass(hwnd, style, CTL3D_ALL,
  1146. OUTCBTHOOK, GetParent(hwnd));
  1147. if (fCan == fTrue)
  1148. SubclassWindow(hwnd, g3d.mpctctl[ct].lpfn);
  1149. return fTrue;
  1150. }
  1151. /*-----------------------------------------------------------------------
  1152. | Ctl3dSubclassDlg
  1153. |
  1154. | Call this during WM_INITDIALOG processing.
  1155. |
  1156. | Arguments:
  1157. | hwndDlg:
  1158. |
  1159. -----------------------------------------------------------------------*/
  1160. PUBLIC BOOL WINAPI Ctl3dSubclassDlg(HWND hwndDlg, WORD grbit)
  1161. {
  1162. HWND hwnd;
  1163. if (!g3d.f3dDialogs)
  1164. return fFalse;
  1165. for(hwnd = GetWindow(hwndDlg, GW_CHILD); hwnd != NULL;
  1166. hwnd = GetWindow(hwnd, GW_HWNDNEXT))
  1167. {
  1168. DoSubclassCtl(hwnd, grbit, OUTCBTHOOK, NULL);
  1169. }
  1170. return fTrue;
  1171. }
  1172. /*-----------------------------------------------------------------------
  1173. | Ctl3dCheckSubclassDlg
  1174. |
  1175. | Call this during WM_INITDIALOG processing.
  1176. |
  1177. | Arguments:
  1178. | hwndDlg:
  1179. |
  1180. -----------------------------------------------------------------------*/
  1181. PRIVATE void CheckChildSubclass(HWND hwnd, WORD grbit, HWND hwndParent)
  1182. {
  1183. // Is this already subclassed by CTL3D?
  1184. // Is our property there ?
  1185. if (LpfnGetDefWndProcNull(hwnd) == (FARPROC) NULL)
  1186. {
  1187. // No, how did this slip by, try a subclass again.
  1188. DoSubclassCtl(hwnd, grbit, OUTCBTHOOK, hwndParent);
  1189. }
  1190. else
  1191. {
  1192. // Yes, we have subclassed this control.
  1193. // Is our subclass still on the chain ?
  1194. BOOL fSubclass;
  1195. // Make sure subclassing isn't disabled...
  1196. if (GetProp(hwnd, (LPCTSTR)g3d.aCtl3dDisable))
  1197. return;
  1198. fSubclass = 666;
  1199. SendMessage((HWND) hwnd, WM_CHECKSUBCLASS, 0, (LPARAM)(int FAR *)&fSubclass);
  1200. if ( fSubclass == 666 )
  1201. SendMessage((HWND) hwnd, WM_CHECKSUBCLASS_OLD, 0, (LPARAM)(int FAR *)&fSubclass);
  1202. if ( fSubclass == 666 ) // Evil
  1203. {
  1204. // We have been un-subclassed by some bad app ( common dialogs in Win16 )
  1205. // Remove the Prop, and subclass again, take that.
  1206. Win32Only(RemoveProp(hwnd, (LPCTSTR) g3d.aCtl3d));
  1207. Win16Only(RemoveProp(hwnd, (LPCTSTR) g3d.aCtl3dLow));
  1208. Win16Only(RemoveProp(hwnd, (LPCTSTR) g3d.aCtl3dHigh));
  1209. DoSubclassCtl(hwnd, grbit, OUTCBTHOOK, hwndParent);
  1210. }
  1211. }
  1212. }
  1213. PUBLIC BOOL WINAPI Ctl3dCheckSubclassDlg(HWND hwndDlg, WORD grbit)
  1214. {
  1215. HWND hwnd, hwnd2;
  1216. if (!g3d.f3dDialogs)
  1217. return fFalse;
  1218. for (hwnd = GetWindow(hwndDlg, GW_CHILD); hwnd != NULL;
  1219. hwnd = GetWindow(hwnd, GW_HWNDNEXT))
  1220. {
  1221. CheckChildSubclass(hwnd, grbit, NULL);
  1222. for (hwnd2 = GetWindow(hwnd, GW_CHILD); hwnd2 != NULL;
  1223. hwnd2 = GetWindow(hwnd2, GW_HWNDNEXT))
  1224. {
  1225. CheckChildSubclass(hwnd2, grbit, hwnd);
  1226. }
  1227. }
  1228. return fTrue;
  1229. }
  1230. /*-----------------------------------------------------------------------
  1231. | Ctl3dSubclassDlgEx
  1232. |
  1233. | Call this during WM_INITDIALOG processing. This is like
  1234. | Ctl3dSubclassDlg but it also subclasses the dialog window itself
  1235. | so the app doesn't need to.
  1236. |
  1237. | Arguments:
  1238. | hwndDlg:
  1239. |
  1240. -----------------------------------------------------------------------*/
  1241. PUBLIC BOOL WINAPI Ctl3dSubclassDlgEx(HWND hwndDlg, DWORD grbit)
  1242. {
  1243. HWND hwnd;
  1244. if (!g3d.f3dDialogs)
  1245. return fFalse;
  1246. for(hwnd = GetWindow(hwndDlg, GW_CHILD); hwnd != NULL;
  1247. hwnd = GetWindow(hwnd, GW_HWNDNEXT))
  1248. {
  1249. DoSubclassCtl(hwnd, LOWORD(grbit), OUTCBTHOOK, NULL);
  1250. }
  1251. //
  1252. // Now Subclass the dialog window as well
  1253. //
  1254. SubclassWindow((HWND) hwndDlg, (FARPROC)Ctl3dDlgProc);
  1255. return fTrue;
  1256. }
  1257. /*-----------------------------------------------------------------------
  1258. | Ctl3dCtlColor
  1259. |
  1260. | Common CTL_COLOR processor for 3d UITF dialogs & alerts.
  1261. |
  1262. | Arguments:
  1263. | hdc:
  1264. | lParam:
  1265. |
  1266. | Returns:
  1267. | appropriate brush if g3d.f3dDialogs. Returns fFalse otherwise
  1268. |
  1269. -----------------------------------------------------------------------*/
  1270. PUBLIC HBRUSH WINAPI Ctl3dCtlColor(HDC hdc, LPARAM lParam)
  1271. {
  1272. #ifdef WIN32
  1273. return (HBRUSH) fFalse;
  1274. #else
  1275. HWND hwndParent;
  1276. Assert(CTLCOLOR_MSGBOX < CTLCOLOR_BTN);
  1277. Assert(CTLCOLOR_EDIT < CTLCOLOR_BTN);
  1278. Assert(CTLCOLOR_LISTBOX < CTLCOLOR_BTN);
  1279. if(g3d.f3dDialogs)
  1280. {
  1281. if (HIWORD(lParam) >= CTLCOLOR_LISTBOX)
  1282. {
  1283. if (HIWORD(lParam) == CTLCOLOR_LISTBOX &&
  1284. (g3d.verWindows >= ver40 ||
  1285. ((GetWindow(LOWORD(lParam), GW_CHILD) == NULL ||
  1286. (GetWindowLong(LOWORD(lParam), GWL_STYLE) & 0x03) == CBS_DROPDOWNLIST))))
  1287. {
  1288. // if it doesn't have a child then it must be a list box
  1289. // don't do brush stuff for drop down lists or else
  1290. // it draws funny grey inside the edit rect
  1291. goto DefWP;
  1292. }
  1293. SetTextColor(hdc, g3d.clrt.rgcv[icvBtnText]);
  1294. SetBkColor(hdc, g3d.clrt.rgcv[icvBtnFace]);
  1295. return g3d.brt.mpicvhbr[icvBtnFace];
  1296. }
  1297. }
  1298. DefWP:
  1299. hwndParent = GetParent(LOWORD(lParam));
  1300. if (hwndParent == NULL)
  1301. return fFalse;
  1302. return (HBRUSH) DefWindowProc(hwndParent, WM_CTLCOLOR, (WPARAM) hdc, (LONG) lParam);
  1303. #endif
  1304. }
  1305. /*-----------------------------------------------------------------------
  1306. | Ctl3dCtlColorEx
  1307. |
  1308. | Common CTL_COLOR processor for 3d UITF dialogs & alerts.
  1309. |
  1310. | Arguments:
  1311. |
  1312. | Returns:
  1313. | appropriate brush if g3d.f3dDialogs. Returns fFalse otherwise
  1314. |
  1315. -----------------------------------------------------------------------*/
  1316. PUBLIC HBRUSH WINAPI Ctl3dCtlColorEx(UINT wm, WPARAM wParam, LPARAM lParam)
  1317. {
  1318. #ifdef WIN32
  1319. Assert(WM_CTLCOLORMSGBOX < WM_CTLCOLORBTN);
  1320. Assert(WM_CTLCOLOREDIT < WM_CTLCOLORBTN);
  1321. Assert(WM_CTLCOLORLISTBOX < WM_CTLCOLORBTN);
  1322. if(g3d.f3dDialogs)
  1323. {
  1324. if (wm >= WM_CTLCOLORLISTBOX && wm != WM_CTLCOLORSCROLLBAR)
  1325. {
  1326. if (wm == WM_CTLCOLORLISTBOX &&
  1327. (g3d.verWindows >= ver40 ||
  1328. ((GetWindow((HWND) lParam, GW_CHILD) == NULL ||
  1329. (GetWindowLong((HWND) lParam, GWL_STYLE) & 0x03) == CBS_DROPDOWNLIST))))
  1330. {
  1331. // if it doesn't have a child then it must be a list box
  1332. // don't do brush stuff for drop down lists or else
  1333. // it draws funny grey inside the edit rect
  1334. return (HBRUSH) fFalse;
  1335. }
  1336. SetTextColor((HDC) wParam, g3d.clrt.rgcv[icvBtnText]);
  1337. SetBkColor((HDC) wParam, g3d.clrt.rgcv[icvBtnFace]);
  1338. return g3d.brt.mpicvhbr[icvBtnFace];
  1339. }
  1340. }
  1341. return (HBRUSH) fFalse;
  1342. #else
  1343. return Ctl3dCtlColor(wParam, lParam);
  1344. #endif
  1345. }
  1346. /*-----------------------------------------------------------------------
  1347. | Ctl3dColorChange
  1348. |
  1349. | App calls this when it gets a WM_SYSCOLORCHANGE message
  1350. |
  1351. | Returns:
  1352. | TRUE if successful.
  1353. |
  1354. -----------------------------------------------------------------------*/
  1355. PUBLIC BOOL WINAPI Ctl3dColorChange(VOID)
  1356. {
  1357. BOOL bResult;
  1358. Win32Only(EnterCriticalSection(&g_CriticalSection));
  1359. bResult = InternalCtl3dColorChange(fFalse);
  1360. Win32Only(LeaveCriticalSection(&g_CriticalSection));
  1361. return bResult;
  1362. }
  1363. PRIVATE LONG WINAPI
  1364. Ctl3dDlgFramePaintI(HWND hwnd, UINT wm, WPARAM wParam, LPARAM lParam, BOOL fDefWP);
  1365. /*-----------------------------------------------------------------------
  1366. | Ctl3dDlgFramePaint
  1367. |
  1368. | App calls this when it gets a NC_PAINT message
  1369. |
  1370. | Returns:
  1371. | TRUE if successful.
  1372. |
  1373. -----------------------------------------------------------------------*/
  1374. PUBLIC LONG WINAPI Ctl3dDlgFramePaint(HWND hwnd, UINT wm, WPARAM wParam, LPARAM lParam)
  1375. {
  1376. return Ctl3dDlgFramePaintI(hwnd, wm, wParam, lParam, TRUE);
  1377. }
  1378. // Ctl3dDlgFramePaintI used only internally by Ctl3d
  1379. PRIVATE LONG WINAPI
  1380. Ctl3dDlgFramePaintI(HWND hwnd, UINT wm, WPARAM wParam, LPARAM lParam, BOOL fDefWP)
  1381. {
  1382. LONG lResult;
  1383. LONG lStyle;
  1384. BOOL fBorder;
  1385. WNDPROC defProc = fDefWP ? NULL : (WNDPROC) LpfnGetDefWndProc(hwnd, ctMax);
  1386. if (defProc != NULL)
  1387. lResult = CallWindowProc((FARPROC)defProc, hwnd, wm, wParam, lParam);
  1388. else
  1389. lResult = DefWindowProc(hwnd, wm, wParam, lParam);
  1390. if (!g3d.f3dDialogs)
  1391. return lResult;
  1392. if ( IsIconic(hwnd) )
  1393. return lResult;
  1394. fBorder = CTL3D_BORDER;
  1395. SendMessage(hwnd, WM_DLGBORDER, 0, (LPARAM)(int FAR *)&fBorder);
  1396. lStyle = GetWindowLong(hwnd, GWL_STYLE);
  1397. if (fBorder != CTL3D_NOBORDER && (lStyle & (WS_VISIBLE|WS_DLGFRAME|DS_MODALFRAME)) == (WS_VISIBLE|WS_DLGFRAME|DS_MODALFRAME))
  1398. {
  1399. BOOL fCaption;
  1400. HBRUSH hbrSav;
  1401. HDC hdc;
  1402. RC rc;
  1403. RC rcFill;
  1404. int dyFrameTop;
  1405. fCaption = (lStyle & WS_CAPTION) == WS_CAPTION;
  1406. dyFrameTop = g3d.dyFrame - (fCaption ? dyBorder : 0);
  1407. hdc = GetWindowDC(hwnd);
  1408. GetWindowRect(hwnd, (LPRECT) &rc);
  1409. rc.xRight = rc.xRight-rc.xLeft;
  1410. rc.yBot = rc.yBot-rc.yTop;
  1411. rc.xLeft = rc.yTop = 0;
  1412. DrawRec3d(hdc, &rc, icvBtnShadow, icvWindowFrame, dr3All);
  1413. InflateRect((LPRECT) &rc, -dxBorder, -dyBorder);
  1414. DrawRec3d(hdc, &rc, icvBtnHilite, icvBtnShadow, dr3All);
  1415. InflateRect((LPRECT) &rc, -dxBorder, -dyBorder);
  1416. hbrSav = SelectObject(hdc, g3d.brt.mpicvhbr[icvBtnFace]);
  1417. rcFill = rc;
  1418. // Left
  1419. rcFill.xRight = rcFill.xLeft+g3d.dxFrame;
  1420. PatFill(hdc, &rcFill);
  1421. // Right
  1422. OffsetRect((LPRECT) &rcFill, rc.xRight-rc.xLeft-g3d.dxFrame, 0);
  1423. PatFill(hdc, &rcFill);
  1424. // Top
  1425. rcFill.xLeft = rc.xLeft + g3d.dxFrame;
  1426. rcFill.xRight = rc.xRight - g3d.dxFrame;
  1427. rcFill.yBot = rcFill.yTop+dyFrameTop;
  1428. PatFill(hdc, &rcFill);
  1429. if (fCaption)
  1430. {
  1431. RC rcT;
  1432. rcT = rcFill;
  1433. rcT.yTop += dyFrameTop;
  1434. rcT.yBot = rcT.yTop + g3d.dyCaption;
  1435. DrawRec3d(hdc, &rcT, icvBtnShadow, icvBtnHilite, dr3All);
  1436. }
  1437. // Bottom
  1438. rcFill.yTop += rc.yBot-rc.yTop-g3d.dxFrame;
  1439. rcFill.yBot = rcFill.yTop + g3d.dyFrame;
  1440. PatFill(hdc, &rcFill);
  1441. #ifdef CHISLEBORDER
  1442. if (fBorder == CTL3D_CHISLEBORDER)
  1443. {
  1444. // This code doesn't work because it draws in the client area
  1445. GetClientRect(hwnd, (LPRECT) &rc);
  1446. OffsetRect((LPRECT) &rc, g3d.dxFrame+2*dxBorder, fCaption ? g3d.dyFrame+g3d.dyCaption : g3d.dyFrame+dyBorder);
  1447. DrawRec3d(hdc, &rc, icvBtnShadow, icvBtnHilite, dr3Bot|dr3Left|dr3Right);
  1448. rc.xLeft++;
  1449. rc.xRight--;
  1450. rc.yBot--;
  1451. DrawRec3d(hdc, &rc, icvBtnHilite, icvBtnShadow, dr3Bot|dr3Left|dr3Right);
  1452. }
  1453. #endif
  1454. SelectObject(hdc, hbrSav);
  1455. ReleaseDC(hwnd, hdc);
  1456. }
  1457. return lResult;
  1458. }
  1459. //begin DBCS: far east short cut key support
  1460. /*-----------------------------------------------------------------------
  1461. | CTL3D Far East Support
  1462. -----------------------------------------------------------------------*/
  1463. /*-----------------------------------------------------------------------
  1464. | Ctl3dWinIniChange
  1465. |
  1466. | App calls this when it gets a WM_WININICHANGE message
  1467. |
  1468. | Returns:
  1469. | none
  1470. |
  1471. -----------------------------------------------------------------------*/
  1472. PUBLIC VOID WINAPI Ctl3dWinIniChange(void)
  1473. {
  1474. TCHAR szShortCutMode[cchShortCutModeMax];
  1475. CodeLpszDecl(szSectionWindows, TEXT("windows"));
  1476. CodeLpszDecl(szEntryShortCutKK, TEXT("kanjimenu"));
  1477. CodeLpszDecl(szEntryShortCutCH, TEXT("hangeulmenu"));
  1478. CodeLpszDecl(szShortCutSbcsKK, TEXT("roman"));
  1479. CodeLpszDecl(szShortCutSbcsCH, TEXT("english"));
  1480. CodeLpszDecl(szShortCutDbcsKK, TEXT("kanji"));
  1481. CodeLpszDecl(szShortCutDbcsCH, TEXT("hangeul"));
  1482. if (!g3d.fDBCS)
  1483. return;
  1484. Win32Only(EnterCriticalSection(&g_CriticalSection));
  1485. g3d.chShortCutPrefix = chShortCutSbcsPrefix;
  1486. GetProfileString(szSectionWindows, szEntryShortCutKK, szShortCutSbcsKK, szShortCutMode, cchShortCutModeMax - 1);
  1487. if (!lstrcmpi(szShortCutMode, szShortCutDbcsKK))
  1488. g3d.chShortCutPrefix = chShortCutDbcsPrefix;
  1489. GetProfileString(szSectionWindows, szEntryShortCutCH, szShortCutSbcsCH, szShortCutMode, cchShortCutModeMax - 1);
  1490. if (!lstrcmpi(szShortCutMode, szShortCutDbcsCH))
  1491. g3d.chShortCutPrefix = chShortCutDbcsPrefix;
  1492. Win32Only(LeaveCriticalSection(&g_CriticalSection));
  1493. }
  1494. //end DBCS
  1495. /*-----------------------------------------------------------------------
  1496. | CTL3D Internal Routines
  1497. -----------------------------------------------------------------------*/
  1498. /*-----------------------------------------------------------------------
  1499. | FInit3dDialogs
  1500. |
  1501. | Initialized 3d stuff
  1502. |
  1503. -----------------------------------------------------------------------*/
  1504. PRIVATE BOOL FAR FInit3dDialogs(VOID)
  1505. {
  1506. HDC hdc;
  1507. WNDCLASS wc;
  1508. #ifdef DLL
  1509. #ifdef V2
  1510. int nChars;
  1511. LPTSTR pCh;
  1512. static TCHAR MyDirectory[260];
  1513. TCHAR OkDirectory[260];
  1514. #endif
  1515. #endif
  1516. //if (g3d.verWindows >= ver40)
  1517. // {
  1518. // g3d.f3dDialogs = fFalse;
  1519. // return fFalse;
  1520. // }
  1521. Win32Only(EnterCriticalSection(&g_CriticalSection));
  1522. #ifdef DLL
  1523. #ifdef V2
  1524. #ifdef WIN32
  1525. {
  1526. TCHAR szT[2];
  1527. CodeLpszDecl(szSpecial, TEXT("Ctl3d_RunAlways"));
  1528. if (GetEnvironmentVariable(szSpecial, szT, 2) != 0 && szT[0] == '1')
  1529. {
  1530. goto AllowBadInstall;
  1531. }
  1532. }
  1533. #endif
  1534. #ifdef WIN32
  1535. #ifdef UNICODE
  1536. if (GetVersion() & 0x80000000)
  1537. {
  1538. Win16Or32(
  1539. CodeLpszDeclA(lpszCtl3d, "CTL3DV2.DLL"),
  1540. CodeLpszDeclA(lpszCtl3d, "CTL3D32.DLL"));
  1541. CodeLpszDeclA(lpszBadInstMsg,
  1542. "This application uses CTL3D32.DLL, which is not the correct version. "
  1543. "This version of CTL3D32.DLL is designed only for Windows NT systems.");
  1544. MessageBoxA(NULL, lpszBadInstMsg, lpszCtl3d, MB_ICONSTOP | MB_OK);
  1545. g3d.f3dDialogs = fFalse;
  1546. goto Return;
  1547. }
  1548. #else
  1549. if (!(GetVersion() & 0x80000000))
  1550. {
  1551. Win16Or32(
  1552. CodeLpszDeclA(lpszCtl3d, "CTL3DV2.DLL"),
  1553. CodeLpszDeclA(lpszCtl3d, "CTL3D32.DLL"));
  1554. CodeLpszDeclA(lpszBadInstMsg,
  1555. "This application uses CTL3D32.DLL, which is not the correct version. "
  1556. "This version of CTL3D32.DLL is designed only for Win32s or Windows 95 systems.");
  1557. MessageBoxA(NULL, lpszBadInstMsg, lpszCtl3d, MB_ICONSTOP | MB_OK);
  1558. g3d.f3dDialogs = fFalse;
  1559. goto Return;
  1560. }
  1561. #endif
  1562. #endif
  1563. #ifndef SPECIAL_WOW_VERSION
  1564. nChars = GetModuleFileName(g3d.hinstLib, MyDirectory, sizeof(MyDirectory)Win32Only(/sizeof(TCHAR)));
  1565. for (pCh = (LPTSTR)(MyDirectory+nChars-1);
  1566. pCh >= (LPTSTR)MyDirectory;
  1567. pCh = Win32Or16(CharPrev(MyDirectory, pCh),AnsiPrev(MyDirectory, pCh)))
  1568. {
  1569. if ( *pCh == '\\' )
  1570. {
  1571. if ( *(pCh-1) != ':' )
  1572. *pCh = 0;
  1573. else
  1574. *(pCh+1) = 0;
  1575. break;
  1576. }
  1577. }
  1578. nChars = GetSystemDirectory(OkDirectory, sizeof(OkDirectory)Win32Only(/sizeof(TCHAR)));
  1579. if ( lstrcmpi(MyDirectory,OkDirectory ) )
  1580. {
  1581. nChars = GetWindowsDirectory(OkDirectory, sizeof(OkDirectory)Win32Only(/sizeof(TCHAR)));
  1582. if ( lstrcmpi(MyDirectory,OkDirectory ) )
  1583. {
  1584. Win16Or32(
  1585. CodeLpszDeclA(lpszCtl3d, "CTL3DV2.DLL"),
  1586. CodeLpszDeclA(lpszCtl3d, "CTL3D32.DLL"));
  1587. Win16Or32(
  1588. CodeLpszDeclA(lpszBadInstMsg,
  1589. "This application uses CTL3DV2.DLL, which has not been correctly installed. "
  1590. "CTL3DV2.DLL must be installed in the Windows system directory."),
  1591. CodeLpszDeclA(lpszBadInstMsg,
  1592. "This application uses CTL3D32.DLL, which has not been correctly installed. "
  1593. "CTL3D32.DLL must be installed in the Windows system directory."));
  1594. Win32Only(LeaveCriticalSection(&g_CriticalSection));
  1595. MessageBoxA(NULL, lpszBadInstMsg, lpszCtl3d, MB_ICONSTOP | MB_OK );
  1596. g3d.f3dDialogs = fFalse;
  1597. goto Return;
  1598. }
  1599. }
  1600. #endif //!SPECIAL_WOW_VERSION
  1601. Win32Only(AllowBadInstall:;)
  1602. #endif
  1603. #endif
  1604. hdc = GetDC(NULL);
  1605. g3d.f3dDialogs = GetDeviceCaps(hdc,BITSPIXEL)*GetDeviceCaps(hdc,PLANES) >= 4;
  1606. // Win 3.1 EGA lies to us...
  1607. if(GetSystemMetrics(SM_CYSCREEN) == 350 && GetSystemMetrics(SM_CXSCREEN) == 640)
  1608. g3d.f3dDialogs = fFalse;
  1609. ReleaseDC(NULL, hdc);
  1610. if (g3d.f3dDialogs)
  1611. {
  1612. int ct;
  1613. CodeLpszDecl(lpszC3dD, TEXT("C3dD"));
  1614. CodeLpszDecl(lpszC3dOld, TEXT("C3d"));
  1615. CodeLpszDecl(lpszC3dLOld, TEXT("C3dL"));
  1616. CodeLpszDecl(lpszC3dHOld, TEXT("C3dH"));
  1617. CodeLpszDecl(lpszC3d, TEXT("C3dNew"));
  1618. CodeLpszDecl(lpszC3dL, TEXT("C3dLNew"));
  1619. CodeLpszDecl(lpszC3dH, TEXT("C3dHNew"));
  1620. g3d.aCtl3dOld = GlobalAddAtom(lpszC3dOld);
  1621. if (g3d.aCtl3dOld == 0)
  1622. {
  1623. g3d.f3dDialogs = fFalse;
  1624. goto Return;
  1625. }
  1626. g3d.aCtl3d = GlobalAddAtom(lpszC3d);
  1627. if (g3d.aCtl3d == 0)
  1628. {
  1629. g3d.f3dDialogs = fFalse;
  1630. goto Return;
  1631. }
  1632. g3d.aCtl3dLowOld = GlobalAddAtom(lpszC3dLOld);
  1633. g3d.aCtl3dHighOld = GlobalAddAtom(lpszC3dHOld);
  1634. if (g3d.aCtl3dLowOld == 0 || g3d.aCtl3dHighOld == 0)
  1635. {
  1636. g3d.f3dDialogs = fFalse;
  1637. return fFalse;
  1638. }
  1639. g3d.aCtl3dLow = GlobalAddAtom(lpszC3dL);
  1640. g3d.aCtl3dHigh = GlobalAddAtom(lpszC3dH);
  1641. if (g3d.aCtl3dLow == 0 || g3d.aCtl3dHigh == 0)
  1642. {
  1643. g3d.f3dDialogs = fFalse;
  1644. return fFalse;
  1645. }
  1646. g3d.aCtl3dDisable = GlobalAddAtom(lpszC3dD);
  1647. if (g3d.aCtl3dDisable == 0)
  1648. {
  1649. g3d.f3dDialogs = fFalse;
  1650. goto Return;
  1651. }
  1652. // DBCS
  1653. g3d.fDBCS = GetSystemMetrics(SM_DBCSENABLED);
  1654. Ctl3dWinIniChange();
  1655. if (InternalCtl3dColorChange(fTrue)) // load bitmap & brushes
  1656. {
  1657. for (ct = 0; ct < ctMax; ct++)
  1658. {
  1659. g3d.mpctctl[ct].lpfn = (FARPROC)mpctcdef[ct].lpfnWndProc;
  1660. Assert(g3d.mpctctl[ct].lpfn != NULL);
  1661. GetClassInfo(NULL, mpctcdef[ct].sz, (LPWNDCLASS) &wc);
  1662. g3d.mpctctl[ct].lpfnDefProc = wc.lpfnWndProc;
  1663. }
  1664. if (GetClassInfo(NULL, WC_DIALOG, &wc))
  1665. g3d.lpfnDefDlgWndProc = (FARPROC) wc.lpfnWndProc;
  1666. else
  1667. g3d.lpfnDefDlgWndProc = (FARPROC) DefDlgProc;
  1668. }
  1669. else
  1670. {
  1671. g3d.f3dDialogs = fFalse;
  1672. }
  1673. }
  1674. Return:
  1675. Win32Only(LeaveCriticalSection(&g_CriticalSection));
  1676. return g3d.f3dDialogs;
  1677. }
  1678. /*-----------------------------------------------------------------------
  1679. | End3dDialogs
  1680. |
  1681. | Called at DLL termination to free 3d dialog stuff
  1682. -----------------------------------------------------------------------*/
  1683. PRIVATE VOID End3dDialogs(VOID)
  1684. {
  1685. int ct;
  1686. Win32Only(EnterCriticalSection(&g_CriticalSection));
  1687. for (ct = 0; ct < ctMax; ct++)
  1688. {
  1689. if(g3d.mpctctl[ct].lpfn != NULL)
  1690. {
  1691. FreeProcInstance(g3d.mpctctl[ct].lpfn);
  1692. g3d.mpctctl[ct].lpfn = NULL;
  1693. }
  1694. }
  1695. DeleteObjects();
  1696. g3d.aCtl3dOld ? GlobalDeleteAtom(g3d.aCtl3dOld) : 0;
  1697. g3d.aCtl3d ? GlobalDeleteAtom(g3d.aCtl3d) : 0;
  1698. g3d.aCtl3dLowOld ? GlobalDeleteAtom(g3d.aCtl3dLowOld) : 0;
  1699. g3d.aCtl3dHighOld ? GlobalDeleteAtom(g3d.aCtl3dHighOld) : 0;
  1700. g3d.aCtl3dLow ? GlobalDeleteAtom(g3d.aCtl3dLow) : 0;
  1701. g3d.aCtl3dHigh ? GlobalDeleteAtom(g3d.aCtl3dHigh) : 0;
  1702. g3d.aCtl3dDisable ? GlobalDeleteAtom(g3d.aCtl3dDisable) : 0;
  1703. g3d.f3dDialogs = fFalse;
  1704. Win32Only(LeaveCriticalSection(&g_CriticalSection));
  1705. }
  1706. PRIVATE BOOL InternalCtl3dColorChange(BOOL fForce)
  1707. {
  1708. ICV icv;
  1709. CLRT clrtNew;
  1710. HBITMAP hbmpCheckboxesNew;
  1711. BRT brtNew;
  1712. if (!g3d.f3dDialogs)
  1713. return fFalse;
  1714. for (icv = 0; icv < icvMax; icv++)
  1715. clrtNew.rgcv[icv] = GetSysColor(mpicvSysColor[icv]);
  1716. if (g3d.verWindows == ver30)
  1717. clrtNew.rgcv[icvBtnHilite] = RGB(0xff, 0xff, 0xff);
  1718. if (clrtNew.rgcv[icvGrayText] == 0L || clrtNew.rgcv[icvGrayText] == clrtNew.rgcv[icvBtnFace])
  1719. {
  1720. if (clrtNew.rgcv[icvBtnFace] == RGB(0x80, 0x80, 0x80))
  1721. clrtNew.rgcv[icvGrayText] = RGB(0xc0, 0xc0, 0xc0);
  1722. else
  1723. clrtNew.rgcv[icvGrayText] = RGB(0x80, 0x80, 0x80);
  1724. }
  1725. if (fForce || MEMCMP(&g3d.clrt, &clrtNew, sizeof(CLRT)))
  1726. {
  1727. hbmpCheckboxesNew = LoadUIBitmap(g3d.hinstLib, MAKEINTRESOURCE(CTL3D_3DCHECK),
  1728. clrtNew.rgcv[icvWindowText],
  1729. clrtNew.rgcv[icvBtnFace],
  1730. clrtNew.rgcv[icvBtnShadow],
  1731. clrtNew.rgcv[icvBtnHilite],
  1732. clrtNew.rgcv[icvWindow],
  1733. clrtNew.rgcv[icvWindowFrame]);
  1734. for (icv = 0; icv < icvBrushMax; icv++)
  1735. brtNew.mpicvhbr[icv] = CreateSolidBrush(clrtNew.rgcv[icv]);
  1736. for (icv = 0; icv < icvBrushMax; icv++)
  1737. if (brtNew.mpicvhbr[icv] == NULL)
  1738. goto OOM;
  1739. if(hbmpCheckboxesNew != NULL)
  1740. {
  1741. DeleteObjects();
  1742. g3d.brt = brtNew;
  1743. g3d.clrt = clrtNew;
  1744. g3d.hbmpCheckboxes = hbmpCheckboxesNew;
  1745. return fTrue;
  1746. }
  1747. else
  1748. {
  1749. OOM:
  1750. for (icv = 0; icv < icvBrushMax; icv++)
  1751. DeleteObjectNull(&brtNew.mpicvhbr[icv]);
  1752. DeleteObjectNull(&hbmpCheckboxesNew);
  1753. return fFalse;
  1754. }
  1755. }
  1756. return fTrue;
  1757. }
  1758. /*-----------------------------------------------------------------------
  1759. | Ctl3dDlgProc
  1760. |
  1761. | Subclass DlgProc for use w/ Ctl3dAutoSubclass
  1762. |
  1763. |
  1764. | Arguments:
  1765. | HWND hwnd:
  1766. | int wm:
  1767. | WORD wParam:
  1768. | LPARAM lParam:
  1769. |
  1770. | Returns:
  1771. |
  1772. -----------------------------------------------------------------------*/
  1773. LRESULT __export _loadds WINAPI Ctl3dDlgProc(HWND hwnd, UINT wm, WPARAM wParam, LPARAM lParam)
  1774. {
  1775. HBRUSH hbrush;
  1776. FARPROC lpfnDlgProc;
  1777. TCHAR szClass[cchClassMax];
  1778. if ( wm == WM_NCDESTROY )
  1779. return CleanupSubclass(hwnd, wm, wParam, lParam, ctMax);
  1780. if ( GetProp(hwnd,(LPCTSTR) g3d.aCtl3dDisable) )
  1781. return CallWindowProc(LpfnGetDefWndProc(hwnd, ctMax), hwnd, wm, wParam, lParam);
  1782. switch (wm)
  1783. {
  1784. case WM_CHECKSUBCLASS_OLD:
  1785. case WM_CHECKSUBCLASS:
  1786. *(int FAR *)lParam = fTrue;
  1787. return ctMax+1000;
  1788. case WM_INITDIALOG:
  1789. {
  1790. long l;
  1791. BOOL fSubclass;
  1792. FARPROC lpfnWinProc;
  1793. lpfnWinProc = LpfnGetDefWndProc(hwnd, ctMax);
  1794. if (g3d.verWindows >= ver40 && (GetWindowLong(hwnd, GWL_STYLE) & 0x04))
  1795. fSubclass = fFalse;
  1796. else
  1797. fSubclass = fTrue;
  1798. SendMessage(hwnd, WM_DLGSUBCLASS, 0, (LPARAM)(int FAR *)&fSubclass);
  1799. if (!fSubclass)
  1800. {
  1801. Ctl3dUnsubclassCtl(hwnd);
  1802. return CallWindowProc(lpfnWinProc, hwnd, wm, wParam, lParam);
  1803. }
  1804. l = CallWindowProc(lpfnWinProc, hwnd, wm, wParam, lParam);
  1805. if (g3d.verWindows < ver40 || !(GetWindowLong(hwnd, GWL_STYLE) & 0x04))
  1806. Ctl3dCheckSubclassDlg(hwnd, CTL3D_ALL);
  1807. return l;
  1808. }
  1809. case WM_NCPAINT:
  1810. case WM_NCACTIVATE:
  1811. case WM_SETTEXT:
  1812. if (g3d.verWindows >= ver40 || IsIconic(hwnd) )
  1813. return CallWindowProc(LpfnGetDefWndProc(hwnd, ctMax), hwnd, wm, wParam, lParam);
  1814. else
  1815. return Ctl3dDlgFramePaintI(hwnd, wm, wParam, lParam, FALSE);
  1816. #ifdef WIN32
  1817. case WM_CTLCOLORSCROLLBAR:
  1818. case WM_CTLCOLORBTN:
  1819. case WM_CTLCOLORDLG:
  1820. case WM_CTLCOLOREDIT:
  1821. case WM_CTLCOLORLISTBOX:
  1822. case WM_CTLCOLORMSGBOX:
  1823. case WM_CTLCOLORSTATIC:
  1824. #else
  1825. case WM_CTLCOLOR:
  1826. #endif
  1827. // Is this really a dialog
  1828. GetClassName(hwnd, szClass, sizeof(szClass)Win32Only(/sizeof(TCHAR)));
  1829. if (lstrcmp(TEXT("#32770"),szClass) != 0 )
  1830. {
  1831. #ifdef WIN32
  1832. hbrush = (HBRUSH) CallWindowProc(LpfnGetDefWndProc(hwnd, ctMax), hwnd,
  1833. wm-WM_CTLCOLORMSGBOX+CTLMSGOFFSET, wParam, lParam);
  1834. #else
  1835. hbrush = (HBRUSH) CallWindowProc(LpfnGetDefWndProc(hwnd, ctMax), hwnd,
  1836. CTL3D_CTLCOLOR, wParam, lParam);
  1837. #endif
  1838. if (hbrush == (HBRUSH) fFalse || hbrush == (HBRUSH)1)
  1839. hbrush = Ctl3dCtlColorEx(wm, wParam, lParam);
  1840. }
  1841. else
  1842. {
  1843. lpfnDlgProc = (FARPROC) GetWindowLong(hwnd, DWL_DLGPROC);
  1844. if (lpfnDlgProc == NULL )
  1845. {
  1846. hbrush = Ctl3dCtlColorEx(wm, wParam, lParam);
  1847. }
  1848. else
  1849. {
  1850. #ifdef WIN32
  1851. if ( (LONG)lpfnDlgProc > 0xFFFF0000 && g3d.verWindows <= ver31)
  1852. {
  1853. // We have a Uni-code / non Unicode issue.
  1854. // If this is before Daytona, then I CAN NOT call because it may be NULL, but
  1855. // the returned value is not-null. NT Bug.
  1856. // So Just send our own message to the window proc instead
  1857. hbrush = (HBRUSH) CallWindowProc(LpfnGetDefWndProc(hwnd, ctMax), hwnd,
  1858. wm-WM_CTLCOLORMSGBOX+CTLMSGOFFSET, wParam, lParam);
  1859. if (hbrush == (HBRUSH) fFalse || hbrush == (HBRUSH)1)
  1860. hbrush = Ctl3dCtlColorEx(wm, wParam, lParam);
  1861. }
  1862. else
  1863. {
  1864. #endif
  1865. hbrush = (HBRUSH) CallWindowProc(lpfnDlgProc, hwnd, wm, wParam, lParam);
  1866. if (hbrush == (HBRUSH) fFalse || hbrush == (HBRUSH)1)
  1867. {
  1868. #ifdef WIN32
  1869. hbrush = (HBRUSH) CallWindowProc(LpfnGetDefWndProc(hwnd, ctMax), hwnd,
  1870. wm-WM_CTLCOLORMSGBOX+CTLMSGOFFSET, wParam, lParam);
  1871. #else
  1872. hbrush = (HBRUSH) CallWindowProc(LpfnGetDefWndProc(hwnd, ctMax), hwnd,
  1873. CTL3D_CTLCOLOR, wParam, lParam);
  1874. #endif
  1875. if (hbrush == (HBRUSH) fFalse || hbrush == (HBRUSH)1)
  1876. hbrush = Ctl3dCtlColorEx(wm, wParam, lParam);
  1877. }
  1878. }
  1879. #ifdef WIN32
  1880. }
  1881. #endif
  1882. }
  1883. if (hbrush != (HBRUSH) fFalse)
  1884. return (LRESULT)hbrush;
  1885. break;
  1886. }
  1887. return CallWindowProc(LpfnGetDefWndProc(hwnd, ctMax), hwnd, wm, wParam, lParam);
  1888. }
  1889. PRIVATE BOOL NEAR DoesChildNeedSubclass(HWND hwnd)
  1890. {
  1891. if (!LpfnGetDefWndProcNull(hwnd))
  1892. return fFalse;
  1893. if (g3d.verWindows >= ver40 && GetWindowLong(hwnd, GWL_STYLE) & 0x04)
  1894. return fFalse;
  1895. return fTrue;
  1896. }
  1897. /*-----------------------------------------------------------------------
  1898. | Ctl3dHook
  1899. |
  1900. | CBT Hook to watch for window creation. Automatically subclasses all
  1901. | dialogs w/ Ctl3dDlgProc
  1902. |
  1903. | Arguments:
  1904. | int code:
  1905. | WORD wParam:
  1906. | LPARAM lParam:
  1907. |
  1908. | Returns:
  1909. |
  1910. -----------------------------------------------------------------------*/
  1911. LRESULT __export _loadds WINAPI Ctl3dHook(int code, WPARAM wParam, LPARAM lParam)
  1912. {
  1913. int iclihk;
  1914. HANDLE htask;
  1915. htask = Win32Or16((HANDLE)GetCurrentThreadId(), GetCurrentTask());
  1916. Win32Only(EnterCriticalSection(&g_CriticalSection));
  1917. if (htask != g3d.htaskCache)
  1918. {
  1919. for (iclihk = 0; iclihk < g3d.iclihkMac; iclihk++)
  1920. {
  1921. if (g3d.rgclihk[iclihk].htask == htask)
  1922. {
  1923. g3d.iclihkCache = iclihk;
  1924. g3d.htaskCache = htask;
  1925. break;
  1926. }
  1927. }
  1928. if ( iclihk == g3d.iclihkMac )
  1929. {
  1930. // didn't find task in hook table. This could be bad, but
  1931. // returning 0L is about all we can doo.
  1932. //
  1933. // Actually not. The hhook isn't used anyway just set it to NULL.
  1934. // and call the next hook..... KGM
  1935. Win32Only(LeaveCriticalSection(&g_CriticalSection));
  1936. return CallNextHookEx((HHOOK)0L, code, wParam, lParam);
  1937. }
  1938. }
  1939. iclihk = g3d.iclihkCache;
  1940. Win32Only(LeaveCriticalSection(&g_CriticalSection));
  1941. if (code == HCBT_CREATEWND)
  1942. {
  1943. LPCREATESTRUCT lpcs;
  1944. lpcs = ((LPCBT_CREATEWND)lParam)->lpcs;
  1945. if (lpcs->lpszClass == WC_DIALOG)
  1946. {
  1947. if (g3d.verBase == 32)
  1948. {
  1949. BOOL fSubclass;
  1950. if (g3d.verWindows >= ver40 && (GetWindowLong((HWND)wParam, GWL_STYLE) & 0x04))
  1951. fSubclass = fFalse;
  1952. else
  1953. fSubclass = fTrue;
  1954. SendMessage((HWND)wParam, WM_DLGSUBCLASS, 0, (LPARAM)(int FAR *)&fSubclass);
  1955. if (fSubclass)
  1956. SubclassWindow((HWND)wParam, (FARPROC) Ctl3dDlgProc);
  1957. }
  1958. else
  1959. {
  1960. HookSubclassWindow((HWND)wParam, (FARPROC) Ctl3dDlgProc);
  1961. }
  1962. goto Zing;
  1963. }
  1964. if (!(g3d.rgclihk[iclihk].dwFlags & CTL3D_SUBCLASS_DYNCREATE))
  1965. goto Zing;
  1966. if (DoesChildNeedSubclass(lpcs->hwndParent) ||
  1967. (lpcs->hwndParent && g3d.verBase != 24 &&
  1968. DoesChildNeedSubclass(GetParent(lpcs->hwndParent))))
  1969. {
  1970. DoSubclassCtl((HWND)wParam, CTL3D_ALL, INCBTHOOK, lpcs->hwndParent);
  1971. }
  1972. }
  1973. Zing:;
  1974. Win32Only(return CallNextHookEx(g3d.rgclihk[iclihk].hhook, code, wParam, lParam));
  1975. #ifdef DLL
  1976. Win16Only(return (*g3d.lpfnCallNextHookEx)(g3d.rgclihk[iclihk].hhook, code, wParam, lParam));
  1977. #else
  1978. Win16Only(return (CallNextHookEx(g3d.rgclihk[iclihk].hhook, code, wParam, lParam)));
  1979. #endif
  1980. }
  1981. /*-----------------------------------------------------------------------
  1982. | CTL3D F* routines
  1983. |
  1984. | These routines determine whether or not the given control may be
  1985. | subclassed. They may recursively call DoSubclassCtl in the
  1986. | case of multi-control controls
  1987. |
  1988. | Returns:
  1989. | fTrue if can subclass the given control.
  1990. -----------------------------------------------------------------------*/
  1991. PRIVATE BOOL FBtn(HWND hwnd, LONG style, WORD grbit, WORD wCallFlags, HWND hwndParent)
  1992. {
  1993. if (g3d.verWindows >= ver40)
  1994. {
  1995. return fFalse;
  1996. }
  1997. style &= ~(BS_LEFTTEXT);
  1998. return ( LOWORD(style) >= BS_PUSHBUTTON && LOWORD(style) <= BS_AUTORADIOBUTTON);
  1999. }
  2000. PRIVATE BOOL FEdit(HWND hwnd, LONG style, WORD grbit, WORD wCallFlags, HWND hwndParent)
  2001. {
  2002. if (g3d.verWindows >= ver40 && hwndParent)
  2003. {
  2004. TCHAR szClass[cchClassMax];
  2005. GetClassName(hwndParent, szClass, sizeof(szClass)Win32Only(/sizeof(TCHAR)));
  2006. if (lstrcmp(szClass, mpctcdef[ctCombo].sz) == 0 )
  2007. return fFalse;
  2008. else
  2009. return fTrue;
  2010. }
  2011. else
  2012. return fTrue;
  2013. }
  2014. PRIVATE BOOL FList(HWND hwnd, LONG style, WORD grbit, WORD wCallFlags, HWND hwndParent)
  2015. {
  2016. if (g3d.verWindows >= ver40 && hwndParent)
  2017. {
  2018. TCHAR szClass[cchClassMax];
  2019. GetClassName(hwndParent, szClass, sizeof(szClass)Win32Only(/sizeof(TCHAR)));
  2020. if (lstrcmp(szClass, mpctcdef[ctCombo].sz) == 0 )
  2021. return fFalse;
  2022. else
  2023. return fTrue;
  2024. }
  2025. else
  2026. return fTrue;
  2027. }
  2028. PRIVATE BOOL FComboList(HWND hwnd, LONG style, WORD grbit, WORD wCallFlags, HWND hwndParent)
  2029. {
  2030. if (g3d.verWindows >= ver40)
  2031. return fFalse;
  2032. if ( wCallFlags == INCBTHOOK )
  2033. {
  2034. LONG style;
  2035. style = GetWindowLong(hwndParent, GWL_STYLE);
  2036. if (!(((style & 0x0003) == CBS_DROPDOWN) || ((style & 0x0003) == CBS_DROPDOWNLIST)))
  2037. return fTrue;
  2038. else
  2039. return fFalse;
  2040. }
  2041. return fTrue;
  2042. }
  2043. PRIVATE BOOL FCombo(HWND hwnd, LONG style, WORD grbit, WORD wCallFlags, HWND hwndParent)
  2044. {
  2045. HWND hwndEdit;
  2046. HWND hwndList;
  2047. if (g3d.verWindows >= ver40)
  2048. return fFalse;
  2049. if ((style & 0x0003) == CBS_DROPDOWN)
  2050. {
  2051. if ( wCallFlags == INCBTHOOK )
  2052. {
  2053. return fFalse;
  2054. }
  2055. // Subclass edit so bottom border of the edit draws properly...This case
  2056. // is specially handled in ListEditPaint3d
  2057. hwndEdit = GetWindow(hwnd, GW_CHILD);
  2058. if (hwndEdit != NULL)
  2059. DoSubclassCtl(hwndEdit, CTL3D_EDITS, wCallFlags, hwnd);
  2060. return fTrue;
  2061. }
  2062. else if ((style & 0x0003) == CBS_DROPDOWNLIST )
  2063. {
  2064. return fTrue;
  2065. }
  2066. else // assume simple // if ((style & 0x0003) == CBS_SIMPLE)
  2067. {
  2068. if ( wCallFlags == INCBTHOOK )
  2069. {
  2070. return fTrue;
  2071. }
  2072. hwndList = GetWindow(hwnd, GW_CHILD);
  2073. if (hwndList != NULL)
  2074. {
  2075. // Subclass list & edit box so they draw properly. We also
  2076. // subclass the combo so we can hide/show/move it and the
  2077. // 3d effects outside the client area get erased
  2078. DoSubclassCtl(hwndList, CTL3D_LISTBOXES, wCallFlags, hwnd);
  2079. hwndEdit = GetWindow(hwndList, GW_HWNDNEXT);
  2080. if (hwndEdit != NULL)
  2081. DoSubclassCtl(hwndEdit, CTL3D_EDITS, wCallFlags, hwnd);
  2082. return fTrue;
  2083. }
  2084. return fFalse;
  2085. }
  2086. }
  2087. PRIVATE BOOL FStatic(HWND hwnd, LONG style, WORD grbit, WORD wCallFlags, HWND hwndParent)
  2088. {
  2089. int wStyle;
  2090. wStyle = LOWORD(style) & 0x1f;
  2091. return (wStyle != SS_ICON &&
  2092. ((grbit & CTL3D_STATICTEXTS) &&
  2093. (wStyle <= SS_RIGHT || wStyle == SS_LEFTNOWORDWRAP) ||
  2094. ((grbit & CTL3D_STATICFRAMES) &&
  2095. ((wStyle >= SS_BLACKRECT && wStyle <= SS_WHITEFRAME) ||
  2096. (g3d.verWindows < ver40 && wStyle >= 0x10 && wStyle <= 0x12)))));
  2097. }
  2098. /*-----------------------------------------------------------------------
  2099. | DoSubclassCtl
  2100. |
  2101. | Actually subclass the control
  2102. |
  2103. |
  2104. | Arguments:
  2105. | HWND hwnd:
  2106. | WORD grbit:
  2107. | WORD wCallFlags
  2108. | Returns:
  2109. |
  2110. -----------------------------------------------------------------------*/
  2111. PRIVATE BOOL DoSubclassCtl(HWND hwnd, WORD grbit, WORD wCallFlags, HWND hwndParent)
  2112. {
  2113. LONG style;
  2114. int ct;
  2115. BOOL fCan;
  2116. TCHAR szClass[cchClassMax];
  2117. // Is this already subclassed by CTL3D?
  2118. if (LpfnGetDefWndProcNull(hwnd) != (FARPROC) NULL)
  2119. return fFalse;
  2120. GetClassName(hwnd, szClass, sizeof(szClass)Win32Only(/sizeof(TCHAR)));
  2121. for (ct = 0; ct < ctMax; ct++)
  2122. {
  2123. if ((mpctcdef[ct].msk & grbit) &&
  2124. (lstrcmp(mpctcdef[ct].sz,szClass) == 0))
  2125. {
  2126. style = GetWindowLong(hwnd, GWL_STYLE);
  2127. fCan = mpctcdef[ct].lpfnFCanSubclass(hwnd, style, grbit, wCallFlags, hwndParent);
  2128. if (fCan == fTrue)
  2129. {
  2130. if ( wCallFlags == INCBTHOOK && g3d.verBase == 16 )
  2131. HookSubclassWindow(hwnd, g3d.mpctctl[ct].lpfn);
  2132. else
  2133. SubclassWindow(hwnd, g3d.mpctctl[ct].lpfn);
  2134. }
  2135. return fCan != fFalse;
  2136. }
  2137. }
  2138. return fFalse;
  2139. }
  2140. /*-----------------------------------------------------------------------
  2141. | Inval3dCtl
  2142. |
  2143. | Invalidate the controls rect in response to a WM_SHOWWINDOW or
  2144. | WM_WINDOWPOSCHANGING message. This is necessary because ctl3d draws
  2145. | the 3d effects of listboxes, combos & edits outside the controls client
  2146. | rect.
  2147. |
  2148. | Arguments:
  2149. | HWND hwnd:
  2150. | WINDOWPOS FAR *lpwp:
  2151. |
  2152. | Returns:
  2153. |
  2154. -----------------------------------------------------------------------*/
  2155. PRIVATE VOID Inval3dCtl(HWND hwnd, WINDOWPOS FAR *lpwp)
  2156. {
  2157. RC rc;
  2158. HWND hwndParent;
  2159. LONG lStyle;
  2160. unsigned flags;
  2161. GetWindowRect(hwnd, (LPRECT) &rc);
  2162. lStyle = GetWindowLong(hwnd, GWL_STYLE);
  2163. if (lStyle & WS_VISIBLE)
  2164. {
  2165. if (lpwp != NULL)
  2166. {
  2167. flags = lpwp->flags;
  2168. //
  2169. // Is all this necessary ? Are we moving or sizing ?
  2170. //
  2171. if ( !((flags & SWP_HIDEWINDOW) || (flags & SWP_SHOWWINDOW)) &&
  2172. (flags & SWP_NOMOVE) && (flags & SWP_NOSIZE) )
  2173. // Nope
  2174. return;
  2175. // handle integral height listboxes (or any other control which
  2176. // shrinks from the bottom)
  2177. if ((flags & (SWP_NOMOVE|SWP_NOSIZE)) == SWP_NOMOVE &&
  2178. (lpwp->cx == (rc.xRight-rc.xLeft) && lpwp->cy <= (rc.yBot-rc.yTop)))
  2179. rc.yTop = rc.yTop+lpwp->cy+1; // +1 to offset InflateRect
  2180. }
  2181. InflateRect((LPRECT) &rc, 1, 1);
  2182. hwndParent = GetParent(hwnd);
  2183. ScreenToClient(hwndParent, (LPPOINT) &rc);
  2184. ScreenToClient(hwndParent, ((LPPOINT) &rc)+1);
  2185. if(lStyle & WS_VSCROLL)
  2186. rc.xRight ++;
  2187. InvalidateRect(hwndParent, (LPRECT) &rc, fFalse);
  2188. }
  2189. }
  2190. /*-----------------------------------------------------------------------
  2191. | Val3dCtl
  2192. |
  2193. -----------------------------------------------------------------------*/
  2194. PRIVATE VOID Val3dCtl(HWND hwnd)
  2195. {
  2196. RC rc;
  2197. HWND hwndParent;
  2198. LONG lStyle;
  2199. lStyle = GetWindowLong(hwnd, GWL_STYLE);
  2200. GetWindowRect(hwnd, (LPRECT) &rc);
  2201. InflateRect((LPRECT) &rc, 1, 1);
  2202. hwndParent = GetParent(hwnd);
  2203. ScreenToClient(hwndParent, (LPPOINT) &rc);
  2204. ScreenToClient(hwndParent, ((LPPOINT) &rc)+1);
  2205. if(lStyle & WS_VSCROLL)
  2206. rc.xRight ++;
  2207. ValidateRect(hwndParent, (LPRECT) &rc);
  2208. }
  2209. /*-----------------------------------------------------------------------
  2210. | CTL3D Subclass Wndprocs
  2211. -----------------------------------------------------------------------*/
  2212. /* These values are assumed for bit shifting operations */
  2213. #define BFCHECK 0x0003
  2214. #define BFSTATE 0x0004
  2215. #define BFFOCUS 0x0008
  2216. #define BFINCLICK 0x0010 /* Inside click code */
  2217. #define BFCAPTURED 0x0020 /* We have mouse capture */
  2218. #define BFMOUSE 0x0040 /* Mouse-initiated */
  2219. #define BFDONTCLICK 0x0080 /* Don't check on get focus */
  2220. #define bpText 0x0002
  2221. #define bpCheck 0x0004
  2222. #define bpFocus 0x0008 // must be same as BFFOCUS
  2223. #define bpBkgnd 0x0010
  2224. #define bpEraseGroupText 0x0020
  2225. PRIVATE VOID DrawPushButton(HWND hwnd, HDC hdc, RC FAR *lprc, LPTSTR lpch, int cch, WORD bs, BOOL fDown)
  2226. {
  2227. // int dxyBrdr;
  2228. int dxyShadow;
  2229. HBRUSH hbrSav;
  2230. RC rcInside;
  2231. rcInside = *lprc;
  2232. // if (!(grbitStyle & bitFCoolButtons))
  2233. {
  2234. DrawRec3d(hdc, lprc, icvWindowFrame, icvWindowFrame, dr3All);
  2235. InflateRect((LPRECT) &rcInside, -1, -1);
  2236. if (bs == LOWORD(BS_DEFPUSHBUTTON) && IsWindowEnabled(hwnd))
  2237. {
  2238. // dxyBrdr = 2;
  2239. DrawRec3d(hdc, &rcInside, icvWindowFrame, icvWindowFrame, dr3All);
  2240. InflateRect((LPRECT) &rcInside, -1, -1);
  2241. }
  2242. // else
  2243. // dxyBrdr = 1;
  2244. // Notch the corners
  2245. PatBlt(hdc, lprc->xLeft, lprc->yTop, dxBorder, dyBorder, PATCOPY);
  2246. /* Top xRight corner */
  2247. PatBlt(hdc, lprc->xRight - dxBorder, lprc->yTop, dxBorder, dyBorder, PATCOPY);
  2248. /* yBot xLeft corner */
  2249. PatBlt(hdc, lprc->xLeft, lprc->yBot - dyBorder, dxBorder, dyBorder, PATCOPY);
  2250. /* yBot xRight corner */
  2251. PatBlt(hdc, lprc->xRight - dxBorder, lprc->yBot - dyBorder, dxBorder, dyBorder, PATCOPY);
  2252. dxyShadow = 1 + !fDown;
  2253. }
  2254. // else
  2255. // dxyShadow = 1;
  2256. // draw upper left hilite/shadow
  2257. if (fDown)
  2258. hbrSav = SelectObject(hdc, g3d.brt.mpicvhbr[icvBtnShadow]);
  2259. else
  2260. hbrSav = SelectObject(hdc, g3d.brt.mpicvhbr[icvBtnHilite]);
  2261. PatBlt(hdc, rcInside.xLeft, rcInside.yTop, dxyShadow,
  2262. (rcInside.yBot - rcInside.yTop), PATCOPY);
  2263. PatBlt(hdc, rcInside.xLeft, rcInside.yTop,
  2264. (rcInside.xRight - rcInside.xLeft), dxyShadow, PATCOPY);
  2265. // draw lower right shadow (only if not down)
  2266. if (!fDown) // || (grbitStyle & bitFCoolButtons))
  2267. {
  2268. int i;
  2269. if (fDown)
  2270. SelectObject(hdc, g3d.brt.mpicvhbr[icvBtnHilite]);
  2271. else
  2272. SelectObject(hdc, g3d.brt.mpicvhbr[icvBtnShadow]);
  2273. rcInside.yBot--;
  2274. rcInside.xRight--;
  2275. for (i = 0; i < dxyShadow; i++)
  2276. {
  2277. PatBlt(hdc, rcInside.xLeft, rcInside.yBot,
  2278. rcInside.xRight - rcInside.xLeft + dxBorder, dyBorder,
  2279. PATCOPY);
  2280. PatBlt(hdc, rcInside.xRight, rcInside.yTop, dxBorder,
  2281. rcInside.yBot - rcInside.yTop, PATCOPY);
  2282. if (i < dxyShadow-1)
  2283. InflateRect((LPRECT) &rcInside, -dxBorder, -dyBorder);
  2284. }
  2285. }
  2286. // draw the button face
  2287. rcInside.xLeft++;
  2288. rcInside.yTop++;
  2289. SelectObject(hdc, g3d.brt.mpicvhbr[icvBtnFace]);
  2290. PatBlt(hdc, rcInside.xLeft, rcInside.yTop, rcInside.xRight-rcInside.xLeft,
  2291. rcInside.yBot - rcInside.yTop, PATCOPY);
  2292. // Draw the durned text
  2293. if(!IsWindowEnabled(hwnd))
  2294. SetTextColor(hdc, g3d.clrt.rgcv[icvGrayText]);
  2295. {
  2296. int dy;
  2297. int dx;
  2298. MyGetTextExtent(hdc, lpch, &dx, &dy);
  2299. rcInside.yTop += (rcInside.yBot-rcInside.yTop-dy)/2;
  2300. rcInside.xLeft += (rcInside.xRight-rcInside.xLeft-dx)/2;
  2301. rcInside.yBot = min(rcInside.yTop+dy, rcInside.yBot);
  2302. rcInside.xRight = min(rcInside.xLeft+dx, rcInside.xRight);
  2303. }
  2304. if (fDown)
  2305. {
  2306. OffsetRect((LPRECT) &rcInside, 1, 1);
  2307. rcInside.xRight = min(rcInside.xRight, lprc->xRight-3);
  2308. rcInside.yBot = min(rcInside.yBot, lprc->yBot-3);
  2309. }
  2310. DrawText(hdc, lpch, cch, (LPRECT) &rcInside, DT_LEFT|DT_SINGLELINE);
  2311. if (hwnd == GetFocus())
  2312. {
  2313. InflateRect((LPRECT) &rcInside, 1, 1);
  2314. IntersectRect((LPRECT) &rcInside, (LPRECT) &rcInside, (LPRECT) lprc);
  2315. DrawFocusRect(hdc, (LPRECT) &rcInside);
  2316. }
  2317. if (hbrSav)
  2318. SelectObject(hdc, hbrSav);
  2319. }
  2320. /*-----------------------------------------------------------------------
  2321. | BtnPaint
  2322. |
  2323. | Paint a button
  2324. |
  2325. | Arguments:
  2326. | HWND hwnd:
  2327. | HDC hdc:
  2328. | int bp:
  2329. |
  2330. | Returns:
  2331. |
  2332. -----------------------------------------------------------------------*/
  2333. PRIVATE VOID BtnPaint(HWND hwnd, HDC hdc, int bp)
  2334. {
  2335. RC rc;
  2336. RC rcClient;
  2337. HFONT hfont;
  2338. int bs;
  2339. int bf;
  2340. HBRUSH hbrBtn;
  2341. HWND hwndParent;
  2342. int xBtnBmp;
  2343. int yBtnBmp;
  2344. HBITMAP hbmpSav;
  2345. HDC hdcMem;
  2346. TCHAR szTitle[256];
  2347. int cch;
  2348. BOOL fEnabled;
  2349. BOOL fLeftText;
  2350. bs = (int) GetWindowLong(hwnd, GWL_STYLE);
  2351. fLeftText = (bs & Win32Or16(0x00000020, 0x0020));
  2352. bs &= Win32Or16(0x0000001F, 0x001F);
  2353. hwndParent = GetParent(hwnd);
  2354. SetBkMode(hdc, OPAQUE);
  2355. GetClientRect(hwnd, (LPRECT)&rcClient);
  2356. rc = rcClient;
  2357. if((hfont = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0L)) != NULL)
  2358. hfont = SelectObject(hdc, hfont);
  2359. SetBkColor(hdc, GetSysColor(COLOR_BTNFACE));
  2360. SetTextColor(hdc, GetSysColor(COLOR_BTNTEXT));
  2361. hbrBtn = SEND_COLOR_BUTTON_MESSAGE(hwndParent, hwnd, hdc);
  2362. hbrBtn = SelectObject(hdc, hbrBtn);
  2363. IntersectClipRect(hdc, rc.xLeft, rc.yTop, rc.xRight, rc.yBot);
  2364. if(bp & bpBkgnd && (bs != BS_GROUPBOX))
  2365. PatBlt(hdc, rc.xLeft, rc.yTop, rc.xRight-rc.xLeft, rc.yBot-rc.yTop, PATCOPY);
  2366. fEnabled = IsWindowEnabled(hwnd);
  2367. bf = (int) SendMessage(hwnd, BM_GETSTATE, 0, 0L);
  2368. yBtnBmp = 0;
  2369. xBtnBmp = (((bf&BFCHECK) != 0) | ((bf&BFSTATE) >> 1)) * 14;
  2370. if (!fEnabled)
  2371. xBtnBmp += 14*(2+((bf&BFCHECK) != 0));
  2372. if(bp & (bpText|bpFocus) ||
  2373. bs == BS_PUSHBUTTON || bs == BS_DEFPUSHBUTTON)
  2374. cch = GetWindowText(hwnd, szTitle, sizeof(szTitle)Win32Only(/sizeof(TCHAR)));
  2375. switch(bs)
  2376. {
  2377. #ifdef DEBUG
  2378. default:
  2379. Assert(fFalse);
  2380. break;
  2381. #endif
  2382. case BS_PUSHBUTTON:
  2383. case BS_DEFPUSHBUTTON:
  2384. DrawPushButton(hwnd, hdc, &rcClient, szTitle, cch, LOWORD(bs), bf & BFSTATE);
  2385. break;
  2386. case BS_RADIOBUTTON:
  2387. case BS_AUTORADIOBUTTON:
  2388. yBtnBmp = 13;
  2389. goto DrawBtn;
  2390. case BS_3STATE:
  2391. case BS_AUTO3STATE:
  2392. Assert((BFSTATE >> 1) == 2);
  2393. if((bf & BFCHECK) == 2)
  2394. yBtnBmp = 26;
  2395. // fall through
  2396. case BS_CHECKBOX:
  2397. case BS_AUTOCHECKBOX:
  2398. DrawBtn:
  2399. if(bp & bpCheck)
  2400. {
  2401. hdcMem = CreateCompatibleDC(hdc);
  2402. if(hdcMem != NULL)
  2403. {
  2404. hbmpSav = SelectObject(hdcMem, g3d.hbmpCheckboxes);
  2405. if(hbmpSav != NULL)
  2406. {
  2407. if (fLeftText)
  2408. BitBlt(hdc, rc.xRight - 14, rc.yTop+(rc.yBot-rc.yTop-13)/2,
  2409. 14, 13, hdcMem, xBtnBmp, yBtnBmp, SRCCOPY);
  2410. else
  2411. BitBlt(hdc, rc.xLeft, rc.yTop+(rc.yBot-rc.yTop-13)/2,
  2412. 14, 13, hdcMem, xBtnBmp, yBtnBmp, SRCCOPY);
  2413. SelectObject(hdcMem, hbmpSav);
  2414. }
  2415. DeleteDC(hdcMem);
  2416. }
  2417. }
  2418. if(bp & bpText)
  2419. {
  2420. // BUG! this assumes we have only 1 hbm3dCheck type
  2421. if (fLeftText)
  2422. rc.xRight = rcClient.xRight - (14+4);
  2423. else
  2424. rc.xLeft = rcClient.xLeft + 14+4;
  2425. if(!fEnabled)
  2426. SetTextColor(hdc, g3d.clrt.rgcv[icvGrayText]);
  2427. DrawText(hdc, szTitle, cch, (LPRECT) &rc, DT_VCENTER|DT_LEFT|DT_SINGLELINE);
  2428. }
  2429. if(bp & bpFocus)
  2430. {
  2431. int dx;
  2432. int dy;
  2433. MyGetTextExtent(hdc, szTitle, &dx, &dy);
  2434. rc.yTop = (rc.yBot-rc.yTop-dy)/2;
  2435. rc.yBot = rc.yTop+dy;
  2436. rc.xLeft = rcClient.xLeft;
  2437. if (fLeftText)
  2438. {
  2439. rc.xLeft = rcClient.xLeft;
  2440. rcClient.xRight -= (14+4);
  2441. }
  2442. else
  2443. rc.xLeft = rcClient.xLeft + (14+4);
  2444. rc.xRight = rc.xLeft + dx;
  2445. InflateRect((LPRECT) &rc, 1, 1);
  2446. IntersectRect((LPRECT) &rc, (LPRECT) &rc, (LPRECT) &rcClient);
  2447. DrawFocusRect(hdc, (LPRECT) &rc);
  2448. }
  2449. break;
  2450. case BS_GROUPBOX:
  2451. if(bp & (bpText|bpCheck))
  2452. {
  2453. int dy;
  2454. int dx;
  2455. MyGetTextExtent(hdc, szTitle, &dx, &dy);
  2456. if (dy == 0)
  2457. {
  2458. int dxT;
  2459. MyGetTextExtent(hdc, TEXT("X"), &dxT, &dy);
  2460. }
  2461. rc.xLeft += 4;
  2462. rc.xRight = rc.xLeft + dx + 4;
  2463. rc.yBot = rc.yTop + dy;
  2464. if (bp & bpEraseGroupText)
  2465. {
  2466. RC rcT;
  2467. rcT = rc;
  2468. rcT.xRight = rcClient.xRight;
  2469. // Hack!
  2470. ClientToScreen(hwnd, (LPPOINT) &rcT);
  2471. ClientToScreen(hwnd, ((LPPOINT) &rcT)+1);
  2472. ScreenToClient(hwndParent, (LPPOINT) &rcT);
  2473. ScreenToClient(hwndParent, ((LPPOINT) &rcT)+1);
  2474. InvalidateRect(hwndParent, (LPRECT) &rcT, fTrue);
  2475. return;
  2476. }
  2477. rcClient.yTop += dy/2;
  2478. rcClient.xRight--;
  2479. rcClient.yBot--;
  2480. DrawRec3d(hdc, &rcClient, icvBtnShadow, icvBtnShadow, dr3All);
  2481. OffsetRect((LPRECT) &rcClient, 1, 1);
  2482. DrawRec3d(hdc, &rcClient, icvBtnHilite, icvBtnHilite, dr3All);
  2483. if(!fEnabled)
  2484. SetTextColor(hdc, g3d.clrt.rgcv[icvGrayText]);
  2485. DrawText(hdc, szTitle, cch, (LPRECT) &rc, DT_LEFT|DT_SINGLELINE);
  2486. }
  2487. break;
  2488. }
  2489. SelectObject(hdc, hbrBtn);
  2490. if(hfont != NULL)
  2491. SelectObject(hdc, hfont);
  2492. }
  2493. LRESULT __export _loadds WINAPI BtnWndProc3d(HWND hwnd, UINT wm, WPARAM wParam, LPARAM lParam)
  2494. {
  2495. LONG lRet;
  2496. LONG lStyle;
  2497. PAINTSTRUCT ps;
  2498. HDC hdc;
  2499. int bf;
  2500. int bfNew;
  2501. int bp;
  2502. if ( wm == WM_NCDESTROY )
  2503. return CleanupSubclass(hwnd, wm, wParam, lParam, ctButton);
  2504. if ( GetProp(hwnd,(LPCTSTR) g3d.aCtl3dDisable) )
  2505. return CallWindowProc(LpfnGetDefWndProc(hwnd, ctButton), hwnd, wm, wParam, lParam);
  2506. switch(wm)
  2507. {
  2508. case WM_CHECKSUBCLASS_OLD:
  2509. case WM_CHECKSUBCLASS:
  2510. *(int FAR *)lParam = fTrue;
  2511. return ctButton+1000;
  2512. case WM_SETTEXT:
  2513. lStyle = GetWindowLong(hwnd, GWL_STYLE);
  2514. if ((lStyle & WS_VISIBLE) && (LOWORD(lStyle) & 0x1f) == BS_GROUPBOX)
  2515. {
  2516. // total hack -- if group box text length shortens then
  2517. // we have to erase the old text. BtnPaint will Invalidate
  2518. // the rect of the text so everything will redraw.
  2519. bp = bpText | bpEraseGroupText;
  2520. }
  2521. else
  2522. {
  2523. bp = bpText|bpCheck|bpBkgnd;
  2524. }
  2525. goto DoIt;
  2526. case BM_SETSTATE:
  2527. case BM_SETCHECK:
  2528. bp = bpCheck;
  2529. goto DoIt;
  2530. case WM_KILLFOCUS:
  2531. // HACK! Windows will go into an infinite loop trying to sync the
  2532. // states of the AUTO_RADIOBUTTON in this group. (we turn off the
  2533. // visible bit so it gets skipped in the enumeration)
  2534. // Disable this code by clearing the STATE bit
  2535. if ((LOWORD(GetWindowLong(hwnd, GWL_STYLE)) & 0x1F) == BS_AUTORADIOBUTTON)
  2536. SendMessage(hwnd, BM_SETSTATE, 0, 0L);
  2537. bp = 0;
  2538. goto DoIt;
  2539. case WM_ENABLE:
  2540. bp = bpCheck | bpText;
  2541. goto DoIt;
  2542. case WM_SETFOCUS:
  2543. // HACK! if wParam == NULL we may be activated via the task manager
  2544. // Erase background of control because a WM_ERASEBKGND messsage has not
  2545. // arrived yet for the dialog
  2546. // bp = wParam == (WPARAM)NULL ? (bpCheck | bpText | bpBkgnd) : (bpCheck | bpText);
  2547. bp = bpCheck | bpText | bpBkgnd;
  2548. DoIt:
  2549. bf = (int) SendMessage(hwnd, BM_GETSTATE, 0, 0L);
  2550. if((lStyle = GetWindowLong(hwnd, GWL_STYLE)) & WS_VISIBLE)
  2551. {
  2552. if ( wm != WM_SETFOCUS )
  2553. SetWindowLong(hwnd, GWL_STYLE, lStyle & ~(WS_VISIBLE));
  2554. lRet = CallWindowProc(LpfnGetDefWndProc(hwnd, ctButton), hwnd, wm, wParam, lParam);
  2555. if ( wm != WM_SETFOCUS )
  2556. SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE)|WS_VISIBLE);
  2557. bfNew = (int) SendMessage(hwnd, BM_GETSTATE, 0, 0L);
  2558. if((wm != BM_SETSTATE && wm != BM_SETCHECK) ||
  2559. bf != bfNew)
  2560. {
  2561. hdc = GetDC(hwnd);
  2562. if (hdc != NULL)
  2563. {
  2564. Assert(BFFOCUS == bpFocus);
  2565. /* If the check state changed, redraw no matter what,
  2566. because it won't have during the above call to the def
  2567. wnd proc */
  2568. if ((bf & BFCHECK) != (bfNew & BFCHECK))
  2569. bp |= bpCheck;
  2570. ExcludeUpdateRgn(hdc, hwnd);
  2571. BtnPaint(hwnd, hdc, bp|((bf^bfNew)&BFFOCUS));
  2572. ReleaseDC(hwnd, hdc);
  2573. }
  2574. }
  2575. return lRet;
  2576. }
  2577. break;
  2578. case WM_PAINT:
  2579. bf = (int) SendMessage(hwnd, BM_GETSTATE, 0, 0L);
  2580. if ((hdc = (HDC) wParam) == NULL)
  2581. hdc = BeginPaint(hwnd, &ps);
  2582. if(GetWindowLong(hwnd, GWL_STYLE) & WS_VISIBLE)
  2583. BtnPaint(hwnd, hdc, bpText|bpCheck|(bf&BFFOCUS));
  2584. if (wParam == (WPARAM)NULL)
  2585. EndPaint(hwnd, &ps);
  2586. return 0L;
  2587. }
  2588. return CallWindowProc(LpfnGetDefWndProc(hwnd, ctButton), hwnd, wm, wParam, lParam);
  2589. }
  2590. void ListEditPaint3d(HWND hwnd, BOOL fEdit, int ct)
  2591. {
  2592. CTLID id;
  2593. RC rc;
  2594. HDC hdc;
  2595. HWND hwndParent;
  2596. LONG lStyle;
  2597. DR3 dr3;
  2598. if(!((lStyle = GetWindowLong(hwnd, GWL_STYLE)) & WS_VISIBLE))
  2599. return;
  2600. if ((ct == ctCombo && (lStyle & 0x003) == CBS_DROPDOWNLIST))
  2601. {
  2602. if ( SendMessage(hwnd, CB_GETDROPPEDSTATE,0,0L) )
  2603. return;
  2604. }
  2605. if (fEdit)
  2606. HideCaret(hwnd);
  2607. GetWindowRect(hwnd, (LPRECT) &rc);
  2608. ScreenToClient(hwndParent = GetParent(hwnd), (LPPOINT) &rc);
  2609. ScreenToClient(hwndParent, ((LPPOINT) &rc)+1);
  2610. hdc = GetDC(hwndParent);
  2611. dr3 = dr3All;
  2612. if(lStyle & WS_HSCROLL)
  2613. dr3 = dr3 & ~dr3Bot;
  2614. if(lStyle & WS_VSCROLL)
  2615. dr3 = dr3 & ~dr3Right;
  2616. // don't draw the top if it's a listbox of a simple combo
  2617. id = GetControlId(hwnd);
  2618. if (id == (CTLID) (1000 + fEdit))
  2619. {
  2620. TCHAR szClass[cchClassMax];
  2621. BOOL fSubclass = 666;
  2622. int ctParent;
  2623. // could be superclassed!
  2624. fSubclass = 666;
  2625. ctParent = (int)SendMessage(hwndParent, WM_CHECKSUBCLASS, 0, (LPARAM)(int FAR *)&fSubclass);
  2626. if (fSubclass == 666)
  2627. ctParent = (int)SendMessage(hwndParent, WM_CHECKSUBCLASS_OLD, 0, (LPARAM)(int FAR *)&fSubclass);
  2628. // could be subclassed!
  2629. GetClassName(hwndParent, szClass, sizeof(szClass)Win32Only(/sizeof(TCHAR)));
  2630. if (lstrcmp(szClass, mpctcdef[ctCombo].sz) == 0 ||
  2631. (fSubclass == fTrue && ctParent == ctCombo+1000))
  2632. {
  2633. HWND hwndComboParent;
  2634. hwndComboParent = GetParent(hwndParent);
  2635. Win16Only(GetWindowRect(hwnd, (LPRECT) &rc));
  2636. Win16Only(ScreenToClient(hwndComboParent, (LPPOINT) &rc));
  2637. Win16Only(ScreenToClient(hwndComboParent, ((LPPOINT) &rc)+1));
  2638. Win32Only(MapWindowPoints(hwndParent, hwndComboParent, (POINT*)&rc, 2));
  2639. ReleaseDC(hwndParent, hdc);
  2640. hdc = GetDC(hwndComboParent);
  2641. if (fEdit)
  2642. {
  2643. RC rcList;
  2644. HWND hwndList;
  2645. long style;
  2646. style = GetWindowLong(hwndParent, GWL_STYLE);
  2647. if (!(((style & 0x0003) == CBS_DROPDOWN)
  2648. || ((style & 0x0003) == CBS_DROPDOWNLIST)))
  2649. {
  2650. dr3 &= ~dr3Bot;
  2651. hwndList = GetWindow(hwndParent, GW_CHILD);
  2652. GetWindowRect(hwndList, (LPRECT) &rcList);
  2653. rc.xRight -= rcList.xRight-rcList.xLeft;
  2654. DrawInsetRect3d(hdc, &rc, dr3Bot|dr3HackBotRight);
  2655. rc.xRight += rcList.xRight-rcList.xLeft;
  2656. }
  2657. else
  2658. {
  2659. //
  2660. // Is the drop down on the parent down ? if so don't paint.
  2661. //
  2662. if ( SendMessage(hwndParent, CB_GETDROPPEDSTATE,0,0L) )
  2663. {
  2664. ReleaseDC(hwndComboParent, hdc);
  2665. ShowCaret(hwnd);
  2666. return;
  2667. }
  2668. }
  2669. }
  2670. else
  2671. {
  2672. rc.yTop++;
  2673. dr3 &= ~dr3Top;
  2674. }
  2675. hwndParent = hwndComboParent;
  2676. }
  2677. }
  2678. DrawInsetRect3d(hdc, &rc, dr3);
  2679. if ((ct == ctCombo && (lStyle & 0x003) == CBS_DROPDOWNLIST))
  2680. {
  2681. rc.xLeft = rc.xRight - GetSystemMetrics(SM_CXVSCROLL);
  2682. DrawRec3d(hdc, &rc, icvWindowFrame, icvWindowFrame, dr3Right|dr3Bot);
  2683. Val3dCtl(hwnd);
  2684. }
  2685. else {
  2686. if (lStyle & WS_VSCROLL)
  2687. {
  2688. int SaveLeft;
  2689. rc.xRight++;
  2690. DrawRec3d(hdc, &rc, icvBtnHilite, icvBtnHilite, dr3Right);
  2691. rc.xRight--;
  2692. SaveLeft = rc.xLeft;
  2693. rc.xLeft = rc.xRight - GetSystemMetrics(SM_CXVSCROLL);
  2694. DrawRec3d(hdc, &rc, icvWindowFrame, icvWindowFrame, dr3Bot);
  2695. rc.xLeft = SaveLeft;
  2696. }
  2697. if (lStyle & WS_HSCROLL)
  2698. {
  2699. rc.yBot++;
  2700. DrawRec3d(hdc, &rc, icvBtnHilite, icvBtnHilite, dr3Bot);
  2701. rc.yBot--;
  2702. rc.yTop = rc.yBot - GetSystemMetrics(SM_CXHSCROLL);
  2703. DrawRec3d(hdc, &rc, icvWindowFrame, icvWindowFrame, dr3Right);
  2704. }
  2705. }
  2706. ReleaseDC(hwndParent, hdc);
  2707. if (fEdit)
  2708. ShowCaret(hwnd);
  2709. }
  2710. LONG ShareEditComboWndProc3d(HWND hwnd, UINT wm, WPARAM wParam, LPARAM lParam, int ct)
  2711. {
  2712. LONG l;
  2713. LONG style;
  2714. if ( wm == WM_NCDESTROY )
  2715. return CleanupSubclass(hwnd, wm, wParam, lParam, ct);
  2716. if ( GetProp(hwnd,(LPCTSTR) g3d.aCtl3dDisable) )
  2717. return CallWindowProc(LpfnGetDefWndProc(hwnd, ct), hwnd, wm, wParam, lParam);
  2718. l = CallWindowProc(LpfnGetDefWndProc(hwnd,ct), hwnd, wm, wParam, lParam);
  2719. if (ct == ctCombo)
  2720. {
  2721. style = GetWindowLong(hwnd, GWL_STYLE);
  2722. if ((style & 0x0003) == CBS_DROPDOWN)
  2723. return l;
  2724. }
  2725. switch(wm)
  2726. {
  2727. case WM_CHECKSUBCLASS_OLD:
  2728. case WM_CHECKSUBCLASS:
  2729. *(int FAR *)lParam = fTrue;
  2730. return ctEdit+1000;
  2731. case WM_SHOWWINDOW:
  2732. if (g3d.verWindows < ver31 && wParam == 0)
  2733. Inval3dCtl(hwnd, (WINDOWPOS FAR *) NULL);
  2734. break;
  2735. case WM_WINDOWPOSCHANGING:
  2736. if (g3d.verWindows >= ver31)
  2737. Inval3dCtl(hwnd, (WINDOWPOS FAR *) lParam);
  2738. break;
  2739. case WM_PAINT:
  2740. {
  2741. if (ct != ctCombo ||
  2742. (((style & 0x0003) == CBS_DROPDOWN) || ((style & 0x0003) == CBS_DROPDOWNLIST)))
  2743. ListEditPaint3d(hwnd, TRUE, ct);
  2744. }
  2745. break;
  2746. }
  2747. return l;
  2748. }
  2749. LRESULT __export _loadds WINAPI EditWndProc3d(HWND hwnd, UINT wm, WPARAM wParam, LPARAM lParam)
  2750. {
  2751. return ShareEditComboWndProc3d(hwnd, wm, wParam, lParam, ctEdit);
  2752. }
  2753. LONG SharedListWndProc(HWND hwnd, UINT wm, WPARAM wParam, LPARAM lParam, unsigned ct)
  2754. {
  2755. LONG l;
  2756. if ( wm == WM_NCDESTROY )
  2757. return CleanupSubclass(hwnd, wm, wParam, lParam, ct);
  2758. if ( GetProp(hwnd,(LPCTSTR) g3d.aCtl3dDisable) )
  2759. return CallWindowProc(LpfnGetDefWndProc(hwnd, ct), hwnd, wm, wParam, lParam);
  2760. switch(wm)
  2761. {
  2762. case WM_CHECKSUBCLASS_OLD:
  2763. case WM_CHECKSUBCLASS:
  2764. *(int FAR *)lParam = fTrue;
  2765. return ctList+1000;
  2766. case WM_SHOWWINDOW:
  2767. if (g3d.verWindows < ver31 && wParam == 0)
  2768. Inval3dCtl(hwnd, (WINDOWPOS FAR *) NULL);
  2769. break;
  2770. case WM_WINDOWPOSCHANGING:
  2771. if (g3d.verWindows >= ver31)
  2772. Inval3dCtl(hwnd, (WINDOWPOS FAR *) lParam);
  2773. break;
  2774. case WM_PAINT:
  2775. l = CallWindowProc(LpfnGetDefWndProc(hwnd, ct), hwnd, wm, wParam, lParam);
  2776. ListEditPaint3d(hwnd, FALSE, ct);
  2777. return l;
  2778. case WM_NCCALCSIZE:
  2779. {
  2780. RC rc;
  2781. RC rcNew;
  2782. HWND hwndParent;
  2783. // Inval3dCtl handles this case under Win 3.1
  2784. if (g3d.verWindows >= ver31)
  2785. break;
  2786. GetWindowRect(hwnd, (LPRECT) &rc);
  2787. #ifdef UNREACHABLE
  2788. if (g3d.verWindows >= ver31)
  2789. {
  2790. hwndParent = GetParent(hwnd);
  2791. ScreenToClient(hwndParent, (LPPOINT) &rc);
  2792. ScreenToClient(hwndParent, ((LPPOINT) &rc)+1);
  2793. }
  2794. #endif
  2795. l = CallWindowProc(LpfnGetDefWndProc(hwnd, ct), hwnd, wm, wParam, lParam);
  2796. rcNew = *(RC FAR *)lParam;
  2797. InflateRect((LPRECT) &rcNew, 2, 1); // +1 for border (Should use AdjustWindowRect)
  2798. if (rcNew.yBot < rc.yBot)
  2799. {
  2800. rcNew.yTop = rcNew.yBot+1;
  2801. rcNew.yBot = rc.yBot+1;
  2802. #ifdef ALWAYS
  2803. if (g3d.verWindows < ver31)
  2804. #endif
  2805. {
  2806. hwndParent = GetParent(hwnd);
  2807. ScreenToClient(hwndParent, (LPPOINT) &rcNew);
  2808. ScreenToClient(hwndParent, ((LPPOINT) &rcNew)+1);
  2809. }
  2810. InvalidateRect(hwndParent, (LPRECT) &rcNew, TRUE);
  2811. }
  2812. return l;
  2813. }
  2814. }
  2815. return CallWindowProc(LpfnGetDefWndProc(hwnd, ct), hwnd, wm, wParam, lParam);
  2816. }
  2817. LRESULT __export _loadds WINAPI ListWndProc3d(HWND hwnd, UINT wm, WPARAM wParam, LPARAM lParam)
  2818. {
  2819. return SharedListWndProc(hwnd, wm, wParam, lParam, ctList);
  2820. }
  2821. LRESULT __export _loadds WINAPI ComboWndProc3d(HWND hwnd, UINT wm, WPARAM wParam, LPARAM lParam)
  2822. {
  2823. switch(wm)
  2824. {
  2825. case WM_CHECKSUBCLASS_OLD:
  2826. case WM_CHECKSUBCLASS:
  2827. *(int FAR *)lParam = fTrue;
  2828. return ctCombo+1000;
  2829. }
  2830. return ShareEditComboWndProc3d(hwnd, wm, wParam, lParam, ctCombo);
  2831. }
  2832. void StaticPrint(HWND hwnd, HDC hdc, RC FAR *lprc, LONG style)
  2833. {
  2834. WORD dt;
  2835. LONG cv;
  2836. Win16Or32(HANDLE , LPTSTR )hText;
  2837. int TextLen;
  2838. PatBlt(hdc, lprc->xLeft, lprc->yTop, lprc->xRight-lprc->xLeft, lprc->yBot-lprc->yTop, PATCOPY);
  2839. TextLen = GetWindowTextLength(hwnd);
  2840. #ifndef WIN32
  2841. hText = LocalAlloc(LPTR|LMEM_NODISCARD,(TextLen+5)*sizeof(TCHAR));
  2842. #else
  2843. hText = _alloca((TextLen+5)*sizeof(TCHAR));
  2844. #endif
  2845. if (hText == NULL)
  2846. return;
  2847. if (GetWindowText(hwnd, (NPTSTR)hText, TextLen+2*sizeof(TCHAR)) == 0)
  2848. {
  2849. #ifndef WIN32
  2850. LocalFree(hText);
  2851. #endif
  2852. return;
  2853. }
  2854. if ((style & 0x000f) == SS_LEFTNOWORDWRAP)
  2855. dt = DT_NOCLIP | DT_EXPANDTABS;
  2856. else
  2857. {
  2858. dt = LOWORD(DT_NOCLIP | DT_EXPANDTABS | DT_WORDBREAK | ((style & 0x0000000f)-SS_LEFT));
  2859. }
  2860. if (style & SS_NOPREFIX)
  2861. dt |= DT_NOPREFIX;
  2862. if (style & WS_DISABLED)
  2863. cv = SetTextColor(hdc, g3d.clrt.rgcv[icvGrayText]);
  2864. DrawText(hdc, (NPTSTR)hText, -1, (LPRECT) lprc, dt);
  2865. #ifndef WIN32
  2866. LocalFree(hText);
  2867. #endif
  2868. if (style & WS_DISABLED)
  2869. cv = SetTextColor(hdc, cv);
  2870. }
  2871. void StaticPaint(HWND hwnd, HDC hdc)
  2872. {
  2873. LONG style;
  2874. RC rc;
  2875. style = GetWindowLong(hwnd, GWL_STYLE);
  2876. if(!(style & WS_VISIBLE))
  2877. return;
  2878. GetClientRect(hwnd, (LPRECT) &rc);
  2879. switch(style & 0x1f)
  2880. {
  2881. case SS_BLACKRECT:
  2882. case SS_BLACKFRAME: // Inset rect
  2883. DrawRec3d(hdc, &rc, icvBtnShadow, icvBtnHilite, dr3All);
  2884. break;
  2885. case SS_GRAYRECT:
  2886. case SS_GRAYFRAME:
  2887. case 0x10:
  2888. case 0x11:
  2889. case 0x12:
  2890. rc.xLeft++;
  2891. rc.yTop++;
  2892. DrawRec3d(hdc, &rc, icvBtnHilite, icvBtnHilite, dr3All);
  2893. OffsetRect((LPRECT) &rc, -1, -1);
  2894. DrawRec3d(hdc, &rc, icvBtnShadow, icvBtnShadow, dr3All);
  2895. break;
  2896. case SS_WHITERECT: // outset rect
  2897. case SS_WHITEFRAME:
  2898. DrawRec3d(hdc, &rc, icvBtnHilite, icvBtnShadow, dr3All);
  2899. break;
  2900. case SS_LEFT:
  2901. case SS_CENTER:
  2902. case SS_RIGHT:
  2903. case SS_LEFTNOWORDWRAP:
  2904. {
  2905. HANDLE hfont;
  2906. HBRUSH hbr;
  2907. if((hfont = (HANDLE)SendMessage(hwnd, WM_GETFONT, 0, 0L)) != NULL)
  2908. hfont = SelectObject(hdc, hfont);
  2909. SetBkMode(hdc, OPAQUE);
  2910. if(( hbr = SEND_COLOR_STATIC_MESSAGE(GetParent(hwnd), hwnd, hdc)) != NULL)
  2911. hbr = SelectObject(hdc, hbr);
  2912. StaticPrint(hwnd, hdc, (RC FAR *)&rc, style);
  2913. if (hfont != NULL)
  2914. SelectObject(hdc, hfont);
  2915. if (hbr != NULL)
  2916. SelectObject(hdc, hbr);
  2917. }
  2918. break;
  2919. }
  2920. }
  2921. LRESULT __export _loadds WINAPI StaticWndProc3d(HWND hwnd, UINT wm, WPARAM wParam, LPARAM lParam)
  2922. {
  2923. HDC hdc;
  2924. PAINTSTRUCT ps;
  2925. if ( wm == WM_NCDESTROY )
  2926. return CleanupSubclass(hwnd, wm, wParam, lParam, ctStatic);
  2927. if ( GetProp(hwnd,(LPCTSTR) g3d.aCtl3dDisable) )
  2928. return CallWindowProc(LpfnGetDefWndProc(hwnd, ctStatic), hwnd, wm, wParam, lParam);
  2929. switch (wm)
  2930. {
  2931. case WM_CHECKSUBCLASS_OLD:
  2932. case WM_CHECKSUBCLASS:
  2933. *(int FAR *)lParam = fTrue;
  2934. return ctStatic+1000;
  2935. case WM_PAINT:
  2936. if ((hdc = (HDC) wParam) == NULL)
  2937. {
  2938. hdc = BeginPaint(hwnd, &ps);
  2939. ClipCtlDc(hwnd, hdc);
  2940. }
  2941. StaticPaint(hwnd, hdc);
  2942. if (wParam == (WPARAM)NULL)
  2943. EndPaint(hwnd, &ps);
  2944. return 0L;
  2945. case WM_ENABLE:
  2946. hdc = GetDC(hwnd);
  2947. ClipCtlDc(hwnd, hdc);
  2948. StaticPaint(hwnd, hdc);
  2949. ReleaseDC(hwnd, hdc);
  2950. return 0L;
  2951. }
  2952. return CallWindowProc(LpfnGetDefWndProc(hwnd, ctStatic), hwnd, wm, wParam, lParam);
  2953. }
  2954. /*-----------------------------------------------------------------------
  2955. | LibMain
  2956. -----------------------------------------------------------------------*/
  2957. #ifdef WIN32
  2958. #ifdef DLL
  2959. BOOL CALLBACK LibMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
  2960. #else
  2961. #ifdef SDLL
  2962. BOOL FAR Ctl3dLibMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
  2963. #else
  2964. BOOL FAR LibMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
  2965. #endif
  2966. #endif
  2967. {
  2968. WORD wT;
  2969. DWORD dwVersion;
  2970. BOOL (WINAPI* pfnDisableThreadLibraryCalls)(HMODULE);
  2971. HMODULE hKernel;
  2972. switch(dwReason)
  2973. {
  2974. case DLL_PROCESS_ATTACH:
  2975. // call DisableThreadLibraryCalls if available
  2976. hKernel = GetModuleHandleA("KERNEL32.DLL");
  2977. *(FARPROC*)&pfnDisableThreadLibraryCalls =
  2978. GetProcAddress(hKernel, "DisableThreadLibraryCalls");
  2979. if (pfnDisableThreadLibraryCalls != NULL)
  2980. (*pfnDisableThreadLibraryCalls)(hModule);
  2981. #ifdef DLL
  2982. InitializeCriticalSection(&g_CriticalSection);
  2983. #endif
  2984. EnterCriticalSection(&g_CriticalSection);
  2985. #ifdef SDLL
  2986. g3d.hinstLib = g3d.hmodLib = _hModule;
  2987. #else
  2988. g3d.hinstLib = g3d.hmodLib = hModule;
  2989. #endif
  2990. dwVersion = (DWORD)GetVersion();
  2991. wT = LOWORD(dwVersion);
  2992. // get adjusted windows version
  2993. g3d.verWindows = (LOBYTE(wT) << 8) | HIBYTE(wT);
  2994. // Win32s or Win32 for real (Chicago reports Win32s)
  2995. g3d.verBase =
  2996. (dwVersion & 0x80000000) && g3d.verWindows < ver40 ? 16 : 32;
  2997. g3d.dxFrame = GetSystemMetrics(SM_CXDLGFRAME)-dxBorder;
  2998. g3d.dyFrame = GetSystemMetrics(SM_CYDLGFRAME)-dyBorder;
  2999. g3d.dyCaption = GetSystemMetrics(SM_CYCAPTION);
  3000. g3d.dxSysMenu = GetSystemMetrics(SM_CXSIZE);
  3001. LeaveCriticalSection(&g_CriticalSection);
  3002. }
  3003. return TRUE;
  3004. }
  3005. #else
  3006. #ifdef DLL
  3007. int WINAPI LibMain(HANDLE hModule, WORD wDataSeg, WORD cbHeapSize, LPSTR lpszCmdLine)
  3008. #else
  3009. #ifdef SDLL
  3010. int FAR Ctl3dLibMain(HANDLE hModule, WORD wDataSeg, WORD cbHeapSize, LPSTR lpszCmdLine)
  3011. #else
  3012. #ifdef _BORLAND
  3013. BOOL FAR PASCAL LibMain(HANDLE hModule, WORD wDataSeg, WORD cbHeapSize, LPSTR lpszCmdLine)
  3014. #else
  3015. BOOL FAR LibMain(HANDLE hModule, WORD wDataSeg, WORD cbHeapSize, LPSTR lpszCmdLine)
  3016. #endif
  3017. #endif
  3018. #endif
  3019. {
  3020. WORD wT;
  3021. #ifdef DLL
  3022. #ifdef V2
  3023. CodeLpszDeclA(lpszCtl3d, "CTL3DV2");
  3024. #else
  3025. CodeLpszDeclA(lpszCtl3d, "CTL3D");
  3026. #endif
  3027. CodeLpszDeclA(lpszUser, "user.exe");
  3028. CodeLpszDeclA(lpszSetWindowsHookEx, "SETWINDOWSHOOKEX");
  3029. CodeLpszDeclA(lpszUnhookWindowsHookEx, "UNHOOKWINDOWSHOOKEX");
  3030. CodeLpszDeclA(lpszCallNextHookEx, "CALLNEXTHOOKEX");
  3031. #endif
  3032. g3d.hinstLib = hModule;
  3033. #ifdef DLL
  3034. g3d.hmodLib = GetModuleHandle(lpszCtl3d);
  3035. #else
  3036. #ifdef SDLL
  3037. g3d.hinstLib = _hModule;
  3038. g3d.hmodLib = GetModuleHandle(MAKELP(0,_hModule));
  3039. #else
  3040. g3d.hmodLib = hModule;
  3041. #endif
  3042. #endif
  3043. wT = LOWORD( GetVersion() );
  3044. g3d.verWindows = (LOBYTE(wT) << 8) | HIBYTE(wT);
  3045. if ( GetWinFlags() & 0x4000 )
  3046. g3d.verBase = 24; // More then 16, not yet 32....WOW box on NT
  3047. else
  3048. g3d.verBase = 16; // Regular old 3.1
  3049. g3d.dxFrame = GetSystemMetrics(SM_CXDLGFRAME)-dxBorder;
  3050. g3d.dyFrame = GetSystemMetrics(SM_CYDLGFRAME)-dyBorder;
  3051. g3d.dyCaption = GetSystemMetrics(SM_CYCAPTION);
  3052. g3d.dxSysMenu = GetSystemMetrics(SM_CXSIZE);
  3053. #ifdef DLL
  3054. if (g3d.verWindows >= ver31)
  3055. {
  3056. HANDLE hlib;
  3057. hlib = LoadLibrary(lpszUser);
  3058. if (FValidLibHandle(hlib))
  3059. {
  3060. (FARPROC) g3d.lpfnSetWindowsHookEx = GetProcAddress(hlib, lpszSetWindowsHookEx);
  3061. (FARPROC) g3d.lpfnUnhookWindowsHookEx = GetProcAddress(hlib, lpszUnhookWindowsHookEx);
  3062. (FARPROC) g3d.lpfnCallNextHookEx = GetProcAddress(hlib, lpszCallNextHookEx);
  3063. FreeLibrary(hlib);
  3064. }
  3065. }
  3066. #endif
  3067. return 1;
  3068. }
  3069. #endif // win32
  3070. // convert a RGB into a RGBQ
  3071. #define RGBQ(dw) RGB(GetBValue(dw),GetGValue(dw),GetRValue(dw))
  3072. //
  3073. // LoadUIBitmap() - load a bitmap resource
  3074. //
  3075. // load a bitmap resource from a resource file, converting all
  3076. // the standard UI colors to the current user specifed ones.
  3077. //
  3078. // this code is designed to load bitmaps used in "gray ui" or
  3079. // "toolbar" code.
  3080. //
  3081. // the bitmap must be a 4bpp windows 3.0 DIB, with the standard
  3082. // VGA 16 colors.
  3083. //
  3084. // the bitmap must be authored with the following colors
  3085. //
  3086. // Window Text Black (index 0)
  3087. // Button Shadow gray (index 7)
  3088. // Button Face lt gray (index 8)
  3089. // Button Highlight white (index 15)
  3090. // Window Color yellow (index 11)
  3091. // Window Frame green (index 10)
  3092. //
  3093. // Example:
  3094. //
  3095. // hbm = LoadUIBitmap(hInstance, "TestBmp",
  3096. // GetSysColor(COLOR_WINDOWTEXT),
  3097. // GetSysColor(COLOR_BTNFACE),
  3098. // GetSysColor(COLOR_BTNSHADOW),
  3099. // GetSysColor(COLOR_BTNHIGHLIGHT),
  3100. // GetSysColor(COLOR_WINDOW),
  3101. // GetSysColor(COLOR_WINDOWFRAME));
  3102. //
  3103. // Author: JimBov, ToddLa
  3104. //
  3105. //
  3106. #ifdef WIN32
  3107. HBITMAP PASCAL LoadUIBitmap(
  3108. HANDLE hInstance, // EXE file to load resource from
  3109. LPCTSTR szName, // name of bitmap resource
  3110. COLORREF rgbText, // color to use for "Button Text"
  3111. COLORREF rgbFace, // color to use for "Button Face"
  3112. COLORREF rgbShadow, // color to use for "Button Shadow"
  3113. COLORREF rgbHighlight, // color to use for "Button Hilight"
  3114. COLORREF rgbWindow, // color to use for "Window Color"
  3115. COLORREF rgbFrame) // color to use for "Window Frame"
  3116. {
  3117. HBITMAP hbm;
  3118. LPBITMAPINFO lpbi;
  3119. HRSRC hrsrc;
  3120. HGLOBAL h;
  3121. HDC hdc;
  3122. DWORD size;
  3123. //
  3124. // Load the bitmap resource and make a writable copy.
  3125. //
  3126. hrsrc = FindResource(hInstance, szName, RT_BITMAP);
  3127. if (!hrsrc)
  3128. return(NULL);
  3129. size = SizeofResource( hInstance, hrsrc );
  3130. h = LoadResource(hInstance,hrsrc);
  3131. if (!h)
  3132. return(NULL);
  3133. lpbi = ( LPBITMAPINFO ) GlobalAlloc( GPTR, size );
  3134. if (!lpbi)
  3135. return(NULL);
  3136. CopyMemory( lpbi, h, size );
  3137. *( LPCOLORREF ) &lpbi->bmiColors[0] = RGBQ(rgbText); // Black
  3138. *( LPCOLORREF ) &lpbi->bmiColors[7] = RGBQ(rgbShadow); // gray
  3139. *( LPCOLORREF ) &lpbi->bmiColors[8] = RGBQ(rgbFace); // lt gray
  3140. *( LPCOLORREF ) &lpbi->bmiColors[15] = RGBQ(rgbHighlight); // white
  3141. *( LPCOLORREF ) &lpbi->bmiColors[11] = RGBQ(rgbWindow); // yellow
  3142. *( LPCOLORREF ) &lpbi->bmiColors[10] = RGBQ(rgbFrame); // green
  3143. hdc = GetDC(NULL);
  3144. hbm = CreateDIBitmap(hdc, &lpbi->bmiHeader, CBM_INIT, (LPBYTE)(&lpbi->bmiColors[ 16 ]),
  3145. lpbi, DIB_RGB_COLORS);
  3146. ReleaseDC(NULL, hdc);
  3147. GlobalFree( lpbi );
  3148. return(hbm);
  3149. }
  3150. #else
  3151. HBITMAP PASCAL LoadUIBitmap(
  3152. HANDLE hInstance, // EXE file to load resource from
  3153. LPCTSTR szName, // name of bitmap resource
  3154. COLORREF rgbText, // color to use for "Button Text"
  3155. COLORREF rgbFace, // color to use for "Button Face"
  3156. COLORREF rgbShadow, // color to use for "Button Shadow"
  3157. COLORREF rgbHighlight, // color to use for "Button Hilight"
  3158. COLORREF rgbWindow, // color to use for "Window Color"
  3159. COLORREF rgbFrame) // color to use for "Window Frame"
  3160. {
  3161. LPBYTE lpb;
  3162. HBITMAP hbm;
  3163. LPBITMAPINFOHEADER lpbi;
  3164. HANDLE h;
  3165. HDC hdc;
  3166. LPDWORD lprgb;
  3167. h = LoadResource(hInstance,FindResource(hInstance, szName, RT_BITMAP));
  3168. lpbi = (LPBITMAPINFOHEADER)LockResource(h);
  3169. if (!lpbi)
  3170. return(NULL);
  3171. #ifdef NOTNEEDEDFORCTL3D
  3172. if (lpbi->biSize != sizeof(BITMAPINFOHEADER))
  3173. return NULL;
  3174. if (lpbi->biBitCount != 4)
  3175. return NULL;
  3176. #endif
  3177. lprgb = (LPDWORD)((LPBYTE)lpbi + (int)lpbi->biSize);
  3178. lpb = (LPBYTE)(lprgb + 16);
  3179. lprgb[0] = RGBQ(rgbText); // Black
  3180. // lprgb[7] = RGBQ(rgbFace); // lt gray
  3181. // lprgb[8] = RGBQ(rgbShadow); // gray
  3182. lprgb[7] = RGBQ(rgbShadow); // gray
  3183. lprgb[8] = RGBQ(rgbFace); // lt gray
  3184. lprgb[15] = RGBQ(rgbHighlight); // white
  3185. lprgb[11] = RGBQ(rgbWindow); // yellow
  3186. lprgb[10] = RGBQ(rgbFrame); // green
  3187. hdc = GetDC(NULL);
  3188. hbm = CreateDIBitmap(hdc, lpbi, CBM_INIT, (LPVOID)lpb,
  3189. (LPBITMAPINFO)lpbi, DIB_RGB_COLORS);
  3190. ReleaseDC(NULL, hdc);
  3191. UnlockResource(h);
  3192. FreeResource(h);
  3193. return(hbm);
  3194. }
  3195. #endif // win32
  3196. /*-----------------------------------------------------------------------
  3197. |
  3198. | DLL specific routines
  3199. |
  3200. ---------------------------------------------------------------WESC----*/
  3201. #ifndef WIN32
  3202. #ifdef DLL
  3203. /*-----------------------------------------------------------------------
  3204. | WEP
  3205. -----------------------------------------------------------------------*/
  3206. int FAR PASCAL WEP (int wSystemExit)
  3207. {
  3208. return 1;
  3209. }
  3210. #endif
  3211. #endif