ClassXP.c
上传用户:yffx2008
上传日期:2014-10-12
资源大小:12414k
文件大小:37k
源码类别:

交通/航空行业

开发平台:

Visual C++

  1. ////////////////////////////////////////////////////////////////////////////////////////////////////
  2. // 说明: ClassXP.c 文件
  3. // 更新: 2003-3-10
  4. ////////////////////////////////////////////////////////////////////////////////////////////////////
  5. ////////////////////////////////////////////////////////////////////////////////////////////////////
  6. // 编译预处理
  7. #if _WIN32_WINNT < 0x0400
  8. #define _WIN32_WINNT 0x0400
  9. #endif
  10. #include <Windows.h>
  11. #include "ClassXP.h"
  12. #pragma warning(disable: 4311)
  13. #pragma warning(disable: 4312)
  14. #pragma comment(lib, "Msimg32.lib")
  15. // 导出函数
  16. #ifdef CXP_DLLMODE
  17. #pragma comment(linker, "/EXPORT:ClassXP=_ClassXP@8")
  18. #endif // CXP_DLLMODE
  19. // 强制使用 C 语言方式编译
  20. #ifdef __cplusplus
  21. extern "C"
  22. {
  23. #endif // __cplusplus
  24. ////////////////////////////////////////////////////////////////////////////////////////////////////
  25. ////////////////////////////////////////////////////////////////////////////////////////////////////
  26. // 宏定义
  27. // 窗口类型
  28. #define CXPT_UNKNOWN -1 // 不能处理的类型
  29. #define CXPT_PUSHBUTTON 0 // 按钮
  30. #define CXPT_CHECKBOX 1 // 复选框
  31. #define CXPT_RADIOBOX 2 // 单选框
  32. #define CXPT_EDITBOX 3 // 编辑框
  33. #define CXPT_COMBOBOX 4 // 组合框
  34. // 窗口状态
  35. #define CXPS_DISABLED 0x00000001L // 禁用状态
  36. #define CXPS_PRESSED 0x00000002L // 按下状态
  37. #define CXPS_HOTLIGHT 0x00000004L // 高亮状态 (鼠标在该窗口上)
  38. #define CXPS_FOCUS 0x00000008L // 具有键盘输入焦点
  39. #define CXPS_DEFAULT 0x00000010L // 默认状态 (用于按钮)
  40. #define CXPS_CHECKED 0x00000020L // 选中状态 (用于复选框)
  41. #define CXPS_INDETERMINATE 0x00000040L // 未确定状态 (用于复选框)
  42. #define CXPS_READONLY 0x00000080L // 只读状态 (用于编辑框)
  43. // 设置窗口状态
  44. #define CXPM_SETSTATE(Data, Mask, IsSet) ((IsSet) ? (Data |= Mask) : (Data &= ~Mask))
  45. ////////////////////////////////////////////////////////////////////////////////////////////////////
  46. ////////////////////////////////////////////////////////////////////////////////////////////////////
  47. // CLASSXP 结构,所有的代码都是围绕这个结构而编写的
  48. typedef struct tagCLASSXP
  49. {
  50. HWND hWnd; // 窗口句柄
  51. DWORD dwType; // 窗口的类型
  52. DWORD dwState; // 窗口的状态
  53. WNDPROC wpPrev; // 子类化之前的窗口回调函数地址
  54. struct tagCLASSXP * pNext; // 指向下一个 CLASSXP 结构,这里采用单向链表结构
  55. }CLASSXP, * PCLASSXP;
  56. ////////////////////////////////////////////////////////////////////////////////////////////////////
  57. ////////////////////////////////////////////////////////////////////////////////////////////////////
  58. // MEMDCXP 结构,为了方便使用内存兼容设备场景而设计
  59. typedef struct tagMEMDCXP
  60. {
  61. HWND hWnd; // 窗口句柄,输入参数
  62. HDC hDC; // 窗口设备场景,输出参数
  63. HDC hMemDC; // 窗口内存兼容设备场景,输出参数
  64. BOOL bTransfer; // 是否要用在 hDC 和 hMemDC 间传送数据,输入参数
  65. HBITMAP hBitmap; // 位图句柄,输入和输出参数
  66. }MEMDCXP, *LPMEMDCXP;
  67. ////////////////////////////////////////////////////////////////////////////////////////////////////
  68. ////////////////////////////////////////////////////////////////////////////////////////////////////
  69. // 函数声明
  70. PCLASSXP WINAPI CreateClassXP(HWND hWnd);
  71. PCLASSXP WINAPI DeleteClassXP(HWND hWnd);
  72. PCLASSXP WINAPI GetClassXP(HWND hWnd);
  73. DWORD WINAPI GetWindowTypeXP(HWND hWnd);
  74. HDC WINAPI GetMemDCXP(LPMEMDCXP pMdcxp);
  75. VOID WINAPI ReleaseMemDCXP(LPMEMDCXP pMdcxp);
  76. VOID WINAPI GradientRectXP(HDC hDC, LPRECT pRect,COLORREF crColor[4]);
  77. VOID WINAPI DrawDropGripXP(HDC hDC, LPRECT pRect);
  78. BOOL CALLBACK EnumWndProcXP(HWND hWnd, LPARAM lParam);
  79. LRESULT CALLBACK HookProcXP(int iCode, WPARAM wParam, LPARAM lParam);
  80. LRESULT CALLBACK WindowProcXP(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  81. VOID WINAPI DrawPushButtonXP(PCLASSXP pCxp);
  82. VOID WINAPI DrawCheckBoxXP(PCLASSXP pCxp);
  83. VOID WINAPI DrawRadioBoxXP(PCLASSXP pCxp);
  84. VOID WINAPI DrawEditBoxXP(PCLASSXP pCxp);
  85. VOID WINAPI DrawComboBoxXP(PCLASSXP pCxp);
  86. ////////////////////////////////////////////////////////////////////////////////////////////////////
  87. ////////////////////////////////////////////////////////////////////////////////////////////////////
  88. // 全局变量
  89. HHOOK g_hPrevHookXP = NULL; // 窗口消息 HOOK 句柄
  90. PCLASSXP g_pClassXP = NULL; // 窗口的 CLASSXP 结构指针
  91. #ifdef CXP_DLLMODE
  92. HINSTANCE g_hModuleXP = NULL; // 动态连接库模块句柄
  93. #endif // CXP_DLLMODE
  94. ////////////////////////////////////////////////////////////////////////////////////////////////////
  95. #ifdef CXP_DLLMODE
  96. ////////////////////////////////////////////////////////////////////////////////////////////////////
  97. // 动态连接库主函数
  98. BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, LPVOID pvReserved)
  99. {
  100. if (dwReason == DLL_PROCESS_ATTACH)
  101. {
  102. g_hModuleXP = hModule;
  103. DisableThreadLibraryCalls(hModule);
  104. }
  105. return TRUE;
  106. }
  107. ////////////////////////////////////////////////////////////////////////////////////////////////////
  108. #endif // CXP_DLLMODE
  109. ////////////////////////////////////////////////////////////////////////////////////////////////////
  110. // 设置或取消窗口的 ClassXP 风格
  111. BOOL WINAPI ClassXP(HWND hWnd, BOOL bEnable)
  112. {
  113. BOOL bReturn;
  114. bReturn = FALSE;
  115. // 如果是影响当前进程中的所有窗口
  116. if (hWnd == NULL)
  117. {
  118. // 如果是取消当前进程中的所有窗口
  119. if ((bEnable == FALSE) && (g_hPrevHookXP != NULL))
  120. {
  121. // 枚举当前线程的窗口并取消 ClassXP 风格
  122. EnumThreadWindows(GetCurrentThreadId(), EnumWndProcXP, FALSE);
  123. // 取消窗口消息 HOOK
  124. bReturn = UnhookWindowsHookEx(g_hPrevHookXP);
  125. g_hPrevHookXP = NULL;
  126. }
  127. // 如果是设置当前进程中的所有窗口
  128. else if ((bEnable == TRUE) && (g_hPrevHookXP == NULL))
  129. {
  130. // 枚举当前线程中已存在的窗口并设置为 ClassXP 风格
  131. EnumThreadWindows(GetCurrentThreadId(), EnumWndProcXP, TRUE);
  132. // 安装窗口消息 HOOK
  133. g_hPrevHookXP = SetWindowsHookEx(WH_CALLWNDPROC, HookProcXP, 0, GetCurrentThreadId());
  134. bReturn = (BOOL) g_hPrevHookXP;
  135. }
  136. }
  137. else
  138. {
  139. // 如果是取消指定窗口的 ClassXP 风格
  140. if (bEnable == FALSE)
  141. bReturn = (BOOL) DeleteClassXP(hWnd);
  142. // 如果是设置指定窗口的 ClassXP 风格
  143. else
  144. bReturn = (BOOL) CreateClassXP(hWnd);
  145. }
  146. return bReturn;
  147. }
  148. ////////////////////////////////////////////////////////////////////////////////////////////////////
  149. ////////////////////////////////////////////////////////////////////////////////////////////////////
  150. // 创建并初始化 CLASSXP 数据结构;子类化窗口
  151. // 如果返回 NULL,表示没有创建;否则返回新创建节点的指针,同时 g_pClassXP 指向新创建的节点
  152. PCLASSXP WINAPI CreateClassXP(HWND hWnd)
  153. {
  154. LONG lStyle;
  155. DWORD dwType;
  156. PCLASSXP pCxp;
  157. // 是否已经是 ClassXP 风格
  158. if (GetClassXP(hWnd) == NULL)
  159. {
  160. // 获取窗口类型,如果并判断是否能设置为 ClassXP 风格
  161. dwType = GetWindowTypeXP(hWnd);
  162. if ((dwType >= CXPT_PUSHBUTTON) && (dwType <= CXPT_COMBOBOX))
  163. {
  164. lStyle = GetWindowLong(hWnd, GWL_STYLE);
  165. // 分配存储空间,增加一个节点
  166. pCxp = (PCLASSXP) HeapAlloc(GetProcessHeap(), 0, sizeof(CLASSXP));
  167. pCxp->pNext = g_pClassXP;
  168. g_pClassXP = pCxp;
  169. // 子类化窗口并初始化 CLASSXP 数据结构
  170. pCxp->hWnd = hWnd;
  171. pCxp->dwType = dwType;
  172. pCxp->dwState = (lStyle & WS_DISABLED) ? CXPS_DISABLED : 0;
  173. if (hWnd == GetFocus())
  174. pCxp->dwState |= CXPS_FOCUS;
  175. pCxp->wpPrev = (WNDPROC) SetWindowLong(hWnd, GWL_WNDPROC, (LONG) WindowProcXP);
  176. // 按窗口类型分别 CLASSXP 数据结构
  177. switch (dwType)
  178. {
  179. case CXPT_PUSHBUTTON:
  180. case CXPT_CHECKBOX:
  181. case CXPT_RADIOBOX:
  182. if ((lStyle & SS_TYPEMASK) == BS_DEFPUSHBUTTON)
  183. pCxp->dwState |= CXPS_DEFAULT;
  184. lStyle = (LONG) SendMessage(hWnd, BM_GETCHECK, 0, 0);
  185. if (lStyle == BST_CHECKED)
  186. pCxp->dwState |= CXPS_CHECKED;
  187. else if (lStyle == BST_INDETERMINATE)
  188. pCxp->dwState |= CXPS_INDETERMINATE;
  189. break;
  190. case CXPT_EDITBOX:
  191. if (lStyle & ES_READONLY)
  192. pCxp->dwState |= CXPS_READONLY;
  193. break;
  194. }
  195. // 重画窗口
  196. RedrawWindow(hWnd, NULL, NULL,
  197. RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ERASENOW | RDW_UPDATENOW);
  198. return pCxp;
  199. }
  200. }
  201. return NULL;
  202. }
  203. ////////////////////////////////////////////////////////////////////////////////////////////////////
  204. ////////////////////////////////////////////////////////////////////////////////////////////////////
  205. // 取消窗口子类化;销毁窗口的 CLASSXP 数据结构
  206. // 如果返回值不为 NULL 表示成功删除,返回值为指向上一个节点指针;
  207. // 如果返回 NULL 且 g_pClassXP 为 NULL,表全部节点被删除;
  208. // 否则表示没有找到该节点。
  209. // 致谢: 感谢 dREAMtHEATER 改进此函数!
  210. PCLASSXP WINAPI DeleteClassXP(HWND hWnd)
  211. {
  212. PCLASSXP pDel;
  213. PCLASSXP pCxp;
  214. // 获取待删除的节点指针
  215. pDel = GetClassXP(hWnd);
  216. if (pDel != NULL)
  217. {
  218. // 如果待删除的节点就是 g_pClassXP 节点
  219. if (pDel == g_pClassXP)
  220. pCxp = g_pClassXP = pDel->pNext;
  221. else
  222. {
  223. // 循环查找待删除节点的上一个节点
  224. for (pCxp = g_pClassXP; pCxp != NULL; pCxp = pCxp->pNext)
  225. {
  226. // 如果找到
  227. if (pCxp->pNext == pDel)
  228. {
  229. // 使链表跳过待删除的节点
  230. pCxp->pNext = pDel->pNext;
  231. break;
  232. }
  233. }
  234. }
  235. // 取消窗口子类化并重画窗口
  236. SetWindowLong(hWnd, GWL_WNDPROC, (LONG) pDel->wpPrev);
  237. // 删除堆内存
  238. HeapFree(GetProcessHeap(), 0, pDel);
  239. // 重画窗口
  240. RedrawWindow(hWnd, NULL, NULL,
  241. RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ERASENOW | RDW_UPDATENOW);
  242. return pCxp;
  243. }
  244. return NULL;
  245. }
  246. ////////////////////////////////////////////////////////////////////////////////////////////////////
  247. ////////////////////////////////////////////////////////////////////////////////////////////////////
  248. // 获取窗口的 CLASSXP 数据结构
  249. // 如果返回 NULL,表示没有找到;否则返回节点的指针
  250. PCLASSXP WINAPI GetClassXP(HWND hWnd)
  251. {
  252. PCLASSXP pCxp;
  253. for (pCxp = g_pClassXP; pCxp != NULL; pCxp = pCxp->pNext)
  254. {
  255. if (pCxp->hWnd == hWnd)
  256. return pCxp;
  257. }
  258. return FALSE;
  259. }
  260. ////////////////////////////////////////////////////////////////////////////////////////////////////
  261. ////////////////////////////////////////////////////////////////////////////////////////////////////
  262. // 获取窗口类型
  263. DWORD WINAPI GetWindowTypeXP(HWND hWnd)
  264. {
  265. DWORD lReturn;
  266. char szTemp[MAX_PATH];
  267. static char s_szClass[][32] = 
  268. {
  269. "Button", // 按钮类
  270. "Edit", // 编辑框类
  271. "ComboBox", // 组合框类
  272. #ifdef CXP_DLLMODE
  273. "TButton", // VCL TButton 类
  274. "ThunderCommandButton", // Visual Basic Command Button 类
  275. "ThunderRT6CommandButton", // Visual Basic Command Button 类
  276. "TCheckBox",
  277. "ThunderCheckBox",
  278. "ThunderRT6CheckBox",
  279. "TEdit",
  280. "TNumberEdit",
  281. "ThunderTextBox",
  282. "ThunderRT6TextBox",
  283. "TComboBox",
  284. "ThunderComboBox",
  285. "ThunderRT6ComboBox"
  286. #endif // CXP_DLLMODE
  287. };
  288. // 查找判断匹配的类名称
  289. GetClassName(hWnd, szTemp, sizeof(szTemp));
  290. for (lReturn = 0; lReturn < (sizeof(s_szClass) / sizeof(s_szClass[0])); lReturn++)
  291. {
  292. if (lstrcmpi(szTemp, s_szClass[lReturn]) == 0)
  293. break;
  294. }
  295. switch (lReturn)
  296. {
  297. case 0:
  298. lReturn = GetWindowLong(hWnd, GWL_STYLE);
  299. switch (lReturn & SS_TYPEMASK)
  300. {
  301. case BS_DEFPUSHBUTTON: // 默认按钮
  302. case BS_PUSHBUTTON: // 普通按钮
  303. lReturn = CXPT_PUSHBUTTON;
  304. break;
  305. case BS_CHECKBOX: // 复选框
  306. case BS_AUTOCHECKBOX: // 自动复选框
  307. case BS_3STATE: // 三状态复选框
  308. case BS_AUTO3STATE: // 自动三状态复选框
  309. if (lReturn & BS_PUSHLIKE)
  310. lReturn = CXPT_PUSHBUTTON;
  311. else
  312. lReturn = CXPT_CHECKBOX;
  313. break;
  314. case BS_RADIOBUTTON: // 单选框
  315. case BS_AUTORADIOBUTTON: // 自动单选框
  316. if (lReturn & BS_PUSHLIKE)
  317. lReturn = CXPT_PUSHBUTTON;
  318. else
  319. lReturn = CXPT_RADIOBOX;
  320. break;
  321. default: // 未知类型
  322. lReturn = CXPT_UNKNOWN;
  323. }
  324. break;
  325. case 1: // 编辑框
  326. lReturn = CXPT_EDITBOX;
  327. break;
  328. case 2: // 组合框
  329. if ((GetWindowLong(hWnd, GWL_STYLE) & 0x00000003) == CBS_SIMPLE)
  330. lReturn = CXPT_UNKNOWN;
  331. else
  332. lReturn = CXPT_COMBOBOX;
  333. break;
  334. #ifdef CXP_DLLMODE
  335. // VB 和 VCL 的控件,只有在动态连接库方式下才有可能出现这种情况
  336. case 3:
  337. case 4:
  338. case 5:
  339. lReturn = CXPT_PUSHBUTTON;
  340. break;
  341. case 6:
  342. case 7:
  343. case 8:
  344. lReturn = CXPT_CHECKBOX;
  345. break;
  346. case 9:
  347. case 10:
  348. case 11:
  349. case 12:
  350. lReturn = CXPT_EDITBOX;
  351. break;
  352. case 13:
  353. case 14:
  354. case 15:
  355. lReturn = CXPT_COMBOBOX;
  356. break;
  357. #endif // CXP_DLLMODE
  358. default: // 未知类型
  359. lReturn = CXPT_UNKNOWN;
  360. }
  361. return lReturn;
  362. }
  363. ////////////////////////////////////////////////////////////////////////////////////////////////////
  364. ////////////////////////////////////////////////////////////////////////////////////////////////////
  365. // 获取窗口的内存兼容设备场景
  366. HDC WINAPI GetMemDCXP(LPMEMDCXP pMdcxp)
  367. {
  368. RECT Rect;
  369. GetWindowRect(pMdcxp->hWnd, &Rect);
  370. // 创建兼容内存兼容设备场景并设置为透明模式
  371. pMdcxp->hDC = GetWindowDC(pMdcxp->hWnd);
  372. pMdcxp->hMemDC = CreateCompatibleDC(pMdcxp->hDC);;
  373. SetBkMode(pMdcxp->hMemDC, TRANSPARENT);
  374. // 是否已经指定了位图句柄
  375. if (pMdcxp->hBitmap)
  376. {
  377. // 选择位图对象
  378. SelectObject(pMdcxp->hMemDC, pMdcxp->hBitmap);
  379. }
  380. else
  381. {
  382. // 创建并选择位图对象
  383. pMdcxp->hBitmap = (HBITMAP) SelectObject(pMdcxp->hMemDC,
  384. CreateCompatibleBitmap(pMdcxp->hDC, Rect.right - Rect.left, Rect.bottom - Rect.top));
  385. }
  386. // 如果要传送数据
  387. if (pMdcxp->bTransfer == TRUE)
  388. {
  389. BitBlt(pMdcxp->hMemDC, 0, 0,
  390. Rect.right - Rect.left, Rect.bottom - Rect.top, pMdcxp->hDC, 0, 0, SRCCOPY);
  391. }
  392. return pMdcxp->hMemDC;
  393. }
  394. ////////////////////////////////////////////////////////////////////////////////////////////////////
  395. ////////////////////////////////////////////////////////////////////////////////////////////////////
  396. // 获取窗口的内存兼容设备场景
  397. VOID WINAPI ReleaseMemDCXP(LPMEMDCXP pMdcxp)
  398. {
  399. RECT Rect;
  400. // 如果要传送数据
  401. if (pMdcxp->bTransfer == TRUE)
  402. {
  403. GetWindowRect(pMdcxp->hWnd, &Rect);
  404. BitBlt(pMdcxp->hDC, 0, 0,
  405. Rect.right - Rect.left, Rect.bottom - Rect.top, pMdcxp->hMemDC, 0, 0, SRCCOPY);
  406. }
  407. if (pMdcxp->hBitmap)
  408. DeleteObject(SelectObject(pMdcxp->hMemDC, pMdcxp->hBitmap));
  409. DeleteDC(pMdcxp->hMemDC);
  410. ReleaseDC(pMdcxp->hWnd, pMdcxp->hDC);
  411. }
  412. ////////////////////////////////////////////////////////////////////////////////////////////////////
  413. ////////////////////////////////////////////////////////////////////////////////////////////////////
  414. // 绘制渐变矩形
  415. VOID WINAPI GradientRectXP(HDC hDC, LPRECT pRect,COLORREF crColor[4])
  416. {
  417. int i;
  418. TRIVERTEX Tve[4]; 
  419. GRADIENT_RECT GRect;
  420. GRADIENT_TRIANGLE GTrg;
  421. for (i = 0; i < 4; i++)
  422. {
  423. Tve[i].Red = ((COLOR16) GetRValue(crColor[i])) << 8;
  424. Tve[i].Green = ((COLOR16) GetGValue(crColor[i])) << 8;
  425. Tve[i].Blue = ((COLOR16) GetBValue(crColor[i])) << 8;
  426. Tve[i].Alpha = ((COLOR16) (crColor[i] >> 24)) << 8;
  427. }
  428. Tve[0].x = pRect->left;
  429. Tve[0].y = pRect->top;
  430. Tve[1].x = pRect->right;
  431. Tve[1].y = pRect->top;
  432. Tve[2].x = pRect->left;
  433. Tve[2].y = pRect->bottom;
  434. Tve[3].x = pRect->right;
  435. Tve[3].y = pRect->bottom;
  436. if ((crColor[0] == crColor[2]) &&
  437. (crColor[1] == crColor[3]))
  438. i = GRADIENT_FILL_RECT_H;
  439. if ((crColor[0] == crColor[1]) &&
  440. (crColor[2] == crColor[3]))
  441. i = GRADIENT_FILL_RECT_V;
  442. else
  443. i = GRADIENT_FILL_TRIANGLE;
  444. if (i == GRADIENT_FILL_TRIANGLE)
  445. {
  446. GTrg.Vertex1 = 0;
  447. GTrg.Vertex2 = 1;
  448. GTrg.Vertex3 = 2;
  449. }
  450. else
  451. {
  452. GRect.UpperLeft = 0;
  453. GRect.LowerRight = 3;
  454. }
  455. GradientFill(hDC, Tve, 4,
  456. ((i == GRADIENT_FILL_TRIANGLE) ? ((PVOID) &GTrg) : ((PVOID) &GRect)), 1, i);
  457. if (i == GRADIENT_FILL_TRIANGLE)
  458. {
  459. GTrg.Vertex1 = 3;
  460. GradientFill(hDC,Tve, 4, &GTrg, 1, GRADIENT_FILL_TRIANGLE);
  461. }
  462. }
  463. ////////////////////////////////////////////////////////////////////////////////////////////////////
  464. ////////////////////////////////////////////////////////////////////////////////////////////////////
  465. // 绘制渐变矩形
  466. VOID WINAPI DrawDropGripXP(HDC hDC, LPRECT pRect)
  467. {
  468. }
  469. ////////////////////////////////////////////////////////////////////////////////////////////////////
  470. ////////////////////////////////////////////////////////////////////////////////////////////////////
  471. // 枚举窗口回调函数
  472. BOOL CALLBACK EnumWndProcXP(HWND hWnd, LPARAM lParam)
  473. {
  474. // 如果是取消指定窗口的 ClassXP 风格
  475. if (lParam == FALSE)
  476. DeleteClassXP(hWnd);
  477. // 如果是设置指定窗口的 ClassXP 风格
  478. else
  479. CreateClassXP(hWnd);
  480. // 枚举子窗体
  481. EnumChildWindows(hWnd, EnumWndProcXP, lParam);
  482. return TRUE;
  483. }
  484. ////////////////////////////////////////////////////////////////////////////////////////////////////
  485. ////////////////////////////////////////////////////////////////////////////////////////////////////
  486. // 窗口消息 HOOK 回调函数
  487. LRESULT CALLBACK HookProcXP(int iCode, WPARAM wParam, LPARAM lParam)
  488. {
  489. // 设置新建的窗口为 ClassXP 风格
  490. if ((((CWPSTRUCT *) lParam)->message == WM_CREATE) && (iCode >= 0))
  491. CreateClassXP(((CWPSTRUCT *) lParam)->hwnd);
  492. return CallNextHookEx(g_hPrevHookXP, iCode, wParam, lParam);
  493. }
  494. ////////////////////////////////////////////////////////////////////////////////////////////////////
  495. ////////////////////////////////////////////////////////////////////////////////////////////////////
  496. // 窗口子类化回调函数
  497. LRESULT CALLBACK WindowProcXP(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  498. {
  499. LONG lReturn;
  500. PCLASSXP pCxp;
  501. TRACKMOUSEEVENT Tme;
  502. typedef VOID (WINAPI *DRAWXP)(PCLASSXP);
  503. static DRAWXP s_DrawXP[] = 
  504. {
  505. DrawPushButtonXP,
  506. DrawCheckBoxXP,
  507. DrawRadioBoxXP,
  508. DrawEditBoxXP,
  509. DrawComboBoxXP
  510. };
  511. pCxp = GetClassXP(hWnd);
  512. switch (pCxp->dwType)
  513. {
  514. case CXPT_PUSHBUTTON: // 按钮
  515. case CXPT_CHECKBOX: // 复选框
  516. case CXPT_RADIOBOX: // 单选框
  517. switch (uMsg)
  518. {
  519. case BM_SETSTYLE: // 按钮风格改变
  520. CXPM_SETSTATE(pCxp->dwState, CXPS_DEFAULT, wParam & BS_DEFPUSHBUTTON);
  521. s_DrawXP[pCxp->dwType](pCxp);
  522. break;
  523. case BM_SETSTATE: // 设置按钮状态
  524. lReturn = (LONG) CallWindowProc(pCxp->wpPrev, hWnd, uMsg, wParam, lParam);
  525. CXPM_SETSTATE(pCxp->dwState, CXPS_PRESSED, wParam);
  526. s_DrawXP[pCxp->dwType](pCxp);
  527. return lReturn;
  528. case BM_SETCHECK: // 设置选中状态
  529. lReturn = (LONG) CallWindowProc(pCxp->wpPrev, hWnd, uMsg, wParam, lParam);
  530. CXPM_SETSTATE(pCxp->dwState, CXPS_CHECKED, (wParam == BST_CHECKED));
  531. CXPM_SETSTATE(pCxp->dwState, CXPS_INDETERMINATE, (wParam == BST_INDETERMINATE));
  532. s_DrawXP[pCxp->dwType](pCxp);
  533. return lReturn;
  534. case WM_SETTEXT: // 设置窗口文本
  535. lReturn = (LONG) DefWindowProc(hWnd, uMsg, wParam, lParam);
  536. s_DrawXP[pCxp->dwType](pCxp);
  537. return lReturn;
  538. case WM_PAINT: // 窗口重画
  539. lReturn = (LONG) DefWindowProc(hWnd, uMsg, wParam, lParam);
  540. s_DrawXP[pCxp->dwType](pCxp);
  541. return lReturn;
  542. }
  543. break;
  544. case CXPT_EDITBOX: // 编辑框
  545. if (uMsg == WM_NCPAINT)
  546. {
  547. lReturn = (LONG) DefWindowProc(hWnd, uMsg, wParam, lParam);
  548. DrawEditBoxXP(pCxp);
  549. return lReturn;
  550. }
  551. else if (uMsg == EM_SETREADONLY)
  552. {
  553. CXPM_SETSTATE(pCxp->dwState, CXPS_READONLY, wParam);
  554. DrawEditBoxXP(pCxp);
  555. }
  556. break;
  557. case CXPT_COMBOBOX: // 组合框
  558. switch (uMsg)
  559. {
  560. case WM_PAINT:
  561. case WM_NCPAINT:
  562. lReturn = (LONG) CallWindowProc(pCxp->wpPrev, hWnd, uMsg, wParam, lParam);
  563. DrawComboBoxXP(pCxp);
  564. return lReturn;
  565. case WM_LBUTTONDOWN:
  566. pCxp->dwState |= CXPS_PRESSED;
  567. break;
  568. case WM_LBUTTONUP:
  569. pCxp->dwState &= ~CXPS_PRESSED;
  570. break;
  571. }
  572. break;
  573. }
  574. // 调用原来的回调函数
  575. lReturn = (LONG) CallWindowProc(pCxp->wpPrev, hWnd, uMsg, wParam, lParam);
  576. // 对所有窗口相同的处理
  577. switch (uMsg)
  578. {
  579. case WM_MOUSEMOVE: // 窗口移动
  580. if (((pCxp->dwState & CXPS_HOTLIGHT) == 0) && ((wParam & MK_LBUTTON) == 0))
  581. {
  582. pCxp->dwState |= CXPS_HOTLIGHT;
  583. s_DrawXP[pCxp->dwType](pCxp);
  584. // 追踪鼠标移出消息一次
  585. Tme.cbSize = sizeof(TRACKMOUSEEVENT);
  586. Tme.dwFlags = TME_LEAVE;
  587. Tme.hwndTrack = hWnd;
  588. TrackMouseEvent(&Tme);
  589. }
  590. break;
  591. case WM_MOUSELEAVE: // 鼠标移出
  592. if (pCxp->dwState & CXPS_HOTLIGHT)
  593. {
  594. pCxp->dwState &= ~CXPS_HOTLIGHT;
  595. s_DrawXP[pCxp->dwType](pCxp);
  596. }
  597. break;
  598. case WM_ENABLE: // 窗口被设置为禁用或可用
  599. CXPM_SETSTATE(pCxp->dwState, CXPS_DISABLED, !wParam);
  600. s_DrawXP[pCxp->dwType](pCxp);
  601. break;
  602. case WM_SETFOCUS: // 获得焦点
  603. pCxp->dwState |= CXPS_FOCUS;
  604. s_DrawXP[pCxp->dwType](pCxp);
  605. break;
  606. case WM_KILLFOCUS: // 丢失焦点
  607. pCxp->dwState &= ~CXPS_FOCUS;
  608. s_DrawXP[pCxp->dwType](pCxp);
  609. break;
  610. case WM_DESTROY: // 窗口销毁
  611. DeleteClassXP(hWnd);
  612. }
  613. return lReturn;
  614. }
  615. ////////////////////////////////////////////////////////////////////////////////////////////////////
  616. ////////////////////////////////////////////////////////////////////////////////////////////////////
  617. // 绘制按钮
  618. VOID WINAPI DrawPushButtonXP(PCLASSXP pCxp)
  619. {
  620. int i;
  621. RECT Rect;
  622. MEMDCXP Mdcxp;
  623. HANDLE hHandle;
  624. COLORREF crColor;
  625. char szTemp[256];
  626. static COLORREF s_crGradientXP[][4] =
  627. {
  628. {0x00C1CCD1, 0x00C1CCD1, 0x00EEF1F2, 0xFFEEF1F2},
  629. {0x00CFF0FF, 0x00CFF0FF, 0x000097E5, 0xFF0097E5},
  630. {0x00BDCBD6, 0x00C6CFD6, 0x00EFF3F7, 0xFFEFF3F7},
  631. {0x00FFE7CE, 0x00FFE7CE, 0x00EE8269, 0xFFEE8269},
  632. {0x00FFFFFF, 0x00FFFFFF, 0x00D6DFE2, 0xFFD6DFE2},
  633. {0x00DEE3E7, 0x00E7E7E7, 0x00DEE3E7, 0xFFDEE3E7},
  634. {0x00FBFCFC, 0x00FBFCFC, 0x00E6EBEC, 0xFFE6EBEC},
  635. };
  636. // 获取内存兼容设备场景
  637. Mdcxp.hWnd = pCxp->hWnd;
  638. Mdcxp.bTransfer = FALSE;
  639. Mdcxp.hBitmap = NULL;
  640. GetMemDCXP(&Mdcxp);
  641. // 获取窗口大小
  642. GetWindowRect(pCxp->hWnd, &Rect);
  643. Rect.right -= Rect.left;
  644. Rect.bottom -= Rect.top;
  645. Rect.left = Rect.top = 0;
  646. // 画最外面的框,颜色与系统按钮颜色一直
  647. FrameRect(Mdcxp.hMemDC, &Rect, GetSysColorBrush(COLOR_BTNFACE));
  648. // 画最第二层边框
  649. InflateRect(&Rect, -1, -1);
  650. hHandle = (HANDLE) CreateSolidBrush(
  651. (pCxp->dwState & CXPS_DISABLED) ? (GetSysColor(COLOR_BTNFACE) - 0x00202020) : 0x00733C00);
  652. FrameRect(Mdcxp.hMemDC, &Rect, (HBRUSH) hHandle);
  653. DeleteObject((HGDIOBJ) hHandle);
  654. // 画热点框渐变背景
  655. InflateRect(&Rect, -1, -1);
  656. if (pCxp->dwState & CXPS_DISABLED)
  657. {
  658. i = -1;
  659. hHandle = (HANDLE) CreateSolidBrush(0x00EAF4F5);
  660. FillRect(Mdcxp.hMemDC, &Rect, (HBRUSH) hHandle);
  661. DeleteObject((HGDIOBJ) hHandle);
  662. }
  663. else
  664. {
  665. if (pCxp->dwState & CXPS_PRESSED)
  666. i = 0;
  667. else if (pCxp->dwState & CXPS_HOTLIGHT)
  668. i = 1;
  669. else if ((pCxp->dwState & CXPS_CHECKED) || (pCxp->dwState & CXPS_INDETERMINATE))
  670. i = 2;
  671. else if ((pCxp->dwState & CXPS_FOCUS) || (pCxp->dwState & CXPS_DEFAULT))
  672. i = 3;
  673. else
  674. i = 4;
  675. GradientRectXP(Mdcxp.hMemDC, &Rect, s_crGradientXP[i]);
  676. }
  677. // 画文字区域渐变背景
  678. InflateRect(&Rect, -2, -2);
  679. if ((pCxp->dwState & CXPS_PRESSED) ||
  680. (pCxp->dwState & CXPS_CHECKED) ||
  681. (pCxp->dwState & CXPS_INDETERMINATE))
  682. i = 5;
  683. else if (!(pCxp->dwState & CXPS_DISABLED))
  684. i = 6;
  685. if ((i == 5) || (i == 6))
  686. GradientRectXP(Mdcxp.hMemDC, &Rect, s_crGradientXP[i]);
  687. // 用与系统按钮一直的颜色第二层边框的四角像素
  688. crColor = GetSysColor(COLOR_BTNFACE);
  689. SetPixel(Mdcxp.hMemDC, 1, 1, crColor);
  690. SetPixel(Mdcxp.hMemDC, 1, Rect.bottom + 2, crColor);
  691. SetPixel(Mdcxp.hMemDC, Rect.right + 2, Rect.bottom + 2, crColor);
  692. SetPixel(Mdcxp.hMemDC, Rect.right + 2, 1, crColor);
  693. // 画第二层边框的拐角像素,太罗嗦了,千万别仔细看:)
  694. crColor = (pCxp->dwState & CXPS_DISABLED) ?
  695. (GetSysColor(COLOR_BTNFACE) - 0x00151515) : 0x00A57D52;
  696. SetPixel(Mdcxp.hMemDC, 2, 2, crColor);
  697. SetPixel(Mdcxp.hMemDC, 2, Rect.bottom + 1, crColor);
  698. SetPixel(Mdcxp.hMemDC, Rect.right + 1, Rect.bottom + 1, crColor);
  699. SetPixel(Mdcxp.hMemDC, Rect.right + 1, 2, crColor);
  700. crColor = (pCxp->dwState & CXPS_DISABLED) ?
  701. (GetSysColor(COLOR_BTNFACE) - 0x00111111) : 0x00AD967B;
  702. SetPixel(Mdcxp.hMemDC, 1, 2, crColor);
  703. SetPixel(Mdcxp.hMemDC, 2, 1, crColor);
  704. SetPixel(Mdcxp.hMemDC, Rect.right + 1, 1, crColor);
  705. SetPixel(Mdcxp.hMemDC, Rect.right + 2, 2, crColor);
  706. SetPixel(Mdcxp.hMemDC, Rect.right + 1, Rect.bottom + 2, crColor);
  707. SetPixel(Mdcxp.hMemDC, Rect.right + 2, Rect.bottom + 1, crColor);
  708. SetPixel(Mdcxp.hMemDC, 2, Rect.bottom + 2, crColor);
  709. SetPixel(Mdcxp.hMemDC, 1, Rect.bottom + 1, crColor);
  710. // 如果有焦点,画出焦点框
  711. if (pCxp->dwState & CXPS_FOCUS)
  712. {
  713. InflateRect(&Rect, 1, 1);
  714. DrawFocusRect(Mdcxp.hMemDC, &Rect);
  715. }
  716. // 画文字
  717. if (GetWindowText(pCxp->hWnd, szTemp, sizeof(szTemp)))
  718. {
  719. if (pCxp->dwState & CXPS_PRESSED)
  720. OffsetRect(&Rect, 1, 1);
  721. SetTextColor(Mdcxp.hMemDC,
  722. ((pCxp->dwState & CXPS_INDETERMINATE) || (pCxp->dwState & CXPS_DISABLED)) ?
  723. 0x0094A2A5: 0x00000000);
  724. hHandle = (HANDLE) SelectObject(Mdcxp.hMemDC,
  725. (HGDIOBJ) SendMessage(pCxp->hWnd, WM_GETFONT, 0, 0));
  726. DrawText(Mdcxp.hMemDC, szTemp, -1, &Rect, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
  727. SelectObject(Mdcxp.hMemDC, (HGDIOBJ) hHandle);
  728. }
  729. Mdcxp.bTransfer = TRUE;
  730. ReleaseMemDCXP(&Mdcxp);
  731. }
  732. ////////////////////////////////////////////////////////////////////////////////////////////////////
  733. ////////////////////////////////////////////////////////////////////////////////////////////////////
  734. // 绘制复选框
  735. VOID WINAPI DrawCheckBoxXP(PCLASSXP pCxp)
  736. {
  737. int i;
  738. RECT Rect;
  739. MEMDCXP Mdcxp;
  740. HANDLE hHandle;
  741. char szTemp[256];
  742. COLORREF crColor;
  743. static COLORREF s_crGradientXP[][4] =
  744. {
  745. {0x00A5B2B5, 0x00CED7D6, 0x00CED7D6, 0x00DEEFF7},
  746. {0x00CEF3FF, 0x0063CBFF, 0x0063CBFF, 0x0031B2FF},
  747. {0x00D6DFDE, 0x00EFF3F7, 0x00EFF3F7, 0x00FFFFFF}
  748. };
  749. // 获取内存兼容设备场景
  750. Mdcxp.hWnd = pCxp->hWnd;
  751. Mdcxp.bTransfer = FALSE;
  752. Mdcxp.hBitmap = NULL;
  753. GetMemDCXP(&Mdcxp);
  754. // 获取窗口大小
  755. GetWindowRect(pCxp->hWnd, &Rect);
  756. Rect.right -= Rect.left;
  757. Rect.bottom -= Rect.top;
  758. Rect.left = Rect.top = 0;
  759. // 填充背景
  760. FillRect(Mdcxp.hMemDC, &Rect, GetSysColorBrush(COLOR_BTNFACE));
  761. // 画最外面的框
  762. Rect.left = 0;
  763. Rect.right = 13;
  764. Rect.top = (Rect.bottom - 13) / 2;
  765. Rect.bottom = Rect.top + 13;
  766. hHandle = (HANDLE) CreateSolidBrush(
  767. (pCxp->dwState & CXPS_DISABLED) ? (GetSysColor(COLOR_BTNFACE) - 0x00202020) : 0x00845118);
  768. FrameRect(Mdcxp.hMemDC, &Rect, (HBRUSH) hHandle);
  769. DeleteObject((HGDIOBJ) hHandle);
  770. // 画热点框渐变背景
  771. InflateRect(&Rect, -1, -1);
  772. if (pCxp->dwState & CXPS_DISABLED)
  773. FillRect(Mdcxp.hMemDC, &Rect, GetStockObject(WHITE_BRUSH));
  774. else
  775. {
  776. if (pCxp->dwState & CXPS_PRESSED)
  777. i = 0;
  778. else if (pCxp->dwState & CXPS_HOTLIGHT)
  779. i = 1;
  780. else
  781. i = 2;
  782. GradientRectXP(Mdcxp.hMemDC, &Rect, s_crGradientXP[i]);
  783. }
  784. // 画内框
  785. InflateRect(&Rect, -2, -2);
  786. if ((pCxp->dwState & CXPS_INDETERMINATE) ||
  787. ((pCxp->dwState & CXPS_HOTLIGHT) && (!(pCxp->dwState & CXPS_PRESSED))))
  788. {
  789. if (pCxp->dwState & CXPS_INDETERMINATE)
  790. {
  791. if (pCxp->dwState & CXPS_DISABLED)
  792. crColor = 0x00BDCBCE;
  793. else if (pCxp->dwState & CXPS_PRESSED)
  794. crColor = 0x00188A18;
  795. else if (pCxp->dwState & CXPS_HOTLIGHT)
  796. crColor = 0x0021A221;
  797. else
  798. crColor = 0x0073C373;
  799. }
  800. else if (pCxp->dwState & CXPS_CHECKED)
  801. crColor = 0x00F7F7F7;
  802. else
  803. crColor = 0x00E7E7E7;
  804. hHandle = (HANDLE) CreateSolidBrush(crColor);
  805. FillRect(Mdcxp.hMemDC, &Rect, (HBRUSH) hHandle);
  806. DeleteObject((HGDIOBJ) hHandle);
  807. }
  808. // 画框内选中标志
  809. if (pCxp->dwState & CXPS_CHECKED)
  810. {
  811. hHandle = (HANDLE) SelectObject(Mdcxp.hMemDC,
  812. CreatePen(PS_SOLID, 1, (pCxp->dwState & CXPS_DISABLED) ? 0x000BDCBCE : 0x0021A221));
  813. for (i = 3; i < 10; i++)
  814. {
  815. MoveToEx(Mdcxp.hMemDC, i, Rect.top + ((i < 6) ? i - 1 : (9 - i)), NULL);
  816. LineTo(Mdcxp.hMemDC, i, Rect.top + ((i < 6) ? i + 2 : (12 - i)));
  817. }
  818. DeleteObject(SelectObject(Mdcxp.hMemDC, (HGDIOBJ) hHandle));
  819. }
  820. // 画文字
  821. if (GetWindowText(pCxp->hWnd, szTemp, sizeof(szTemp)))
  822. {
  823. SetTextColor(Mdcxp.hMemDC, GetSysColor((pCxp->dwState & CXPS_DISABLED) ?  COLOR_GRAYTEXT: COLOR_BTNTEXT));
  824. hHandle = (HANDLE) SelectObject(Mdcxp.hMemDC,
  825. (HGDIOBJ) SendMessage(pCxp->hWnd, WM_GETFONT, 0, 0));
  826. Rect.left = 18;
  827. Rect.top -= 2;
  828. Rect.bottom = Rect.top + 1 + DrawText(Mdcxp.hMemDC, szTemp, -1, &Rect,
  829. DT_CALCRECT | DT_SINGLELINE | DT_VCENTER);
  830. DrawText(Mdcxp.hMemDC, szTemp, -1, &Rect, DT_SINGLELINE | DT_VCENTER);
  831. SelectObject(Mdcxp.hMemDC, (HGDIOBJ) hHandle);
  832. // 如果有焦点,画出焦点框
  833. if (pCxp->dwState & CXPS_FOCUS)
  834. {
  835. InflateRect(&Rect, 1, 1);
  836. DrawFocusRect(Mdcxp.hMemDC, &Rect);
  837. }
  838. }
  839. Mdcxp.bTransfer = TRUE;
  840. ReleaseMemDCXP(&Mdcxp);
  841. }
  842. ////////////////////////////////////////////////////////////////////////////////////////////////////
  843. ////////////////////////////////////////////////////////////////////////////////////////////////////
  844. // 绘制单选框
  845. VOID WINAPI DrawRadioBoxXP(PCLASSXP pCxp)
  846. {
  847. int i;
  848. RECT Rect;
  849. MEMDCXP Mdcxp;
  850. HANDLE hHandle;
  851. char szTemp[256];
  852. COLORREF crColor;
  853. static COLORREF s_crGradientXP[][4] =
  854. {
  855. {0x00A5B2B5, 0x00CED7D6, 0x00CED7D6, 0x00DEEFF7},
  856. {0x00CEF3FF, 0x0063CBFF, 0x0063CBFF, 0x0031B2FF},
  857. {0x00D6DFDE, 0x00EFF3F7, 0x00EFF3F7, 0x00FFFFFF}
  858. };
  859. // 获取内存兼容设备场景
  860. Mdcxp.hWnd = pCxp->hWnd;
  861. Mdcxp.bTransfer = FALSE;
  862. Mdcxp.hBitmap = NULL;
  863. GetMemDCXP(&Mdcxp);
  864. // 获取窗口大小
  865. GetWindowRect(pCxp->hWnd, &Rect);
  866. Rect.right -= Rect.left;
  867. Rect.bottom -= Rect.top;
  868. Rect.left = Rect.top = 0;
  869. // 填充背景
  870. FillRect(Mdcxp.hMemDC, &Rect, GetSysColorBrush(COLOR_BTNFACE));
  871. // 画最外面的框
  872. Rect.left = 0;
  873. Rect.right = 13;
  874. Rect.top = (Rect.bottom - 13) / 2;
  875. Rect.bottom = Rect.top + 13;
  876. hHandle = (HANDLE) CreateSolidBrush(
  877. (pCxp->dwState & CXPS_DISABLED) ? (GetSysColor(COLOR_BTNFACE) - 0x00202020) : 0x00845118);
  878. FrameRect(Mdcxp.hMemDC, &Rect, (HBRUSH) hHandle);
  879. DeleteObject((HGDIOBJ) hHandle);
  880. // 画热点框渐变背景
  881. InflateRect(&Rect, -1, -1);
  882. if (pCxp->dwState & CXPS_DISABLED)
  883. FillRect(Mdcxp.hMemDC, &Rect, GetStockObject(WHITE_BRUSH));
  884. else
  885. {
  886. if (pCxp->dwState & CXPS_PRESSED)
  887. i = 0;
  888. else if (pCxp->dwState & CXPS_HOTLIGHT)
  889. i = 1;
  890. else
  891. i = 2;
  892. GradientRectXP(Mdcxp.hMemDC, &Rect, s_crGradientXP[i]);
  893. }
  894. // 画内框
  895. InflateRect(&Rect, -2, -2);
  896. if ((pCxp->dwState & CXPS_INDETERMINATE) ||
  897. ((pCxp->dwState & CXPS_HOTLIGHT) && (!(pCxp->dwState & CXPS_PRESSED))))
  898. {
  899. if (pCxp->dwState & CXPS_INDETERMINATE)
  900. {
  901. if (pCxp->dwState & CXPS_DISABLED)
  902. crColor = 0x00BDCBCE;
  903. else if (pCxp->dwState & CXPS_PRESSED)
  904. crColor = 0x00188A18;
  905. else if (pCxp->dwState & CXPS_HOTLIGHT)
  906. crColor = 0x0021A221;
  907. else
  908. crColor = 0x0073C373;
  909. }
  910. else if (pCxp->dwState & CXPS_CHECKED)
  911. crColor = 0x00F7F7F7;
  912. else
  913. crColor = 0x00E7E7E7;
  914. hHandle = (HANDLE) CreateSolidBrush(crColor);
  915. FillRect(Mdcxp.hMemDC, &Rect, (HBRUSH) hHandle);
  916. DeleteObject((HGDIOBJ) hHandle);
  917. }
  918. // 画框内选中标志
  919. if (pCxp->dwState & CXPS_CHECKED)
  920. {
  921. hHandle = (HANDLE) SelectObject(Mdcxp.hMemDC,
  922. CreatePen(PS_SOLID, 1, (pCxp->dwState & CXPS_DISABLED) ? 0x000BDCBCE : 0x0021A221));
  923. for (i = 3; i < 10; i++)
  924. {
  925. MoveToEx(Mdcxp.hMemDC, i, Rect.top + ((i < 6) ? i - 1 : (9 - i)), NULL);
  926. LineTo(Mdcxp.hMemDC, i, Rect.top + ((i < 6) ? i + 2 : (12 - i)));
  927. }
  928. DeleteObject(SelectObject(Mdcxp.hMemDC, (HGDIOBJ) hHandle));
  929. }
  930. // 画文字
  931. if (GetWindowText(pCxp->hWnd, szTemp, sizeof(szTemp)))
  932. {
  933. SetTextColor(Mdcxp.hMemDC, GetSysColor((pCxp->dwState & CXPS_DISABLED) ?  COLOR_GRAYTEXT: COLOR_BTNTEXT));
  934. hHandle = (HANDLE) SelectObject(Mdcxp.hMemDC,
  935. (HGDIOBJ) SendMessage(pCxp->hWnd, WM_GETFONT, 0, 0));
  936. Rect.left = 18;
  937. Rect.top -= 2;
  938. Rect.bottom = Rect.top + 1 + DrawText(Mdcxp.hMemDC, szTemp, -1, &Rect,
  939. DT_CALCRECT | DT_SINGLELINE | DT_VCENTER);
  940. DrawText(Mdcxp.hMemDC, szTemp, -1, &Rect, DT_SINGLELINE | DT_VCENTER);
  941. SelectObject(Mdcxp.hMemDC, (HGDIOBJ) hHandle);
  942. // 如果有焦点,画出焦点框
  943. if (pCxp->dwState & CXPS_FOCUS)
  944. {
  945. InflateRect(&Rect, 1, 1);
  946. DrawFocusRect(Mdcxp.hMemDC, &Rect);
  947. }
  948. }
  949. Mdcxp.bTransfer = TRUE;
  950. ReleaseMemDCXP(&Mdcxp);
  951. }
  952. ////////////////////////////////////////////////////////////////////////////////////////////////////
  953. ////////////////////////////////////////////////////////////////////////////////////////////////////
  954. // 绘制编辑框
  955. VOID WINAPI DrawEditBoxXP(PCLASSXP pCxp)
  956. {
  957. HDC hDC;
  958. RECT Rect;
  959. LONG lExStyle;
  960. HANDLE hHandle;
  961. lExStyle = GetWindowLong(pCxp->hWnd, GWL_EXSTYLE);
  962. if ((GetWindowLong(pCxp->hWnd, GWL_STYLE) & WS_BORDER) ||
  963. (lExStyle & WS_EX_CLIENTEDGE) || (lExStyle & WS_EX_STATICEDGE))
  964. {
  965. // 由于绘制的东西很少,所以直接绘制而不使用 MEMDCXP 方式
  966. hDC = GetWindowDC(pCxp->hWnd);
  967. // 获取窗口大小
  968. GetWindowRect(pCxp->hWnd, &Rect);
  969. Rect.right -= Rect.left;
  970. Rect.bottom -= Rect.top;
  971. Rect.top = Rect.left = 0;
  972. // 绘制外框
  973. hHandle = (HANDLE) CreateSolidBrush(
  974. (pCxp->dwState & CXPS_DISABLED) ? (GetSysColor(COLOR_BTNFACE) - 0x00202020) : 0x00BD9E7B);
  975. FrameRect(hDC, &Rect, (HBRUSH) hHandle);
  976. DeleteObject((HGDIOBJ) hHandle);
  977. // 绘制内框
  978. if ((lExStyle & WS_EX_CLIENTEDGE) || (lExStyle & WS_EX_STATICEDGE))
  979. {
  980. InflateRect(&Rect, -1, -1);
  981. hHandle = (HANDLE) GetSysColorBrush(
  982. (pCxp->dwState & CXPS_DISABLED) || (pCxp->dwState & CXPS_READONLY) ? COLOR_BTNFACE : COLOR_WINDOW);
  983. FrameRect(hDC, &Rect, (HBRUSH) hHandle);
  984. if ((lExStyle & WS_EX_CLIENTEDGE) && (lExStyle & WS_EX_STATICEDGE))
  985. {
  986. InflateRect(&Rect, -1, -1);
  987. FrameRect(hDC, &Rect, hHandle);
  988. }
  989. }
  990. // 释放设备场景
  991. ReleaseDC(pCxp->hWnd, hDC);
  992. }
  993. }
  994. ////////////////////////////////////////////////////////////////////////////////////////////////////
  995. ////////////////////////////////////////////////////////////////////////////////////////////////////
  996. // 绘制组合框
  997. VOID WINAPI DrawComboBoxXP(PCLASSXP pCxp)
  998. {
  999. int i;
  1000. RECT Rect;
  1001. MEMDCXP Mdcxp;
  1002. HANDLE hHandle;
  1003. static COLORREF s_crGradientXP[][4] =
  1004. {
  1005. {0x00EFF3F7, 0x00DEE7E7, 0x00DEE3E7, 0x00DEE3E7},
  1006. {0x00DEAEA5, 0x00F7CBBD, 0x00DE8273, 0x00F7C7B5},
  1007. {0x00EFC7B5, 0x00E7AE94, 0x00DEA284, 0x00DEA68C},
  1008. {0x00FFE3D6, 0x00F7CBBD, 0x00F7C3AD, 0x00F7C7B5},
  1009. {0x00F7F7F7, 0x00EFF3F7, 0x00EFF3F7, 0x00EFF3F7},
  1010. {0x00DEC3BD, 0x00DEB6AD, 0x00FFE3DE, 0x00F7E3DE},
  1011. {0x00EFDBCE, 0x00EFCFC6, 0x00E7CFC6, 0x00E7CBBD},
  1012. {0x00FFEFE7, 0x00FFE7DE, 0x00FFE3DE, 0x00F7E3DE},
  1013. {0x00F7F7F7, 0x00E7EFEF, 0x00E7EBEF, 0x00DEE7E7},
  1014. {0x00F78E6B, 0x00F79684, 0x00EF9E8C, 0x00EFDFD6},
  1015. {0x00FFFFFF, 0x00FFE3CE, 0x00FFDFC6, 0x00FFDBBD},
  1016. {0x00FFEBE7, 0x00FFCFBD, 0x00FFCBB5, 0x00F7CBAD}
  1017. };
  1018. // 获取内存兼容设备场景
  1019. Mdcxp.hWnd = pCxp->hWnd;
  1020. Mdcxp.bTransfer = TRUE;
  1021. Mdcxp.hBitmap = NULL;
  1022. GetMemDCXP(&Mdcxp);
  1023. // 获取窗口大小
  1024. GetWindowRect(pCxp->hWnd, &Rect);
  1025. Rect.right -= Rect.left;
  1026. Rect.bottom -= Rect.top;
  1027. Rect.top = Rect.left = 0;
  1028. /*if ((GetWindowLong(hWnd, GWL_STYLE) & 0x00000003) == CBS_SIMPLE)
  1029. {
  1030. GetWindow(hWnd, GW_CHILD);
  1031. // 还原并释放内存设备场景
  1032. Mdcxp.bTransfer = TRUE;
  1033. ReleaseMemDCXP(&Mdcxp);
  1034. }*/
  1035. // 绘制外框
  1036. hHandle = (HANDLE) CreateSolidBrush(
  1037. (pCxp->dwState & CXPS_DISABLED) ? (GetSysColor(COLOR_BTNFACE) - 0x00202020) : 0x00BD9E7B);
  1038. FrameRect(Mdcxp.hMemDC, &Rect, (HBRUSH) hHandle);
  1039. DeleteObject((HGDIOBJ) hHandle);
  1040. // 绘制内框
  1041. InflateRect(&Rect, -1, -1);
  1042. hHandle = (HANDLE) GetSysColorBrush((pCxp->dwState & CXPS_DISABLED) ? COLOR_BTNFACE : COLOR_WINDOW);
  1043. FrameRect(Mdcxp.hMemDC, &Rect, (HBRUSH) hHandle);
  1044. InflateRect(&Rect, -1, -1);
  1045. Rect.left = Rect.right - GetSystemMetrics(SM_CYVTHUMB);
  1046. FrameRect(Mdcxp.hMemDC, &Rect, (HBRUSH) hHandle);
  1047. Rect.left++;
  1048. if (pCxp->dwState & CXPS_DISABLED)
  1049. i = 0;
  1050. else if (pCxp->dwState & CXPS_PRESSED)
  1051. i = 1;
  1052. else if (pCxp->dwState & CXPS_HOTLIGHT)
  1053. i = 2;
  1054. else
  1055. i = 3;
  1056. // 绘制下拉外框
  1057. GradientRectXP(Mdcxp.hMemDC, &Rect, s_crGradientXP[i]);
  1058. // 绘制下拉外框拐角像素
  1059. SetPixel(Mdcxp.hMemDC, Rect.left, Rect.top, s_crGradientXP[i + 4][0]);
  1060. SetPixel(Mdcxp.hMemDC, Rect.right - 1, Rect.top, s_crGradientXP[i + 4][1]);
  1061. SetPixel(Mdcxp.hMemDC, Rect.left, Rect.bottom - 1, s_crGradientXP[i + 4][2]);
  1062. SetPixel(Mdcxp.hMemDC, Rect.right - 1, Rect.bottom - 1, s_crGradientXP[i + 4][3]);
  1063. // 绘制下拉内框
  1064. InflateRect(&Rect, -1, -1);
  1065. GradientRectXP(Mdcxp.hMemDC, &Rect, s_crGradientXP[i + 8]);
  1066. // 绘制下拉标志
  1067. Rect.left += (Rect.right - Rect.left) / 2;
  1068. Rect.top += (Rect.bottom - Rect.top) / 2;
  1069. hHandle = (HANDLE) SelectObject(Mdcxp.hMemDC,
  1070. CreatePen(PS_SOLID, 1, (pCxp->dwState & CXPS_DISABLED) ? 0x00C6CBCE : 0x0084614A));
  1071. MoveToEx(Mdcxp.hMemDC, Rect.left - 4, Rect.top - 2, NULL);
  1072. LineTo(Mdcxp.hMemDC, Rect.left, Rect.top + 2);
  1073. LineTo(Mdcxp.hMemDC, Rect.left + 5, Rect.top - 3);
  1074. MoveToEx(Mdcxp.hMemDC, Rect.left - 3, Rect.top - 2, NULL);
  1075. LineTo(Mdcxp.hMemDC, Rect.left, Rect.top + 1);
  1076. LineTo(Mdcxp.hMemDC, Rect.left + 4, Rect.top - 3);
  1077. MoveToEx(Mdcxp.hMemDC, Rect.left - 3, Rect.top - 3, NULL);
  1078. LineTo(Mdcxp.hMemDC, Rect.left, Rect.top);
  1079. LineTo(Mdcxp.hMemDC, Rect.left + 4, Rect.top - 4);
  1080. DeleteObject(SelectObject(Mdcxp.hMemDC, (HGDIOBJ) hHandle));
  1081. // 还原并释放内存设备场景
  1082. Mdcxp.bTransfer = TRUE;
  1083. ReleaseMemDCXP(&Mdcxp);
  1084. }
  1085. ////////////////////////////////////////////////////////////////////////////////////////////////////
  1086. ////////////////////////////////////////////////////////////////////////////////////////////////////
  1087. #ifdef __cplusplus
  1088. #endif // __cplusplus
  1089. ////////////////////////////////////////////////////////////////////////////////////////////////////