Date: 02-16-2022
Return to Index
created by gbSnippets
'A Scintilla window and the document it displays are separate entities. In addition
'to the document that is created when a Scintilla window is created, you can also
'create a document in code.
'The separation of Scintilla window from the document contained in the window allows
'the programmer several options:
'1. Same document in several windows - changes in one window are reflected in all windows
'2. Work with multiple documents in the same Scintilla window
'This snippet covers the first option - having the same document display in multiple
'Scintilla windows, but linked so that changes to one window are updated in the second.
'This is useful for such things as a splitter window.
'Each new document created by Scintilla is assigned a pointer, to which the
'programmer has access. Displaying a document in a window simply requires that
'the pointer be assigned to that window.
'Primary Code:
'When a Scintilla window is created, a new document is also created. To get
'the pointer to that document, use this code:
pDoc = SendMessage(hSci_First, %SCI_GetDocPointer, 0, 0)
'Then, to assign this document to a second window, use this code:
SendMessage(hSci_Second, %SCI_SetDocPointer, 0, pDoc)
'When a second Scintilla window is created, a second, empty document is also
'created. And when SCI_SetDocPointer is applied to the second window the
'document associated with the second window will be lost if no other Scintilla
'window is associated with the second document. So before using the
'SCI_SetDocPointer on the second window, you may need to save it's contents.
'Compilable Example: (Jose Includes)
'In this example, the splitter bars (label controls) are colored red/blue for visibility,
'but an application typically uses colors which match the background color of the dialog
'in order to render the splitter bars invisible - except as the mouse cursor changes when
'it passes over the splitter bars.
#Compiler PBWin 9, PBWin 10
#Compile EXE
#Dim All
%Unicode=1
#Include "Win32api.inc"
#Include "scintilla_gb.inc"
' Equates =============================================================
%IDC_Left = 500 : %IDC_Right = 501 : %IDC_Bottom = 502
%IDC_LabelH = 503 : %IDC_LabelV = 504
' Global Variables =============================================================
Global hDlg, hLib, hLeft, hRight, hBottom, pDoc As DWord
Global SplitVInWork, SplitHInWork, HBarLeft, VBarTop As Long
Global XSplit As Single, YSplit As Single
' Main Function =======================================================================
Function PBMain()
hLib = LoadLibrary("SCILEXER.DLL")
Dialog New Pixels, 0, "Splitter Text",300,300,410,340, %WS_OverlappedWindow Or %WS_ClipChildren To hDlg
Dialog Set Icon hDlg, "aainfo"
'add the controls + splitter bars (labels)
Control Add "Scintilla", hDlg, %IDC_Left, "", 20, 80, 160, 80, %WS_Child Or %WS_Visible Or %WS_Border
Control Handle hDlg, %IDC_Left To hLeft 'get handle to Scintilla window
Control Add "Scintilla", hDlg, %IDC_Bottom, "", 20, 80, 160, 80, %WS_Child Or %WS_Visible Or %WS_Border
Control Handle hDlg, %IDC_Bottom To hBottom 'get handle to Scintilla window
Control Add "Scintilla", hDlg, %IDC_Right, "", 20, 80, 160, 80, %WS_Child Or %WS_Visible Or %WS_Border
Control Handle hDlg, %IDC_Right To hRight 'get handle to Scintilla window
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
Control Set Color hDlg, %IDC_LabelV, %Black, %Red
Control Set Color hDlg, %IDC_LabelH, %Black, %Blue
'initial values
XSplit = 0.4 : YSplit = 0.5 : HBarLeft = 100 : VBarTop = 100
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_InitDialog
InitializeScintilla
PostMessage hLeft, %SCI_SetSel, 0,0 'unselect initially
Case %WM_Command
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
Case %WM_Destroy
If hLib Then FreeLibrary hLib 'free the Scintilla library
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
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
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, vy, hx, hy, h, w, HLeft, VTop, M, T As Long
Dialog Get Client hDlg To w,h
M = 5 'margin around controls
T = 6 'splitter thickness (smallest dimension)
'get the splitter bar positions - top of vertical splitter (VTop) and
'left of horizontal splitter (HLeft). These will be used in positioning
'controls on the dialog. Result depends on whether fixed or percentage
'positioning is selected by the user.
VTop = h - VBarTop
HLeft = HBarLeft
'H splitter bar loc/size
Control Set Loc hDlg, %IDC_LabelH, HLeft, M
Control Set Size hDlg, %IDC_LabelH, T, h - 2*M
'V splitter bar loc/size
Control Set Loc hDlg, %IDC_LabelV, HLEFT + T, VTop
Control Set Size hDlg, %IDC_LabelV, w - HLeft - T - M, T
'Left loc/size
Control Set Loc hDlg, %IDC_Left, M, M
Control Set Size hDlg, %IDC_Left, HLeft - 2*M, h - 2*M
'Right loc/size
Control Set Loc hDlg, %IDC_Right, HLeft + T + M, M
Control Set Size hDlg, %IDC_Right, w - HLeft - T - 2*M, VTop - 2*M
'Bottom loc/size
Control Set Loc hDlg, %IDC_Bottom, HLeft + T + M, VTop + T + M
Control Set Size hDlg, %IDC_Bottom, w - HLeft - T - 2*M, h - VTop - 2*M - T
Dialog Redraw hDlg
End Sub
Sub InitializeScintilla
Local txt As String, i As Long
For i = 0 to 100
txt = txt + "Line " + Str$(i) + $crlf
Next i
txt = Trim$(txt, Chr$(0)) + Chr$(0)
SendMessage hLeft, %SCI_SetText, 0, StrPTR(txt)
SendMessage hLeft, %SCI_SetMarginWidthN, 0, 20
SendMessage hRight, %SCI_SetMarginWidthN, 0, 20
SendMessage hBottom, %SCI_SetMarginWidthN, 0, 20
pDoc = SendMessage(hLeft, %SCI_GetDocPointer, 0, 0)
SendMessage(hRight, %SCI_SetDocPointer, 0, pDoc)
SendMessage(hBottom, %SCI_SetDocPointer, 0, pDoc)
End Sub
'gbs_00644
'Date: 03-10-2012
http://www.garybeene.com/sw/gbsnippets.htm