00001
00002
00003 #define MODULE_SUPERCLASS 1
00004
00005 #pragma warning( disable : 4311 4312 4133)
00006
00007 #include <windows.h>
00008 #include "supercls.h"
00009
00010 ATOM WINAPI RegisterSuperClass (LPWNDCLASS WndClass,
00011 WNDPROC lpfpSCWndProc, int cbClsAdditional,
00012 int cbWndAdditional);
00013 WNDPROC WINAPI GetBCWndProc (HWND hWnd);
00014 WORD WINAPI SetSCClassWord (HWND hWnd, int nIndex, WORD wNewWord);
00015 WORD WINAPI GetSCClassWord (HWND hWnd, int nIndex);
00016 DWORD WINAPI SetSCClassLong (HWND hWnd, int nIndex, DWORD dwNewLong);
00017 DWORD WINAPI GetSCClassLong (HWND hWnd, int nIndex);
00018 WORD WINAPI SetSCWindowWord (HWND hWnd, int nIndex, WORD wNewWord);
00019 WORD WINAPI GetSCWindowWord (HWND hWnd, int nIndex);
00020 DWORD WINAPI GetSCWindowLong (HWND hWnd, int nIndex);
00021 DWORD WINAPI SetSCWindowLong (HWND hWnd, int nIndex,
00022 DWORD dwNewLong);
00023 LRESULT CALLBACK NoAlphaWndProc (HWND hWnd, UINT uMsg,
00024 WPARAM wParam, LPARAM lParam);
00025
00026 #define BCWNDPROCINDEX (sizeof(WNDPROC))
00027 #define CBBCCLSEXTRAINDEX (sizeof(WNDPROC) + sizeof(int))
00028 #define CBBCWNDEXTRAINDEX \
00029 (sizeof(WNDPROC) + sizeof(int) + sizeof(int))
00030
00031 #define MINCBCLSADDTIONAL \
00032 (sizeof(WNDPROC) + sizeof(int) + sizeof(int))
00033
00034 typedef struct {
00035 WNDPROC lpfnSuperClsWndProc;
00036 WNDPROC lpfnBCWndProc;
00037 int cbBCClsExtra;
00038 int cbBCWndExtra;
00039 } SUPERCLSINIT, FAR *LPSUPERCLSINIT;
00040
00041
00042 static LRESULT CALLBACK SuperClsInitWndProc (HWND hWnd, UINT uMsg,
00043 WPARAM wParam, LPARAM lParam) {
00044 LPSUPERCLSINIT lpSuperClsInit;
00045 int cbClsTotal;
00046 switch (uMsg) {
00047 case WM_CREATE:
00048 cbClsTotal = GetClassLong(hWnd, GCL_CBCLSEXTRA);
00049 SetClassLong(hWnd, cbClsTotal - BCWNDPROCINDEX,
00050 (LONG) (((LPCREATESTRUCT) lParam)->lpCreateParams));
00051 break;
00052 case WM_NCDESTROY:
00053 cbClsTotal = GetClassLong(hWnd, GCL_CBCLSEXTRA);
00054 lpSuperClsInit = (LPSUPERCLSINIT)
00055 GetClassLong(hWnd, cbClsTotal - BCWNDPROCINDEX);
00056 SetClassLong(hWnd, cbClsTotal - BCWNDPROCINDEX,
00057 (LONG) lpSuperClsInit->lpfnBCWndProc);
00058 SetClassWord(hWnd, cbClsTotal - CBBCCLSEXTRAINDEX,
00059 (WORD)lpSuperClsInit->cbBCClsExtra);
00060 SetClassWord(hWnd, cbClsTotal - CBBCWNDEXTRAINDEX,
00061 (WORD)lpSuperClsInit->cbBCWndExtra);
00062 SetClassLong(hWnd, GCL_WNDPROC,
00063 (LONG) lpSuperClsInit->lpfnSuperClsWndProc);
00064 break;
00065 }
00066 return(DefWindowProc(hWnd, uMsg, wParam, lParam));
00067 }
00068
00069 ATOM WINAPI RegisterSuperClass (LPWNDCLASS WndClass,
00070 WNDPROC lpfnSCWndProc, int cbClsAdditional,
00071 int cbWndAdditional) {
00072 HWND hWnd;
00073 SUPERCLSINIT SuperClsInit;
00074 SuperClsInit.lpfnSuperClsWndProc = lpfnSCWndProc;
00075 SuperClsInit.lpfnBCWndProc = WndClass->lpfnWndProc;
00076 SuperClsInit.cbBCClsExtra = WndClass->cbClsExtra;
00077 SuperClsInit.cbBCWndExtra = WndClass->cbWndExtra;
00078 WndClass->cbClsExtra += cbClsAdditional + MINCBCLSADDTIONAL;
00079 WndClass->cbWndExtra += cbWndAdditional;
00080 WndClass->lpfnWndProc = SuperClsInitWndProc;
00081 if (RegisterClass(WndClass) == 0) return 0;
00082 hWnd = CreateWindow(WndClass->lpszClassName, "", 0, 0, 0, 0, 0,
00083 NULL, NULL, WndClass->hInstance, (LPSTR) &SuperClsInit);
00084 if (hWnd == NULL) {
00085 UnregisterClass(WndClass->lpszClassName,
00086 WndClass->hInstance);
00087 return(FALSE);
00088 }
00089 DestroyWindow(hWnd);
00090 _ValidRangeMsg = RegisterWindowMessage("ValidRange");
00091 _SetRangeMsg = RegisterWindowMessage("SetRange");
00092 return(TRUE);
00093 }
00094
00095 WNDPROC WINAPI GetBCWndProc (HWND hWnd) {
00096 return((WNDPROC) GetClassLong(hWnd,
00097 GetClassLong(hWnd, GCL_CBCLSEXTRA) - BCWNDPROCINDEX));
00098 }
00099
00100 static int NEAR CalcClassByteIndex (HWND hWnd, int nIndex) {
00101 int cbBCClsExtraIndex, cbBCClsExtra;
00102 if (nIndex < 0) return(nIndex);
00103 cbBCClsExtraIndex =
00104 GetClassLong(hWnd, GCL_CBCLSEXTRA) - CBBCCLSEXTRAINDEX;
00105 cbBCClsExtra = GetClassWord(hWnd, cbBCClsExtraIndex);
00106 return(nIndex + cbBCClsExtra);
00107 }
00108
00109 static int NEAR CalcWindowByteIndex (HWND hWnd, int nIndex) {
00110 int cbBCWndExtraIndex, cbBCWndExtra;
00111 if (nIndex < 0) return(nIndex);
00112 cbBCWndExtraIndex =
00113 GetClassLong(hWnd, GCL_CBCLSEXTRA) - CBBCWNDEXTRAINDEX;
00114 cbBCWndExtra = GetClassWord(hWnd, cbBCWndExtraIndex);
00115 return(nIndex + cbBCWndExtra);
00116 }
00117
00118 WORD WINAPI SetSCClassWord (HWND hWnd, int nIndex,
00119 WORD wNewWord) {
00120 nIndex = CalcClassByteIndex(hWnd, nIndex);
00121 return(SetClassWord(hWnd, nIndex, wNewWord));
00122 }
00123
00124 WORD WINAPI GetSCClassWord (HWND hWnd, int nIndex) {
00125 nIndex = CalcClassByteIndex(hWnd, nIndex);
00126 return(GetClassWord(hWnd, nIndex));
00127 }
00128
00129 DWORD WINAPI SetSCClassLong (HWND hWnd, int nIndex,
00130 DWORD dwNewLong) {
00131 nIndex = CalcClassByteIndex(hWnd, nIndex);
00132 return(SetClassLong(hWnd, nIndex, dwNewLong));
00133 }
00134
00135 DWORD WINAPI GetSCClassLong (HWND hWnd, int nIndex) {
00136 nIndex = CalcClassByteIndex(hWnd, nIndex);
00137 return(GetClassLong(hWnd, nIndex));
00138 }
00139
00140 WORD WINAPI SetSCWindowWord (HWND hWnd, int nIndex,
00141 WORD wNewWord) {
00142 nIndex = CalcWindowByteIndex(hWnd, nIndex);
00143 return(SetWindowWord(hWnd, nIndex, wNewWord));
00144 }
00145
00146 WORD WINAPI GetSCWindowWord (HWND hWnd, int nIndex) {
00147 nIndex = CalcWindowByteIndex(hWnd, nIndex);
00148 return(GetWindowWord(hWnd, nIndex));
00149 }
00150
00151 DWORD WINAPI SetSCWindowLong (HWND hWnd, int nIndex,
00152 DWORD dwNewLong) {
00153 nIndex = CalcWindowByteIndex(hWnd, nIndex);
00154 return(SetWindowLong(hWnd, nIndex, dwNewLong));
00155 }
00156
00157 DWORD WINAPI GetSCWindowLong (HWND hWnd, int nIndex) {
00158 nIndex = CalcWindowByteIndex(hWnd, nIndex);
00159 return(GetWindowLong(hWnd, nIndex));
00160 }
00161
00162
00163 #define NOALPHA_CBCLSEXTRA (0)
00164
00165 #define NOALPHA_CBWNDEXTRA (4)
00166 #define GSCWW_LOVALUE (0)
00167 #define GSCWW_HIVALUE (2)
00168
00169 ATOM RegisterNoAlphaWndClass (HINSTANCE hInstance) {
00170 WNDCLASS WndClass;
00171 GetClassInfo(NULL, "EDIT", &WndClass);
00172 WndClass.lpszClassName = "TIDE";
00173 WndClass.hInstance = hInstance;
00174 return(RegisterSuperClass(
00175 &WndClass,
00176 NoAlphaWndProc,
00177 NOALPHA_CBCLSEXTRA,
00178 NOALPHA_CBWNDEXTRA
00179 ));
00180 }
00181
00182 LRESULT CALLBACK NoAlphaWndProc (HWND hWnd, UINT uMsg,
00183 WPARAM wParam, LPARAM lParam) {
00184 LRESULT lResult = 0L;
00185 BOOL fCallBaseClassWndProc = TRUE;
00186 char szValue[10];
00187 int nValue, nLoValue, nHiValue;
00188 if (uMsg == _SetRangeMsg) {
00189 SetSCWindowWord(hWnd, GSCWW_LOVALUE, LOWORD(lParam));
00190 SetSCWindowWord(hWnd, GSCWW_HIVALUE, HIWORD(lParam));
00191 fCallBaseClassWndProc = FALSE;
00192 }
00193 if (uMsg == _ValidRangeMsg) {
00194 GetWindowText(hWnd, szValue, sizeof(szValue));
00195 nValue = atoi(szValue);
00196 nLoValue = GetSCWindowWord(hWnd, GSCWW_LOVALUE);
00197 nHiValue = GetSCWindowWord(hWnd, GSCWW_HIVALUE);
00198 lResult = (nLoValue <= nValue) && (nValue <= nHiValue);
00199 fCallBaseClassWndProc = FALSE;
00200 }
00201 switch (uMsg) {
00202 case WM_CREATE:
00203 SetSCWindowWord(hWnd, GSCWW_LOVALUE, 0);
00204 SetSCWindowWord(hWnd, GSCWW_HIVALUE, 32767);
00205 break;
00206 case WM_CHAR:
00207 if (wParam >= 'A' && wParam <= 'Z')
00208 fCallBaseClassWndProc = FALSE;
00209 if (wParam >= 'a' && wParam <= 'z')
00210 fCallBaseClassWndProc = FALSE;
00211 if (fCallBaseClassWndProc == FALSE) MessageBeep(0);
00212 break;
00213 default:
00214 break;
00215 }
00216 if (fCallBaseClassWndProc) {
00217 lResult =
00218 CallWindowProc((WNDPROC) GetBCWndProc(hWnd), hWnd,
00219 uMsg, wParam, lParam);
00220 }
00221 return(lResult);
00222 }