\ File: splitter.f \ Author: Jeff Kelm \ Created: 12-May-1999 \ Updated: 19-May-1999 Comment: Revision History (most recent first) 19990519 - sFrame now defined in WinBase.f 19990517 - Changed styles of panes for wider border and to use standard NW sizing cursor. - Added result values for WM_LBUTTONDOWN and WM_LBUTTONUP messages (should return 0 if processed). - Added WM_SIZE message processing. 19990512 - Created file Comment; Comment: ------------------------------------------------------ Source: http://www.fortunecity.com/skyscraper/corel/378/winasm_snp.html Author: lord-lucifer@usa.net Multiple-Pane Splitter Bar This bit of code will show you a very easy way to implement a vertical splitter (as in explorer). Using this method, the parent window handles all of the resizing. The child windows are positioned so that only the space between them shows through. This space (which is part of the parent) is the splitter bar. When you create the main window's class, you may want to change the hCursor member to IDC_SIZEWE or something similar so it changes when the mouse is put over it. The iSeparatorPos variable holds the current x-position of the splitter bar. Of course, this is not the only (or best) way to implement these splitter bars. For instance, this method may have difficulty with more than 2 panes, or when there are horiontal and vertical splitters... ; These go into the MainWindow Procedure: mov eax, uMsg cmp eax, WM_MOUSEMOVE je wmmousemove cmp eax,WM_LBUTTONDOWN je wmlbuttondown cmp eax,WM_LBUTTONUP je wmlbuttonup ... ; mouse is moved wmmousemove: test wParam, MK_LBUTTON jz return ; left button is down, move the splitter mov eax, lParam and eax, 0000FFFFh ;LOWORD(lParam = xpos) mov iSeparatorPos, eax ; get the dimensions of the application window invoke GetWindowRect, hWndMainApp, addr rect ; re-size the left pane mov eax, iSeparatorPos dec eax invoke MoveWindow, hWndLeftPane, 0, 0, eax, rect.bottom, TRUE ; now re-size the right pane mov eax, iSeparatorPos inc eax invoke MoveWindow, hWndLRightPane, eax, 0, rect.right, rect.bottom, TRUE jmp return ; Left mouse button is pressed wmlbuttondown: invoke SetCapture, hWnd jmp return ; Left mouse button is released wmlbuttonup: invoke ReleaseCapture jmp return ------------------------------------------------------ Comment; \ create a stack frame on the parameter stack for u bytes, addr is to top-of-stack item \ : sFrame ( u -- xn .. x2 x1 addr) \ u<=100 \ 100 MIN 0 MAX 0 ?DO 0 LOOP sp@ ; NEEDS ApplWin.f NEEDS Editbox.f 0 VALUE hLeft \ handle of left pane 0 VALUE hRight \ handle of right pane \ Does the work of moving the splitter bar : OnMouseMove { hWnd msg wParam lParam \ iSeparator bottom right top left -- result } wParam MK_LBUTTON = IF \ left button is down, move the splitter lParam LOWORD ( iSeparator) TO iSeparator \ get the dimensions of the application window 4 sFrame rel>abs \ save space on stack for rect (bottom right top left) after call hWnd Call GetClientRect DROP TO left TO top TO right TO bottom \ re-size the left pane \ repaint? Hgt Wdt y x hWnd Call MoveWindow TRUE bottom iSeparator 1- 0 0 hLeft Call MoveWindow DROP \ now re-size the right pane TRUE bottom right iSeparator - 1- 0 iSeparator 1+ hRight Call MoveWindow DROP THEN ; \ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \ \\\ Create the application window \ ApplicationWindow wnd \ the parent window Create: wnd Z" Splitter Window" SetText: wnd IDC_SIZEWE NULL Call LoadCursor GCL_HCURSOR GetHandle: wnd Call SetClassLong DROP COLOR_BTNFACE 1+ GCL_HBRBACKGROUND GetHandle: wnd Call SetClassLong ?WinError 750 450 SetSize: wnd 30 20 SetPosition: wnd GenericMultilineEdit lPane \ the left window pane GetHandle: wnd Create: lPane GetHandle: lPane TO hLeft WS_BORDER +Style: lPane WS_EX_CLIENTEDGE +ExStyle: lPane 0 0 SetPosition: lPane 360 423 SetSize: lPane GenericMultilineEdit rPane \ the right window pane GetHandle: wnd Create: rPane GetHandle: rPane TO hRight WS_BORDER +Style: rPane WS_EX_CLIENTEDGE +ExStyle: rPane 362 0 SetPosition: rPane 380 423 SetSize: rPane \ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \ \\\ Define the application window procedure \ : ResizePanes ( w h) GetSize: lPane DROP DUP >R OVER SetSize: lPane SWAP R> - SWAP SetSize: rPane ; \ This performs the actual window functions specific to our application : (MainWndProc) { hWnd msg wParam lParam -- result } msg CASE WM_MOUSEMOVE OF hWnd msg wParam lParam OnMouseMove ENDOF WM_SIZE OF lParam word-split ( w h) ResizePanes 0 ENDOF WM_LBUTTONDOWN OF hWnd Call SetCapture 0 ENDOF WM_LBUTTONUP OF Call ReleaseCapture 0 ENDOF DEFAULTOF lParam wParam msg hWnd Call DefWindowProc ENDOF ENDCASE ; 4 callback MainWndProc (MainWndProc) \ set the window procedure and make the window visible MainWndProc rel>abs SetWindowProc: wnd Show: wnd