// splitter.cpp // // Revision Log // // Date Who SAR Notes // ========== === ======= ===================================== // (c) Reliable Software, 1997, 98 // Bartosz Milewski, www.relisoft.com // #include "Splitter.h" #include "message.h" #include "Canvas.h" #include "WindowMaker.h" #include "WindowClassDefinition.h" #include "ControllerPrimitive.h" using namespace rfc; CPens3d::CPens3d() : _penLight(GetSysColor(COLOR_3DLIGHT)), _penHilight(GetSysColor(COLOR_3DHILIGHT)), _penShadow(GetSysColor(COLOR_3DSHADOW)), _penDkShadow(GetSysColor(COLOR_3DDKSHADOW)) {} void SplitterClassDefinition::RegisterClass(HINSTANCE hInst) { rfc::WindowClassDefinition splitterClass("RSSplitterClass", hInst, CSplitController::WindowProcedure); splitterClass.SetSysCursor(IDC_SIZEWE); splitterClass.SetBgSysColor(COLOR_BTNFACE); splitterClass.Register(); } void SplitterMaker::MakeWindow(WindowHandle & hwndSplitter, WindowHandle hwndParent, int childId) { //ChildWinMaker splitterMaker("RSSplitterClass", hwndParent, childId); rfc::WindowMaker splitterMaker("RSSplitterClass", hwndParent.GetInstance()); splitterMaker.SetStyleAsChild(hwndParent, childId); splitterMaker.Create(""); hwndSplitter.Init(splitterMaker); splitterMaker.Show(); } LRESULT CALLBACK CSplitController::WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { CSplitController * pCtrl = rfc::GetLong(hwnd); switch (message) { case WM_CREATE: pCtrl = new CSplitController(hwnd, reinterpret_cast(lParam)); rfc::SetLong(hwnd, pCtrl); return 0; case WM_SIZE: pCtrl->Size(LOWORD(lParam), HIWORD(lParam)); return 0; case WM_PAINT: pCtrl->Paint(); return 0; case WM_LBUTTONDOWN: pCtrl->LButtonDown(MAKEPOINTS(lParam)); return 0; case WM_LBUTTONUP: pCtrl->LButtonUp(MAKEPOINTS(lParam)); return 0; case WM_MOUSEMOVE: if (wParam & MK_LBUTTON) pCtrl->LButtonDrag(MAKEPOINTS(lParam)); return 0; case WM_CAPTURECHANGED: pCtrl->CaptureChanged(); return 0; // Revisit: Abort drag when user presses ESC case WM_DESTROY: rfc::SetLong(hwnd, 0); delete pCtrl; pCtrl = 0; return 0; } return DefWindowProc(hwnd, message, wParam, lParam); } CSplitController::CSplitController(HWND hwnd, CREATESTRUCT * pCreat) : _hwnd(hwnd), _hwndParent(pCreat->hwndParent) {} void CSplitController::Paint() { PaintCanvas canvas(_hwnd); { PenHolder pen(canvas, _pens.Light()); canvas.Line(0, 0, 0, _cy - 1); } { PenHolder pen(canvas, _pens.Hilight()); canvas.Line(1, 0, 1, _cy - 1); } { PenHolder pen(canvas, _pens.Shadow()); canvas.Line(_cx - 2, 0, _cx - 2, _cy - 1); } { PenHolder pen(canvas, _pens.DkShadow()); canvas.Line(_cx - 1, 0, _cx - 1, _cy - 1); } } void CSplitController::LButtonDown(POINTS pt) { _hwnd.CaptureMouse(); // Find x offset of splitter // with respect to parent client area POINT ptOrg = {0, 0 }; _hwndParent.ClientToScreen(ptOrg); int xParent = ptOrg.x; ptOrg.x = 0; _hwnd.ClientToScreen(ptOrg); int xChild = ptOrg.x; _dragStart = xChild - xParent + _cx / 2 - pt.x; _dragX = _dragStart + pt.x; // Draw a divider using XOR mode AnimationCanvas canvas(_hwndParent); ModeSetter mode(canvas, R2_NOTXORPEN); canvas.Line(_dragX, 0, _dragX, _cy - 1); } void CSplitController::LButtonDrag(POINTS pt) { if (_hwnd.HasCapture()) { // Erase previous divider and draw new one AnimationCanvas canvas(_hwndParent); ModeSetter mode(canvas, R2_NOTXORPEN); canvas.Line(_dragX, 0, _dragX, _cy - 1); _dragX = _dragStart + pt.x; canvas.Line(_dragX, 0, _dragX, _cy - 1); } } void CSplitController::LButtonUp(POINTS pt) { // Calling ReleaseCapture will send us the WM_CAPTURECHANGED _hwnd.ReleaseMouse(); _hwndParent.SendMessage(MSG_MOVESPLITTER, _dragStart + pt.x); } void CSplitController::CaptureChanged() { // We are losing capture // End drag selection -- for whatever reason // Erase previous divider AnimationCanvas canvas(_hwndParent); ModeSetter mode(canvas, R2_NOTXORPEN); canvas.Line(_dragX, 0, _dragX, _cy - 1); }