註冊窗口類 MySplitter,光標 IDC_SIZEWE,背景色 COLOR_BTNSHADOW。窗口過程處理三大消息:
WM_LBUTTONDOWN:SetCapture 捕獲鼠標。WM_MOUSEMOVE:左鍵按下且捕獲中,用 DeferWindowPos 批量調整左側樹、分隔條、右側列表的寬度/位置,無閃爍。WM_LBUTTONUP:ReleaseCapture 釋放鼠標。利用 R2_NOTXORPEN 繪圖模式:同一位置畫兩次線即可抹除。流程:
WM_LBUTTONDOWN:捕獲鼠標,記錄初始 X,用 XOR 筆畫豎線。WM_MOUSEMOVE:XOR 畫線抹除舊線 → 更新 X → XOR 畫新線。WM_LBUTTONUP:XOR 抹除線 → ReleaseCapture → DeferWindowPos 真正調整子窗口佈局。
static int x;
case WM_LBUTTONDOWN:
{
HDC hdc = GetDC(GetParent(hwnd));
RECT rt; GetWindowRect(hTree, &rt);
SelectObject(hdc, CreatePen(PS_SOLID, 2, 0));
SetROP2(hdc, R2_NOTXORPEN);
x = rt.right - rt.left;
MoveToEx(hdc, x, 0, NULL); LineTo(hdc, x, rt.bottom - rt.top);
ReleaseDC(GetParent(hwnd), hdc);
SetCapture(hwnd);
}
break;
case WM_MOUSEMOVE:
if ((wParam & MK_LBUTTON) && GetCapture() == hwnd) {
HDC hdc = GetDC(GetParent(hwnd));
SelectObject(hdc, CreatePen(PS_SOLID, 2, 0));
SetROP2(hdc, R2_NOTXORPEN);
MoveToEx(hdc, x, 0, NULL); LineTo(hdc, x, rt.bottom - rt.top); // 擦除
x = rt.right - rt.left + LOWORD(lParam);
MoveToEx(hdc, x, 0, NULL); LineTo(hdc, x, rt.bottom - rt.top); // 畫新
ReleaseDC(GetParent(hwnd), hdc);
}
break;
case WM_LBUTTONUP:
// 擦除線、ReleaseCapture、DeferWindowPos 重佈局...
break;
DeferWindowPos 批量佈局避免多次重繪閃爍。