testcustdraw.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. #include "stdafx.h"
  2. #include <windows.h>
  3. #include <commctrl.h>
  4. #include "coolscroll.h"
  5. UINT CALLBACK CoolSB_DrawProc(HDC hdc, UINT uCmdId, UINT uButflags, RECT *rect);
  6. extern HWND hwndScroll;
  7. extern BOOL fCustomDraw ;
  8. extern BOOL fButtons ;
  9. extern BOOL fThumbAlways ;
  10. extern HDC hdcCoolSkin;
  11. HPEN hpen, oldpen;
  12. HPEN whitepen;
  13. HFONT hfont;
  14. HENHMETAFILE hemf=0;
  15. typedef struct
  16. {
  17. int x, y;
  18. int width, height;
  19. } CustomDrawTable;
  20. //
  21. // Define a set of structures which describe
  22. // where-abouts the source "textures" are in the
  23. // custom draw bitmap. We need to know x, y, width and height
  24. // for each scrollbar segment.
  25. //
  26. CustomDrawTable cdt_horz_normal[] =
  27. {
  28. { 0, 0, 16, 16 }, //left arrow NORMAL
  29. { 0, 17, 16, 16 }, //right arrow NORMAL
  30. { 0, 75, 1, 16 }, //page left NORMAL
  31. { 0, 75, 1, 16 }, //page right NORMAL
  32. { -1, -1, -1, -1 }, //padding
  33. { 48, 0, 3, 16 }, //horz thumb (left)复制
  34. { 52, 0, 8, 16 }, //horz thumb (middle)复制到中间
  35. { 61, 0, 3, 16 }, //horz thumb (right)复制
  36. { 50, 0, 2, 16 }, //horz thumb (bottom) 中间拉伸
  37. };
  38. CustomDrawTable cdt_horz_hot[] =
  39. {
  40. { 16, 0, 16, 16 }, //left arrow ACTIVE
  41. { 16, 18, 16, 16 }, //right arrow ACTIVE
  42. { 4, 75, 1, 16 }, //page left ACTIVE
  43. { 4, 75, 1, 16 }, //page right ACTIVE
  44. { -1, -1, -1, -1 }, //padding
  45. { 54, 17, 8, 16 }, //horz thumb (left)
  46. { 54+8, 17, 1, 16 }, //horz thumb (middle)
  47. { 54+8, 17, 8, 16 }, //horz thumb (right)
  48. };
  49. CustomDrawTable cdt_horz_active[] =
  50. {
  51. { 32, 0, 16, 16 }, //left arrow ACTIVE
  52. { 32, 17, 16, 16 }, //right arrow ACTIVE
  53. { 4, 75, 1, 16 }, //page left ACTIVE
  54. { 4, 75, 1, 16 }, //page right ACTIVE
  55. { -1, -1, -1, -1 }, //padding
  56. { 54, 32, 8, 16 }, //horz thumb (left)
  57. { 54+8, 32, 1, 16 }, //horz thumb (middle)
  58. { 54+8, 32, 8, 16 }, //horz thumb (right)
  59. };
  60. CustomDrawTable cdt_vert_normal[] =
  61. {
  62. { 64, 0, 16, 16 }, //up arrow NORMAL
  63. { 64, 16, 16, 16 }, //down arrow NORMAL
  64. { 0, 100, 16, 1 }, //page up NORMAL
  65. { 0, 100, 16, 1 }, //page down NORMAL
  66. { -1, -1, -1, -1 }, //padding
  67. { 112, 0, 16, 3 }, //vert thumb (top) 复制
  68. { 112, 4, 16, 8 }, //vert thumb (middle) 复制到中间
  69. { 112, 13, 16, 3 }, //vert thumb (bottom) 复制
  70. { 112, 2, 16, 2 }, //vert thumb (bottom) 中间拉伸
  71. // { 112, 0, 16, 8 }, //vert thumb (left)
  72. // { 112, 8, 16, 1 }, //vert thumb (middle)
  73. // { 112, 8, 16, 8 }, //vert thumb (right)
  74. };
  75. CustomDrawTable cdt_vert_hot[] =
  76. {
  77. { 80, 0, 16, 16 }, //up arrow ACTIVE
  78. { 80, 17, 16, 16 }, //down arrow ACTIVE
  79. { 4, 75, 16, 1 }, //page up ACTIVE
  80. { 4, 75, 16, 1 }, //page down ACTIVE
  81. { -1, -1, -1, -1 }, //padding
  82. { 112, 15, 16, 8 }, //vert thumb (left)
  83. { 112, 24, 16, 1 }, //vert thumb (middle)
  84. { 112, 24, 16, 8 }, //vert thumb (right)
  85. // { 112, 17, 16, 8 }, //vert thumb (left)
  86. // { 112, 26, 16, 1 }, //vert thumb (middle)
  87. // { 112, 26, 16, 8 }, //vert thumb (right)
  88. };
  89. CustomDrawTable cdt_vert_active[] =
  90. {
  91. { 96, 0, 16, 16 }, //up arrow ACTIVE
  92. { 96, 17, 16, 16 }, //down arrow ACTIVE
  93. { 4, 75, 16, 1 }, //page up ACTIVE
  94. { 4, 75, 16, 1 }, //page down ACTIVE
  95. { -1, -1, -1, -1 }, //padding
  96. { 112, 32, 16, 8 }, //vert thumb (left)
  97. { 112, 41, 16, 1 }, //vert thumb (middle)
  98. { 112, 41, 16, 8 }, //vert thumb (right)
  99. // { 112, 34, 16, 8 }, //vert thumb (left)
  100. // { 112, 43, 16, 1 }, //vert thumb (middle)
  101. // { 112, 43, 16, 8 }, //vert thumb (right)
  102. };
  103. LRESULT HandleCustomDraw(UINT ctrlid, NMCSBCUSTOMDRAW *nm)
  104. {
  105. RECT *rc;
  106. CustomDrawTable *cdt;
  107. UINT code = NM_CUSTOMDRAW;
  108. UNREFERENCED_PARAMETER(ctrlid);
  109. if(nm->dwDrawStage == CDDS_PREPAINT)
  110. {
  111. if(fCustomDraw)
  112. return CDRF_SKIPDEFAULT;
  113. else
  114. return CDRF_DODEFAULT;
  115. }
  116. //the sizing gripper in the bottom-right corner
  117. if(nm->nBar == SB_BOTH)
  118. {
  119. RECT *rc = &nm->rect;
  120. StretchBlt(nm->hdc, rc->left, rc->top, rc->right-rc->left, rc->bottom-rc->top,
  121. hdcCoolSkin, 90, 90, 16, 16, SRCCOPY);
  122. return CDRF_SKIPDEFAULT;
  123. }
  124. if(nm->nBar == SB_HORZ)
  125. {
  126. rc = &nm->rect;
  127. /*if(nm->uState == CDIS_HOT)
  128. cdt = &cdt_horz_hot[nm->uItem];
  129. else if(nm->uState == CDIS_SELECTED)
  130. cdt = &cdt_horz_active[nm->uItem];
  131. else*/
  132. cdt = &cdt_horz_normal[nm->uItem];
  133. if(nm->uItem == HTSCROLL_THUMB)
  134. {
  135. if(rc->bottom -rc->top >16)
  136. {
  137. rc->top =rc->bottom -16;
  138. rc->left -=1;
  139. rc->right +=1;
  140. }
  141. if(rc->right -rc->left <14)//滚动条高度太小,中间三条横线不画
  142. {
  143. if(rc->right -rc->left <3)
  144. {
  145. StretchBlt(nm->hdc, rc->left, rc->top, (rc->right-rc->left)/2, 16, hdcCoolSkin, cdt->x, cdt->y, cdt->width, cdt->height, SRCCOPY);
  146. cdt+=2;
  147. StretchBlt(nm->hdc, rc->left+(rc->right-rc->left)/2, rc->top,(rc->right-rc->left)/2,16,hdcCoolSkin, cdt->x, cdt->y, cdt->width, cdt->height, SRCCOPY);
  148. }
  149. else
  150. {
  151. StretchBlt(nm->hdc, rc->left, rc->top, 3, 16, hdcCoolSkin, cdt->x, cdt->y, cdt->width, cdt->height, SRCCOPY);
  152. cdt+=2;
  153. StretchBlt(nm->hdc, rc->right -3, rc->top , 3, 16, hdcCoolSkin, cdt->x, cdt->y, cdt->width, cdt->height, SRCCOPY);
  154. cdt++;
  155. StretchBlt(nm->hdc, rc->left+3, rc->top, rc->right -rc->left -6,16,hdcCoolSkin, cdt->x, cdt->y, cdt->width, cdt->height, SRCCOPY);
  156. }
  157. }
  158. else
  159. {
  160. StretchBlt(nm->hdc, rc->left, rc->top, 3, 16, hdcCoolSkin, cdt->x, cdt->y, cdt->width, cdt->height, SRCCOPY);
  161. cdt+=2;
  162. StretchBlt(nm->hdc, rc->right-3, rc->top , 3, 16, hdcCoolSkin, cdt->x, cdt->y, cdt->width, cdt->height, SRCCOPY);
  163. cdt++;
  164. StretchBlt(nm->hdc, rc->left+3, rc->top, rc->right-rc->left-6, 16, hdcCoolSkin, cdt->x, cdt->y, cdt->width, cdt->height, SRCCOPY);
  165. cdt-=2;
  166. StretchBlt(nm->hdc, rc->left+(rc->right -rc->left -8)/2, rc->top, 8, 16,hdcCoolSkin, cdt->x, cdt->y, cdt->width, cdt->height, SRCCOPY);
  167. }
  168. return CDRF_SKIPDEFAULT;
  169. }
  170. if(rc->bottom -rc->top >16)
  171. {
  172. rc->top =rc->bottom -16;
  173. if(nm->uItem==0)
  174. {
  175. rc->right -=1;
  176. }
  177. else if(nm->uItem==1)
  178. {
  179. rc->left +=1;
  180. }
  181. else if(nm->uItem==2)
  182. {
  183. rc->left -=1;
  184. }
  185. else if(nm->uItem==3)
  186. {
  187. rc->right +=1;
  188. }
  189. }
  190. }
  191. else if(nm->nBar == SB_VERT)
  192. {
  193. rc = &nm->rect;
  194. /* if(nm->uState == CDIS_HOT)
  195. cdt = &cdt_vert_hot[nm->uItem];
  196. else if(nm->uState == CDIS_SELECTED)
  197. cdt = &cdt_vert_active[nm->uItem];
  198. else*/
  199. cdt = &cdt_vert_normal[nm->uItem];
  200. if(nm->uItem == HTSCROLL_THUMB)
  201. {
  202. if(rc->right -rc->left >16)
  203. {
  204. rc->left =rc->right -16;
  205. rc->top-=1;
  206. rc->bottom +=1;
  207. }
  208. if(rc->bottom -rc->top <14)//滚动条高度太小,中间三条横线不画
  209. {
  210. if(rc->bottom -rc->top <3)
  211. {
  212. StretchBlt(nm->hdc, rc->left, rc->top, 16, (rc->bottom -rc->top)/2, hdcCoolSkin, cdt->x, cdt->y, cdt->width, cdt->height, SRCCOPY);
  213. cdt+=2;
  214. StretchBlt(nm->hdc, rc->left, rc->top+(rc->bottom -rc->top)/2, 16, (rc->bottom -rc->top)/2,hdcCoolSkin, cdt->x, cdt->y, cdt->width, cdt->height, SRCCOPY);
  215. }
  216. else
  217. {
  218. StretchBlt(nm->hdc, rc->left, rc->top, 16, 3, hdcCoolSkin, cdt->x, cdt->y, cdt->width, cdt->height, SRCCOPY);
  219. cdt+=2;
  220. StretchBlt(nm->hdc, rc->left, rc->bottom-3, 16, 3, hdcCoolSkin, cdt->x, cdt->y, cdt->width, cdt->height, SRCCOPY);
  221. cdt++;
  222. StretchBlt(nm->hdc, rc->left, rc->top+3, 16, rc->bottom -rc->top -6,hdcCoolSkin, cdt->x, cdt->y, cdt->width, cdt->height, SRCCOPY);
  223. }
  224. }
  225. else
  226. {
  227. StretchBlt(nm->hdc, rc->left, rc->top, 16, 3, hdcCoolSkin, cdt->x, cdt->y, cdt->width, cdt->height, SRCCOPY);
  228. cdt+=2;
  229. StretchBlt(nm->hdc, rc->left, rc->bottom-3, 16, 3, hdcCoolSkin, cdt->x, cdt->y, cdt->width, cdt->height, SRCCOPY);
  230. cdt++;
  231. StretchBlt(nm->hdc, rc->left, rc->top+3, 16, rc->bottom-rc->top-6,hdcCoolSkin, cdt->x, cdt->y, cdt->width, cdt->height, SRCCOPY);
  232. cdt-=2;
  233. StretchBlt(nm->hdc, rc->left, rc->top+(rc->bottom-rc->top-8)/2, 16, 8,hdcCoolSkin, cdt->x, cdt->y, cdt->width, cdt->height, SRCCOPY);
  234. }
  235. return CDRF_SKIPDEFAULT;
  236. }
  237. if(rc->right -rc->left >16)
  238. {
  239. rc->left =rc->right -16;
  240. if(nm->uItem==0)
  241. {
  242. rc->bottom -=1;
  243. }
  244. else if(nm->uItem==1)
  245. {
  246. rc->top +=1;
  247. }
  248. else if(nm->uItem==2)
  249. {
  250. rc->top -=1;
  251. }
  252. else if(nm->uItem==3)
  253. {
  254. rc->bottom +=1;
  255. }
  256. }
  257. }
  258. else
  259. {
  260. return CDRF_DODEFAULT;
  261. }
  262. //normal bitmaps, use same code for HORZ and VERT
  263. StretchBlt(nm->hdc, rc->left, rc->top, rc->right-rc->left, rc->bottom-rc->top,
  264. hdcCoolSkin, cdt->x, cdt->y, cdt->width, cdt->height, SRCCOPY);
  265. return CDRF_SKIPDEFAULT;
  266. }
  267. void DrawTab(HDC hdcEMF, int x, int tabwidth, int tabheight, int xslope, BOOL active)
  268. {
  269. POINT pts[4];
  270. pts[0].x = x + 0;
  271. pts[0].y = 0;
  272. pts[1].x = x + xslope;
  273. pts[1].y = tabheight;
  274. pts[2].x = x + tabwidth - xslope;
  275. pts[2].y = tabheight;
  276. pts[3].x = x + tabwidth;
  277. pts[3].y = 0;
  278. if(active)
  279. SelectObject(hdcEMF, GetStockObject(WHITE_BRUSH));
  280. else
  281. SelectObject(hdcEMF, GetSysColorBrush(COLOR_3DFACE));
  282. Polygon(hdcEMF, pts, 4);
  283. oldpen = (HPEN)SelectObject(hdcEMF, hpen);
  284. MoveToEx(hdcEMF, pts[1].x+1, pts[1].y, 0);
  285. LineTo(hdcEMF, pts[2].x, pts[2].y);
  286. if(active)
  287. SelectObject(hdcEMF, whitepen);
  288. MoveToEx(hdcEMF, pts[3].x - 1, pts[3].y, 0);
  289. LineTo(hdcEMF, pts[0].x, pts[0].y);
  290. SelectObject(hdcEMF, oldpen);
  291. }
  292. //
  293. // Draw a series of "tabs" into a meta-file,
  294. // which we will use to custom-draw one of the inserted
  295. // scrollbar buttons
  296. //
  297. void InitMetaFile(void)
  298. {
  299. HDC hdcEMF;
  300. RECT rect;
  301. int totalwidth = 120;
  302. int width = 110, height = GetSystemMetrics(SM_CYHSCROLL);
  303. LOGFONT lf;
  304. POINT pts[4];
  305. int tabwidth = 40, tabxslope = 5;
  306. pts[0].x = 0;
  307. pts[0].y = 0;
  308. pts[1].x = tabxslope;
  309. pts[1].y = height - 1;
  310. pts[2].x = tabwidth - tabxslope;
  311. pts[2].y = height - 1;
  312. pts[3].x = tabwidth;
  313. pts[3].y = 0;
  314. hpen = CreatePen(PS_SOLID,0,GetSysColor(COLOR_3DSHADOW));
  315. whitepen = CreatePen(PS_INSIDEFRAME,0,RGB(0xff,0xff,0xff));
  316. SetRect(&rect, 0, 0, totalwidth, height+1);
  317. hdcEMF = CreateEnhMetaFile(NULL, NULL, NULL, NULL);
  318. ZeroMemory(&lf, sizeof(lf));
  319. lf.lfHeight = -MulDiv(7, GetDeviceCaps(hdcEMF, LOGPIXELSY), 72);
  320. lf.lfPitchAndFamily = DEFAULT_PITCH;
  321. lf.lfCharSet = ANSI_CHARSET;
  322. lstrcpy(lf.lfFaceName, "Arial");//Small fonts");
  323. hfont = CreateFontIndirect(&lf);
  324. pts[0].x = 0;
  325. pts[0].y = 0;
  326. pts[1].x = tabxslope;
  327. pts[1].y = height - 1;
  328. pts[2].x = tabwidth - tabxslope;
  329. pts[2].y = height - 1;
  330. pts[3].x = tabwidth;
  331. pts[3].y = 0;
  332. FillRect (hdcEMF, &rect, GetSysColorBrush(COLOR_3DFACE));//GetStockObject(WHITE_BRUSH);
  333. //fit as many lines in as space permits
  334. SelectObject(hdcEMF, GetSysColorBrush(COLOR_3DFACE));
  335. DrawTab(hdcEMF, width-tabwidth, tabwidth, height - 1, tabxslope, FALSE);
  336. DrawTab(hdcEMF, width-tabwidth-tabwidth+tabxslope, tabwidth, height - 1, tabxslope, FALSE);
  337. DrawTab(hdcEMF, 0, tabwidth, height - 1, tabxslope, TRUE);
  338. SelectObject(hdcEMF, hpen);
  339. MoveToEx(hdcEMF, 110, 0, 0);
  340. LineTo(hdcEMF, totalwidth, 0);
  341. SelectObject(hdcEMF, hfont);
  342. SetBkMode(hdcEMF, TRANSPARENT);
  343. TextOut(hdcEMF, 10,1, "Build", 5);
  344. TextOut(hdcEMF, 42,1, "Debug", 5);
  345. TextOut(hdcEMF, 78,1, "Result", 6);
  346. SelectObject(hdcEMF, oldpen);
  347. DeleteObject(hpen);
  348. DeleteObject(whitepen);
  349. hemf = CloseEnhMetaFile(hdcEMF);
  350. }