Code: Select all
#include <windows.h>
#define MINSIZE 50 // The minimal width And height a childwindow should have
#define SBS 2 // Short For SplitterBarSize
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
Static HWND hwndChild1, hwndChild2, hwndChild3;
Static CREATESTRUCT *cs;
Static HCURSOR hcSizeNS, hcSizeEW, hcArrow;
Static int xDiv, yDiv;
Static BOOL xSizing, ySizing;
int xPos, yPos;
RECT rect, focusrect;
HDC hdc;
switch(iMsg)
{
Case WM_CREATE :
cs = (CREATESTRUCT *)lParam;
xDiv = 300;
yDiv = 300;
hwndChild1 = CreateWindowEx(WS_EX_CLIENTEDGE, "Pane 1", "Child 1",
WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN,
0, 0, 0, 0, hwnd, NULL, cs->hInstance, NULL);
hwndChild2 = CreateWindowEx(WS_EX_CLIENTEDGE, "Pane 2", "Child 2",
WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN,
0, 0, 0, 0, hwnd, NULL, cs->hInstance, NULL);
hwndChild3 = CreateWindowEx(WS_EX_CLIENTEDGE, "Pane 3", "Child 3",
WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN,
0, 0, 0, 0, hwnd, NULL, cs->hInstance, NULL);
hcSizeNS = LoadCursor(NULL, IDC_SIZENS);
hcSizeEW = LoadCursor(NULL, IDC_SIZEWE);
hcArrow = LoadCursor(NULL, IDC_ARROW);
Break;
Case WM_SIZE :
GetClientRect(hwnd, &rect);
// Make sure splitterbars are visible
If(xDiv > rect.right - MINSIZE)
{
xDiv = rect.right - MINSIZE;
}
Else If(xDiv < MINSIZE)
{
xDiv = MINSIZE;
}
If(yDiv > rect.bottom - MINSIZE)
{
yDiv = rect.bottom - MINSIZE;
}
Else If(yDiv < MINSIZE)
{
yDiv = MINSIZE;
}
MoveWindow(hwndChild1, rect.left, rect.top + 1,
rect.left + xDiv - SBS, rect.top + yDiv - SBS, FALSE);
MoveWindow(hwndChild2, rect.left + xDiv + SBS,
rect.top + 1, rect.right - rect.left - xDiv - SBS, rect.top + yDiv - SBS, FALSE);
MoveWindow(hwndChild3, rect.left, rect.top + yDiv + SBS,
rect.right - rect.left, rect.bottom - rect. top - yDiv - SBS, FALSE);
InvalidateRect(hwnd, &rect, TRUE);
Break;
Case WM_LBUTTONDOWN :
xPos = (int)LOWORD(lParam);
yPos = (int)HIWORD(lParam);
xSizing = (xPos > xDiv - SBS && xPos < xDiv + SBS);
ySizing = (yPos > yDiv - SBS && yPos < yDiv + SBS);
If(xSizing || ySizing)
{
SetCapture(hwnd); // Track movement of the mousepointer
If(xSizing)
{
SetCursor(hcSizeEW);
}
Else If(ySizing)
{
SetCursor(hcSizeNS);
}
}
Break;
Case WM_LBUTTONUP :
If(xSizing || ySizing)
{
ReleaseCapture();
hdc = GetDC(hwnd);
GetClientRect(hwnd, &rect);
If(xSizing)
{
SetRect(&focusrect, xDiv - SBS, rect.top, xDiv + SBS, yDiv);
DrawFocusRect(hdc, &focusrect);
xSizing = FALSE;
}
If(ySizing)
{
SetRect(&focusrect, rect.left + 1, yDiv - SBS, rect.right, yDiv + SBS);
DrawFocusRect(hdc, &focusrect);
ySizing = FALSE;
}
ReleaseDC(hwnd, hdc);
}
// Post a size message so the childwindows get their new size
PostMessage(hwnd, WM_SIZE, 0, 0);
Break;
Case WM_MOUSEMOVE :
xPos = (int)LOWORD(lParam);
yPos = (int)HIWORD(lParam);
If(wParam == MK_LBUTTON) // Is one of the splitterbars being moved?
{
If(xSizing || ySizing)
{
hdc = GetDC(hwnd);
GetClientRect(hwnd, &rect);
If(xSizing)
{
SetRect(&focusrect, xDiv - SBS, rect.top, xDiv + SBS, yDiv);
DrawFocusRect(hdc, &focusrect);
xDiv = xPos;
SetRect(&focusrect, xDiv - SBS, rect.top, xDiv + SBS, yDiv);
DrawFocusRect(hdc, &focusrect);
}
If(ySizing)
{
SetRect(&focusrect, rect.left + 1, yDiv - SBS, rect.right, yDiv + SBS);
DrawFocusRect(hdc, &focusrect);
yDiv = yPos;
SetRect(&focusrect, rect.left + 1, yDiv - SBS, rect.right, yDiv + SBS);
DrawFocusRect(hdc, &focusrect);
}
ReleaseDC(hwnd, hdc);
}
Break; // Leave
}
If( (xPos > xDiv - SBS && xPos < xDiv + SBS) && GetCursor() != hcSizeEW )
{
SetCursor(hcSizeEW); // hovering above the vertical splitterbar
}
Else If( (yPos > yDiv - SBS && yPos < yDiv + SBS) && GetCursor() != hcSizeNS )
{
SetCursor(hcSizeNS); // hovering above the horizontal splitterbar
}
Else If(GetCursor() != hcArrow)
{
SetCursor(hcArrow); // not hovering above a splitterbar
}
Break;
Case WM_CLOSE :
DestroyWindow(hwnd);
Break;
Case WM_DESTROY :
PostQuitMessage(0);
Break;
}
Return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
LRESULT CALLBACK Child1WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
switch(iMsg)
{
Case WM_CREATE :
Break;
}
Return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
LRESULT CALLBACK Child2WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
switch(iMsg)
{
Case WM_CREATE :
Break;
}
Return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
LRESULT CALLBACK Child3WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
switch(iMsg)
{
Case WM_CREATE :
Break;
}
Return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
char szAppName[] = "SplitterApp";
wndclass.style = 0;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(hInstance, szAppName);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
wndclass.lpszMenuName = szAppName;
wndclass.lpszClassName = szAppName;
RegisterClass(&wndclass);
wndclass.lpfnWndProc = Child1WndProc;
wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wndclass.lpszClassName = "Pane 1";
RegisterClass(&wndclass);
wndclass.lpfnWndProc = Child2WndProc;
wndclass.lpszClassName = "Pane 2";
RegisterClass(&wndclass);
wndclass.lpfnWndProc = Child3WndProc;
wndclass.lpszClassName = "Pane 3";
RegisterClass(&wndclass);
hwnd = CreateWindow(szAppName, szAppName, WS_OVERLAPPEDWINDOW | SW_MAXIMIZE | WS_VISIBLE,
0, 0, 600, 500, NULL, NULL, hInstance, szCmdLine);
While (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Return (int)msg.wParam;
}