没有提供现成的窗口拆分器,实现起来也不难,下面这个例子把窗口拆分成了三个部分。
// splitter.h
#include <windows.h>
#include <windowsx.h>
#include <tchar.h>
// splitter.cpp
#include "splitter.h"
HWND hEdit0, hEdit1, hEdit2;
HCURSOR hSizeNS, hSizeWE;
BOOL bHMoving, bVMoving;
INT nHPos, nVPos;
BOOL OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct)
{
hEdit0 = CreateWindowEx(WS_EX_CLIENTEDGE, _T("Edit"), NULL,
WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE,
0, 0, 0, 0, hwnd, NULL, lpCreateStruct->hInstance, NULL);
hEdit1 = CreateWindowEx(WS_EX_CLIENTEDGE, _T("Edit"), NULL,
WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE,
0, 0, 0, 0, hwnd, NULL, lpCreateStruct->hInstance, NULL);
hEdit2 = CreateWindowEx(WS_EX_CLIENTEDGE, _T("Edit"), NULL,
WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE,
0, 0, 0, 0, hwnd, NULL, lpCreateStruct->hInstance, NULL);
hSizeNS = LoadCursor(NULL, IDC_SIZENS);
hSizeWE = LoadCursor(NULL, IDC_SIZEWE);
bHMoving = bVMoving = FALSE;
nHPos = nVPos = 300;
return TRUE;
}
VOID OnMouseMove(HWND hwnd, INT x, INT y, UINT keyFlags)
{
RECT rc;
GetClientRect(hwnd, &rc);
if (MK_LBUTTON != keyFlags) bHMoving = bVMoving = FALSE;
if ((x < nVPos || bHMoving) && !bVMoving)
{
SetCursor(hSizeNS);
if (MK_LBUTTON == keyFlags && bHMoving)
{
nHPos = y - 2;
SendMessage(hwnd, WM_SIZE, 0, MAKELPARAM(rc.right, rc.bottom));
}
}
else if (x >= nVPos || bVMoving)
{
SetCursor(hSizeWE);
if (MK_LBUTTON == keyFlags && bVMoving)
{
nVPos = x - 2;
SendMessage(hwnd, WM_SIZE, 0, MAKELPARAM(rc.right, rc.bottom));
}
}
}
VOID OnLButtonDown(HWND hwnd, BOOL fDoubleClick, INT x, INT y, UINT keyFlags)
{
SetCapture(hwnd);
if (x < nVPos)
{
SetCursor(hSizeNS);
bHMoving = TRUE;
}
else
{
SetCursor(hSizeWE);
bVMoving = TRUE;
}
}
VOID OnLButtonUp(HWND hwnd, INT x, INT y, UINT keyFlags)
{
ReleaseCapture();
bHMoving = bVMoving = FALSE;
}
VOID OnSize(HWND hwnd, UINT state, INT cx, INT cy)
{
if (SIZE_MINIMIZED != state)
{
if (cy - 39 < nHPos) nHPos = cy - 39;
else if (35 > nHPos) nHPos = 35;
if (cx - 39 < nVPos) nVPos = cx - 39;
else if (35 > nVPos) nVPos = 35;
}
MoveWindow(hEdit0, 0, 0, nVPos, nHPos, TRUE);
MoveWindow(hEdit1, 0, nHPos + 5, nVPos, cy - nHPos - 5, TRUE);
MoveWindow(hEdit2, nVPos + 5, 0, cx - nVPos - 5, cy, TRUE);
}
VOID OnDestroy(HWND hwnd) { PostQuitMessage(0); }
LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
HANDLE_MSG(hwnd, WM_CREATE, OnCreate);
HANDLE_MSG(hwnd, WM_MOUSEMOVE, OnMouseMove);
HANDLE_MSG(hwnd, WM_LBUTTONDOWN, OnLButtonDown);
HANDLE_MSG(hwnd, WM_LBUTTONUP, OnLButtonUp);
HANDLE_MSG(hwnd, WM_SIZE, OnSize);
HANDLE_MSG(hwnd, WM_DESTROY, OnDestroy);
default: return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}
VOID SplitterMain()
{
WNDCLASS wnd = { 0 };
MSG msg;
wnd.lpfnWndProc = WndProc;
wnd.hInstance = GetModuleHandle(NULL);
wnd.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
wnd.lpszClassName = _T("Splitter");
if (!CreateWindow((TCHAR*)RegisterClass(&wnd), _T("Splitter"), WS_OVERLAPPEDWINDOW | WS_VISIBLE,
(GetSystemMetrics(SM_CXSCREEN) - 640) >> 1,
(GetSystemMetrics(SM_CYSCREEN) - 480) >> 1,
640, 480, NULL, NULL, wnd.hInstance, NULL)) ExitProcess(0);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
ExitProcess(msg.wParam);
}
Win32 SDK 拆分窗口。
Win32 SDK 拆分窗口。2009-06-30 22:55