【绘制边界拖动轨迹(筛状实心矩形)】
类似“最佳性能”配置下拖动窗口时,目标边界所出现的轨迹。主要用于分割条的拖动处理,提高流畅性。移植自WTL。
使用方法:
DrawGhostBar(窗口句柄, 绘制的阴影矩形)
此函数将矩形内的像素按筛子状反色,看上去就好像一个阴影一样。在同一位置再次调用此函数将会再次反色,消除阴影。
使用示例:
case WM_MOUSEMOVE:
{
POINTS pts = MAKEPOINTS(lParam); // 获取鼠标指针位置
RECT rc = { 0 };
GetClientRect(hWnd, &rc); // 获取客户区大小(用于矩形高度)
rc.left = pts.x - 10; // 设定矩形宽度
rc.right = pts.x + 10;
static RECT oldRc = { 0 };
DrawGhostBar(hWnd, &oldRc); // 消除旧矩形
oldRc = rc;
DrawGhostBar(hWnd, &rc); // 绘制新矩形
}
return 0;
效果:
源代码:
// 创建筛子状画刷
HBRUSH GetHalftoneBrush()
{
HBRUSH halftoneBrush = NULL;
// 用筛子状图案填充位块(0101 / 1010)
WORD grayPattern[8] = { 0 };
for (int j = 0; j < 8; j++)
grayPattern[j] = (WORD)(0x5555 << (j & 1));
// 从位块创建位图
HBITMAP grayBitmap = CreateBitmap(8, 8, 1, 1, &grayPattern);
if (grayBitmap != NULL)
{
// 从位图创建图案画刷
halftoneBrush = CreatePatternBrush(grayBitmap);
// 删除位图
DeleteObject(grayBitmap);
}
return halftoneBrush;
}
// 绘制边界拖动轨迹
void DrawGhostBar(HWND hWnd, RECT *pRect)
{
// 把客户区坐标转换为窗口坐标
RECT rcWnd = { 0 };
GetWindowRect(hWnd, &rcWnd);
MapWindowPoints(NULL, hWnd, (LPPOINT)&rcWnd, 2);
OffsetRect(pRect, -rcWnd.left, -rcWnd.top);
// 绘制边界拖动轨迹
HDC hDC = GetWindowDC(hWnd);
if (hDC)
{
// 获取筛子画刷(见函数GetHalftoneBrush)
HBRUSH hBrush = GetHalftoneBrush();
if (hBrush != NULL)
{
// 使用筛子画刷并保留原画刷
HBRUSH hBrushOld = (HBRUSH)SelectObject(hDC, hBrush);
// 按画刷反色像素,绘制矩形
PatBlt(hDC, pRect->left, pRect->top,
pRect->right - pRect->left, pRect->bottom - pRect->top, PATINVERT);
// 恢复原画刷
SelectObject(hDC, hBrushOld);
// 删除筛子画刷
DeleteObject(hBrush);
}
ReleaseDC(hWnd, hDC);
}
}
【绘制(经典的)选择框(筛状空心矩形)】
方法与绘制框架轨迹类似,只要把内部矩形排除就行了。
使用示例:
case WM_MOUSEMOVE:
{
POINTS pts = MAKEPOINTS(lParam); // 获取鼠标指针位置
RECT rc = { 100, 100, pts.x, pts.y }; // 指定选择矩形位置
static RECT oldRc = { 0 };
DrawSelectRect(hWnd, &oldRc); // 消除旧矩形
oldRc = rc;
DrawSelectRect(hWnd, &rc); // 绘制新矩形
}
return 0;
效果:
源代码:
// 绘制选择框
void DrawSelectRect(HWND hWnd, RECT *pRect)
{
// 计算内部矩形的大小
RECT innerRect = *pRect;
InflateRect(&innerRect,
2 * (innerRect.left > innerRect.right) - 1,
2 * (innerRect.top > innerRect.bottom) - 1);
// 绘制选择框
HDC hDC = GetDC(hWnd);
if (hDC)
{
// 获取筛子画刷(见函数GetHalftoneBrush)
HBRUSH hBrush = GetHalftoneBrush();
if (hBrush != NULL)
{
// 使用筛子画刷并保留原画刷
HBRUSH hBrushOld = (HBRUSH)SelectObject(hDC, hBrush);
// 排除内部矩形
ExcludeClipRect(hDC, innerRect.left, innerRect.top,
innerRect.right, innerRect.bottom);
// 按画刷反色像素,绘制外部矩形
PatBlt(hDC, pRect->left, pRect->top,
pRect->right - pRect->left, pRect->bottom - pRect->top, PATINVERT);
// 恢复原画刷
SelectObject(hDC, hBrushOld);
// 删除筛子画刷
DeleteObject(hBrush);
}
ReleaseDC(hWnd, hDC);
}
}