I can't find any splitter window example in all codes i have
i have something from other compiler and C but not in Oxygenbasic.
So i decided that i need one to split in my case listbox (listview) control from
scintilla control in AurelEdit in first place .
Splitter window is just window in most cases child window of main and his main purpose
is to divide two controls or more in same time changing they size .
'########################################################################
'create splitter window
spx = 171 : spy = 58 : spw = 8 : sph = 414
INT spStyle = WS_VISIBLE | WS_CHILD | WS_SYSMENU | WS_BORDER
splitWin = SETWINDOW("",spx,spy,spw,sph, win, spStyle)
then under WM_SIZE:
in my case splitter window is vertical but can be horizontal too
'set splitter window vertical size
MoveWindow(splitWin,spx, 58, 8,(h-76)-6 , 1 )
What i have found so far is old XBlite code
with subclassed static control as splitter bar
FUNCTION StaticProc (hWnd, msg, wParam, lParam)
SPLITTERDATA spdata
STATIC splitterX0, splitterY0
SHARED hCursorH, hCursorV
SHARED moveX, moveY
RECT rect
STATIC fTrackMouse
TRACKMOUSEEVENT tme
hWndParent = GetParent (hWnd)
pData = GetWindowLongA (hWndParent, $$GWL_USERDATA) ' get splitter data
IF pData THEN RtlMoveMemory (&spdata, pData, SIZE(SPLITTERDATA)) ' copy data into local struct spdata
SELECT CASE msg
CASE $$WM_LBUTTONDOWN:
style = spdata.style ' get horz or vert splitter style
IF style = $$SS_HORZ THEN
SetCursor (hCursorH) ' set cursor
ELSE
SetCursor (hCursorV)
END IF
SetCapture (hWnd) ' capture the mouse to static control
splitterX0 = LOWORD (lParam) ' get initial x mouse position
splitterY0 = HIWORD (lParam)
CASE $$WM_LBUTTONUP:
ReleaseCapture () ' release the mouse
hSplitter = GetParent (hWnd)
SendMessageA (GetParent (hSplitter), $$WM_SPITTER_BAR_MOVED, 0, 0)
CASE $$WM_MOUSELEAVE:
fTrackMouse = 0
SetCursor (LoadCursorA (0, $$IDC_ARROW)) ' change cursor back to standard arrow
CASE $$WM_MOUSEMOVE:
style = spdata.style
IF style = $$SS_HORZ THEN
last = SetCursor (hCursorH) ' change cursor
ELSE
last = SetCursor (hCursorV)
END IF
IFZ fTrackMouse THEN
tme.cbSize = SIZE(tme)
tme.dwFlags = $$TME_LEAVE
tme.hwndTrack = hWnd
ret = TrackMouseEvent (&tme)
fTrackMouse = $$TRUE
END IF
IF (wParam & $$MK_LBUTTON) THEN ' left button down (drag)
IF style = $$SS_HORZ THEN
moveX = LOWORD (lParam) - splitterX0 ' get delta x mouse position
IFZ moveX THEN RETURN
ELSE
moveY = HIWORD (lParam) - splitterY0
IFZ moveY THEN RETURN
END IF
GetClientRect (hWndParent, &rect) ' get parent size and send WM_SIZE message to splitter control
SendMessageA (hWndParent, $$WM_SIZE, 0, MAKELONG(rect.right, rect.bottom))
END IF
CASE ELSE :
RETURN CallWindowProcA (#old_proc, hWnd, msg, wParam, lParam)
END SELECT
END FUNCTION
Also
I found one from PowerBasic Garry Beene snippets.
I complile it with PB10.3 and work well.
'Compilable Example:
#COMPILER PBWIN 9, PBWIN 10
#COMPILE EXE
#DIM ALL
#DEBUG ERROR ON 'catch array/pointer errors - OFF in production
#DEBUG DISPLAY ON 'display untrapped errors - OFF in production
#INCLUDE "Win32api.inc"
#RESOURCE "gbsnippets.pbr"
%IDC_Left = 500 : %IDC_Right = 501 : %IDC_Bottom = 502
%IDC_LabelH = 532 : %IDC_LabelV = 533 : %IDC_StatusBar = 536 : %IDM_Alternate = 534
%IDC_Toolbar = 537 : %IDM_ShowBottom = 600 : %IDM_Fixed = 601 : %IDT_New = 602
%ID_ImageList = 700 : %IDT_X = 701 : %IDT_Y = 702 : %IDT_Z = 703
' Global Variables: handles =============================================================
GLOBAL hDlg AS DWORD, hTree AS DWORD, hList AS DWORD, hMenu AS DWORD
GLOBAL SplitVInWork AS LONG, SplitHInWork AS LONG, ShowBottom&, hMenuOptions AS DWORD
GLOBAL XSplit AS SINGLE, YSplit AS SINGLE, AlternateLayout&, hLst AS DWORD
GLOBAL HBarLeft AS LONG, VBarTop AS LONG, FixedSplitterBar&
' Main Function =======================================================================
FUNCTION PBMAIN()
DIALOG NEW PIXELS, 0, "Splitter Text",300,300,410,340, %WS_OVERLAPPEDWINDOW OR %WS_CLIPCHILDREN TO hDlg
CONTROL ADD STATUSBAR, hDlg, %IDC_StatusBar, "",0,0,0,0 'xy, xxyy ignored, %ccs_bottom by default
CONTROL ADD TOOLBAR, hDlg, %IDC_Toolbar, "Toolbar",0,0,0,0 'xy, xxyy, txt$ ignored, %ccs_top by default
'create imagelist for Toolbar
IMAGELIST NEW ICON 16,16,32,3 TO hLst
IMAGELIST ADD ICON hLst, "x" '1
IMAGELIST ADD ICON hLst, "y" '2
IMAGELIST ADD ICON hLst, "z" '3
'attach imagelist
TOOLBAR SET IMAGELIST hDlg, %IDC_Toolbar, hLst, 0
'create buttons
TOOLBAR ADD BUTTON hDlg, %IDC_Toolbar, 1, %IDT_X, %TBSTYLE_CHECK, "X"
TOOLBAR ADD BUTTON hDlg, %IDC_Toolbar, 2, %IDT_Y, %TBSTYLE_CHECK, "Y"
TOOLBAR ADD BUTTON hDlg, %IDC_Toolbar, 3, %IDT_Y, %TBSTYLE_CHECK, "Z"
'create menu
MENU NEW BAR TO hMenu
MENU NEW POPUP TO hMenuOptions
MENU ADD POPUP, hMenu, "&Options", hMenuOptions, %MF_ENABLED
MENU ADD STRING, hMenuOptions, "&Alternate Layout", %IDM_Alternate, %MF_ENABLED
MENU ADD STRING, hMenuOptions, "&Hide Bottom", %IDM_ShowBottom, %MF_ENABLED
MENU ADD STRING, hMenuOptions, "&Fixed Position", %IDM_Fixed, %MF_ENABLED
MENU ATTACH hMenu, hDlg
The XSed-Editor from XBLite (last Sign of Live in 2020) was made as a fork from Jose's SED-Editor.
So in Jose's code there should also be this feature.
Yes Theo it is by Jose
and yes it have splitter but horizontal with some sort of tiny button or
rebar docker or something ..but i need simple splitter nothing fancy
by the way Garry example work well too.
spliter from XBlite as splitter from Powerbasic ..both uses static control if i get it right
in PB is called LABEL.
In o2 i use child Window..and finally get it that mouse pointer cursor
change when is over that splitter window
SELECT hWnd
CASE splitWin
select wMsg
CASE WM_LBUTTONDOWN
CASE WM_MOUSEMOVE
GetMouseX = LoWord(lParam)
GetMouseY = HiWord(lParam)
if (GetMouseX > spx+1) or (GetMouseX < spx+7)
SetCursor(LoadCursor(0, IDC_SIZEWE)) ' change cursor back to standard arrow
end if
end select
Well so far nothing
this DDT syntax is very awkward and is not easy to translate code from PowerBasic to OxygenBasic
even on PB Garry examples work really well and properly ...also he use Dialogs not Windows.
Garry made great job with all this snippets..
There is example without subclassing :
'Features:
'1. Two different layouts
'2. Both a horizontal and vertical splitter bars (horizontal bar can be removed)
'3. Splitter bar positions can be fixed position or positioned on a percentage basis
'Primary Code;
'Due to the length of this example, on a description will be covered in this section.
'See the compilable example below for the source code.
'Splitter bar action is accomplished by detecting the presence of a mouse click and
'drag movement. This can be done by monitoring mouse action over a control, over simply
'over an area of the dialog. This approach uses label controls as the splitter bars - one
'for vertical splitting and one for horizontal splitting.
'The code sections/functions used in the compilable example below are:
'1. %WM_SetCursor - detects mouse clicks and movement
'2. Sub MoveBarUpDown - moves horizontal bar in response to mouse action
'3. Sub MoveBarLeftRight - moves vertical bar in response to mouse action
'4. Sub ResizeWindow - adjusts controls in response to user resizing of dialog
'5. Sub ResizeSplitterBars - adjust splitter bars in response to user resizing of dialog
'6. Sub SetControlVisibility - used to show/hide controls according to layout option selection
'Compilable Example:
#COMPILER PBWIN 9, PBWIN 10
#COMPILE EXE
#DIM ALL
#DEBUG ERROR ON 'catch array/pointer errors - OFF in production
#DEBUG DISPLAY ON 'display untrapped errors - OFF in production
#INCLUDE "Win32api.inc"
#RESOURCE "gbsnippets.pbr"
%IDC_Left = 500 : %IDC_Right = 501 : %IDC_Bottom = 502
%IDC_LabelH = 532 : %IDC_LabelV = 533 : %IDC_StatusBar = 536 : %IDM_Alternate = 534
%IDC_Toolbar = 537 : %IDM_ShowBottom = 600 : %IDM_Fixed = 601 : %IDT_New = 602
%ID_ImageList = 700 : %IDT_X = 701 : %IDT_Y = 702 : %IDT_Z = 703
' Global Variables: handles =============================================================
GLOBAL hDlg AS DWORD, hTree AS DWORD, hList AS DWORD, hMenu AS DWORD
GLOBAL SplitVInWork AS LONG, SplitHInWork AS LONG, ShowBottom&, hMenuOptions AS DWORD
GLOBAL XSplit AS SINGLE, YSplit AS SINGLE, AlternateLayout&, hLst AS DWORD
GLOBAL HBarLeft AS LONG, VBarTop AS LONG, FixedSplitterBar&
' Main Function =======================================================================
FUNCTION PBMAIN()
DIALOG NEW PIXELS, 0, "Splitter Text",300,300,410,340, %WS_OVERLAPPEDWINDOW OR %WS_CLIPCHILDREN TO hDlg
CONTROL ADD STATUSBAR, hDlg, %IDC_StatusBar, "",0,0,0,0 'xy, xxyy ignored, %ccs_bottom by default
CONTROL ADD TOOLBAR, hDlg, %IDC_Toolbar, "Toolbar",0,0,0,0 'xy, xxyy, txt$ ignored, %ccs_top by default
'create imagelist for Toolbar
IMAGELIST NEW ICON 16,16,32,3 TO hLst
IMAGELIST ADD ICON hLst, "x" '1
IMAGELIST ADD ICON hLst, "y" '2
IMAGELIST ADD ICON hLst, "z" '3
'attach imagelist
TOOLBAR SET IMAGELIST hDlg, %IDC_Toolbar, hLst, 0
'create buttons
TOOLBAR ADD BUTTON hDlg, %IDC_Toolbar, 1, %IDT_X, %TBSTYLE_CHECK, "X"
TOOLBAR ADD BUTTON hDlg, %IDC_Toolbar, 2, %IDT_Y, %TBSTYLE_CHECK, "Y"
TOOLBAR ADD BUTTON hDlg, %IDC_Toolbar, 3, %IDT_Y, %TBSTYLE_CHECK, "Z"
'create menu
MENU NEW BAR TO hMenu
MENU NEW POPUP TO hMenuOptions
MENU ADD POPUP, hMenu, "&Options", hMenuOptions, %MF_ENABLED
MENU ADD STRING, hMenuOptions, "&Alternate Layout", %IDM_Alternate, %MF_ENABLED
MENU ADD STRING, hMenuOptions, "&Hide Bottom", %IDM_ShowBottom, %MF_ENABLED
MENU ADD STRING, hMenuOptions, "&Fixed Position", %IDM_Fixed, %MF_ENABLED
MENU ATTACH hMenu, hDlg
'add the controls + splitter bars (labels)
CONTROL ADD TEXTBOX, hDlg, %IDC_Left, "TopLeft", 20, 80, 160, 80
CONTROL ADD TEXTBOX, hDlg, %IDC_Bottom, "Bottom", 20, 200, 370, 90
CONTROL ADD TEXTBOX, hDlg, %IDC_Right, "TopRight", 220, 55, 170, 100
CONTROL ADD LABEL, hDlg, %IDC_LabelH, "", 200, 45, 6, 125, %SS_NOTIFY , %WS_EX_CLIENTEDGE ' up/down - does horizontal split
CONTROL ADD LABEL, hDlg, %IDC_LabelV, "", 0,170, 410, 6, %SS_NOTIFY , %WS_EX_CLIENTEDGE ' left/right - does vertical split
XSplit = 0.5 : YSplit = 0.5 : ShowBottom& = 1 : HBarLeft = 100 : VBarTop = 100
MENU SET STATE hMenuOptions, BYCMD %IDM_ShowBottom, ShowBottom& * 8
DIALOG SHOW MODAL hDlg CALL DlgProc()
END FUNCTION
'monitor mouse movement=================================
CALLBACK FUNCTION DlgProc() AS LONG
LOCAL iReturn AS LONG, x AS LONG, y AS LONG, w AS LONG, h AS LONG
SELECT CASE CB.MSG
CASE %WM_COMMAND
SELECT CASE CB.CTL
CASE %IDM_Alternate
AlternateLayout& = AlternateLayout& XOR 1 'flip between 0 and 1
MENU SET STATE hMenuOptions, BYCMD %IDM_Alternate, AlternateLayout& * 8
ResizeWindow
CASE %IDM_ShowBottom
ShowBottom& = ShowBottom& XOR 1 'flip between 0 and 1
MENU SET STATE hMenuOptions, BYCMD %IDM_ShowBottom, ShowBottom& * 8
ResizeWindow
CASE %IDM_Fixed
FixedSplitterBar& = FixedSplitterBar& XOR 1 'flip between 0 and 1
MENU SET STATE hMenuOptions, BYCMD %IDM_Fixed, FixedSplitterBar& * 8
DIALOG GET CLIENT hDlg TO w,h
'adjusts VBarTop/HBarLeft or xSplit/ySplit when option is changed
'both are not kept current at all times - only the pair in use
IF FixedSplitterBar& THEN
VBarTop = h - ySplit * h
HBarLeft = xSplit * w
ELSE
ySplit = (h-VBarTop) / h
xSplit = HBarLeft / w
END IF
ResizeWindow
CASE %IDT_X, %IDT_Y, %IDT_Z
MSGBOX "No action. Toolbar included just to show how splitter bars work with toolbar in place.", %MB_OK + %MB_ICONINFORMATION, "Toolbar Button Pressed"
END SELECT
CASE %WM_SIZE
ResizeWindow
CASE %WM_SetCursor
iReturn = GetDlgCtrlID (CB.WPARAM)
'identify over which label control the mouse action took place
IF iReturn = %IDC_LabelH THEN MOUSEPTR 9 : FUNCTION = 1 '9 = horizontal cursor
IF iReturn = %IDC_LabelV THEN MOUSEPTR 7 : FUNCTION = 1 '7 = vertical cursor
'monitors the 3 basic splitter bar mouse actions, lbuttondown, mousemose, lbuttonup
SELECT CASE HI(WORD, CB.LPARAM)
CASE %WM_LBUTTONDOWN
'sets flags to say splitter action has started (no actual movement yet)
IF iReturn = %IDC_LabelV THEN SplitVInWork = 1
IF iReturn = %IDC_LabelH THEN SplitHInWork = 1
CASE %WM_MOUSEMOVE
'Repositions splitter bars to match mouse position (if position has changed)
IF SplitVInWork THEN IF MoveBarUpDown THEN ResizeWindow
IF SplitHInWork THEN IF MoveBarLeftRight THEN ResizeWindow
CASE %WM_LBUTTONUP
'sets flags to say splitter action has ended
SplitHInWork = 0 : SplitVInWork = 0
END SELECT
END SELECT
END FUNCTION
FUNCTION MoveBarUpDown AS LONG
LOCAL pt AS POINT, h AS LONG, w AS LONG
STATIC oldY AS LONG
DIALOG GET CLIENT hDlg TO w,h
GetCursorPos pt 'pt has xy screen coordinates
ScreenToClient hDlg, pt 'pt now has client coordinates
' If h-pt.y < 50 Then Exit Function 'limit right motion 'optional
' If pt.y < 50 Then Exit Function 'optional
YSplit = (pt.y-3) / h 'actually, should only do one or the other
VBarTop = h - (Pt.y-3) 'actually, should only do one or the other
IF pt.y <> oldY THEN FUNCTION = %True : oldY = pt.y
END FUNCTION
FUNCTION MoveBarLeftRight AS LONG
LOCAL pt AS POINT, h AS LONG, w AS LONG
STATIC oldX AS LONG
DIALOG GET CLIENT hDlg TO w,h
GetCursorPos pt 'pt has xy screen coordinates
ScreenToClient hDlg, pt 'pt now has client coordinates
' If w-pt.x < 50 Then Exit Function 'limit right motion 'optional
' If pt.x < 50 Then Exit Function 'optional
XSplit = (pt.x-3) / w 'actually, should only do one or the other
HBarLeft = pt.x-3 'actually, should only do one or the other
IF pt.x <> oldX THEN FUNCTION = %True : oldX = pt.x
END FUNCTION
SUB ResizeWindow
LOCAL vx AS LONG, vy AS LONG, hx AS LONG, hy AS LONG, h AS LONG, w AS LONG
SetControlVisibility
ResizeSplitterBars
DIALOG GET SIZE hDlg TO w,h
CONTROL GET LOC hDlg, %IDC_LabelH TO hx, hy
CONTROL GET LOC hDlg, %IDC_LabelV TO vx, vy
'Resize controls
IF ShowBottom& = 0 THEN
'simple side by side of tree and richedit
CONTROL SET LOC hDlg, %IDC_Left, 5, 47
CONTROL SET SIZE hDlg, %IDC_Left, hx - 10, h - 122
CONTROL SET LOC hDlg, %IDC_Right, hx + 9, 47
CONTROL SET SIZE hDlg, %IDC_Right, w - hx - 24, h - 122
STATUSBAR SET PARTS hDlg, %IDC_StatusBar, w/3, w/3, w/3
ELSEIF AlternateLayout& = 0 THEN
'left beside right - both over bottom
CONTROL SET LOC hDlg, %IDC_Left, 5, 47
CONTROL SET SIZE hDlg, %IDC_Left, hx - 10, vy - 50
CONTROL SET LOC hDlg, %IDC_Right, hx + 9, 47
CONTROL SET SIZE hDlg, %IDC_Right, w - hx - 24, vy - 50
CONTROL SET LOC hDlg, %IDC_Bottom, 5, vy + 8
CONTROL SET SIZE hDlg, %IDC_Bottom, w - 20, h - vy - 85
STATUSBAR SET PARTS hDlg, %IDC_StatusBar, w/3, w/3, w/3
ELSEIF AlternateLayout& THEN
'left over bottom, right top-to-bottom of page
CONTROL SET LOC hDlg, %IDC_Left, 5, 47
CONTROL SET SIZE hDlg, %IDC_Left, hx - 10, vy - 50
CONTROL SET LOC hDlg, %IDC_Right, hx + 9, 47
CONTROL SET SIZE hDlg, %IDC_Right, w - hx - 24, h - 122
CONTROL SET LOC hDlg, %IDC_Bottom, 5, vy + 8
CONTROL SET SIZE hDlg, %IDC_Bottom, hx - 10, h - vy - 85
STATUSBAR SET PARTS hDlg, %IDC_StatusBar, w/3, w/3, w/3
END IF
DIALOG REDRAW hDlg
END SUB
SUB ResizeSplitterBars
LOCAL h AS LONG, w AS LONG, HLeft AS LONG, VTop AS LONG
DIALOG GET CLIENT hDlg TO w,h
'position does not depend on layout
IF FixedSplitterBar& THEN
VTop = h - VBarTop
HLeft = HBarLeft
ELSE
VTop = ySplit*h
HLeft = xSplit*w
END IF
CONTROL SET LOC hDlg, %IDC_LabelV, 5, VTop
CONTROL SET LOC hDlg, %IDC_LabelH, HLeft, 45
IF ShowBottom& = 0 THEN
CONTROL SET SIZE hDlg, %IDC_LabelH, 6, h-66 'tree + richedit only
ELSEIF AlternateLayout& = 0 THEN
CONTROL SET SIZE hDlg, %IDC_LabelV, w-12, 6
CONTROL SET SIZE hDlg, %IDc_LabelH, 6, VTop-48
ELSEIF AlternateLayout& THEN
'tree over listview. richedit top-to-bottom of page
CONTROL SET SIZE hDlg, %IDC_LabelV, HLeft-10, 6
CONTROL SET SIZE hDlg, %IDC_LabelH, 6, h - 66
END IF
END SUB
SUB SetControlVisibility
'Find controls are always visible
'Left, Right Controls are always visible
IF ShowBottom& = 0 THEN
'simple side by side of left and right (no bottom)
CONTROL SHOW STATE hDlg, %IDC_LabelV, %SW_HIDE
CONTROL SHOW STATE hDlg, %IDC_Bottom, %SW_HIDE
CONTROL SHOW STATE hDlg, %IDC_Statusbar, %SW_SHOW
ELSE
'either layout, with bottom showing
'left beside right, both ver bottom OR
'left over bottom, right top-to-bottom of page
CONTROL SHOW STATE hDlg, %IDC_LabelV, %SW_SHOW
CONTROL SHOW STATE hDlg, %IDC_Bottom, %SW_SHOW
CONTROL SHOW STATE hDlg, %IDC_Statusbar, %SW_SHOW
END IF
END SUB
Here is an example of a splitter using a modal dialog...
//KickResource "D:\Dev\Oxygen\o2\~code\~~~Resource.res" //Kick precompiler add a manifest for CommonControl-6 to co2.exe
//KickSwicht -run -64
//KickEnd
'*Add a resource manifest
'See interesting autosizing '\Oxygen\o2\demos\WinGUI\Autosizing\Demo7Dlg.o2bas
#autodim off
uses dialogs // \Oxygen\o2\inc\Dialogs.inc
%EditTop 101
%EditBot 102
%SplitHorz 902
%WM_NCACTIVATE 0x086
%WM_GETMINMAXINFO 0x0024
%WM_SETCURSOR 0x0020
%WM_NEXTDLGCTL 0x28
%IDC_SIZENS 32645
%IMAGE_CURSOR 2
%LR_LOADTRANSPARENT 0x20
%LR_SHARED 0x8000
%HWND_DESKTOP 0
%SIZE_MINIMIZED 1
%RDW_FRAME 0x0400
%RDW_ERASE 0x0004
%RDW_INVALIDATE 0x0001
%DWLP_MSGRESULT 0
type POINTFLOAT
single x
single y
end type
function MakeIntResource(byval word wInteger) as dword
return wInteger
end function
%ICC_STANDARD_CLASSES 0x4000
type INIT_COMMON_CONTROLSEX
DWORD dwSize
DWORD dwICC
end type
! function InitCommonControlsEx lib "COMCTL32.DLL" ALIAS "InitCommonControlsEx"
(BYREF lpInitCtrls AS INIT_COMMON_CONTROLSEX) as long 'nzok
'_____________________________________________________________________________
function DlgProc(sys hDlg, uint uMsg, sys wParam, lParam) as bool callback
static point DlgArea
point CursorPos
static point Delta
static point SplitPos
static pointfloat Ratio
rect rcSplitHorz
static sys hCursorUpDwn
static sys hSplitHorz
static sys hEditTop
static sys hEditBot
static dword Marge
static sys hDragging
select case uMsg
case WM_INITDIALOG
static sys hBrush = CreateSolidBrush(Blue)
static sys hIcon = ExtractIcon(GETMODULEHANDLE(""), "Shell32.dll", 294) 'o
SendMessage(hDlg, WM_SETICON, ICON_SMALL, hIcon)
hEditTop = GetDlgItem(hDlg, EditTop)
hEditBot = GetDlgItem(hDlg, EditBot)
hSplitHorz = GetDlgItem(hDlg, SplitHorz)
hCursorUpDwn = LoadCursor(NULL, MakeIntResource(IDC_SIZENS))
GetWindowRect(hSplitHorz, rcSplitHorz)
MapWindowPoints(HWND_DESKTOP, hDlg, @rcSplitHorz, 2)
Marge = rcSplitHorz.Left * 2
Ratio.Y = 0.40 'Top of splitter bar / height of client area
PostMessage(hEditTop, %EM_SETSEL, -1, 0) 'Set caret at the end of text
case WM_COMMAND
sys id = loword(wParam)
sys event = hiword(wParam)
select case id
case IDCANCEL 'Escape key
EndDialog(hDlg, 0)
end select
case WM_SETCURSOR
if wParam = hSplitHorz then
SetCursor(hCursorUpDwn)
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, true)
if hiword(LPARAM) = WM_LBUTTONDOWN then
GetCursorPos(CursorPos)
ScreenToClient(hDlg, CursorPos)
Delta.y = CursorPos.y - SplitPos.y 'Offset between top of splitter bar and vertical cursor position inside splitter bar
hDragging = wParam
SetCapture(hDlg) 'To get cursor pos and button-up feedback even when the cursor is not inside the dialog.
end if
return true
end if
return false
case WM_MOUSEMOVE
if hDragging = hSplitHorz then 'Cursor on horizontal splitterbar
CursorPos.y = hiword(LPARAM)
if CursorPos.y >= Delta.y + 5 then 'Prevent over top border dialog limit
if CursorPos.y <= DlgArea.y - Delta.y - 5 then 'Prevent over bottom border dialog limit
SplitPos.y = CursorPos.y - Delta.y
Ratio.Y = SplitPos.y / DlgArea.Y
MoveWindow(hSplitHorz, Marge, SplitPos.y, DlgArea.x - Marge * 2, Marge \ 2, true)
MoveWindow(hEditBot, Marge, SplitPos.y + Marge, DlgArea.x - Marge * 2, DlgArea.Y - SplitPos.y - Marge * 2, true)
MoveWindow(hEditTop, Marge, Marge, DlgArea.X - Marge * 2, convert long(SplitPos.y - Marge * 1.7), true)
end if
end if
end if
case WM_LBUTTONUP 'Left mouse button down to up transition
if hDragging then
ReleaseCapture() 'See SetCapture()
hDragging = false
end if
case WM_SIZE
if wParam <> SIZE_MINIMIZED then
DlgArea.X = loword(LPARAM)
DlgArea.Y = hiword(LPARAM)
SplitPos.y = DlgArea.Y * Ratio.Y
if SplitPos.y > DlgArea.Y - Marge then SplitPos.y = DlgArea.Y - Marge 'Prevent over top dialog limit
if SplitPos.y < 1 then SplitPos.y = 1 'Prevent under bottom dialog limit
MoveWindow(hSplitHorz, Marge, SplitPos.y, DlgArea.x - Marge * 2, Marge \ 2, true)
MoveWindow(hEditBot, Marge, SplitPos.y + Marge, DlgArea.x - Marge * 2, convert long(DlgArea.Y - SplitPos.y - Marge * 2), true)
MoveWindow(hEditTop, Marge, Marge, convert long(DlgArea.X - Marge * 2), convert long(SplitPos.y - Marge * 1.7), true)
RedrawWindow(hEditBot, BYVAL NULL, BYVAL NULL, RDW_FRAME | RDW_ERASE | RDW_INVALIDATE)
end if
case WM_GETMINMAXINFO
MINMAXINFO *MinMaxInfoPtr
@MinMaxInfoPtr = lParam
MinMaxInfoPtr.ptMinTrackSize.X = 350
MinMaxInfoPtr.ptMinTrackSize.Y = 100
case WM_NCACTIVATE
static sys hFocusBak
if wParam = false then 'Application loose focus
hFocusBak = GetFocus()
elseif hFocusBak then
SendMessage(hDlg, WM_NEXTDLGCTL, hFocusBak, 1)
hFocusBak = false
end if
return false
case WM_CTLCOLORSTATIC
if lParam = hSplitHorz then
return(hBrush)
end if
case WM_CLOSE
EndDialog(hDlg, 0)
case WM_DESTROY
DestroyIcon(hIcon)
DeleteObject(hBrush)
case else
return false
end select
return true
end function
'_____________________________________________________________________________
function WinMain()
INIT_COMMON_CONTROLSEX InitControlStruct
InitControlStruct.dwSize = SIZEOF(INIT_COMMON_CONTROLSEX)
InitControlStruct.dwICC = %ICC_STANDARD_CLASSES
InitCommonControlsEX(InitControlStruct)
Dialog(0, 0, 250, 200, "SplitterBar" & sizeof(sys) * 8, WS_VISIBLE | WS_CAPTION | WS_MINIMIZEBOX |
WS_MAXIMIZEBOX | WS_SIZEBOX | WS_SYSMENU | WS_CLIPSIBLINGS | DS_CENTER | DS_SETFONT, 10, "Segoe UI", 0)
string sEdit = quote
-EditQuote- You may resize this dialog in both directions.
The blue STATIC act as splitterbar.
Action should be appropriate even when the drag goes very fast or out of border
-EditQuote-
Control(sEdit, EditTop, "Edit", ES_MULTILINE | ES_LEFT | ES_MULTILINE | WS_TABSTOP | WS_VSCROLL,
2, 2, 246, 100, WS_EX_LEFT | WS_EX_CLIENTEDGE, 0)
Control("", SplitHorz, "Static", WS_CHILD | WS_VISIBLE | SS_NOTIFY, 2, 103, 246, 2, 0, 0)
sEdit = quote
-EditQuote- The splitterbar will stop at the maximum top and maximum bottom.
If the dialog is resized vertically, the splitterbar will move in proportion.
The mouse cursor will change to IDC_SIZENS north-south double arrow when over the splitterbar.
Maximizing the window is no problem.
-EditQuote-
Control(sEdit, EditBot, "Edit", ES_MULTILINE | ES_LEFT | ES_MULTILINE | WS_TABSTOP | WS_VSCROLL,
2, 106, 246, 90, WS_EX_LEFT | WS_EX_CLIENTEDGE, 0)
CreateModalDialog(null, @DlgProc, 0)
end function
'_____________________________________________________________________________
WinMain()
end
'_____________________________________________________________________________
'
An other example of a splitter using SDK...
//KickResource "D:\Dev\Oxygen\o2\~code\~~~Resource.res" //Kick add a manifest for CommonControl-6
//KickEnd
//*See also D:\Dev\Oxygen\o2\demos\WinGUI\Autosizing\Demo7Dlg.o2bas
//*Add a resource manifest
#autodim off
uses dialogs
%EditTop 101
%EditBot 102
%SplitHorz 902
%WM_NCACTIVATE 0x086
%WM_GETMINMAXINFO 0x0024
%WM_SETCURSOR 0x0020
%WM_NEXTDLGCTL 0x28
%IDC_SIZENS 32645
%HWND_DESKTOP 0
%SIZE_MINIMIZED 1
%RDW_FRAME 0x0400
%RDW_ERASE 0x0004
%RDW_INVALIDATE 0x0001
%SPI_GETICONTITLELOGFONT 0x001F
%COLOR_BTNFACE 15
type NONCLIENTMETRICS
long cbSize
long iBorderWidth
long iScrollWidth
long iScrollHeight
long iCaptionWidth
LOGFONT iCaptionHeight
long lfCaptionFont
long iSMCaptionWidth
LOGFONT iSMCaptionHeight
long lfSMCaptionFont
long iMenuWidth
LOGFONT iMenuHeight
LOGFONT lfMenuFont
LOGFONT lfStatusFont
LOGFONT fMessageFont
end type
type POINTFLOAT
single x
single y
end type
function MakeIntResource(byval word wInteger) as dword
return wInteger
end function
%ICC_STANDARD_CLASSES 0x4000
type INIT_COMMON_CONTROLSEX
DWORD dwSize
DWORD dwICC
end type
! function InitCommonControlsEx lib "COMCTL32.DLL" ALIAS "InitCommonControlsEx"(BYREF lpInitCtrls AS INIT_COMMON_CONTROLSEX) as long
'_____________________________________________________________________________
function WndProc(sys hWnd, wMsg, wParam, lparam) as sys callback
static point DlgArea
point CursorPos
static point Delta
static point SplitPos
static pointfloat Ratio
rect rcSplitHorz
static sys hCursorUpDwn
static dword Marge
static sys hDragging
static sys hEditTop
static sys hSplitHorz
static sys hEditBot
select case wMsg
case WM_CREATE
static sys hBrush = CreateSolidBrush(Blue)
hCursorUpDwn = LoadCursor(NULL, MakeIntResource(IDC_SIZENS))
PostMessage(hEditTop, %EM_SETSEL, -1, 0) 'Set caret at the end of text
PostMessage(hEditBot, %EM_SETSEL, -1, 0) 'Set caret at the end of text
return(1)
case WM_COMMAND
sys id = loword(wParam)
sys event = hiword(wParam)
select case id
case IDCANCEL 'Escape key
SendMessage(hwnd, WM_CLOSE, 0, 0)
return(0)
end select
case WM_SETCURSOR
if wParam = hSplitHorz then
SetCursor(hCursorUpDwn)
if hiword(LPARAM) = WM_LBUTTONDOWN then 'Left mouse button up to down transition
GetCursorPos(CursorPos)
ScreenToClient(hWnd, CursorPos)
Delta.y = CursorPos.y - SplitPos.y 'Offset between top of splitter bar and vertical cursor position inside splitter bar
hDragging = wParam
SetCapture(hWnd) 'To get cursor pos and button-up feedback even when the cursor is not inside the dialog.
end if
return(true)
end if
case WM_MOUSEMOVE
if hDragging = hSplitHorz then 'Cursor on horizontal splitterbar
CursorPos.y = hiword(LPARAM)
if CursorPos.y >= Delta.y + 5 then 'Prevent over top border dialog limit
if CursorPos.y <= DlgArea.y - Delta.y - 5 then 'Prevent over bottom border dialog limit
SplitPos.y = CursorPos.y - Delta.y
Ratio.Y = SplitPos.y / DlgArea.Y
MoveWindow(hSplitHorz, Marge, SplitPos.y, DlgArea.x - Marge * 2, Marge \ 1, true)
MoveWindow(hEditBot, Marge, SplitPos.y + Marge * 2 - 1, DlgArea.x - Marge * 2, DlgArea.Y - SplitPos.y - Marge * 1, true)
MoveWindow(hEditTop, Marge, Marge, DlgArea.X - Marge * 2, convert long(SplitPos.y - Marge * 1.7), true)
end if
end if
return(0)
end if
case WM_LBUTTONUP 'Left mouse button down to up transition
if hDragging then
ReleaseCapture() 'See SetCapture()
hDragging = false
return(0)
end if
case WM_SIZE
if wParam <> SIZE_MINIMIZED then
DlgArea.X = loword(LPARAM)
DlgArea.Y = hiword(LPARAM)
if hEditBot = 0 then 'Om app start first init
hEditTop = GetDlgItem(hWnd, EditTop)
hSplitHorz = GetDlgItem(hWnd, SplitHorz)
hEditBot = GetDlgItem(hWnd, EditBot)
GetWindowRect(hSplitHorz, rcSplitHorz)
MapWindowPoints(HWND_DESKTOP, hWnd, @rcSplitHorz, 2)
Marge = rcSplitHorz.Left * 2
Ratio.Y = 0.40 'Top of splitter bar / height of client area
end if
SplitPos.y = DlgArea.Y * Ratio.Y
if SplitPos.y > DlgArea.Y - Marge then SplitPos.y = DlgArea.Y - Marge 'Prevent over top dialog limit
if SplitPos.y < 1 then SplitPos.y = 1 'Prevent under dialog bottom limit
MoveWindow(hSplitHorz, Marge, SplitPos.y, DlgArea.x - Marge * 2, Marge \ 1, true)
MoveWindow(hEditBot, Marge, SplitPos.y + Marge * 2 - 1, DlgArea.x - Marge * 2, DlgArea.Y - SplitPos.y - Marge * 1, true)
MoveWindow(hEditTop, Marge, Marge, DlgArea.X - Marge * 2, convert long(SplitPos.y - Marge * 1.7), true)
RedrawWindow(hEditBot, BYVAL NULL, BYVAL NULL, RDW_FRAME | RDW_ERASE | RDW_INVALIDATE)
return(0)
end if
case WM_GETMINMAXINFO 'Set minimim/maximum dialog size
MINMAXINFO *MinMaxInfoPtr
@MinMaxInfoPtr = lParam
MinMaxInfoPtr.ptMinTrackSize.X = 350
MinMaxInfoPtr.ptMinTrackSize.Y = 100
return(0)
case WM_NCACTIVATE
static sys hFocusBak
if wParam = false then 'Application loose focus
hFocusBak = GetFocus()
return(true)
elseif hFocusBak then
SendMessage(hWnd, WM_NEXTDLGCTL, hFocusBak, 1)
hFocusBak = false
return(0)
end if
return(DefWindowProc(hWnd, wMsg, wParam, lParam))
case WM_CTLCOLORSTATIC
if lParam = hSplitHorz then
return(hBrush)
end if
case WM_KEYDOWN
Select wParam
Case 27
SendMessage(hwnd, WM_CLOSE, 0, 0) 'Escape key to exit
return(0)
End Select
case WM_DESTROY
DeleteObject(hBrush)
PostQuitMessage(0)
return(0)
end select
return(DefWindowProc(hWnd, wMsg, wParam, lParam))
end function
'_____________________________________________________________________________
function WinMain()
NONCLIENTMETRICS NonClient
WndClass wc
Msg wm
sys inst, hwnd, hControl, hIcon, inst
sys WindowWidth, WindowHeight, WindowPosX, WindowPosY
WindowWidth = 250
WindowHeight = 300
WindowPosX = (GetSystemMetrics(SM_CXSCREEN) - WindowWidth) \ 2
WindowPosY = (GetSystemMetrics(SM_CYSCREEN) - WindowHeight) \ 2
NonClient.cbSize = SIZEOF(NONCLIENTMETRICS)
hIcon = ExtractIcon GETMODULEHANDLE(""), "Shell32.dll", 294 'o
inst = GetModuleHandle(0)
wc.style = CS_HREDRAW | CS_VREDRAW
wc.lpfnWndProc = @WndProc
wc.cbClsExtra = 0
wc.cbWndExtra = 0
wc.hInstance = inst
wc.hIcon = hIcon
wc.hCursor = LoadCursor(0, IDC_ARROW)
wc.hbrBackground = COLOR_BTNFACE + 1
wc.lpszMenuName = null
wc.lpszClassName = strptr("OXYGEN BASIC")
RegisterClass(@wc)
INIT_COMMON_CONTROLSEX InitControlStruct
InitControlStruct.dwSize = SIZEOF(INIT_COMMON_CONTROLSEX)
InitControlStruct.dwICC = %ICC_STANDARD_CLASSES
InitCommonControlsEX(InitControlStruct) 'nzok
LOGFONT LogicalFont
SystemParametersInfo(SPI_GETICONTITLELOGFONT, SIZEOF(LOGFONT), @LogicalFont, 0)
sys hFont = CreateFontIndirect(@LogicalFont)
hwnd = CreateWindowEx(0, wc.lpszClassName, "SplitterBar" & sizeof(sys) * 8 & " - o2 v. " & o2version,
WS_OVERLAPPED | WS_BORDER | WS_DLGFRAME | WS_CAPTION | WS_SYSMENU |
WS_MINIMIZEBOX | WS_SIZEBOX | WS_CLIPSIBLINGS,
WindowPosX, WindowPosY,
WindowWidth, WindowHeight, HWND_DESKTOP, 0, inst, 0)
string sEdit = quote
-EditQuote1- You may resize this dialog in both directions.
The blue STATIC act as splitterbar.
Action should be appropriate even when the drag goes very fast or out of border
-EditQuote1-
hControl = CreateWindowEx(WS_EX_LEFT | WS_EX_CLIENTEDGE, 'Extended styles
"Edit", 'Class name
StrPtr(sEdit), 'Caption
WS_CHILD | WS_VISIBLE | WS_TABSTOP | 'Window styles
WS_VSCROLL |ES_MULTILINE | ES_LEFT, 'Class styles
2, 2, 'Left, top
246, 100, 'Width, height
hWnd, EditTop, 'Handle of parent, control ID
inst, NULL) 'Handle of instance, creation parameters
SendMessage(hControl, WM_SETFONT, hFont, true)
hControl = CreateWindowEx(0, 'Extended styles
"Static", 'Class name
"", 'Caption
WS_CHILD | WS_VISIBLE | 'Window styles
SS_NOTIFY, 'Class styles
2, 103, 'Left, top
246, 2, 'Width, height
hWnd, SplitHorz, 'Handle of parent, control ID
inst, NULL) 'Handle of instance, creation parameters
sEdit = quote
-EditQuote2- The splitterbar will stop at the maximum top and maximum bottom.
If the dialog is resized vertically, the splitterbar will move in proportion.
The mouse cursor will change to IDC_SIZENS north-south double arrow when over the splitterbar.
Maximizing the window is no problem.
-EditQuote2-
hControl = CreateWindowEx(WS_EX_LEFT | WS_EX_CLIENTEDGE, 'Extended styles
"Edit", 'Class name
StrPtr(sEdit), 'Caption
WS_CHILD | WS_VISIBLE | WS_TABSTOP | 'Window styles
WS_VSCROLL |ES_MULTILINE | ES_LEFT, 'Class styles
2, 106, 'Left, top
246, 90, 'Width, height
hWnd, EditBot, 'Handle of parent, control ID
inst, NULL) 'Handle of instance, creation parameters
SendMessage(hControl, WM_SETFONT, hFont, true)
ShowWindow(hwnd, SW_SHOW)
UpdateWindow(hwnd)
sys bRet
do while bRet := GetMessage(@wm, 0, 0, 0)
if bRet <> -1 then
TranslateMessage(@wm)
DispatchMessage(@wm)
end if
wend
DeleteObject(hFont)
end function
'_____________________________________________________________________________
WinMain()
end
'_____________________________________________________________________________
'
thanks Piere i will try
Hello,
in the Oxygen distribution there is also \demos\WinGUI\Autosizing\SmallApp.o2bas which applies some kind of a horizontal splitting window. The splitter bar can be dragged horizontally.
From what this example come ?
is that from PowerBasic ?
and what is
MoveWindow(hEditTop, Marge, Marge, convert long(DlgArea.X - Marge * 2), convert long(SplitPos.y - Marge * 1.7), true)
i mean ..is convert some strange new command i have never see before ??
Yep,
I did code the original in PowerBASIC.
While learning Oxygen, I thought it was a good idea to translate it.
You will find "convert" in the o2 .chm help.
Convert a type to another type, or convert an expresstio no a specific type.
PowerBASIC will most of the time convert automatically a function parameter of the wrong type,
aka a SINGLE to a DWORD or an expression as parameter.
O2 does it also,
but in this particular case...
MoveWindow(hEditTop, Marge, Marge, DlgArea.X - Marge * 2, convert long(SplitPos.y - Marge * 1.7), true)
I had bad result, all went fine as soon as I converted the expression "SplitPos.y - Marge * 1.7" to a long, using convert long().
I guess the "1.7" was the bad guy.
Note that only convert long() that have "1.7" in them must be keeped.
Some others, I forgot to remove them, they are not needed. I updated the SDK example above.
Maybe Charles will tell us the exact rules for this...
Hi Piere
I am in process to modify your example that work with my include awinh037.inc
but i never see this before :
string sEdit = quote
-EditQuote1- You may resize this dialog in both directions.
The blue STATIC act as splitterbar.
Action should be appropriate even when the drag goes very fast or out of border
-EditQuote1-
ouch is that new way for string ???
anyway color static to blue is great ..i like it
and whole program work really well
:)
Hi Zlatko,
Don't know when it was implemented. I saw the tag name for super-quotes "quote"
while trying some code demo from Charles, "\demos\Basics\SuperQuote.o2bas" then I looked in the help.
It is indeed a pretty sharp way to easily write big multi-lines string...
One more fantastic idea from Charles that make life easier. Thank to him!
Have a great coding day...