// ctl3d.c // Two-letter Module Descriptor: d3 // **************************************************************************** // Copyright (C) B. Cameron Lesiuk, 1999. All rights reserved. // Permission to use/copy this code is granted for non-commercial use only. // B. Cameron Lesiuk // Victoria, BC, Canada // wi961@freenet.victoria.bc.ca // **************************************************************************** // This module handles ctl3xxx.dll functionality. // This module encapsulates the .dll functionality so that we have more // control over it. Simply compile and link in this file instead of the .DLL // or associated static library. You can still use the standard <ctl3d.h> include // file because this file exactly replicates the .DLL functionality based on <ctl3d.h>. // // This module is self-contained and doesn't need any Init or Wrapup calls except // for the normal CTL3D calls. #include<windows.h> #include<ctl3d.h> #include<stdio.h> #include"debug.h" /* Defines */ #define D3_STATE_NOT_LOADED 0 /* NOTE: for STATE vars, >0 means good load, <0 means error/noload */ #define D3_STATE_LOADED 1 #define D3_STATE_ERROR (-1) #define D3_STATE_DONT_LOAD (-2) #define D3_STATE_INTERNAL (-3) //#define D3_STATE_INTERNAL (-3) /* operation is internal -- no .DLL loaded or required*/ #define D3_PROC_ATOM "CTL3DL-DefProcAtom" #define D3_PROC_ATOMLOW "CTL3DL-DefProcAtom-Low" #define D3_PROC_ATOMHI "CTL3DL-DefProcAtom-Hi" /* Globals */ /* All globals in this module start with "d3" for 3-D Link */ HINSTANCE d3_hInst=NULL; int d3_State=D3_STATE_NOT_LOADED; //int d3_State=D3_STATE_DONT_LOAD; /* Private (local) function prototypes */ int d3InitCtl3d(void); //LRESULT CALLBACK _export d3InternalSubclassProc(HWND p_hWnd, UINT p_message,WPARAM p_wParam, LPARAM p_lParam); //BOOL d3SubClassWnd(HWND p_hWnd); /* CTL3D Function handle (variable) declarations */ BOOL WINAPI (*d3_Ctl3dSubclassDlg)(HWND p_a, WORD p_b); BOOL WINAPI (*d3_Ctl3dSubclassDlgEx)(HWND, DWORD); WORD WINAPI (*d3_Ctl3dGetVer)(void); BOOL WINAPI (*d3_Ctl3dEnabled)(void); HBRUSH WINAPI (*d3_Ctl3dCtlColor)(HDC, LONG); // ARCHAIC, use Ctl3dCtlColorEx HBRUSH WINAPI (*d3_Ctl3dCtlColorEx)(UINT wm, WPARAM wParam, LPARAM lParam); BOOL WINAPI (*d3_Ctl3dColorChange)(void); BOOL WINAPI (*d3_Ctl3dSubclassCtl)(HWND); BOOL WINAPI (*d3_Ctl3dSubclassCtlEx)(HWND, int); BOOL WINAPI (*d3_Ctl3dUnsubclassCtl)(HWND); LONG WINAPI (*d3_Ctl3dDlgFramePaint)(HWND, UINT, WPARAM, LPARAM); BOOL WINAPI (*d3_Ctl3dAutoSubclass)(HANDLE); BOOL WINAPI (*d3_Ctl3dIsAutoSubclass)(VOID); BOOL WINAPI (*d3_Ctl3dUnAutoSubclass)(VOID); BOOL WINAPI (*d3_Ctl3dRegister)(HANDLE); BOOL WINAPI (*d3_Ctl3dUnregister)(HANDLE); //begin DBCS: far east short cut key support VOID WINAPI (*d3_Ctl3dWinIniChange)(void); //end DBCS /* Actual Procedures */ int d3InitCtl3d() { UINT l_emf; DWORD l_winver; char l_buf[100]; if (d3_State) { /* we've already tried to load, or we're instructed to load/not load */ if (d3_State>0) return TRUE; return FALSE; } // d3_State=D3_STATE_INTERNAL; // return FALSE; dbPrint("CTL3D: Init"); /* Check our version of windows */ l_winver=GetVersion(); sprintf(l_buf,"CTL3D: Win %li.%02li, O/S %04X",l_winver&0x000000FFL, (l_winver&0x0000FF00L)>>8,HIWORD(l_winver)); dbPrint(l_buf); if ((l_winver&0x000000FFL)==3) { /* need at least version 3.10 to run! */ if (((l_winver&0x0000FF00L)>>8)<10) { /* pre-3.10 (probably 3.0) - no load */ dbPrint("CTL3D: LOAD ABORTED - Pre-3.10 version of windows"); d3_State=D3_STATE_DONT_LOAD; return FALSE; } else if (((l_winver&0x0000FF00L)>>8)>=95) /* windows 95 */ { dbPrint("CTL3D: LOAD ABORTED - 3.95-3.99 version of windows. Using internal methods"); d3_State=D3_STATE_INTERNAL; return FALSE; } /* otherwise, we're ok to load libraries! */ } else if ((l_winver&0x000000FFL)>3) { /* Post-win3.11 -> don't load */ dbPrint("CTL3D: WARNING - Post-3.XX version of windows. Using internal methods "); d3_State=D3_STATE_INTERNAL; return FALSE; } else { /* Pre-win3.0 -> don't load */ dbPrint("CTL3D: LOAD ABORTED - Pre-3.00 version of windows"); d3_State=D3_STATE_DONT_LOAD; return FALSE; } l_emf=SetErrorMode(SEM_NOOPENFILEERRORBOX); #ifdef WIN32 dbPrint("CTL3D: Loading 32-bit library CTL3D32.DLL"); d3_hInst=LoadLibrary("CTL3D32.DLL"); if (d3_hInst==0) { sprintf(l_buf,"CTL3D: Library load failed (error 0x%lX)",(unsigned long)GetLastError()); #else dbPrint("CTL3D: Loading 16-bit library CTL3DV2.DLL"); d3_hInst=LoadLibrary("CTL3DV2.DLL"); if (d3_hInst<=HINSTANCE_ERROR) { // switch(d3_hInst) // { // case 0: // system error // case 2: // file not found // case 3: // path not found // case 5: // sharing/protection error // case 8: // lib required separate data segment for each task // case 10: // Incorrect Windows version // case 11: // Executable file is invalid // case 12: // Wrong O/S // case 13: // Designed for DOS 4.0 // case 14: // Unknown executable type/format // case 15: // attempt to load real-mode executable (earlier version of Windows) // case 16: // Attempt was made to load a second instance of an executable file containing multiple data segments that were not marked read-only // case 19: // Attempt to load compressed executable file. Decompress it first. // case 20: // DLL file is invalid. DLL file is corrupt. // case 21: // Requires 32-bit extension // default: // break; // } sprintf(l_buf,"CTL3D: Library load failed (error 0x%lX)",(unsigned long)d3_hInst); #endif dbPrint(l_buf); SetErrorMode(l_emf); d3_State=D3_STATE_ERROR; d3_hInst=NULL; return FALSE; } dbPrint("CTL3D: Fetching procedure handles"); if (((FARPROC)d3_Ctl3dSubclassDlg=GetProcAddress(d3_hInst,"Ctl3dSubclassDlg"))==NULL) d3_State=D3_STATE_ERROR; if (((FARPROC)d3_Ctl3dSubclassDlgEx=GetProcAddress(d3_hInst,"Ctl3dSubclassDlgEx"))==NULL) d3_State=D3_STATE_ERROR; if (((FARPROC)d3_Ctl3dGetVer=GetProcAddress(d3_hInst,"Ctl3dGetVer"))==NULL) d3_State=D3_STATE_ERROR; if (((FARPROC)d3_Ctl3dEnabled=GetProcAddress(d3_hInst,"Ctl3dEnabled"))==NULL) d3_State=D3_STATE_ERROR; if (((FARPROC)d3_Ctl3dCtlColor=GetProcAddress(d3_hInst,"Ctl3dCtlColor"))==NULL) d3_State=D3_STATE_ERROR; if (((FARPROC)d3_Ctl3dCtlColorEx=GetProcAddress(d3_hInst,"Ctl3dCtlColorEx"))==NULL) d3_State=D3_STATE_ERROR; if (((FARPROC)d3_Ctl3dColorChange=GetProcAddress(d3_hInst,"Ctl3dColorChange"))==NULL) d3_State=D3_STATE_ERROR; if (((FARPROC)d3_Ctl3dSubclassCtl=GetProcAddress(d3_hInst,"Ctl3dSubclassCtl"))==NULL) d3_State=D3_STATE_ERROR; // if (((FARPROC)d3_Ctl3dSubclassCtlEx=GetProcAddress(d3_hInst,"Ctl3dSubclassCtlEx"))==NULL) // d3_State=D3_STATE_ERROR; // if (((FARPROC)d3_Ctl3dUnsubclassCtl=GetProcAddress(d3_hInst,"Ctl3dUnsubclassCtl"))==NULL) // d3_State=D3_STATE_ERROR; if (((FARPROC)d3_Ctl3dDlgFramePaint=GetProcAddress(d3_hInst,"Ctl3dDlgFramePaint"))==NULL) d3_State=D3_STATE_ERROR; if (((FARPROC)d3_Ctl3dAutoSubclass=GetProcAddress(d3_hInst,"Ctl3dAutoSubclass"))==NULL) d3_State=D3_STATE_ERROR; // if (((FARPROC)d3_Ctl3dIsAutoSubclass=GetProcAddress(d3_hInst,"Ctl3dIsAutoSubclass"))==NULL) // d3_State=D3_STATE_ERROR; // if (((FARPROC)d3_Ctl3dUnAutoSubclass=GetProcAddress(d3_hInst,"Ctl3dUnAutoSubclass"))==NULL) // d3_State=D3_STATE_ERROR; if (((FARPROC)d3_Ctl3dRegister=GetProcAddress(d3_hInst,"Ctl3dRegister"))==NULL) d3_State=D3_STATE_ERROR; if (((FARPROC)d3_Ctl3dUnregister=GetProcAddress(d3_hInst,"Ctl3dUnregister"))==NULL) d3_State=D3_STATE_ERROR; //begin DBCS: far east short cut key support if (((FARPROC)d3_Ctl3dWinIniChange=GetProcAddress(d3_hInst,"Ctl3dWinIniChange"))==NULL) d3_State=D3_STATE_ERROR; //end DBCS if (d3_State<0) { dbPrint("CTL3D: Error fetching handles. Library released."); FreeLibrary(d3_hInst); d3_hInst=NULL; return FALSE; } dbPrint("CTL3D: Handles fetched. CTL3D Ready."); d3_State=D3_STATE_LOADED; return TRUE; } BOOL WINAPI Ctl3dSubclassDlg(HWND p_a, WORD p_b) { if (d3InitCtl3d()) return (*d3_Ctl3dSubclassDlg)(p_a,p_b); return FALSE; } BOOL WINAPI Ctl3dSubclassDlgEx(HWND p_a, DWORD p_b) { // HWND l_hWnd; if (d3InitCtl3d()) return (*d3_Ctl3dSubclassDlgEx)(p_a,p_b); // else if (d3_State==D3_STATE_INTERNAL) // { // /* internal sub-class this dialog box */ // /* Note: Parameter p_b is ignored. */ // /* First, subclass parent */ // if (!d3SubClassWnd(p_a)) // return FALSE; // /* Now subclass all child windows */ // for(l_hWnd=GetWindow(p_a,GW_CHILD);l_hWnd;l_hWnd=GetWindow(l_hWnd,GW_HWNDNEXT)) // { // d3SubClassWnd(l_hWnd); // } // return TRUE; // } return FALSE; } //BOOL d3SubClassWnd(HWND p_hWnd) // { // FARPROC l_TempProc; // HDC l_hDC; // // l_TempProc=(FARPROC)SetWindowLong(p_hWnd,GWL_WNDPROC,(LONG)d3InternalSubclassProc); //#ifdef WIN32 // if (!SetProp(p_hWnd,D3_PROC_ATOM,(HANDLE)l_TempProc)) // { // SetWindowLong(p_hWnd,GWL_WNDPROC,(LONG)l_TempProc); // return FALSE; // } //#else // if (SetProp(p_hWnd,D3_PROC_ATOMLOW,(HANDLE)LOWORD(l_TempProc))) // { // if (!SetProp(p_hWnd,D3_PROC_ATOMHI,(HANDLE)HIWORD(l_TempProc))) // { // RemoveProp(p_hWnd,D3_PROC_ATOMLOW); // SetWindowLong(p_hWnd,GWL_WNDPROC,(LONG)l_TempProc); // return FALSE; // } // } // else // { // SetWindowLong(p_hWnd,GWL_WNDPROC,(LONG)l_TempProc); // return FALSE; // } //#endif ///* didn't work // l_hDC=GetWindowDC(p_hWnd); // SetBkColor(l_hDC,RGB(198,198,198)); // ReleaseDC(p_hWnd,l_hDC); // l_hDC=GetDC(p_hWnd); // SetBkColor(l_hDC,RGB(198,198,198)); // ReleaseDC(p_hWnd,l_hDC); */ // return TRUE; // } WORD WINAPI Ctl3dGetVer() { if (d3InitCtl3d()) return (*d3_Ctl3dGetVer)(); return 0; } BOOL WINAPI Ctl3dEnabled() { if (d3InitCtl3d()) return (*d3_Ctl3dEnabled)(); return FALSE; } HBRUSH WINAPI Ctl3dCtlColor(HDC p_a, LONG p_b) // ARCHAIC, use Ctl3dCtlColorEx { if (d3InitCtl3d()) return (*d3_Ctl3dCtlColor)(p_a,p_b); return NULL; } HBRUSH WINAPI Ctl3dCtlColorEx(UINT p_wm, WPARAM p_wParam, LPARAM p_lParam) { if (d3InitCtl3d()) return (*d3_Ctl3dCtlColorEx)(p_wm,p_wParam,p_lParam); return NULL; } BOOL WINAPI Ctl3dColorChange() { if (d3InitCtl3d()) return (*d3_Ctl3dColorChange)(); return FALSE; } BOOL WINAPI Ctl3dSubclassCtl(HWND p_a) { if (d3InitCtl3d()) return (*d3_Ctl3dSubclassCtl)(p_a); return FALSE; } /*BOOL WINAPI Ctl3dSubclassCtlEx(HWND p_a, int p_b) { if (d3InitCtl3d()) return (*d3_Ctl3dSubclassCtlEx)(p_a,p_b); return FALSE; } BOOL WINAPI Ctl3dUnsubclassCtl(HWND p_a) { if (d3InitCtl3d()) return (*d3_Ctl3dUnsubclassCtl)(p_a); return FALSE; } */ LONG WINAPI Ctl3dDlgFramePaint(HWND p_a, UINT p_b, WPARAM p_c, LPARAM p_d) { if (d3InitCtl3d()) return (*d3_Ctl3dDlgFramePaint)(p_a,p_b,p_c,p_d); return 0L; } BOOL WINAPI Ctl3dAutoSubclass(HANDLE p_a) { if (d3InitCtl3d()) return (*d3_Ctl3dAutoSubclass)(p_a); return FALSE; } /*BOOL WINAPI Ctl3dIsAutoSubclass() { if (d3InitCtl3d()) return (*d3_Ctl3dIsAutoSubclass)(); return FALSE; } BOOL WINAPI Ctl3dUnAutoSubclass() { if (d3InitCtl3d()) return (*d3_Ctl3dUnAutoSubclass)(); return FALSE; } */ BOOL WINAPI Ctl3dRegister(HANDLE p_a) { if (d3InitCtl3d()) return (*d3_Ctl3dRegister)(p_a); return FALSE; } BOOL WINAPI Ctl3dUnregister(HANDLE p_b) { int rc=0; if (d3InitCtl3d()) { #ifdef WIN32 if (d3_hInst) #else if (d3_hInst>HINSTANCE_ERROR) #endif { rc=(*d3_Ctl3dUnregister)(p_b); FreeLibrary(d3_hInst); d3_State=D3_STATE_NOT_LOADED; d3_hInst=NULL; } return(rc); } return FALSE; } //begin DBCS: far east short cut key support VOID WINAPI Ctl3dWinIniChange() { if (d3InitCtl3d()) (*d3_Ctl3dWinIniChange)(); return; } //end DBCS /* LRESULT CALLBACK _export d3InternalSubclassProc(HWND p_hWnd, UINT p_message, WPARAM p_wParam, LPARAM p_lParam) { FARPROC l_DefProc; RECT l_rect; switch (p_message) { case WM_ERASEBKGND: GetClientRect(p_hWnd,&l_rect); FillRect((HDC)p_wParam,&l_rect,GetStockObject(LTGRAY_BRUSH)); return 1L; case WM_DESTROY: #ifdef WIN32 l_DefProc=(FARPROC)GetProp(p_hWnd,D3_PROC_ATOM); RemoveProp(p_hWnd,D3_PROC_ATOM); #else l_DefProc=(FARPROC)MAKELONG(GetProp(p_hWnd,D3_PROC_ATOMLOW),GetProp(p_hWnd,D3_PROC_ATOMHI)); RemoveProp(p_hWnd,D3_PROC_ATOMLOW); RemoveProp(p_hWnd,D3_PROC_ATOMHI); #endif SetWindowLong(p_hWnd,GWL_WNDPROC,(LONG)l_DefProc); return ((LRESULT)(*l_DefProc)((HWND)p_hWnd,(UINT)p_message, (WPARAM)p_wParam,(LPARAM)p_lParam)); default: break; } #ifdef WIN32 l_DefProc=(FARPROC)GetProp(p_hWnd,D3_PROC_ATOM); #else l_DefProc=(FARPROC)MAKELONG(GetProp(p_hWnd,D3_PROC_ATOMLOW),GetProp(p_hWnd,D3_PROC_ATOMHI)); #endif return ((LRESULT)(*l_DefProc)((HWND)p_hWnd,(UINT)p_message, (WPARAM)p_wParam,(LPARAM)p_lParam)); } */ /* This function is intended to be used last in a dialog box operation. * It handles the WM_CTLCOLOR (Win16) or WM_CTLCOLOR*(Win32) to set * the background nicely. */ #pragma argsused BOOL d3DlgMessageCheck(HWND p_hWnd, UINT p_message, WPARAM p_wParam, LPARAM p_lParam) { if (d3_State==D3_STATE_LOADED) return FALSE; #ifdef WIN32 switch (p_message) { case WM_CTLCOLORBTN: case WM_CTLCOLORSTATIC: // SetBkColor((HDC)p_wParam,GetStockObject(LTGRAY_BRUSH)); SetBkMode((HDC)p_wParam,TRANSPARENT); /* fall through to the following */ case WM_CTLCOLORDLG: return (BOOL)(GetStockObject(LTGRAY_BRUSH)); case WM_CTLCOLOREDIT: case WM_CTLCOLORLISTBOX: case WM_CTLCOLORSCROLLBAR: default: break; } #else /* Win16 */ dbPrint("CTL3DL: Warning - untested code!"); if (p_message==WM_CTLCOLOR) { switch(HIWORD(p_lParam) { case CTLCOLOR_STATIC: SetBkMode((HDC)p_wParam,TRANSPARENT); case CTLCOLOR_DLG: return (BOOL)(GetStockObject(LTGRAY_BRUSH)); case CTLCOLOR_BTN: case CTLCOLOR_EDIT: case CTLCOLOR_LISTBOX: case CTLCOLOR_MSGBOX: case CTLCOLOR_SCROLLBAR: default: break; } } #endif return FALSE; }