Example25: Multiple Views

Category: Controls - Scintilla

Date: 02-16-2022

Return to Index


 
'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(WordCB.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


created by gbSnippets
http://www.garybeene.com/sw/gbsnippets.htm