📄 scrlbar.c
字号:
/*
* Copyright (c) 2000 Greg Haerr <greg@censoft.com>
* Portions Copyright (c) 1999, 2000, Wei Yongming.
* jmt: scrollbar thumb ported
*
* Microwindows win32 Scrollbars control
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MWINCLUDECOLORS /* jmt: for color macros */
#include "windows.h"
#include "wintern.h"
#include "wintools.h"
#include "mwsystem.h"
/* scrollbar status/positions*/
#define SBS_UNKNOWN 0x0000
#define SBS_LEFTARROW 0x0001
#define SBS_RIGHTARROW 0x0002
#define SBS_LEFTSPACE 0x0004
#define SBS_RIGHTSPACE 0x0008
#define SBS_HORZTHUMB 0x0010
#define SBS_UPARROW 0x0020
#define SBS_DOWNARROW 0x0040
#define SBS_UPSPACE 0x0080
#define SBS_DOWNSPACE 0x0100
#define SBS_VERTTHUMB 0x0200
#define SBS_MASK 0x03ff
#define SBS_DISABLED 0x4000
#define SBS_HIDE 0x8000
#define MWM_DEFBARLEN 18
#define MWM_MINBARLEN 8
static LRESULT CALLBACK
ScrollbarControlProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
int WINAPI MwRegisterScrollbarControl(HINSTANCE hInstance)
{
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_GLOBALCLASS;
wc.lpfnWndProc = (WNDPROC)ScrollbarControlProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = 0; /*LoadCursor(NULL, IDC_ARROW);*/
wc.hbrBackground= GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName= "SCROLLBAR";
return RegisterClass(&wc);
}
static DWORD GetWindowStyle (HWND hwnd)
{
return hwnd->style;
}
static int
wndGetBorder(HWND hwnd)
{
if (hwnd->style & WS_BORDER) {
if ((hwnd->style & WS_CAPTION) == WS_CAPTION)
return mwSYSMETRICS_CXFRAME;
return mwSYSMETRICS_CXBORDER;
}
return 0;
}
static BOOL
wndGetVScrollBarRect (HWND hwnd, RECT* rcVBar)
{
int cx,cy; RECT rc;
MWSCROLLBARINFO* pData;
pData = (MWSCROLLBARINFO *)hwnd->userdata;
rc = hwnd->winrect;
cx=rc.right-rc.left;
cy=rc.bottom-rc.top;
rcVBar->left = hwnd->winrect.right - cx
- wndGetBorder (hwnd);
rcVBar->right = hwnd->winrect.right - wndGetBorder (hwnd);
rcVBar->top = hwnd->winrect.top;
rcVBar->bottom = hwnd->winrect.bottom - wndGetBorder (hwnd);
return TRUE;
}
static BOOL
wndGetHScrollBarRect (HWND hwnd, RECT* rcHBar)
{
int cx,cy; RECT rc;
MWSCROLLBARINFO* pData;
pData = (MWSCROLLBARINFO *)hwnd->userdata;
rc = hwnd->winrect;
cx=rc.right-rc.left;
cy=rc.bottom-rc.top;
rcHBar->top = hwnd->winrect.bottom - cy
- wndGetBorder (hwnd);
rcHBar->bottom = hwnd->winrect.bottom - wndGetBorder (hwnd);
rcHBar->left = hwnd->winrect.left;
rcHBar->right = hwnd->winrect.right - wndGetBorder (hwnd);
return TRUE;
}
void
MwPaintScrollbars(HWND hwnd, HDC hdc, DWORD style)
{
BOOL vertbar = (style==SBS_VERT);
BOOL horzbar = (style==SBS_HORZ);
BOOL fGotDC = FALSE;
RECT rc,rc2;
POINT p3[3];
int shrink=2;
int start = 0;
RECT rcHBar, rcVBar;
int cx,cy;
MWSCROLLBARINFO* pData;
pData = (MWSCROLLBARINFO *)hwnd->userdata;
rc = hwnd->winrect;
cx=rc.right-rc.left;
cy=rc.bottom-rc.top;
if (!hdc && (horzbar || vertbar)) {
hdc = GetWindowDC(hwnd);
fGotDC = TRUE;
}
if (vertbar) {
#if 1
/* bkgnd */
rc2.left=rc.left; rc2.right=rc2.left+ cx;
rc2.top=rc.top;
rc2.bottom=rc2.top+ cx;
FillRect(hdc, &rc2, (HBRUSH)(COLOR_BTNFACE+1));
rc2.top=rc.bottom- cx;
rc2.bottom=rc2.top+ cx;
FillRect(hdc, &rc2, (HBRUSH)(COLOR_BTNFACE+1));
#endif
/* up */
Draw3dUpDownState(hdc, rc.left, rc.top,
cx, cx,
pData->status & SBS_UPARROW);
/* down */
Draw3dUpDownState(hdc, rc.left,rc.bottom-cx,
cx, cx,
pData->status & SBS_DOWNARROW);
/* jmt: draw arrows */
SelectObject(hdc,GetStockObject(BLACK_BRUSH));
/* up */
p3[0].x= rc.left + (cx/2) - 1;
p3[0].y= rc.top + 2 + shrink;
p3[1].x= rc.left + 2 + shrink - 1;
p3[1].y= rc.top + (cx-4) - shrink;
p3[2].x= rc.left + (cx-4) - shrink;
p3[2].y= rc.top + (cx-4) - shrink;
Polygon(hdc,p3,3);
/* down */
p3[0].x= rc.left + (cx/2) - 1;
p3[0].y= rc.bottom - 4 - shrink;
p3[1].x= rc.left + 2 + shrink - 1;
p3[1].y= rc.bottom-cx + 2 + shrink;
p3[2].x= rc.left + (cx-4) - shrink;
p3[2].y= rc.bottom-cx + 2 + shrink;
Polygon(hdc,p3,3);
/* draw moving bar */
wndGetVScrollBarRect (hwnd, &rcVBar);
rcVBar.left -- ;
/*rcVBar.right -- ;*/
start = rcVBar.top + cx + pData->barStart;
if (start + pData->barLen > rcVBar.bottom)
start = rcVBar.bottom - pData->barLen;
if (pData->barLen == 0)
pData->barLen=rc.bottom-rc.top-(cx*2);
/* bkgnd */
rc2.left=rc.left; rc2.right=rc.right/*-1*/;
rc2.top=rc.top+cx;
rc2.bottom=start;
if (rc2.bottom>rc2.top)
FillRect(hdc, &rc2, (HBRUSH)GetStockObject(DKGRAY_BRUSH));
rc2.top=start+pData->barLen;
rc2.bottom=rc.bottom-cx;
if (rc2.bottom>rc2.top)
FillRect(hdc, &rc2, (HBRUSH)GetStockObject(DKGRAY_BRUSH));
Draw3dUpFrame (hdc, rcVBar.left, start, rcVBar.right,
start + pData->barLen);
/*printf("barv:(l,t,r,b):(%d,%d,%d,%d)\n",
rcVBar.left, start, rcVBar.right,
start + pData->barLen);*/
}
if (horzbar) {
#if 1
/* bkgnd */
rc2.top=rc.top; rc2.bottom=rc2.top+ cy;
rc2.left=rc.left;
rc2.right=rc2.left+ cy;
FillRect(hdc, &rc2, (HBRUSH)(COLOR_BTNFACE+1));
rc2.left=rc.right- cy;
rc2.right=rc2.left+ cy;
FillRect(hdc, &rc2, (HBRUSH)(COLOR_BTNFACE+1));
#endif
/* left */
Draw3dUpDownState(hdc, rc.left, rc.top,
cy, cy,
pData->status & SBS_LEFTARROW);
/* right */
Draw3dUpDownState(hdc, rc.right-cy, rc.top,
cy, cy,
pData->status & SBS_RIGHTARROW);
/* jmt: draw arrows */
SelectObject(hdc,GetStockObject(BLACK_BRUSH));
/* left */
p3[0].x= rc.left + 2 + shrink;
p3[0].y= rc.top + (cy/2) ;
p3[1].x= rc.left + (cy-4) - shrink ;
p3[1].y= rc.top + 2 + shrink;
p3[2].x= rc.left + (cy-4) - shrink;
p3[2].y= rc.bottom - 4 - shrink + 1;
Polygon(hdc,p3,3);
/* right */
p3[0].x= rc.right - 4 - shrink;
p3[0].y= rc.top + (cy/2) ;
p3[1].x= rc.right-cy + 2 + shrink ;
p3[1].y= rc.top + 2 + shrink;
p3[2].x= rc.right-cy + 2 + shrink;
p3[2].y= rc.bottom - 4 - shrink + 1;
Polygon(hdc,p3,3);
/* draw moving bar. */
wndGetHScrollBarRect (hwnd, &rcHBar);
rcHBar.top -- ;
/*rcHBar.bottom -- ;*/
start = rcHBar.left + cy + pData->barStart;
if (start + pData->barLen > rcHBar.right)
start = rcHBar.right - pData->barLen;
if (pData->barLen == 0)
pData->barLen=rc.right-rc.left-(cy*2);
/* bkgnd */
rc2.top=rc.top; rc2.bottom=rc.bottom/*-1*/;
rc2.left=rc.left+cy;
rc2.right=start;
if (rc2.right>rc2.left)
FillRect(hdc, &rc2, (HBRUSH)GetStockObject(DKGRAY_BRUSH));
rc2.left=start+pData->barLen;
rc2.right=rc.right-cy;
if (rc2.right>rc2.left)
FillRect(hdc, &rc2, (HBRUSH)GetStockObject(DKGRAY_BRUSH));
Draw3dUpFrame (hdc, start, rcHBar.top, start + pData->barLen,
rcHBar.bottom);
/*printf("barh:(l,t,r,b):(%d,%d,%d,%d)\n",
start, rcHBar.top, start + pData->barLen,
rcHBar.bottom);*/
}
if (fGotDC)
ReleaseDC(hwnd, hdc);
}
/* handle a non-client message for a scrollbar*/
void
MwHandleMessageScrollbar(HWND hwnd, WPARAM hitcode, LPARAM lParam, UINT msg, DWORD style)
{
int pos = SBS_UNKNOWN;
BOOL vertbar = (style==SBS_VERT);
BOOL horzbar = (style==SBS_HORZ);
int * pStat;
POINT pt;
RECT rc;
static BOOL bDraw;
static int downPos = SBS_UNKNOWN;
static int sbCode;
int newThumbPos;
int itemMoveable,itemCount,itemVisible,moveRange; /* jmt:2k0819 */
int moveTop,moveBottom,moveLeft,moveRight; /* jmt:2k0819 */
int cx,cy;
MWSCROLLBARINFO* pData;
pData = (MWSCROLLBARINFO *)hwnd->userdata;
rc = hwnd->winrect;
cx=rc.right-rc.left;
cy=rc.bottom-rc.top;
POINTSTOPOINT(pt, lParam);
for (;;) { /* use for() to allow break statement*/
if (vertbar)
{
pStat = &pData->status;
rc = hwnd->winrect;
rc.bottom = rc.top + cx;
if (PtInRect(&rc, pt))
{
pos = SBS_UPARROW;
break;
}
rc.bottom = hwnd->winrect.bottom;
rc.top = rc.bottom - cx;
if (PtInRect(&rc, pt))
{
pos = SBS_DOWNARROW;
break;
}
pos = SBS_VERTTHUMB;
} else if (horzbar)
{
pStat = &pData->status;
rc = hwnd->winrect;
rc.right = rc.left + cy;
if (PtInRect(&rc, pt)) {
pos = SBS_LEFTARROW;
break;
}
rc.right = hwnd->winrect.right;
rc.left = rc.right - cy;
if (PtInRect(&rc, pt)) {
pos = SBS_RIGHTARROW;
break;
}
pos = SBS_HORZTHUMB;
} else
return;
break;
}
if (pos == SBS_UNKNOWN)
return;
*pStat &= ~SBS_MASK; /* remove stray mouse states*/
if (msg == WM_NCLBUTTONDOWN || msg == WM_NCLBUTTONDBLCLK)
*pStat |= pos;
else *pStat &= ~pos;
if (msg == WM_NCLBUTTONDOWN || msg == WM_NCLBUTTONDBLCLK)
bDraw=TRUE;
if (bDraw)
MwPaintScrollbars(hwnd, NULL,style);
if (pos == SBS_UPARROW || pos == SBS_LEFTARROW) /* jmt:2k0820 */
{
if (pData->curPos != pData->minPos)
sbCode = SB_LINEUP;
}
else if (pos == SBS_DOWNARROW || pos == SBS_RIGHTARROW) /* jmt:2k0820 */
{
if (pData->curPos != pData->maxPos)
sbCode = SB_LINEDOWN;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -