📄 bargraph.pas
字号:
// 当前鼠标所处的Bar
Bar := BarGraph_BarFromPoint(hWnd, x, y);
// 当前处于选中的Bar
nSelectedBar := GetThisData(hWnd).nSelectedBar;
// 位于最初按下的Bar
if (Bar = GetThisData(hWnd).nMouseDownBar) then
begin
if (nSelectedBar <> Bar) then
begin
GetThisData(hWnd).nSelectedBar := Bar;
InvalidateRect(hWnd, nil, FALSE); // 刷新
end
end else
begin
if (nSelectedBar <> GetThisData(hWnd).nCancelBar) then
begin
GetThisData(hWnd).nSelectedBar := GetThisData(hWnd).nCancelBar;
InvalidateRect(hWnd, nil, FALSE); // 刷新
end;
end;
end;
end;
// BarGraph控件WM_SETFOCUS处理
procedure BarGraph_OnSetFocus(hWnd, hWndOldFocus: HWND);
begin
// 刷新(得到焦点之后需要高亮的Bar)
InvalidateRect(hWnd, nil, FALSE);
end;
// BarGraph控件WM_KILLFOCUS处理
procedure BarGraph_OnKillFocus(hWnd, hWndNewFocus: HWND);
begin
// 放弃鼠标消息接管(取消本次选择)
if (GetCapture() = hWnd) then ReleaseCapture();
// 刷新(失去焦点之后没有高亮的Bar)
InvalidateRect(hWnd, nil, FALSE);
end;
// BarGraph控件WM_CAPTURECHANGED处理
procedure BarGraph_OnCaptureChanged(hWnd, hWndNewCapture: HWND);
begin
// 失去鼠标消息接管, 默认作取消处理
GetThisData(hWnd).nSelectedBar := GetThisData(hWnd).nCancelBar;
InvalidateRect(hWnd, nil, FALSE);
end;
// BarGraph控件WM_KEYDOWN处理
procedure BarGraph_OnKey(hWnd: HWND; vk: UINT; fDown: BOOL; cRepeat: Integer; flags: UINT);
var
pThis: PThisData;
begin
if (fDown) then // 按下
begin
pThis := GetThisData(hWnd);
case (vk) of
VK_LEFT, VK_RIGHT:
begin
// 根据方向键作循环移动
if (vk = VK_LEFT) then
Inc(pThis.nSelectedBar, pThis.cBars - 1)
else
Inc(pThis.nSelectedBar, 1);
pThis.nSelectedBar := pThis.nSelectedBar mod pThis.cBars;
// 刷新(高亮显示其他Bar)
InvalidateRect(hWnd, nil, FALSE);
end;
VK_RETURN, VK_SPACE:
begin
// 通知父窗体单击事件
BarGraph_NotifyParent(hWnd, UINT(NM_CLICK), pThis.nSelectedBar);
end;
end;
end;
end;
// BarGraph控件WM_PAINT处理
procedure BarGraph_OnPaint(hWnd: HWND);
var
ps: TPaintStruct;
Bar: UINT;
rcClient, rcBar: TRect;
hbrFrame, hbrOriginal, hbrBk: HBRUSH;
pThis: PThisData;
fHighlight: BOOL;
hpenNew, hpenOriginal: HPEN;
begin
pThis := GetThisData(hWnd);
// 开始绘制
BeginPaint(hWnd, ps);
// 绘制坐标轴
GetClientRect(hWnd, rcClient);
hpenNew := CreatePen(PS_SOLID, 1, BarGraph_GetTextColor(hWnd));
hpenOriginal := SelectObject(ps.hdc, hpenNew);
MoveToEx(ps.hdc, rcClient.Left, rcClient.Top, nil);
LineTo(ps.hdc, rcClient.Left, rcClient.Bottom - 1);
LineTo(ps.hdc, rcClient.Right, rcClient.Bottom - 1);
SelectObject(ps.hdc, hpenOriginal);
DeleteObject(hpenNew);
Inc(rcClient.Left);
Dec(rcClient.Bottom);
// 绘制每个Bar
Bar := 0;
while (Bar < pThis.cBars) do
begin
// 取当前Bar绘制范围
BarGraph_GetBarRect(hWnd, Bar, @rcBar);
// 绘制当前Bar的边框
hbrFrame := CreateSolidBrush(BarGraph_GetTextColor(hWnd));
FrameRect(ps.hdc, rcBar, hbrFrame);
DeleteObject(hbrFrame);
InflateRect(rcBar, -1, -1);
// 如果当前Bar被选中, 且控件拥有焦点, 则背景颜色设为高亮
fHighlight := (Bar = pThis.nSelectedBar) and (GetFocus() = hWnd);
if fHighlight then
SetBkColor(ps.hdc, GetSysColor(COLOR_HIGHLIGHT))
else
SetBkColor(ps.hdc, BarGraph_GetBkColor(hWnd));
// 使用特定画刷填充
SetBrushOrgEx(ps.hdc, 0, 0, nil);
hbrOriginal := SelectObject(ps.hdc, PBar(DWORD(pThis.ptBar) + Bar * SizeOf(TBar)).hbr);
PatBlt(ps.hdc, rcBar.Left, rcBar.Top,
rcBar.Right - rcBar.Left, rcBar.Bottom - rcBar.Top, PATCOPY);
SelectObject(ps.hdc, hbrOriginal);
// 恢复完整绘制范围
InflateRect(rcBar, 1, 1);
// 排除在剪裁区域外
ExcludeClipRect(ps.hdc, rcBar.Left, rcBar.Top, rcBar.Right, rcBar.Bottom);
// 下一个Bar
Inc(Bar);
end;
// 填充背景色
SetBrushOrgEx(ps.hdc, 0, 0, nil);
hbrBk := CreateSolidBrush(BarGraph_GetBkColor(hWnd));
hbrOriginal := SelectObject(ps.hdc, hbrBk);
PatBlt(ps.hdc, rcClient.Left, rcClient.Top,
rcClient.Right - rcClient.Left, rcClient.Bottom - rcClient.Top, PATCOPY);
SelectObject(ps.hdc, hbrOriginal);
DeleteObject(hbrBk);
// 完成绘制
EndPaint(hWnd, ps);
end;
// BarGraph控件BGM_GETBARS处理
function BarGraph_OnGetBars(hWnd: HWND): PBar; stdcall;
begin
Result := GetThisData(hWnd).PtBar;
end;
// BarGraph控件BGM_GETCOUNT处理
function BarGraph_OnGetCount(hWnd: HWND): UINT; stdcall;
begin
Result := GetThisData(hWnd).cBars;
end;
// BarGraph控件BGM_SETBARS处理
procedure BarGraph_OnSetBars(hWnd: HWND; cBars: UINT; PtBar: PBar); stdcall;
var
pThis: PThisData;
begin
pThis := GetThisData(hWnd);
pThis.PtBar := PtBar;
pThis.cBars := cBars;
pThis.nSelectedBar := 0;
InvalidateRect(hWnd, nil, FALSE);
end;
// BarGraph控件BGM_GETHEIGHT处理
function BarGraph_OnGetHeight(hWnd: HWND): UINT; stdcall;
begin
Result := GetThisData(hWnd).nHeight;
end;
// BarGraph控件BGM_SETHEIGHT处理
procedure BarGraph_OnSetHeight(hWnd: HWND; nHeightNew: UINT); stdcall;
begin
GetThisData(hWnd).nHeight := nHeightNew;
InvalidateRect(hWnd, nil, FALSE);
end;
// BarGraph控件BGM_SETBKCOLOR处理
procedure BarGraph_OnSetBkColor(hWnd: HWND; cr: COLORREF); stdcall;
begin
GetThisData(hWnd).crBk := cr;
InvalidateRect(hWnd, nil, FALSE);
end;
// BarGraph控件BGM_GETBKCOLOR处理
function BarGraph_OnGetBkColor(hWnd: HWND): COLORREF; stdcall;
begin
Result := GetThisData(hWnd).crBk;
end;
// BarGraph控件BGM_SETTEXTCOLOR处理
procedure BarGraph_OnSetTextColor(hWnd: HWND; cr: COLORREF); stdcall;
begin
GetThisData(hWnd).crText := cr;
InvalidateRect(hWnd, nil, FALSE);
end;
// BarGraph控件BGM_GETTEXTCOLOR处理
function BarGraph_OnGetTextColor(hWnd: HWND): COLORREF; stdcall;
begin
Result := GetThisData(hWnd).crText;
end;
// BarGraph控件消息处理过程
function BarGraph_WndProc(hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
Result := 0;
case (uMsg) of
// 标准窗体消息
WM_CREATE:
begin
if BarGraph_OnCreate(hWnd, PCreateStruct(lParam)) = FALSE then
Result := -1; // 阻止建立控件
end;
WM_DESTROY:
begin
BarGraph_OnDestroy(hWnd);
end;
WM_GETDLGCODE:
begin
Result := BarGraph_OnGetDlgCode(hWnd, PMsg(lParam));
end;
WM_PAINT:
begin
BarGraph_OnPaint(hWnd);
end;
WM_LBUTTONDOWN:
begin
BarGraph_OnLButtonDown(hWnd, FALSE, LOWORD(lParam), HIWORD(lParam), wParam);
end;
WM_LBUTTONUP:
begin
BarGraph_OnLButtonUp(hWnd, LOWORD(lParam), HIWORD(lParam), wParam);
end;
WM_MOUSEMOVE:
begin
BarGraph_OnMouseMove(hWnd, LOWORD(lParam), HIWORD(lParam), wParam);
end;
WM_SETFOCUS:
begin
BarGraph_OnSetFocus(hWnd, wParam);
end;
WM_KILLFOCUS:
begin
BarGraph_OnKillFocus(hWnd, wParam);
end;
WM_CAPTURECHANGED:
begin
BarGraph_OnCaptureChanged(hWnd, lParam);
end;
WM_KEYDOWN:
begin
BarGraph_OnKey(hWnd, wParam, TRUE, LOWORD(lParam), HIWORD(lParam));
end;
// 控件自定消息
BGM_SETBARS:
begin
BarGraph_OnSetBars(hWnd, wParam, PBar(lParam));
end;
BGM_GETBARS:
begin
Result := LRESULT(BarGraph_OnGetBars(hWnd));
end;
BGM_GETCOUNT:
begin
Result := BarGraph_OnGetCount(hWnd);
end;
BGM_SETHEIGHT:
begin
BarGraph_OnSetHeight(hWnd, wParam);
end;
BGM_GETHEIGHT:
begin
Result := BarGraph_OnGetHeight(hWnd);
end;
BGM_SETBKCOLOR:
begin
BarGraph_OnSetBkColor(hWnd, lParam);
end;
BGM_GETBKCOLOR:
begin
Result := BarGraph_OnGetBkColor(hWnd);
end;
BGM_SETTEXTCOLOR:
begin
BarGraph_OnSetTextColor(hWnd, lParam);
end;
BGM_GETTEXTCOLOR:
begin
Result := BarGraph_OnGetTextColor(hWnd);
end;
else Result := DefWindowProc(hWnd, uMsg, wParam, lParam);
end;
end;
// 注册BarGraph控件
function BarGraph_RegisterClass(HInst: THandle; fGlobalClass: BOOL): ATOM; stdcall;
var
wc: TWndClassEx;
begin
ZeroMemory(@wc, SizeOf(wc));
wc.cbSize := SizeOf(wc);
wc.style := CS_HREDRAW or CS_VREDRAW;
wc.lpfnWndProc := @BarGraph_WndProc;
wc.cbWndExtra := SizeOf(T_BarGraph_WndExtraBytes);
wc.hInstance := HInst;
wc.hCursor := LoadCursor(0, IDC_ARROW);
wc.lpszClassName := WC_BARGRAPH;
if (fGlobalClass) then
wc.style := wc.style or CS_GLOBALCLASS;
Result := RegisterClassEx(wc);
end;
// 注销BarGraph控件
function BarGraph_UnregisterClass(HInst: THandle): BOOL; stdcall;
begin
Result := UnregisterClass(WC_BARGRAPH, HInst);
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -