Sukhwinder Singh
asked on
Which Component is used for text editors edit window?
Hello,
I have 1 question related to VB 6.0
Which Component is mostly used for creating a Text editor's edit window(where files are displayed and edited). For example to enable syntax highlighting. Textbox cannot be used because of its size limit and also it doesn't allow highlighting particular words. Should I use Rich Text Box? Do most editors like Editplus, Ultraedit etc. use richtext box and save file as plain text? Or they use some commercial component for this purpose (which I cannot use). But I think rtf cannot be used to show line numbers on left side and to disable selection of these line nos when selecting text; as these editors allow.
I have 1 question related to VB 6.0
Which Component is mostly used for creating a Text editor's edit window(where files are displayed and edited). For example to enable syntax highlighting. Textbox cannot be used because of its size limit and also it doesn't allow highlighting particular words. Should I use Rich Text Box? Do most editors like Editplus, Ultraedit etc. use richtext box and save file as plain text? Or they use some commercial component for this purpose (which I cannot use). But I think rtf cannot be used to show line numbers on left side and to disable selection of these line nos when selecting text; as these editors allow.
Why not create your own word processor control? It is easier that it sounds.
Set your form's keypreview to true and you can pickup all key down/press/up events on your form. The hard bit is handling the caret and knowing where the operator is typing.
Here is some code to show that VB is fast enough for the job.
1) Create new project:
2) Set the form scalemode to pixel
3) Add a command button: command1
4) Add a VScroll: VScroll1
5) Add a picture box: picture1 and set AutoRedraw to true
6) Paste the following code and hit run, then click load.
Resize and scroll at will. Have fun...
If you want to go this way I could help further.....
Option Explicit
Dim Loaded As Boolean
Private Type LineDef
startword As Long
lastword As Long
End Type
Private Type Pointerdef
Para As Long ' Pointer to Para
LIP As Long ' Line in Para
End Type
Private Type FontDef
Font As Font
SpaceWidth As Long
LineHeight As Long
End Type
Dim MyFonts() As FontDef
Private Type ParaDef
Text As String
WordCount As Long
Words() As String
Fonts() As Long
PosX() As Long
WLen() As Long ' Length of each word
Lines() As LineDef ' words in each line
End Type
Private Type DocDef
Name As String
Paras() As ParaDef
ALP() As Pointerdef ' Absolute line pointer to para ans line within para
End Type
Dim PB As PictureBox ' or picturebox
Dim Doc As DocDef
Dim CP As Long ' Current Para
Dim CW As Long ' Current Word
Dim CC As Long ' Current Character In Word
Dim TLOS As Long ' topline on screen
Dim SpaceWidth As Long
Dim ML As Long
Dim MR As Long
Dim MT As Long
Dim MB As Long
Dim w As Long
Dim h As Long
Dim LineHeight
Sub DisplayData()
' Get Size of window
w = PB.ScaleWidth - ML - MR
h = PB.ScaleHeight - MT - MB
Dim PosX As Long
Dim posY As Long
Dim lc As Long
Dim abslc As Long ' absolute linecount
PB.Cls ' clear window
Dim wc As Long ' word count
lc = 0
Dim startword As Long
Dim lastword As Long
Dim MaxHeight As Long
Dim cf As Long ' current font
Dim lf As Long ' last font
Dim P As Long
posY = MT
'Dim st As Single
'st = Timer
Do
PosX = ML
PB.CurrentY = posY ' if using multi fonts needs to be set for each word
abslc = TLOS + lc
If abslc > UBound(Doc.ALP) Then Exit Do
P = Doc.ALP(abslc).Para ' para for this line
MaxHeight = 0
startword = Doc.Paras(P).Lines(Doc.ALP (abslc).LI P).startwo rd
lastword = Doc.Paras(P).Lines(Doc.ALP (abslc).LI P).lastwor d
For wc = startword To lastword
cf = Doc.Paras(P).Fonts(wc)
If cf <> lf Then
' set new font here
'set pb.font = myfonts.font
lf = cf
End If
PB.CurrentX = Doc.Paras(P).PosX(wc)
PB.Print Doc.Paras(P).Words(wc);
If MyFonts(cf).LineHeight > MaxHeight Then
MaxHeight = MyFonts(cf).LineHeight
End If
Next wc
lc = lc + 1
posY = posY + MaxHeight
If posY + MyFonts(cf).LineHeight > h Then Exit Do
Loop
'MsgBox Format(Timer - st, "0.000") + " seconds to display page"
End Sub
Private Sub Command1_Click()
Dim YourText As String
ReDim Lines(0) As String
ReDim Doc.Paras(UBound(Lines))
Dim pc As Long
Dim wc As Long
Dim cf As Long
ReDim MyFonts(0)
Dim ddone As Boolean
Dim estlos As Long
Dim vs As VB.VScrollBar
' Create some test data
Dim ok
Dim k As Long
For wc = 1 To 4
YourText = YourText + "Here is an example of some test data. "
Next wc
k = Val(InputBox("How many KB in your test data"))
If k < 1 Then
k = 1
End If
k = k * 1024
YourText = Trim(YourText) + vbCrLf
Do
YourText = YourText + YourText
If Len(YourText) > k Then Exit Do
Loop
YourText = Left(YourText, k)
' Start the data loading
' set margins
ML = 10 ' left
MR = 10 ' right
MT = 10 ' top
MB = 10 ' bottom
Set PB = Picture1 ' pb can be a form or a picture box
PB.Font.Name = "Arial"
' Get Size of window
w = PB.ScaleWidth - ML - MR
h = PB.ScaleHeight - MT - MB
Set MyFonts(0).Font = PB.Font
MyFonts(0).SpaceWidth = PB.TextWidth(Space$(1))
MyFonts(0).LineHeight = PB.TextHeight("Z") + 1 ' 1 pixel gap between lines
estlos = h / MyFonts(0).LineHeight
'First get paragraphs:
Lines = Split(YourText, vbCrLf)
YourText = ""
ReDim Doc.Paras(UBound(Lines))
ReDim Doc.ALP(100)
Dim lc As Long ' current line
Dim pos As Long
Dim startword As Long
Dim tlc As Long ' total line count
Dim st As Single
st = Timer
' Now Get Words
For pc = 0 To UBound(Lines)
lc = 0
pos = 0
Doc.Paras(pc).Text = Lines(pc)
Lines(pc) = ""
Doc.Paras(pc).WordCount = 0
If Len(Doc.Paras(pc).Text) > 0 Then
Doc.Paras(pc).Words = Split(Doc.Paras(pc).Text, Space$(1))
Doc.Paras(pc).WordCount = UBound(Doc.Paras(pc).Words ) + 1
ReDim Doc.Paras(pc).WLen(Doc.Par as(pc).Wor dCount - 1)
ReDim Doc.Paras(pc).PosX(Doc.Par as(pc).Wor dCount - 1)
ReDim Doc.Paras(pc).Fonts(Doc.Pa ras(pc).Wo rdCount - 1)
ReDim Doc.Paras(pc).Lines(10)
'Doc.Paras(lc)
' How big is each word?
startword = 0
pos = 0
For wc = 0 To Doc.Paras(pc).WordCount - 1
cf = 0
Doc.Paras(pc).Fonts(wc) = cf
Doc.Paras(pc).WLen(wc) = PB.TextWidth(Doc.Paras(pc) .Words(wc) )
If pos + Doc.Paras(pc).WLen(wc) + MyFonts(cf).SpaceWidth > w Then
pos = 0
Doc.Paras(pc).PosX(wc) = pos
Doc.Paras(pc).Lines(lc).st artword = startword
Doc.Paras(pc).Lines(lc).la stword = wc - 1
startword = wc
If tlc > UBound(Doc.ALP) Then
ReDim Preserve Doc.ALP(tlc)
End If
Doc.ALP(tlc).LIP = lc
Doc.ALP(tlc).Para = pc
tlc = tlc + 1 ' increase the absolute line count
lc = lc + 1 ' and line within para count
If lc > UBound(Doc.Paras(pc).Lines ) Then
ReDim Preserve Doc.Paras(pc).Lines(lc + 10)
End If
Else
Doc.Paras(pc).PosX(wc) = pos
End If
pos = pos + Doc.Paras(pc).WLen(wc) + MyFonts(cf).SpaceWidth
Next wc
ReDim Preserve Doc.Paras(pc).Lines(lc)
If tlc > UBound(Doc.ALP) Then
ReDim Preserve Doc.ALP(tlc + tlc * 0.25 + 100)
End If
Doc.ALP(tlc).LIP = lc
Doc.ALP(tlc).Para = pc
tlc = tlc + 1 ' increase the absolute line count
Doc.Paras(pc).Lines(lc).st artword = startword
Doc.Paras(pc).Lines(lc).la stword = Doc.Paras(pc).WordCount - 1
End If
If Not ddone Then
If tlc - 10 > estlos Then
DisplayData
DoEvents
ddone = True
End If
End If
Next pc
Set vs = VScroll1
vs.Value = 0
vs.Max = tlc
ReDim Preserve Doc.ALP(tlc - 1)
Erase Lines
MsgBox "Data loaded in: " + Format(Timer - st, "0.000") + "seconds"
Loaded = True
CP = 0 ' Current Para
CW = 0 ' Currnt Word
CC = 0 ' Currnt Character In Word
End Sub
Private Sub Form_Load()
Command1.Caption = "Load Data"
End Sub
Private Sub Form_Resize()
Command1.Move 0, 0
Picture1.Move 0, Command1.Height, Me.ScaleWidth - VScroll1.Width, _
Me.ScaleHeight - Command1.Height
VScroll1.Top = Picture1.Top
VScroll1.Height = Picture1.Height
VScroll1.Left = Picture1.Width
If Loaded Then
w = PB.ScaleWidth - ML - MR
h = PB.ScaleHeight - MT - MB
RepaginateDocument Doc, w, h
DisplayData
End If
End Sub
Private Sub VScroll1_Change()
VScroll1_Scroll
End Sub
Private Sub VScroll1_Scroll()
TLOS = VScroll1.Value
DisplayData
End Sub
Private Sub RepaginateDocument(ByRef Doc As DocDef, w As Long, h As Long)
Dim pc As Long
Dim wc As Long
Dim lc As Long
Dim pos As Long
Dim tlc As Long ' total line count
Dim startword As Long
Dim lastword As Long
Dim cf As Long
Dim vs
tlc = 0
For pc = 0 To UBound(Doc.Paras)
lc = 0
pos = 0
startword = 0
pos = 0
For wc = 0 To Doc.Paras(pc).WordCount - 1
cf = Doc.Paras(pc).Fonts(wc)
If pos + Doc.Paras(pc).WLen(wc) + MyFonts(cf).SpaceWidth > w Then
pos = 0
Doc.Paras(pc).PosX(wc) = pos
Doc.Paras(pc).Lines(lc).st artword = startword
Doc.Paras(pc).Lines(lc).la stword = wc - 1
startword = wc
If tlc > UBound(Doc.ALP) Then
ReDim Preserve Doc.ALP(tlc)
End If
Doc.ALP(tlc).LIP = lc
Doc.ALP(tlc).Para = pc
tlc = tlc + 1 ' increase the absolute line count
lc = lc + 1 ' and line within para count
If lc > UBound(Doc.Paras(pc).Lines ) Then
ReDim Preserve Doc.Paras(pc).Lines(lc + 10)
End If
Else
Doc.Paras(pc).PosX(wc) = pos
End If
pos = pos + Doc.Paras(pc).WLen(wc) + MyFonts(cf).SpaceWidth
Next wc
ReDim Preserve Doc.Paras(pc).Lines(lc)
If tlc > UBound(Doc.ALP) Then
ReDim Preserve Doc.ALP(tlc + 100 + tlc * 0.25)
End If
Doc.ALP(tlc).LIP = lc
Doc.ALP(tlc).Para = pc
tlc = tlc + 1 ' increase the absolute line count
Doc.Paras(pc).Lines(lc).st artword = startword
Doc.Paras(pc).Lines(lc).la stword = Doc.Paras(pc).WordCount - 1
Next pc
Set vs = VScroll1
vs.Value = 0
vs.Max = tlc
ReDim Preserve Doc.ALP(tlc - 1)
End Sub
Set your form's keypreview to true and you can pickup all key down/press/up events on your form. The hard bit is handling the caret and knowing where the operator is typing.
Here is some code to show that VB is fast enough for the job.
1) Create new project:
2) Set the form scalemode to pixel
3) Add a command button: command1
4) Add a VScroll: VScroll1
5) Add a picture box: picture1 and set AutoRedraw to true
6) Paste the following code and hit run, then click load.
Resize and scroll at will. Have fun...
If you want to go this way I could help further.....
Option Explicit
Dim Loaded As Boolean
Private Type LineDef
startword As Long
lastword As Long
End Type
Private Type Pointerdef
Para As Long ' Pointer to Para
LIP As Long ' Line in Para
End Type
Private Type FontDef
Font As Font
SpaceWidth As Long
LineHeight As Long
End Type
Dim MyFonts() As FontDef
Private Type ParaDef
Text As String
WordCount As Long
Words() As String
Fonts() As Long
PosX() As Long
WLen() As Long ' Length of each word
Lines() As LineDef ' words in each line
End Type
Private Type DocDef
Name As String
Paras() As ParaDef
ALP() As Pointerdef ' Absolute line pointer to para ans line within para
End Type
Dim PB As PictureBox ' or picturebox
Dim Doc As DocDef
Dim CP As Long ' Current Para
Dim CW As Long ' Current Word
Dim CC As Long ' Current Character In Word
Dim TLOS As Long ' topline on screen
Dim SpaceWidth As Long
Dim ML As Long
Dim MR As Long
Dim MT As Long
Dim MB As Long
Dim w As Long
Dim h As Long
Dim LineHeight
Sub DisplayData()
' Get Size of window
w = PB.ScaleWidth - ML - MR
h = PB.ScaleHeight - MT - MB
Dim PosX As Long
Dim posY As Long
Dim lc As Long
Dim abslc As Long ' absolute linecount
PB.Cls ' clear window
Dim wc As Long ' word count
lc = 0
Dim startword As Long
Dim lastword As Long
Dim MaxHeight As Long
Dim cf As Long ' current font
Dim lf As Long ' last font
Dim P As Long
posY = MT
'Dim st As Single
'st = Timer
Do
PosX = ML
PB.CurrentY = posY ' if using multi fonts needs to be set for each word
abslc = TLOS + lc
If abslc > UBound(Doc.ALP) Then Exit Do
P = Doc.ALP(abslc).Para ' para for this line
MaxHeight = 0
startword = Doc.Paras(P).Lines(Doc.ALP
lastword = Doc.Paras(P).Lines(Doc.ALP
For wc = startword To lastword
cf = Doc.Paras(P).Fonts(wc)
If cf <> lf Then
' set new font here
'set pb.font = myfonts.font
lf = cf
End If
PB.CurrentX = Doc.Paras(P).PosX(wc)
PB.Print Doc.Paras(P).Words(wc);
If MyFonts(cf).LineHeight > MaxHeight Then
MaxHeight = MyFonts(cf).LineHeight
End If
Next wc
lc = lc + 1
posY = posY + MaxHeight
If posY + MyFonts(cf).LineHeight > h Then Exit Do
Loop
'MsgBox Format(Timer - st, "0.000") + " seconds to display page"
End Sub
Private Sub Command1_Click()
Dim YourText As String
ReDim Lines(0) As String
ReDim Doc.Paras(UBound(Lines))
Dim pc As Long
Dim wc As Long
Dim cf As Long
ReDim MyFonts(0)
Dim ddone As Boolean
Dim estlos As Long
Dim vs As VB.VScrollBar
' Create some test data
Dim ok
Dim k As Long
For wc = 1 To 4
YourText = YourText + "Here is an example of some test data. "
Next wc
k = Val(InputBox("How many KB in your test data"))
If k < 1 Then
k = 1
End If
k = k * 1024
YourText = Trim(YourText) + vbCrLf
Do
YourText = YourText + YourText
If Len(YourText) > k Then Exit Do
Loop
YourText = Left(YourText, k)
' Start the data loading
' set margins
ML = 10 ' left
MR = 10 ' right
MT = 10 ' top
MB = 10 ' bottom
Set PB = Picture1 ' pb can be a form or a picture box
PB.Font.Name = "Arial"
' Get Size of window
w = PB.ScaleWidth - ML - MR
h = PB.ScaleHeight - MT - MB
Set MyFonts(0).Font = PB.Font
MyFonts(0).SpaceWidth = PB.TextWidth(Space$(1))
MyFonts(0).LineHeight = PB.TextHeight("Z") + 1 ' 1 pixel gap between lines
estlos = h / MyFonts(0).LineHeight
'First get paragraphs:
Lines = Split(YourText, vbCrLf)
YourText = ""
ReDim Doc.Paras(UBound(Lines))
ReDim Doc.ALP(100)
Dim lc As Long ' current line
Dim pos As Long
Dim startword As Long
Dim tlc As Long ' total line count
Dim st As Single
st = Timer
' Now Get Words
For pc = 0 To UBound(Lines)
lc = 0
pos = 0
Doc.Paras(pc).Text = Lines(pc)
Lines(pc) = ""
Doc.Paras(pc).WordCount = 0
If Len(Doc.Paras(pc).Text) > 0 Then
Doc.Paras(pc).Words = Split(Doc.Paras(pc).Text, Space$(1))
Doc.Paras(pc).WordCount = UBound(Doc.Paras(pc).Words
ReDim Doc.Paras(pc).WLen(Doc.Par
ReDim Doc.Paras(pc).PosX(Doc.Par
ReDim Doc.Paras(pc).Fonts(Doc.Pa
ReDim Doc.Paras(pc).Lines(10)
'Doc.Paras(lc)
' How big is each word?
startword = 0
pos = 0
For wc = 0 To Doc.Paras(pc).WordCount - 1
cf = 0
Doc.Paras(pc).Fonts(wc) = cf
Doc.Paras(pc).WLen(wc) = PB.TextWidth(Doc.Paras(pc)
If pos + Doc.Paras(pc).WLen(wc) + MyFonts(cf).SpaceWidth > w Then
pos = 0
Doc.Paras(pc).PosX(wc) = pos
Doc.Paras(pc).Lines(lc).st
Doc.Paras(pc).Lines(lc).la
startword = wc
If tlc > UBound(Doc.ALP) Then
ReDim Preserve Doc.ALP(tlc)
End If
Doc.ALP(tlc).LIP = lc
Doc.ALP(tlc).Para = pc
tlc = tlc + 1 ' increase the absolute line count
lc = lc + 1 ' and line within para count
If lc > UBound(Doc.Paras(pc).Lines
ReDim Preserve Doc.Paras(pc).Lines(lc + 10)
End If
Else
Doc.Paras(pc).PosX(wc) = pos
End If
pos = pos + Doc.Paras(pc).WLen(wc) + MyFonts(cf).SpaceWidth
Next wc
ReDim Preserve Doc.Paras(pc).Lines(lc)
If tlc > UBound(Doc.ALP) Then
ReDim Preserve Doc.ALP(tlc + tlc * 0.25 + 100)
End If
Doc.ALP(tlc).LIP = lc
Doc.ALP(tlc).Para = pc
tlc = tlc + 1 ' increase the absolute line count
Doc.Paras(pc).Lines(lc).st
Doc.Paras(pc).Lines(lc).la
End If
If Not ddone Then
If tlc - 10 > estlos Then
DisplayData
DoEvents
ddone = True
End If
End If
Next pc
Set vs = VScroll1
vs.Value = 0
vs.Max = tlc
ReDim Preserve Doc.ALP(tlc - 1)
Erase Lines
MsgBox "Data loaded in: " + Format(Timer - st, "0.000") + "seconds"
Loaded = True
CP = 0 ' Current Para
CW = 0 ' Currnt Word
CC = 0 ' Currnt Character In Word
End Sub
Private Sub Form_Load()
Command1.Caption = "Load Data"
End Sub
Private Sub Form_Resize()
Command1.Move 0, 0
Picture1.Move 0, Command1.Height, Me.ScaleWidth - VScroll1.Width, _
Me.ScaleHeight - Command1.Height
VScroll1.Top = Picture1.Top
VScroll1.Height = Picture1.Height
VScroll1.Left = Picture1.Width
If Loaded Then
w = PB.ScaleWidth - ML - MR
h = PB.ScaleHeight - MT - MB
RepaginateDocument Doc, w, h
DisplayData
End If
End Sub
Private Sub VScroll1_Change()
VScroll1_Scroll
End Sub
Private Sub VScroll1_Scroll()
TLOS = VScroll1.Value
DisplayData
End Sub
Private Sub RepaginateDocument(ByRef Doc As DocDef, w As Long, h As Long)
Dim pc As Long
Dim wc As Long
Dim lc As Long
Dim pos As Long
Dim tlc As Long ' total line count
Dim startword As Long
Dim lastword As Long
Dim cf As Long
Dim vs
tlc = 0
For pc = 0 To UBound(Doc.Paras)
lc = 0
pos = 0
startword = 0
pos = 0
For wc = 0 To Doc.Paras(pc).WordCount - 1
cf = Doc.Paras(pc).Fonts(wc)
If pos + Doc.Paras(pc).WLen(wc) + MyFonts(cf).SpaceWidth > w Then
pos = 0
Doc.Paras(pc).PosX(wc) = pos
Doc.Paras(pc).Lines(lc).st
Doc.Paras(pc).Lines(lc).la
startword = wc
If tlc > UBound(Doc.ALP) Then
ReDim Preserve Doc.ALP(tlc)
End If
Doc.ALP(tlc).LIP = lc
Doc.ALP(tlc).Para = pc
tlc = tlc + 1 ' increase the absolute line count
lc = lc + 1 ' and line within para count
If lc > UBound(Doc.Paras(pc).Lines
ReDim Preserve Doc.Paras(pc).Lines(lc + 10)
End If
Else
Doc.Paras(pc).PosX(wc) = pos
End If
pos = pos + Doc.Paras(pc).WLen(wc) + MyFonts(cf).SpaceWidth
Next wc
ReDim Preserve Doc.Paras(pc).Lines(lc)
If tlc > UBound(Doc.ALP) Then
ReDim Preserve Doc.ALP(tlc + 100 + tlc * 0.25)
End If
Doc.ALP(tlc).LIP = lc
Doc.ALP(tlc).Para = pc
tlc = tlc + 1 ' increase the absolute line count
Doc.Paras(pc).Lines(lc).st
Doc.Paras(pc).Lines(lc).la
Next pc
Set vs = VScroll1
vs.Value = 0
vs.Max = tlc
ReDim Preserve Doc.ALP(tlc - 1)
End Sub
listening
ASKER
Hello inthedark
Thank you. I think you have spent some time for this long code. Example you provided is very good but there is small problem.
I did everything as you said but when I executed the program and straight way tried to move scroller run time error occurred:
Runtime error 91:
Object Variable or with block variable not set:
Sub DisplayData()
' Get Size of window
->w = PB.ScaleWidth - ML - MR
h = PB.ScaleHeight - MT - MB
Problem is with PB. I think it doesn't contain any valid object references at that time.
Problem doesn't arise when I first load data and then use scroll bar.
You have used picturebox as edit window. So question is:
1. Can it be used to highlight different keywords with different colors and fonts (as in editplus)?
2. Is there any limit on amount of data it can load.
Because when I tried to load 1044 kb of data it took 40 seconds but edit plus took only 7 seconds to load 1044 kb (even binary file) file even when it is a complete editor.
3. Do you think every one uses their custom controls for editors? Or there is any other control provided with VB enterprise edition which can be used? Or these editors are created in VC++?
Thank you. I think you have spent some time for this long code. Example you provided is very good but there is small problem.
I did everything as you said but when I executed the program and straight way tried to move scroller run time error occurred:
Runtime error 91:
Object Variable or with block variable not set:
Sub DisplayData()
' Get Size of window
->w = PB.ScaleWidth - ML - MR
h = PB.ScaleHeight - MT - MB
Problem is with PB. I think it doesn't contain any valid object references at that time.
Problem doesn't arise when I first load data and then use scroll bar.
You have used picturebox as edit window. So question is:
1. Can it be used to highlight different keywords with different colors and fonts (as in editplus)?
2. Is there any limit on amount of data it can load.
Because when I tried to load 1044 kb of data it took 40 seconds but edit plus took only 7 seconds to load 1044 kb (even binary file) file even when it is a complete editor.
3. Do you think every one uses their custom controls for editors? Or there is any other control provided with VB enterprise edition which can be used? Or these editors are created in VC++?
I have modified the loading and now it loads 1044000 bytes in just 0.020 seconds.
So I only make if calculate size of words when it needs to display a line.
Dim st As Single
st = Timer
For pc = 0 To UBound(Lines)
lc = 0
pos = 0
Doc.Paras(pc).Text = Lines(pc)
Lines(pc) = ""
' whole load of stuff deleted from here
Next pc
Erase Lines
MsgBox "Data loaded in: " + Format(Timer - st, "0.000") + "seconds"
The target time for loading a 1MB file for me is 3.5 seconds as this is how long MS Word takes.
So I only make if calculate size of words when it needs to display a line.
Dim st As Single
st = Timer
For pc = 0 To UBound(Lines)
lc = 0
pos = 0
Doc.Paras(pc).Text = Lines(pc)
Lines(pc) = ""
' whole load of stuff deleted from here
Next pc
Erase Lines
MsgBox "Data loaded in: " + Format(Timer - st, "0.000") + "seconds"
The target time for loading a 1MB file for me is 3.5 seconds as this is how long MS Word takes.
>1. Can it be used to highlight different keywords with >different colors and fonts (as in editplus)?
If you create the code you can make it do anything..
>2. Is there any limit on amount of data it can load.
Same limitation as any other program.
If you create the code you can make it do anything..
>2. Is there any limit on amount of data it can load.
Same limitation as any other program.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
What I asked about syntax highlighting is that is it possible to to something like changing color of different words using different colors using Picture box. Like changing fontsize of one word and changing font of another.
indianmunda, what time zone are you in?
I will post some other code that you will need but I would prefer to email it to you. I am going to be busy for a few days so it could be some time before I can get back to you.
I have now improved the loading example as with super large documents you can't page directly to the end of the document. But I have now resolved this - instead of using the scroll bar to select a line of the screen I will multiply the number of paragraphs by 10 and use this as a key to the line to display, so the user can page doen in paragraphs and won't know the difference. Or I may just add up each line in all paragraphs and do away with an absolute pointer to a specifc line - the problem with this is that for documents whic are serveral MB it would get slower - so the solution would be to be able to handle both types of addressing for best of both worlds. In this way the max value can be found in a split second. When all the paras in the document have been calculated to see how many lines on the screen that they would occupy the program will then revert to using absolute addressing to a specific line.
All you have seen so far is the code to display the data real fast. But there are two major step for you to achieve next:
1) Control of Caret - I have created a handy simple class which does this.
2) Interfacing with the keyboard - I will post some examples of the keyboard events that you need to handle - but they were written for a different concept.
As you can guess I have already written sevral word processors. But the last version I created I was not happy with the load speed as it used Public Classes which are very slow.
Eventually I will take the loading example above and make a WP program from it - but not for serveral weeks.
You asked how to handle words with different Fonts/colours:
First you need to understand the document structure:
' Pointers to the start and end words for each line within a para.
Private Type LineDef
startword As Long
lastword As Long
End Type
' An element for an absolute line number which points to a specifc line within a paragraph.
' I intend to make this redudant.
Private Type Pointerdef
Para As Long ' Pointer to Para
LIP As Long ' Line in Para
End Type
' Each word can point to a different font.
' So for each font variation you need one of these
Simple:
Private Type FontDef
StyleName as String
Font As Font ' Points to a collection of pre-loaded fonts
SpaceWidth As Long
LineHeight As Long
End Type
More Complex:
Private Type FontDef
StyleName as String
FontName as String
FontSize as String
Color
Bold
etc.
SpaceWidth As Long
LineHeight As Long
End Type
' Are store of the fonts used in the document
' This should be moved to be a part of the DocDef structure
Dim MyFonts() As FontDef
' Each Paragrapgs is loaded into this structure:
Private Type ParaDef
Text As String
WordCount As Long
Words() As String
WordsAttributes() As String
Fonts() As Long
PosX() As Long
WLen() As Long ' Length of each word
Lines() As LineDef ' words in each line
End Type
' This structure contains document data
' I will move the document parameters and fonts into here
Private Type DocDef
Name As String
Paras() As ParaDef
ALP() As Pointerdef ' Absolute line pointer to para and line within para
MyFonts() as FontDef
Parameters() AS ParamsDef ' Create a structure to hold document parameters
End Type
So when displaying a word you can see if the Word's font has changed
' Each Word can have a different font pointer
Word = Doc.Paras(CP).Word(WC)
CF = Doc.Paras(CP).Fonts(WC)
So when displaying a word you can see if the Font has Changed:
If CF <> LF Then ' Current Font <> Last Font
Set PB.Font = Doc.MyFonts(CF).Font
End If
This means that you have to preload all of the required fonts into Doc.MyFonts()
Another more simple way to do it is to store the Font details in the FontDefs struture the you can say:
If CF <> LF Then ' Current Font <> Last Font
PB.Font.Name = Doc.MyFonts(CF).FontName
PB.Font.Size = Doc.MyFonts(CF).FontSize
PB.Font.Bold = Doc.MyFonts(CF).FontBold
etc.
End If
I will post some other code that you will need but I would prefer to email it to you. I am going to be busy for a few days so it could be some time before I can get back to you.
I have now improved the loading example as with super large documents you can't page directly to the end of the document. But I have now resolved this - instead of using the scroll bar to select a line of the screen I will multiply the number of paragraphs by 10 and use this as a key to the line to display, so the user can page doen in paragraphs and won't know the difference. Or I may just add up each line in all paragraphs and do away with an absolute pointer to a specifc line - the problem with this is that for documents whic are serveral MB it would get slower - so the solution would be to be able to handle both types of addressing for best of both worlds. In this way the max value can be found in a split second. When all the paras in the document have been calculated to see how many lines on the screen that they would occupy the program will then revert to using absolute addressing to a specific line.
All you have seen so far is the code to display the data real fast. But there are two major step for you to achieve next:
1) Control of Caret - I have created a handy simple class which does this.
2) Interfacing with the keyboard - I will post some examples of the keyboard events that you need to handle - but they were written for a different concept.
As you can guess I have already written sevral word processors. But the last version I created I was not happy with the load speed as it used Public Classes which are very slow.
Eventually I will take the loading example above and make a WP program from it - but not for serveral weeks.
You asked how to handle words with different Fonts/colours:
First you need to understand the document structure:
' Pointers to the start and end words for each line within a para.
Private Type LineDef
startword As Long
lastword As Long
End Type
' An element for an absolute line number which points to a specifc line within a paragraph.
' I intend to make this redudant.
Private Type Pointerdef
Para As Long ' Pointer to Para
LIP As Long ' Line in Para
End Type
' Each word can point to a different font.
' So for each font variation you need one of these
Simple:
Private Type FontDef
StyleName as String
Font As Font ' Points to a collection of pre-loaded fonts
SpaceWidth As Long
LineHeight As Long
End Type
More Complex:
Private Type FontDef
StyleName as String
FontName as String
FontSize as String
Color
Bold
etc.
SpaceWidth As Long
LineHeight As Long
End Type
' Are store of the fonts used in the document
' This should be moved to be a part of the DocDef structure
Dim MyFonts() As FontDef
' Each Paragrapgs is loaded into this structure:
Private Type ParaDef
Text As String
WordCount As Long
Words() As String
WordsAttributes() As String
Fonts() As Long
PosX() As Long
WLen() As Long ' Length of each word
Lines() As LineDef ' words in each line
End Type
' This structure contains document data
' I will move the document parameters and fonts into here
Private Type DocDef
Name As String
Paras() As ParaDef
ALP() As Pointerdef ' Absolute line pointer to para and line within para
MyFonts() as FontDef
Parameters() AS ParamsDef ' Create a structure to hold document parameters
End Type
So when displaying a word you can see if the Word's font has changed
' Each Word can have a different font pointer
Word = Doc.Paras(CP).Word(WC)
CF = Doc.Paras(CP).Fonts(WC)
So when displaying a word you can see if the Font has Changed:
If CF <> LF Then ' Current Font <> Last Font
Set PB.Font = Doc.MyFonts(CF).Font
End If
This means that you have to preload all of the required fonts into Doc.MyFonts()
Another more simple way to do it is to store the Font details in the FontDefs struture the you can say:
If CF <> LF Then ' Current Font <> Last Font
PB.Font.Name = Doc.MyFonts(CF).FontName
PB.Font.Size = Doc.MyFonts(CF).FontSize
PB.Font.Bold = Doc.MyFonts(CF).FontBold
etc.
End If
ASKER
Once again thank you very much sir
ASKER
I forgot to mention my time zone is gmt + 5:30 and myemail ssruprai@hotmail.com. Whenever you are free you can send that code.
Thanks
Thanks
ASKER
Hello,
What I want is an editor similar to VB's Code Editor(but it is limited). An editor for programming like editplus(http://www.editplus.com/). You can check editplus and then you'll know what I want to do. I don't want a word processor like wordpad or MsWord and text will be saved as plain text.
So I want a syntax file to be loaded in memory according to file extension of the current file. So when someone opens .Java file then words like int, long and for etc. should be highlighted in different colors. When editing a file when someone types a keyword it should automatically highlighted.
But problem is how to change color or font of only that particular word in Picture Box. I mean is there any way where I can do something like:
pictureBox.currentword.for eColor = vbRed or
pictureBox.words(35).foreC olor = vbRed or
pictureBox.words(35).font = "Times new Roman"
So, problem is giving a word a foreColor, backcolor or a font property. I think you got the Idea.
What I want is an editor similar to VB's Code Editor(but it is limited). An editor for programming like editplus(http://www.editplus.com/). You can check editplus and then you'll know what I want to do. I don't want a word processor like wordpad or MsWord and text will be saved as plain text.
So I want a syntax file to be loaded in memory according to file extension of the current file. So when someone opens .Java file then words like int, long and for etc. should be highlighted in different colors. When editing a file when someone types a keyword it should automatically highlighted.
But problem is how to change color or font of only that particular word in Picture Box. I mean is there any way where I can do something like:
pictureBox.currentword.for
pictureBox.words(35).foreC
pictureBox.words(35).font = "Times new Roman"
So, problem is giving a word a foreColor, backcolor or a font property. I think you got the Idea.
ASKER
Control created using above code loads text very fast but scrolling speed isn't acceptable at all. Which means refreshing has a big problem.
Questions Asked 20
Last 10 Grades Given B A B B C B B B B A
Question Grading Record 13 Answers Graded / 13 Answers Received
Also, you may want to re-read the EE Guidelines (https://www.experts-exchange.com/jsp/cmtyQuestAnswer.jsp) regarding grading standards used here.
Thanks,
Anthony