#include "stdafx.h" #include #include #include "coolscroll.h" UINT CALLBACK CoolSB_DrawProc(HDC hdc, UINT uCmdId, UINT uButflags, RECT *rect); extern HWND hwndScroll; extern BOOL fCustomDraw ; extern BOOL fButtons ; extern BOOL fThumbAlways ; extern HDC hdcCoolSkin; HPEN hpen, oldpen; HPEN whitepen; HFONT hfont; HENHMETAFILE hemf=0; typedef struct { int x, y; int width, height; } CustomDrawTable; // // Define a set of structures which describe // where-abouts the source "textures" are in the // custom draw bitmap. We need to know x, y, width and height // for each scrollbar segment. // CustomDrawTable cdt_horz_normal[] = { { 0, 0, 16, 16 }, //left arrow NORMAL { 0, 17, 16, 16 }, //right arrow NORMAL { 0, 75, 1, 16 }, //page left NORMAL { 0, 75, 1, 16 }, //page right NORMAL { -1, -1, -1, -1 }, //padding { 48, 0, 3, 16 }, //horz thumb (left)复制 { 52, 0, 8, 16 }, //horz thumb (middle)复制到中间 { 61, 0, 3, 16 }, //horz thumb (right)复制 { 50, 0, 2, 16 }, //horz thumb (bottom) 中间拉伸 }; CustomDrawTable cdt_horz_hot[] = { { 16, 0, 16, 16 }, //left arrow ACTIVE { 16, 18, 16, 16 }, //right arrow ACTIVE { 4, 75, 1, 16 }, //page left ACTIVE { 4, 75, 1, 16 }, //page right ACTIVE { -1, -1, -1, -1 }, //padding { 54, 17, 8, 16 }, //horz thumb (left) { 54+8, 17, 1, 16 }, //horz thumb (middle) { 54+8, 17, 8, 16 }, //horz thumb (right) }; CustomDrawTable cdt_horz_active[] = { { 32, 0, 16, 16 }, //left arrow ACTIVE { 32, 17, 16, 16 }, //right arrow ACTIVE { 4, 75, 1, 16 }, //page left ACTIVE { 4, 75, 1, 16 }, //page right ACTIVE { -1, -1, -1, -1 }, //padding { 54, 32, 8, 16 }, //horz thumb (left) { 54+8, 32, 1, 16 }, //horz thumb (middle) { 54+8, 32, 8, 16 }, //horz thumb (right) }; CustomDrawTable cdt_vert_normal[] = { { 64, 0, 16, 16 }, //up arrow NORMAL { 64, 16, 16, 16 }, //down arrow NORMAL { 0, 100, 16, 1 }, //page up NORMAL { 0, 100, 16, 1 }, //page down NORMAL { -1, -1, -1, -1 }, //padding { 112, 0, 16, 3 }, //vert thumb (top) 复制 { 112, 4, 16, 8 }, //vert thumb (middle) 复制到中间 { 112, 13, 16, 3 }, //vert thumb (bottom) 复制 { 112, 2, 16, 2 }, //vert thumb (bottom) 中间拉伸 // { 112, 0, 16, 8 }, //vert thumb (left) // { 112, 8, 16, 1 }, //vert thumb (middle) // { 112, 8, 16, 8 }, //vert thumb (right) }; CustomDrawTable cdt_vert_hot[] = { { 80, 0, 16, 16 }, //up arrow ACTIVE { 80, 17, 16, 16 }, //down arrow ACTIVE { 4, 75, 16, 1 }, //page up ACTIVE { 4, 75, 16, 1 }, //page down ACTIVE { -1, -1, -1, -1 }, //padding { 112, 15, 16, 8 }, //vert thumb (left) { 112, 24, 16, 1 }, //vert thumb (middle) { 112, 24, 16, 8 }, //vert thumb (right) // { 112, 17, 16, 8 }, //vert thumb (left) // { 112, 26, 16, 1 }, //vert thumb (middle) // { 112, 26, 16, 8 }, //vert thumb (right) }; CustomDrawTable cdt_vert_active[] = { { 96, 0, 16, 16 }, //up arrow ACTIVE { 96, 17, 16, 16 }, //down arrow ACTIVE { 4, 75, 16, 1 }, //page up ACTIVE { 4, 75, 16, 1 }, //page down ACTIVE { -1, -1, -1, -1 }, //padding { 112, 32, 16, 8 }, //vert thumb (left) { 112, 41, 16, 1 }, //vert thumb (middle) { 112, 41, 16, 8 }, //vert thumb (right) // { 112, 34, 16, 8 }, //vert thumb (left) // { 112, 43, 16, 1 }, //vert thumb (middle) // { 112, 43, 16, 8 }, //vert thumb (right) }; LRESULT HandleCustomDraw(UINT ctrlid, NMCSBCUSTOMDRAW *nm) { RECT *rc; CustomDrawTable *cdt; UINT code = NM_CUSTOMDRAW; UNREFERENCED_PARAMETER(ctrlid); if(nm->dwDrawStage == CDDS_PREPAINT) { if(fCustomDraw) return CDRF_SKIPDEFAULT; else return CDRF_DODEFAULT; } //the sizing gripper in the bottom-right corner if(nm->nBar == SB_BOTH) { RECT *rc = &nm->rect; StretchBlt(nm->hdc, rc->left, rc->top, rc->right-rc->left, rc->bottom-rc->top, hdcCoolSkin, 90, 90, 16, 16, SRCCOPY); return CDRF_SKIPDEFAULT; } if(nm->nBar == SB_HORZ) { rc = &nm->rect; /*if(nm->uState == CDIS_HOT) cdt = &cdt_horz_hot[nm->uItem]; else if(nm->uState == CDIS_SELECTED) cdt = &cdt_horz_active[nm->uItem]; else*/ cdt = &cdt_horz_normal[nm->uItem]; if(nm->uItem == HTSCROLL_THUMB) { if(rc->bottom -rc->top >16) { rc->top =rc->bottom -16; rc->left -=1; rc->right +=1; } if(rc->right -rc->left <14)//滚动条高度太小,中间三条横线不画 { if(rc->right -rc->left <3) { StretchBlt(nm->hdc, rc->left, rc->top, (rc->right-rc->left)/2, 16, hdcCoolSkin, cdt->x, cdt->y, cdt->width, cdt->height, SRCCOPY); cdt+=2; 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); } else { StretchBlt(nm->hdc, rc->left, rc->top, 3, 16, hdcCoolSkin, cdt->x, cdt->y, cdt->width, cdt->height, SRCCOPY); cdt+=2; StretchBlt(nm->hdc, rc->right -3, rc->top , 3, 16, hdcCoolSkin, cdt->x, cdt->y, cdt->width, cdt->height, SRCCOPY); cdt++; StretchBlt(nm->hdc, rc->left+3, rc->top, rc->right -rc->left -6,16,hdcCoolSkin, cdt->x, cdt->y, cdt->width, cdt->height, SRCCOPY); } } else { StretchBlt(nm->hdc, rc->left, rc->top, 3, 16, hdcCoolSkin, cdt->x, cdt->y, cdt->width, cdt->height, SRCCOPY); cdt+=2; StretchBlt(nm->hdc, rc->right-3, rc->top , 3, 16, hdcCoolSkin, cdt->x, cdt->y, cdt->width, cdt->height, SRCCOPY); cdt++; StretchBlt(nm->hdc, rc->left+3, rc->top, rc->right-rc->left-6, 16, hdcCoolSkin, cdt->x, cdt->y, cdt->width, cdt->height, SRCCOPY); cdt-=2; 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); } return CDRF_SKIPDEFAULT; } if(rc->bottom -rc->top >16) { rc->top =rc->bottom -16; if(nm->uItem==0) { rc->right -=1; } else if(nm->uItem==1) { rc->left +=1; } else if(nm->uItem==2) { rc->left -=1; } else if(nm->uItem==3) { rc->right +=1; } } } else if(nm->nBar == SB_VERT) { rc = &nm->rect; /* if(nm->uState == CDIS_HOT) cdt = &cdt_vert_hot[nm->uItem]; else if(nm->uState == CDIS_SELECTED) cdt = &cdt_vert_active[nm->uItem]; else*/ cdt = &cdt_vert_normal[nm->uItem]; if(nm->uItem == HTSCROLL_THUMB) { if(rc->right -rc->left >16) { rc->left =rc->right -16; rc->top-=1; rc->bottom +=1; } if(rc->bottom -rc->top <14)//滚动条高度太小,中间三条横线不画 { if(rc->bottom -rc->top <3) { StretchBlt(nm->hdc, rc->left, rc->top, 16, (rc->bottom -rc->top)/2, hdcCoolSkin, cdt->x, cdt->y, cdt->width, cdt->height, SRCCOPY); cdt+=2; 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); } else { StretchBlt(nm->hdc, rc->left, rc->top, 16, 3, hdcCoolSkin, cdt->x, cdt->y, cdt->width, cdt->height, SRCCOPY); cdt+=2; StretchBlt(nm->hdc, rc->left, rc->bottom-3, 16, 3, hdcCoolSkin, cdt->x, cdt->y, cdt->width, cdt->height, SRCCOPY); cdt++; StretchBlt(nm->hdc, rc->left, rc->top+3, 16, rc->bottom -rc->top -6,hdcCoolSkin, cdt->x, cdt->y, cdt->width, cdt->height, SRCCOPY); } } else { StretchBlt(nm->hdc, rc->left, rc->top, 16, 3, hdcCoolSkin, cdt->x, cdt->y, cdt->width, cdt->height, SRCCOPY); cdt+=2; StretchBlt(nm->hdc, rc->left, rc->bottom-3, 16, 3, hdcCoolSkin, cdt->x, cdt->y, cdt->width, cdt->height, SRCCOPY); cdt++; StretchBlt(nm->hdc, rc->left, rc->top+3, 16, rc->bottom-rc->top-6,hdcCoolSkin, cdt->x, cdt->y, cdt->width, cdt->height, SRCCOPY); cdt-=2; 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); } return CDRF_SKIPDEFAULT; } if(rc->right -rc->left >16) { rc->left =rc->right -16; if(nm->uItem==0) { rc->bottom -=1; } else if(nm->uItem==1) { rc->top +=1; } else if(nm->uItem==2) { rc->top -=1; } else if(nm->uItem==3) { rc->bottom +=1; } } } else { return CDRF_DODEFAULT; } //normal bitmaps, use same code for HORZ and VERT StretchBlt(nm->hdc, rc->left, rc->top, rc->right-rc->left, rc->bottom-rc->top, hdcCoolSkin, cdt->x, cdt->y, cdt->width, cdt->height, SRCCOPY); return CDRF_SKIPDEFAULT; } void DrawTab(HDC hdcEMF, int x, int tabwidth, int tabheight, int xslope, BOOL active) { POINT pts[4]; pts[0].x = x + 0; pts[0].y = 0; pts[1].x = x + xslope; pts[1].y = tabheight; pts[2].x = x + tabwidth - xslope; pts[2].y = tabheight; pts[3].x = x + tabwidth; pts[3].y = 0; if(active) SelectObject(hdcEMF, GetStockObject(WHITE_BRUSH)); else SelectObject(hdcEMF, GetSysColorBrush(COLOR_3DFACE)); Polygon(hdcEMF, pts, 4); oldpen = (HPEN)SelectObject(hdcEMF, hpen); MoveToEx(hdcEMF, pts[1].x+1, pts[1].y, 0); LineTo(hdcEMF, pts[2].x, pts[2].y); if(active) SelectObject(hdcEMF, whitepen); MoveToEx(hdcEMF, pts[3].x - 1, pts[3].y, 0); LineTo(hdcEMF, pts[0].x, pts[0].y); SelectObject(hdcEMF, oldpen); } // // Draw a series of "tabs" into a meta-file, // which we will use to custom-draw one of the inserted // scrollbar buttons // void InitMetaFile(void) { HDC hdcEMF; RECT rect; int totalwidth = 120; int width = 110, height = GetSystemMetrics(SM_CYHSCROLL); LOGFONT lf; POINT pts[4]; int tabwidth = 40, tabxslope = 5; pts[0].x = 0; pts[0].y = 0; pts[1].x = tabxslope; pts[1].y = height - 1; pts[2].x = tabwidth - tabxslope; pts[2].y = height - 1; pts[3].x = tabwidth; pts[3].y = 0; hpen = CreatePen(PS_SOLID,0,GetSysColor(COLOR_3DSHADOW)); whitepen = CreatePen(PS_INSIDEFRAME,0,RGB(0xff,0xff,0xff)); SetRect(&rect, 0, 0, totalwidth, height+1); hdcEMF = CreateEnhMetaFile(NULL, NULL, NULL, NULL); ZeroMemory(&lf, sizeof(lf)); lf.lfHeight = -MulDiv(7, GetDeviceCaps(hdcEMF, LOGPIXELSY), 72); lf.lfPitchAndFamily = DEFAULT_PITCH; lf.lfCharSet = ANSI_CHARSET; lstrcpy(lf.lfFaceName, "Arial");//Small fonts"); hfont = CreateFontIndirect(&lf); pts[0].x = 0; pts[0].y = 0; pts[1].x = tabxslope; pts[1].y = height - 1; pts[2].x = tabwidth - tabxslope; pts[2].y = height - 1; pts[3].x = tabwidth; pts[3].y = 0; FillRect (hdcEMF, &rect, GetSysColorBrush(COLOR_3DFACE));//GetStockObject(WHITE_BRUSH); //fit as many lines in as space permits SelectObject(hdcEMF, GetSysColorBrush(COLOR_3DFACE)); DrawTab(hdcEMF, width-tabwidth, tabwidth, height - 1, tabxslope, FALSE); DrawTab(hdcEMF, width-tabwidth-tabwidth+tabxslope, tabwidth, height - 1, tabxslope, FALSE); DrawTab(hdcEMF, 0, tabwidth, height - 1, tabxslope, TRUE); SelectObject(hdcEMF, hpen); MoveToEx(hdcEMF, 110, 0, 0); LineTo(hdcEMF, totalwidth, 0); SelectObject(hdcEMF, hfont); SetBkMode(hdcEMF, TRANSPARENT); TextOut(hdcEMF, 10,1, "Build", 5); TextOut(hdcEMF, 42,1, "Debug", 5); TextOut(hdcEMF, 78,1, "Result", 6); SelectObject(hdcEMF, oldpen); DeleteObject(hpen); DeleteObject(whitepen); hemf = CloseEnhMetaFile(hdcEMF); }