ComboXP.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. // ComboXP.cpp: implementation of the CComboXP class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. /**************以下设置必需包含在每个子类中**********************/
  5. //头部
  6. ////////////////////////////////////////////////////////////////////////////////////////////////////
  7. // 编译预处理
  8. #if _WIN32_WINNT < 0x0400
  9. #define _WIN32_WINNT 0x0400
  10. #endif
  11. // 强制使用 C 语言方式编译
  12. #ifdef __cplusplus
  13. extern "C"
  14. {
  15. #endif // __cplusplus
  16. #include "ComboXP.h"
  17. #include "ScrollXP.H"
  18. //////////////////////////////////////////////////////////////////////////////////////////////////
  19. // 全局变量
  20. extern HHOOK g_hPrevHookXP ; // 窗口消息 HOOK 句柄
  21. extern PCLASSXP g_pClassXP ; // 窗口的 CLASSXP 结构指针
  22. extern COLORREF g_crDialogbkColor; // 窗口背景颜色
  23. //////////////////////////////////////////////////////////////
  24. ////////////////////////////////////////////////////////////////////////////////////////////////////
  25. // 绘制组合框
  26. VOID WINAPI ComboDrawComboBoxXP(PCLASSXP pCxp)
  27. {
  28. /* int i;
  29. RECT Rect;
  30. MEMDCXP Mdcxp;
  31. HANDLE hHandle;
  32. static COLORREF s_crGradientXP[][4] =
  33. {
  34. {0x00EFF3F7, 0x00DEE7E7, 0x00DEE3E7, 0x00DEE3E7},
  35. {0x00DEAEA5, 0x00F7CBBD, 0x00DE8273, 0x00F7C7B5},
  36. {0x00EFC7B5, 0x00E7AE94, 0x00DEA284, 0x00DEA68C},
  37. {0x00FFE3D6, 0x00F7CBBD, 0x00F7C3AD, 0x00F7C7B5},
  38. {0x00F7F7F7, 0x00EFF3F7, 0x00EFF3F7, 0x00EFF3F7},
  39. {0x00DEC3BD, 0x00DEB6AD, 0x00FFE3DE, 0x00F7E3DE},
  40. {0x00EFDBCE, 0x00EFCFC6, 0x00E7CFC6, 0x00E7CBBD},
  41. {0x00FFEFE7, 0x00FFE7DE, 0x00FFE3DE, 0x00F7E3DE},
  42. {0x00F7F7F7, 0x00E7EFEF, 0x00E7EBEF, 0x00DEE7E7},
  43. {0x00F78E6B, 0x00F79684, 0x00EF9E8C, 0x00EFDFD6},
  44. {0x00FFFFFF, 0x00FFE3CE, 0x00FFDFC6, 0x00FFDBBD},
  45. {0x00FFEBE7, 0x00FFCFBD, 0x00FFCBB5, 0x00F7CBAD}
  46. };
  47. // 获取内存兼容设备场景
  48. Mdcxp.hWnd = pCxp->hWnd;
  49. Mdcxp.bTransfer = TRUE;
  50. Mdcxp.hBitmap = NULL;
  51. GetMemDCXP(&Mdcxp);
  52. // 获取窗口大小
  53. GetWindowRect(pCxp->hWnd, &Rect);
  54. Rect.right -= Rect.left;
  55. Rect.bottom -= Rect.top;
  56. Rect.top = Rect.left = 0;
  57. // 绘制外框
  58. hHandle = (HANDLE) CreateSolidBrush(
  59. (pCxp->dwState & CXPS_DISABLED) ? (GetSysColor(COLOR_BTNFACE) - 0x00202020) : 0x00BD9E7B);
  60. FrameRect(Mdcxp.hMemDC, &Rect, (HBRUSH) hHandle);
  61. DeleteObject((HGDIOBJ) hHandle);
  62. // 绘制内框
  63. InflateRect(&Rect, -1, -1);
  64. // hHandle = (HANDLE) GetSysColorBrush((pCxp->dwState & CXPS_DISABLED) ? COLOR_BTNFACE : COLOR_WINDOW);
  65. if (pCxp->dwState & CXPS_DISABLED)
  66. hHandle = (HANDLE) GetSysColorBrush(g_crDialogbkColor);
  67. else
  68. hHandle = (HANDLE) GetSysColorBrush(COLOR_WINDOW);
  69. FrameRect(Mdcxp.hMemDC, &Rect, (HBRUSH) hHandle);
  70. InflateRect(&Rect, -1, -1);
  71. Rect.left = Rect.right - GetSystemMetrics(SM_CYVTHUMB);
  72. FrameRect(Mdcxp.hMemDC, &Rect, (HBRUSH) hHandle);
  73. Rect.left++;
  74. if (pCxp->dwState & CXPS_DISABLED)
  75. i = 0;
  76. else if (pCxp->dwState & CXPS_PRESSED)
  77. i = 1;
  78. else if (pCxp->dwState & CXPS_HOTLIGHT)
  79. i = 2;
  80. else
  81. i = 3;
  82. // 绘制下拉外框
  83. GradientRectXP(Mdcxp.hMemDC, &Rect, s_crGradientXP[i]);
  84. // 绘制下拉外框拐角像素
  85. SetPixel(Mdcxp.hMemDC, Rect.left, Rect.top, s_crGradientXP[i + 4][0]);
  86. SetPixel(Mdcxp.hMemDC, Rect.right - 1, Rect.top, s_crGradientXP[i + 4][1]);
  87. SetPixel(Mdcxp.hMemDC, Rect.left, Rect.bottom - 1, s_crGradientXP[i + 4][2]);
  88. SetPixel(Mdcxp.hMemDC, Rect.right - 1, Rect.bottom - 1, s_crGradientXP[i + 4][3]);
  89. // 绘制下拉内框
  90. InflateRect(&Rect, -1, -1);
  91. GradientRectXP(Mdcxp.hMemDC, &Rect, s_crGradientXP[i + 8]);
  92. // 绘制下拉标志
  93. Rect.left += (Rect.right - Rect.left) / 2;
  94. Rect.top += (Rect.bottom - Rect.top) / 2;
  95. hHandle = (HANDLE) SelectObject(Mdcxp.hMemDC,
  96. CreatePen(PS_SOLID, 1, (pCxp->dwState & CXPS_DISABLED) ? 0x00C6CBCE : 0x0084614A));
  97. MoveToEx(Mdcxp.hMemDC, Rect.left - 4, Rect.top - 2, NULL);
  98. LineTo(Mdcxp.hMemDC, Rect.left, Rect.top + 2);
  99. LineTo(Mdcxp.hMemDC, Rect.left + 5, Rect.top - 3);
  100. MoveToEx(Mdcxp.hMemDC, Rect.left - 3, Rect.top - 2, NULL);
  101. LineTo(Mdcxp.hMemDC, Rect.left, Rect.top + 1);
  102. LineTo(Mdcxp.hMemDC, Rect.left + 4, Rect.top - 3);
  103. MoveToEx(Mdcxp.hMemDC, Rect.left - 3, Rect.top - 3, NULL);
  104. LineTo(Mdcxp.hMemDC, Rect.left, Rect.top);
  105. LineTo(Mdcxp.hMemDC, Rect.left + 4, Rect.top - 4);
  106. DeleteObject(SelectObject(Mdcxp.hMemDC, (HGDIOBJ) hHandle));
  107. // 还原并释放内存设备场景
  108. Mdcxp.bTransfer = TRUE;
  109. ReleaseMemDCXP(&Mdcxp);
  110. */
  111. RECT Rect;
  112. MEMDCXP Mdcxp;
  113. HANDLE hHandle;
  114. // 获取窗口大小
  115. GetWindowRect(pCxp->hWnd, &Rect);
  116. Rect.right -= Rect.left;
  117. Rect.bottom -= Rect.top;
  118. Rect.top = Rect.left = 0;
  119. //在WIN98下会把箭头绘到下拉窗口中
  120. if (Rect.bottom>2*GetSystemMetrics(SM_CYVTHUMB))
  121. return;
  122. // 获取内存兼容设备场景
  123. Mdcxp.hWnd = pCxp->hWnd;
  124. Mdcxp.bTransfer = TRUE;
  125. Mdcxp.hBitmap = NULL;
  126. GetMemDCXP(&Mdcxp);
  127. #ifdef CXP_BKCOLOR
  128. hHandle = (HANDLE) CreateSolidBrush(
  129. (pCxp->lState & CXPS_DISABLED) ? (CXP_BKCOLOR - 0x00202020) : 0x00BD9E7B);
  130. #else // CXP_BKCOLOR
  131. hHandle = (HANDLE) CreateSolidBrush(
  132. (pCxp->dwState & CXPS_DISABLED) ? (GetSysColor(COLOR_BTNFACE) - 0x00202020) : 0x00BD9E7B);
  133. #endif // CXP_BKCOLOR
  134. // 绘制外框
  135. FrameRect(Mdcxp.hMemDC, &Rect, (HBRUSH) hHandle);
  136. DeleteObject((HGDIOBJ) hHandle);
  137. // 绘制内框
  138. InflateRect(&Rect, -1, -1);
  139. #ifdef CXP_BKCOLOR
  140. hHandle = (HANDLE) CreateSolidBrush(
  141. (pCxp->dwState & CXPS_DISABLED) ? CXP_BKCOLOR : GetSysColor(COLOR_WINDOW));
  142. #else // CXP_BKCOLOR
  143. hHandle = (HANDLE) GetSysColorBrush(
  144. (pCxp->dwState & CXPS_DISABLED) ? COLOR_BTNFACE : COLOR_WINDOW);
  145. #endif // CXP_BKCOLOR
  146. FrameRect(Mdcxp.hMemDC, &Rect, (HBRUSH) hHandle);
  147. InflateRect(&Rect, -1, -1);
  148. Rect.left = Rect.right - GetSystemMetrics(SM_CYVTHUMB);
  149. FrameRect(Mdcxp.hMemDC, &Rect, (HBRUSH) hHandle);
  150. #ifdef CXP_BKCOLOR
  151. DeleteObject(hHandle);
  152. #endif // CXP_BKCOLOR
  153. Rect.left++;
  154. ScrollDrowThumbXP(Mdcxp.hMemDC, Rect, pCxp->dwState | CXPH_DOWNWARDS | CXPH_LARGEARROW);
  155. //MoveToEx(Mdcxp.hMemDC, 0, 0);
  156. /*if (pCxp->iType == CXPT_COMBOBOX)
  157. {
  158. char szTemp[1024];
  159. HDC h = GetWindowDC(NULL);
  160. wsprintf(szTemp, "%d", Sbi.dxyLineButton);
  161. TextOut(h, 100, 100, szTemp, lstrlen(szTemp));
  162. ReleaseDC(NULL, h);
  163. }
  164. if (GetWindowLong(pCxp->hWnd, GWL_STYLE) & CBS_AUTOHSCROLL )
  165. {
  166. pCxp->lState &= ~CXPS_HORIZON;
  167. ScrollBarXP(Mdcxp.hMemDC, pCxp);
  168. }*/
  169. // 还原并释放内存设备场景
  170. Mdcxp.bTransfer = TRUE;
  171. ReleaseMemDCXP(&Mdcxp);
  172. }
  173. BOOL WINAPI ComboOnMouseDown(PCLASSXP pCxp)
  174. {
  175. RECT Rect;
  176. POINT point;
  177. // 获取窗口大小
  178. GetWindowRect(pCxp->hWnd, &Rect);
  179. Rect.right -= Rect.left;
  180. Rect.bottom -= Rect.top;
  181. Rect.top = Rect.left = 0;
  182. GetCursorPos(&point);
  183. Rect.left = Rect.right - 2 * GetSystemMetrics(SM_CYVTHUMB);
  184. if(Rect.left < 0) Rect.left = 0;
  185. ScreenToClient(pCxp->hWnd, &point);
  186. if(!PtInRect(&Rect,point)) return FALSE;
  187. pCxp->dwState |= CXPS_PRESSED;
  188. ComboDrawComboBoxXP(pCxp);
  189. Sleep(300);
  190. pCxp->dwState &= ~CXPS_PRESSED;
  191. ComboDrawComboBoxXP(pCxp);
  192. return TRUE;
  193. //
  194. }
  195. /****************************************************************/
  196. LRESULT ComboWindowProc(PCLASSXP pCxp, UINT message,WPARAM wParam, LPARAM lParam)
  197. {
  198. LONG lReturn;
  199. POINT point;
  200. HWND hWnd = pCxp->hWnd;
  201. switch (message)
  202. {
  203. case WM_NCPAINT:
  204. case WM_PAINT:
  205. lReturn = (LONG) CallWindowProc(pCxp->wpPrev, hWnd, message, wParam, lParam);
  206. //lReturn = DefWindowProc(hWnd, message, wParam, lParam);
  207. ComboDrawComboBoxXP(pCxp);
  208. return lReturn;
  209. case WM_NCLBUTTONDOWN:
  210. return 0;
  211. case WM_LBUTTONDOWN:
  212. ComboOnMouseDown(pCxp);
  213. lReturn = (LONG) CallWindowProc(pCxp->wpPrev, hWnd, message, wParam, lParam);
  214. return lReturn;
  215. case WM_LBUTTONUP:
  216. pCxp->dwState &= ~CXPS_PRESSED;
  217. lReturn = (LONG) CallWindowProc(pCxp->wpPrev, hWnd, message, wParam, lParam);
  218. ComboDrawComboBoxXP(pCxp);
  219. return lReturn;
  220. //lReturn = DefWindowProc(hWnd, message, wParam, lParam);
  221. break;
  222. }
  223. // 调用原来的回调函数
  224. lReturn = (LONG) CallWindowProc(pCxp->wpPrev, hWnd, message, wParam, lParam);
  225. if (message == WM_NCDESTROY) // 窗口销毁
  226. DeleteClassXP(hWnd);
  227. return lReturn;
  228. }
  229. /**************以下设置必需包含在每个子类中**********************/
  230. //尾部
  231. #ifdef __cplusplus
  232. }
  233. #endif // __cplusplus
  234. /*****************************************************************/