- Scintilla VB ActiveX control On planet source code – I was able to make this one work: make the activeX control in the highest directory there will be error on load but it works > then add a reference to the Demo project forms > change their names to the ones used in the code hlMain & sciMain then it runs. It maybe the same content that is up on SourceForge. I think it may be using the installation of the Scintilla SciLexer.dll that I happened to get via TourtouseSVN. This copy of the DLL was responsible for making the simple VB example work with "Scintilla in Visual Basic" shown below. I tried it on a new machine and the editing area was not created because it did not have the incidental copy of SciLexer.dll.
- This page's Project Code for download on Planet Source Code It is the same code here on the Scintilla.org site
- Scintilla Settings / Configuration File
- cEditXP – a much more involved VB6 project using Scintilla
- Scintilla VB ActiveX control on SourceForge
SubClassing
- Page with alot of Windows subclassing and messaging small code tutorials
- VB Helper SubClassing Tutorial
- SubClassing and Hooking with Visual Basic
Shell Reparenting
Scintilla in VB
Before I begin let me state that yes I am aware that there is an activex control which wraps some of Scintilla's features. However like any such control it lacks many of the features Scintilla offers, and isn't updated to support any new features Scintilla adds. Along with that it has several fairly large bugs in it. My goal in this tutorial is to explain how to either use Scintilla without a wrapper or learn enough about how to make use of it to add any features that the control lacks.
What is Scintilla
For those of you who havn't seen Scintilla yet Check it out here. I take absolutly no credit for Scintilla. I didn't write it, nor have I even modified it. I'll admit it's code goes way beyond my own abilities. As for what it is? Well it's an excellent, free and opensource Library providing extensive support for syntax highlighting and it even offers code folding. It's quite stable, and cross platform. You can make use of it from just about any language that supports API calls in windows. This means yes VB can make use of it :)
The total source code for this tutorial is included with this submission. Before we get started you should download the source as this code makes use of 2 modules. These modules are fairly basic and very self explanitory. The one is some ini reading and writing code. Credit for this module goes total an author on PSC. Unfortunatly I was unable to find the original on PSC as I've had it quite some time, so I don't know who to name credit to so I'll just leave it at I didn't write it. The second module is actually from the ScintillaVB control and it's some of Scintilla's major constants.
Starting Out The first thing you will need to do is create an application. Name the form whatever you want. This is not important. Add the following api's at the top of the form's source code. You can also make them public and place them in a module if you want.
Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Integer Private Declare Function CreateWindowEx Lib "user32" Alias "CreateWindowExA" (ByVal dwExStyle As Long, ByVal lpClassName As String, ByVal lpWindowName As String, ByVal dwStyle As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hWndParent As Long, ByVal hMenu As Long, ByVal hInstance As Long, lpParam As Any) As Long Private Declare Function SetFocusEx Lib "user32" Alias "SetFocus" (ByVal hwnd As Long) As Long Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal msg As Long, ByVal wp As Long, ByVal lp As Long) As Long Private Declare Function SendMessageString Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal msg As Long, ByVal wp As Long, ByVal lp As Any) As Long Private Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal m As Long, ByVal left As Long, ByVal top As Long, ByVal width As Long, ByVal height As Long, ByVal flags As Long) As Long Dim sci As Long |
Those are just a few API's we will need for doing this work. Now let's move on to the form load event. This is where we will actually make it all happen.
'Dim str as string. This variable will do nothing more than hold 'a default piece of text. Dim str As String 'Here we actually load the DLL into memory. sciLexer.dll is the 'Scintilla DLL LoadLibrary ("SciLexer.DLL") 'Here we create a window using the Scintilla library which we 'created with the previous line. We assign it a generic name, 'set it as a child and visible. Give it's parents Handle, and 'set it to the application in question and assign the newly created 'handle to the variable sci sci = CreateWindowEx(WS_EX_CLIENTEDGE, "Scintilla", _ "TEST", WS_CHILD Or WS_VISIBLE, 0, 0, 200, 200, _ frmMain.hwnd, 0, App.hInstance, 0) 'Here just for fun we are setting the background color for highlighting 'to a different color SendMessage sci, SCI_SETSELBACK, 1, &HFFEFD0 'Give the str variable a string. This will be placed in the new Scintilla 'Window as text. str = "int Main(){" & Chr(10) & " printf('Hello world\n\r');" & Chr(10) & " return 0;" & Chr(10) & "}" 'Add the text that we assigned to the string variable to the scintilla window SendMessageString sci, SCI_ADDTEXT, Len(str), str 'Load a custom highlighter. This is the fun part LoadHighlighter 'Setfocus to the scintilla window SetFocusEx sci |
The variables explain what each line does. But basicly as a recap what were doing here is loading the DLL into memory, Creating a window using that library, and Setting some text to it. The LoadHighlighter code does some of the major stuff. The rest of the code is as follows:
'Resize window
SetWindowPos sci, 0, 2, 2, frmMain.width / 15 – 12, _
frmMain.height / 15 – 30, 0
End Sub
Public Sub LoadHighlighter()
'Declare a few variables we will use
Dim i As Long
Dim s As String
Dim m As Long
Dim l
Dim d() As String
'Clear all the scintilla styles
SetScintilla SCI_STYLECLEARALL, 0, 0
'Set the keywords to the scintilla control
For i = 0 To 7
s = ReadINI("data", "Keywords[" & i & "]", App.Path & "\CPP.chl")
SetScintillaString SCI_SETKEYWORDS, i, s
Next i
'Set the styles.
For i = 0 To 127
s = ReadINI("data", "style[" & i & "]", App.Path & "\CPP.chl")
If s <> "" Then
d = Split(s, ":")
l = Hex(d(9))
m = Int(d(9))
SetScintilla SCI_STYLESETSIZE, i, 12
If (d(0) = "B") Then
SetScintilla SCI_STYLESETBOLD, i, 1
Else
SetScintilla SCI_STYLESETBOLD, i, 0
End If
SetScintilla SCI_STYLESETFORE, i, m
End If
Next i
'SendMessageString sci, SCI_SETKEYWORDS, 0, "if then else"
SetScintilla SCI_SETLEXER, 3, 0
End Sub
Private Sub SetScintillaString(lSCIData, lDataNum As Long, strWords As String)
'Sends a message containing a string to the scintilla window
SendMessageString sci, lSCIData, lDataNum, strWords
End Sub
Private Sub SetScintilla(lWhatToDo As Long, lNumber As Long, lValue As Long)
'Sends a message containing a long value to the scintilla window
SendMessage sci, lWhatToDo, lNumber, lValue
End Sub
Recap
Essentially everything is sent to scintilla threw SendMessage or SendMessageString. The 2 functions, SetScintilla and SetScintillaString just wrap around those 2 api calls to make what your sending to scintilla a little easier to understand. Examples of which to use would be to set the keywords you'd use SetScintillaString. To set the colors or any of the styles IE forecolor, backcolor, bold, italic, etc. You'd use SetScintilla.
In the sample source for setting the keywords we use This: SetScintillaString SCI_KEYWORDS, I, STR
* SCI_KEYWORDS is a constant which tells scintilla you want to set the keywords.
* I is just a number. Scintilla supports up to 8 sets of keywords so what were doing here is in LoadHighlighter were going 0 to 7 and reading the keywords out of each keyword number and I here tells scintilla we are setting that set of keywords.
* STR is the string which we have set using the ini reading code to the appropriate Keywords. In the sample source for setting the forecolor we use This:
SetScintilla SCI_STYLESETFORE, i, m
* SCI_STYLESETFORE is a constant which when sent to scintilla tells it were setting a forecolor to one of the styles. * i is a number from 0 to 127. Scintilla supports a total of 128 style bits. * m is the value we are setting the forecolor to. VB color values will work for this.
Once again this is a really basic tutorial. You can do a ton of things with Scintilla. Because of it's setup you can have embeded language IE ASP and PHP within HTML, code folding such as what the Visual Studio .Net supports, and much more. It also makes it incredibly easy to add exporting features so you can export the highlighted source code to another format IE HTML or RTF. In fact all the highlighting involved in the code on this tutorial was done using cEditMX which utilizes Scintilla.
I highly recomend you go to The Scintilla Site and check out all the great information available as well as the dll itself which is updated on a regular basis. Also check out ScintillaVB Control. It is a good starting point, it just needs a lot of work, especially in it's overall support for scintilla. Hopefully with this tutorial you got a basic understanding of how it all works so you can do just that.
This content was originally created by the guy who created cEditMX which uses Scintilla. He has long since abandoned the effort in this area.
0 Comments