📄 coolscroll.c
字号:
SetRect(&ctrl, rect->right - butwidth, rect->top, rect->right, rect->bottom);
RotateRect0(sb, &ctrl);
if(fCustomDraw)
PostCustomDrawNotify(hwnd, hdc, sb->nBarType, &ctrl, SB_LINERIGHT, fMouseDownR, fMouseOverR, uRightButFlags & DFCS_INACTIVE);
else
DrawScrollArrow(sb, hdc, &ctrl, uRightButFlags, fMouseDownR, fMouseOverR);
RotateRect0(sb, &ctrl);
}
//not enough room for the scrollbar, so just draw the buttons (scaled in size to fit)
else
{
butwidth = scrollwidth / 2;
//LEFT ARROW
SetRect(&ctrl, rect->left, rect->top, rect->left + butwidth, rect->bottom);
RotateRect0(sb, &ctrl);
if(fCustomDraw)
PostCustomDrawNotify(hwnd, hdc, sb->nBarType, &ctrl, SB_LINELEFT, fMouseDownL, fMouseOverL, uLeftButFlags & DFCS_INACTIVE);
else
DrawScrollArrow(sb, hdc, &ctrl, uLeftButFlags, fMouseDownL, fMouseOverL);
RotateRect0(sb, &ctrl);
//RIGHT ARROW
OffsetRect(&ctrl, scrollwidth - butwidth, 0);
RotateRect0(sb, &ctrl);
if(fCustomDraw)
PostCustomDrawNotify(hwnd, hdc, sb->nBarType, &ctrl, SB_LINERIGHT, fMouseDownR, fMouseOverR, uRightButFlags & DFCS_INACTIVE);
else
DrawScrollArrow(sb, hdc, &ctrl, uRightButFlags, fMouseDownR, fMouseOverR);
RotateRect0(sb, &ctrl);
//if there is a gap between the buttons, fill it with a solid color
//if(butwidth & 0x0001)
if(ctrl.left != rect->left + butwidth)
{
ctrl.left --;
ctrl.right -= butwidth;
RotateRect0(sb, &ctrl);
if(fCustomDraw)
PostCustomDrawNotify(hwnd, hdc, sb->nBarType, &ctrl, SB_PAGERIGHT, 0, 0, 0);
else
DrawCheckedRect(hdc, &ctrl, crCheck1, crCheck2);
RotateRect0(sb, &ctrl);
}
}
#ifdef CUSTOM_DRAW
PostCustomPrePostPaint(hwnd, hdc, sb, CDDS_POSTPAINT);
#endif
return fCustomDraw;
}
//
// Draw a vertical scrollbar using the horizontal draw routine, but
// with the coordinates adjusted accordingly
//
static LRESULT NCDrawVScrollbar(SCROLLBAR *sb, HWND hwnd, HDC hdc, const RECT *rect, UINT uDrawFlags)
{
LRESULT ret;
RECT rc;
rc = *rect;
RotateRect(&rc);
ret = NCDrawHScrollbar(sb, hwnd, hdc, &rc, uDrawFlags);
RotateRect(&rc);
return ret;
}
//
// Generic wrapper function for the scrollbar drawing
//
static LRESULT NCDrawScrollbar(SCROLLBAR *sb, HWND hwnd, HDC hdc, const RECT *rect, UINT uDrawFlags)
{
if(sb->nBarType == SB_HORZ)
return NCDrawHScrollbar(sb, hwnd, hdc, rect, uDrawFlags);
else
return NCDrawVScrollbar(sb, hwnd, hdc, rect, uDrawFlags);
}
#ifdef INCLUDE_BUTTONS
//
// Draw the specified bitmap centered in the rectangle
//
static void DrawImage(HDC hdc, HBITMAP hBitmap, RECT *rc)
{
BITMAP bm;
int cx;
int cy;
HDC memdc;
HBITMAP hOldBM;
RECT rcDest = *rc;
POINT p;
SIZE delta;
COLORREF colorOld;
if(hBitmap == NULL)
return;
// center bitmap in caller's rectangle
GetObject(hBitmap, sizeof bm, &bm);
cx = bm.bmWidth;
cy = bm.bmHeight;
delta.cx = (rc->right-rc->left - cx) / 2;
delta.cy = (rc->bottom-rc->top - cy) / 2;
if(rc->right-rc->left > cx)
{
SetRect(&rcDest, rc->left+delta.cx, rc->top + delta.cy, 0, 0);
rcDest.right = rcDest.left + cx;
rcDest.bottom = rcDest.top + cy;
p.x = 0;
p.y = 0;
}
else
{
p.x = -delta.cx;
p.y = -delta.cy;
}
// select checkmark into memory DC
memdc = CreateCompatibleDC(hdc);
hOldBM = (HBITMAP)SelectObject(memdc, hBitmap);
// set BG color based on selected state
colorOld = SetBkColor(hdc, GetSysColor(COLOR_3DFACE));
BitBlt(hdc, rcDest.left, rcDest.top, rcDest.right-rcDest.left, rcDest.bottom-rcDest.top, memdc, p.x, p.y, SRCCOPY);
// restore
SetBkColor(hdc, colorOld);
SelectObject(memdc, hOldBM);
DeleteDC(memdc);
}
//
// Draw the specified metafile
//
static void DrawMetaFile(HDC hdc, HENHMETAFILE hemf, RECT *rect)
{
RECT rc;
POINT pt;
SetRect(&rc, 0, 0, rect->right-rect->left, rect->bottom-rect->top);
SetWindowOrgEx(hdc, -rect->left, -rect->top, &pt);
PlayEnhMetaFile(hdc, hemf, &rc);
SetWindowOrgEx(hdc, pt.x, pt.y, 0);
}
//
// Draw a single scrollbar inserted button, in whatever style
// it has been defined to use.
//
static UINT DrawScrollButton(SCROLLBUT *sbut, HDC hdc, const RECT *pctrl, UINT flags)
{
NMCSBCUSTOMDRAW nmcd;
HWND hwnd;
RECT rect = *pctrl;
UINT f;
switch(sbut->uButType & SBBT_MASK)
{
case SBBT_OWNERDRAW:
hwnd = WindowFromDC(hdc);
//fill in the standard header
nmcd.hdr.hwndFrom = hwnd;
nmcd.hdr.idFrom = GetWindowLong(hwnd, GWL_ID);
nmcd.hdr.code = NM_COOLSB_CUSTOMDRAW;
nmcd.dwDrawStage = CDDS_ITEMPREPAINT;
nmcd.nBar = SB_INSBUT;
nmcd.rect = *pctrl;
nmcd.uItem = sbut->uCmdId;
nmcd.hdc = hdc;
nmcd.uState = flags;
IntersectClipRect(hdc, rect.left, rect.top, rect.right, rect.bottom);
SendMessage(GetParent(hwnd), WM_NOTIFY, nmcd.hdr.idFrom, (LPARAM)&nmcd);
SelectClipRgn(hdc, NULL);
break;
case SBBT_FIXED:
flags &= ~SBBS_PUSHED;
case SBBT_TOGGLEBUTTON:
if(sbut->uState != SBBS_NORMAL)
flags |= SBBS_PUSHED;
//intentionally fall through here...
case SBBT_PUSHBUTTON:
f = flags & SBBS_PUSHED ? DFCS_PUSHED | DFCS_FLAT : 0;
if(sbut->uButType & SBBM_LEFTARROW)
{
DrawFrameControl(hdc, &rect, DFC_SCROLL, DFCS_SCROLLLEFT | f);
}
else if(sbut->uButType & SBBM_RIGHTARROW)
{
DrawFrameControl(hdc, &rect, DFC_SCROLL, DFCS_SCROLLRIGHT | f);
}
else if(sbut->uButType & SBBM_UPARROW)
{
DrawFrameControl(hdc, &rect, DFC_SCROLL, DFCS_SCROLLUP | f);
}
else if(sbut->uButType & SBBM_DOWNARROW)
{
DrawFrameControl(hdc, &rect, DFC_SCROLL, DFCS_SCROLLDOWN | f);
}
else
{
//
if(flags & SBBS_PUSHED)
{
if(sbut->uButType & SBBM_RECESSED)
{
InflateRect(&rect, -1, -1);
DrawEdge(hdc, &rect, EDGE_SUNKEN, BF_RECT|BF_FLAT);
InflateRect(&rect, 1, 1);
FrameRect(hdc, &rect, GetSysColorBrush(COLOR_3DDKSHADOW));
InflateRect(&rect, -2, -2);
}
else
{
DrawEdge(hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_FLAT | BF_ADJUST);
InflateRect(&rect, 1, 1);
}
}
else
{
// draw the button borders
if(sbut->uButType & SBBM_TYPE2)
{
DrawFrameControl(hdc, &rect, DFC_BUTTON, DFCS_BUTTONPUSH);
InflateRect(&rect, -2, -2);
}
else if(sbut->uButType & SBBM_TYPE3)
{
DrawFrameControl(hdc, &rect, DFC_BUTTON, DFCS_BUTTONPUSH);
InflateRect(&rect, -1, -1);
}
else
{
DrawEdge(hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
rect.bottom++;
rect.right++;
}
OffsetRect(&rect, -1, -1);
rect.top++; rect.left++;
}
if(sbut->hBmp)
{
PaintRect(hdc, &rect, GetSysColor(COLOR_3DFACE));
if(flags & SBBS_PUSHED)
{
rect.top++; rect.left++;
}
IntersectClipRect(hdc, rect.left, rect.top, rect.right,rect.bottom);
DrawImage(hdc, sbut->hBmp, &rect);
SelectClipRgn(hdc, 0);
}
else if(sbut->hEmf)
{
PaintRect(hdc, &rect, GetSysColor(COLOR_3DFACE));
InflateRect(&rect, -1, -1);
if(flags & SBBS_PUSHED)
{
rect.top++; rect.left++;
}
IntersectClipRect(hdc, rect.left, rect.top, rect.right,rect.bottom);
DrawMetaFile(hdc, sbut->hEmf, &rect);
SelectClipRgn(hdc, 0);
}
else
{
PaintRect(hdc, &rect, GetSysColor(COLOR_3DFACE));
}
}
break;
case SBBT_BLANK:
PaintRect(hdc, &rect, GetSysColor(COLOR_3DFACE));
break;
case SBBT_FLAT:
DrawBlankButton(hdc, &rect, BF_FLAT);
break;
case SBBT_DARK:
PaintRect(hdc, &rect, GetSysColor(COLOR_3DDKSHADOW));
break;
}
return 0;
}
//
// Draw any buttons inserted into the horizontal scrollbar
// assume that the button widths have already been calculated
// Note: RECT *rect is the rectangle of the scrollbar
// leftright: 1 = left, 2 = right, 3 = both
//
static LRESULT DrawHorzButtons(SCROLLBAR *sbar, HDC hdc, const RECT *rect, int leftright)
{
int i;
int xposl, xposr;
RECT ctrl;
SCROLLBUT *sbut = sbar->sbButtons;
xposl = rect->left - sbar->nButSizeBefore;
xposr = rect->right;
for(i = 0; i < sbar->nButtons; i++)
{
if((leftright & SBBP_LEFT) && sbut[i].uPlacement == SBBP_LEFT)
{
int butwidth = GetSingleButSize(sbar, &sbut[i]);
SetRect(&ctrl, xposl, rect->top, xposl + butwidth, rect->bottom);
RotateRect0(sbar, &ctrl);
DrawScrollButton(&sbut[i], hdc, &ctrl, SBBS_NORMAL);
xposl += butwidth;
}
if((leftright & SBBP_RIGHT) && sbut[i].uPlacement == SBBP_RIGHT)
{
int butwidth = GetSingleButSize(sbar, &sbut[i]);
SetRect(&ctrl, xposr, rect->top, xposr + butwidth, rect->bottom);
RotateRect0(sbar, &ctrl);
DrawScrollButton(&sbut[i], hdc, &ctrl, SBBS_NORMAL);
xposr += butwidth;
}
}
return 0;
}
static LRESULT DrawVertButtons(SCROLLBAR *sbar, HDC hdc, const RECT *rect, int leftright)
{
RECT rc = *rect;
RotateRect(&rc);
DrawHorzButtons(sbar, hdc, &rc, leftright);
return 0;
}
#endif // INCLUDE_BUTTONS
//
// Define these two for proper processing of NCPAINT
// NOT needed if we don't bother to mask the scrollbars we draw
// to prevent the old window procedure from accidently drawing over them
//
HDC CoolSB_GetDC(HWND hwnd, WPARAM wParam)
{
// I just can't figure out GetDCEx, so I'll just use this:
return GetWindowDC(hwnd);
/*
RECT rc;
DWORD flags = 0x10000;
HRGN hrgn = (HRGN)wParam;
if(hrgn == (HRGN)1)
{
GetWindowRect(hwnd, &rc);
OffsetRect(&rc, -rc.left, -rc.top);
hrgn = CreateRectRgnIndirect(&rc);
}
if(GetWindowLong(hwnd, GWL_STYLE) & WS_CLIPCHILDREN)
flags |= DCX_CLIPCHILDREN;
if(GetWindowLong(hwnd, GWL_STYLE) & WS_CLIPSIBLINGS)
flags |= DCX_CLIPSIBLINGS;
return GetDCEx(hwnd, hrgn, flags | DCX_CACHE|DCX_NORESETATTRS|DCX_WINDOW | DCX_INTERSECTUPDATE);
*/
//return GetDCEx(hwnd, NULL, flags | DCX_WINDOW| DCX_NORESETATTRS);
}
static LRESULT NCPaint(SCROLLWND *sw, HWND hwnd, WPARAM wParam, LPARAM lParam)
{
SCROLLBAR *sb;
HDC hdc;
HRGN hrgn;
RECT winrect, rect;
HRGN clip;
BOOL fUpdateAll = ((LONG)wParam == 1);
BOOL fCustomDraw = FALSE;
UINT ret;
DWORD dwStyle;
GetWindowRect(hwnd, &winrect);
//if entire region needs painting, then make a region to cover the entire window
if(fUpdateAll)
hrgn = (HRGN)wParam;
else
hrgn = (HRGN)wParam;
//hdc = GetWindowDC(hwnd);
hdc = CoolSB_GetDC(hwnd, wParam);
//
// Only draw the horizontal scrollbar if the window is tall enough
//
sb = &sw->sbarHorz;
if(sb->fScrollVisible)
{
int hbarwidth = 0, leftright = 0;
//get the screen coordinates of the whole horizontal scrollbar area
GetHScrollRect(sw, hwnd, &rect);
//make the coordinates relative to the window for drawing
OffsetRect(&rect, -winrect.left, -winrect.top);
#ifdef INCLUDE_BUTTONS
//work out the size of any inserted buttons so we can dra them
sb->nButSizeBefore = GetButtonSize(sb, hwnd, SBBP_LEFT);
sb->nButSizeAfter = GetButtonSize(sb, hwnd, SBBP_RIGHT);
//make sure there is room for the buttons
hbarwidth = rect.right - rect.left;
//check that we can fit any left/right buttons in the available space
if(sb->nButSizeAfter < (hbarwidth - MIN_COOLSB_SIZE))
{
//adjust the scrollbar rectangle to fit the buttons into
sb->fButVisibleAfter = TRUE;
rect.right -= sb->nButSizeAfter;
leftright |= SBBP_RIGHT;
//check that there is enough space for the right buttons
if(sb->nButSizeBefore + sb->nButSizeAfter < (hbarwidth - MIN_COOLSB_SIZE))
{
sb->fButVisibleBefore = TRUE;
rect.left += sb->nButSizeBefore;
leftright |= SBBP_LEFT;
}
else
sb->fButVisibleBefore = FALSE;
}
else
sb->fButVisibleAfter = FALSE;
DrawHorzButtons(sb, hdc, &rect, leftright);
#endif// INCLUDE_BUTTONS
if(uCurrentScrollbar == SB_HORZ)
fCustomDraw |= NCDrawHScrollbar(sb, hwnd, hdc, &rect, uScrollTimerPortion);
else
fCustomDraw |= NCDrawHScrollbar(sb, hwnd, hdc, &rect, HTSCROLL_NONE);
}
//
// Only draw the vertical scrollbar if the window is wide enough to accomodate it
//
sb = &sw->sbarVert;
if(sb->fScrollVisible)
{
int vbarheight = 0, updown = 0;
//get the screen cooridinates of the whole horizontal scrollbar area
GetVScrollRect(sw, hwnd, &rect);
//make the coordinates relative to the window for drawing
OffsetRect(&rect, -winrect.left, -winrect.top);
#ifdef INCLUDE_BUTTONS
//work out the size of any inserted buttons so we can dra them
sb->nButSizeBefore = GetButtonSize(sb, hwnd, SBBP_LEFT);
sb->nButSizeAfter = GetButtonSize(sb, hwnd, SBBP_RIGHT);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -