Solved

Which Component is used for text editors edit window?

Posted on 2002-04-06
13
276 Views
Last Modified: 2010-05-02
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.
0
Comment
Question by:Sukhwinder Singh
13 Comments
 
LVL 75

Expert Comment

by:Anthony Perkins
ID: 6923423
Please maintain your open questions.  For the record:

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 (http://www.experts-exchange.com/jsp/cmtyQuestAnswer.jsp) regarding grading standards used here.

Thanks,
Anthony
0
 
LVL 17

Expert Comment

by:inthedark
ID: 6923428
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).LIP).startword
    lastword = Doc.Paras(P).Lines(Doc.ALP(abslc).LIP).lastword
   
    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.Paras(pc).WordCount - 1)
        ReDim Doc.Paras(pc).PosX(Doc.Paras(pc).WordCount - 1)
        ReDim Doc.Paras(pc).Fonts(Doc.Paras(pc).WordCount - 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).startword = startword
                Doc.Paras(pc).Lines(lc).lastword = 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).startword = startword
        Doc.Paras(pc).Lines(lc).lastword = 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).startword = startword
            Doc.Paras(pc).Lines(lc).lastword = 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).startword = startword
    Doc.Paras(pc).Lines(lc).lastword = Doc.Paras(pc).WordCount - 1

Next pc
Set vs = VScroll1

vs.Value = 0
vs.Max = tlc

ReDim Preserve Doc.ALP(tlc - 1)

End Sub
0
 
LVL 100

Expert Comment

by:mlmcc
ID: 6923447
listening
0
 

Author Comment

by:Sukhwinder Singh
ID: 6924270
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++?

0
 
LVL 17

Expert Comment

by:inthedark
ID: 6924384
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.
0
 
LVL 17

Expert Comment

by:inthedark
ID: 6924388
>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.
0
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 
LVL 17

Accepted Solution

by:
inthedark earned 75 total points
ID: 6924462
So the loading is now super fast 5800% faster than MS Word.
It loads a file of 1MB in just 0.060 seconds. But screen resize needs a little more thought. I will be busy for a few days - have fun....



VERSION 5.00
Begin VB.Form frmWP2
   AutoRedraw      =   -1  'True
   Caption         =   "Form1"
   ClientHeight    =   7545
   ClientLeft      =   60
   ClientTop       =   345
   ClientWidth     =   9660
   LinkTopic       =   "Form1"
   ScaleHeight     =   503
   ScaleMode       =   3  'Pixel
   ScaleWidth      =   644
   StartUpPosition =   3  'Windows Default
   Begin VB.Timer Timer1
      Left            =   7740
      Top             =   30
   End
   Begin VB.CommandButton Command1
      Caption         =   "Command1"
      Height          =   465
      Left            =   360
      TabIndex        =   2
      Top             =   0
      Width           =   1455
   End
   Begin VB.VScrollBar VScroll1
      Height          =   5025
      Left            =   7440
      TabIndex        =   1
      Top             =   480
      Width           =   345
   End
   Begin VB.PictureBox Picture1
      AutoRedraw      =   -1  'True
      Height          =   5025
      Left            =   360
      ScaleHeight     =   4965
      ScaleWidth      =   7005
      TabIndex        =   0
      Top             =   480
      Width           =   7065
   End
   Begin VB.Label Label1
      AutoSize        =   -1  'True
      Caption         =   "Label1"
      Height          =   195
      Left            =   4890
      TabIndex        =   4
      Top             =   60
      Width           =   480
   End
   Begin VB.Label lblTLOS
      AutoSize        =   -1  'True
      Caption         =   "lblTLOS"
      Height          =   195
      Left            =   2160
      TabIndex        =   3
      Top             =   90
      Width           =   570
   End
End
Attribute VB_Name = "frmWP2"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit
Dim GF As New zGF

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
  RepaginateRequired As Boolean
  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
  PointerToALP As Long
  Loaded As Boolean
End Type

Private Type DocDef
    Name As String
    Paras() As ParaDef
    ALP() As Pointerdef      ' Absolute line pointer to para ans line within para
    ALPCount As Long
    LastParaLoaded As Long         ' -1 = none loaded
    Loaded As Boolean
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
lblTLOS.Caption = "Top Line: " + CStr(TLOS)
Do
   
    PosX = ML
    PB.CurrentY = posY ' if using multi fonts needs to be set for each word
       
    abslc = TLOS + lc
    Do
        If abslc > Doc.ALPCount - 1 Then
       
            If Doc.Loaded Then Exit Do
            LoadNextPara
           
            If Doc.LastParaLoaded < UBound(Doc.Paras) Then
               
                Doc.LastParaLoaded = Doc.LastParaLoaded + 1
                LoadPara Doc.LastParaLoaded
            Else
                Doc.Loaded = True
                VScroll1.Max = Doc.ALPCount - 1
               
                Exit Do
            End If
       
        End If
        If abslc <= Doc.ALPCount - 1 Then Exit Do
    Loop
   
    If abslc > Doc.ALPCount - 1 Then Exit Do
   
    P = Doc.ALP(abslc).Para ' para for this line
   
    MaxHeight = 0
   
    startword = Doc.Paras(P).Lines(Doc.ALP(abslc).LIP).startword
    lastword = Doc.Paras(P).Lines(Doc.ALP(abslc).LIP).lastword
    If startword >= 0 Then
   
        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
    Else
        MaxHeight = MyFonts(0).LineHeight
    End If
   
    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



Sub LoadNextPara()
If Doc.LastParaLoaded < UBound(Doc.Paras) Then
    Doc.LastParaLoaded = Doc.LastParaLoaded + 1
    LoadPara Doc.LastParaLoaded
Else
    Doc.Loaded = True
    VScroll1.Max = Doc.ALPCount - 1
End If
End Sub

Sub LoadPara(pc As Long)

Dim lc As Long      ' lines in the para
Dim xpos As Long
Dim wc As Long
Dim cf As Long
Dim tlc As Long
Dim pos As Long
lc = 0
pos = 0
Dim startword As Long
Dim lastword As Long


Doc.Paras(pc).WordCount = 0
Doc.Paras(pc).PointerToALP = Doc.ALPCount

If Len(Doc.Paras(pc).Text) > 0 Then
   
    If Not Doc.Paras(pc).Loaded Then
   
        Doc.Paras(pc).Words = Split(Doc.Paras(pc).Text, Space$(1))
        wc = UBound(Doc.Paras(pc).Words)
        Doc.Paras(pc).WordCount = wc + 1
        ReDim Doc.Paras(pc).WLen(wc)
        ReDim Doc.Paras(pc).PosX(wc)
        ReDim Doc.Paras(pc).Fonts(wc)
    End If
   
    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
        If Not Doc.Paras(pc).Loaded Then
            Doc.Paras(pc).WLen(wc) = PB.TextWidth(Doc.Paras(pc).Words(wc))
        End If
        If pos + Doc.Paras(pc).WLen(wc) + MyFonts(cf).SpaceWidth > w Then
            pos = 0
            Doc.Paras(pc).PosX(wc) = pos
            GoSub CreateNewLine
            startword = wc
            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)
    wc = Doc.Paras(pc).WordCount
    GoSub CreateNewLine
Else
    ' blank para just drop one line
    ReDim Doc.Paras(pc).Lines(0)
    GoSub CreateNewLine
    Doc.Paras(pc).Lines(0).startword = -1
    Doc.Paras(pc).Lines(0).lastword = 0
End If

Doc.Paras(pc).Loaded = True
If Not Doc.Loaded Then
    If Doc.ALPCount - 1 > VScroll1.Max Then
        VScroll1.Max = Doc.ALPCount + 100
    End If
End If
GoTo Exiter:

CreateNewLine:

    Doc.Paras(pc).Lines(lc).startword = startword
    Doc.Paras(pc).Lines(lc).lastword = wc - 1
   
    Doc.ALPCount = Doc.ALPCount + 1
    tlc = Doc.ALPCount - 1
   
    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
Return

Exiter:

End Sub

Sub RepaginatePara(CP 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).startword = startword
            Doc.Paras(pc).Lines(lc).lastword = 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).startword = startword
    Doc.Paras(pc).Lines(lc).lastword = Doc.Paras(pc).WordCount - 1

Next pc
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)


'YourText = GF.ReadFile("d:\tmp.txt")

' 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

Doc.LastParaLoaded = -1
Doc.Loaded = False
Doc.ALPCount = 0

For pc = 0 To UBound(Lines)
    lc = 0
    pos = 0
    Doc.Paras(pc).Text = Lines(pc)
    Doc.Paras(pc).Loaded = False
    Doc.Paras(pc).PointerToALP = -1
    Lines(pc) = ""
Next pc


Erase Lines

CP = 0 ' Current Para
CW = 0 ' Currnt Word
CC = 0 ' Currnt Character In Word

VScroll1.Max = UBound(Doc.Paras) * 4 ' guess at size of file
DisplayData
VScroll1.LargeChange = h / MyFonts(0).LineHeight
MsgBox "Data loaded in: " + Format(Timer - st, "0.000") + "seconds total bytes=" + CStr(k)

Loaded = True

Timer1.Interval = 1


End Sub

Private Sub Form_Load()

Command1.Caption = "Load Data"
Set PB = Picture1

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
    VScroll1.LargeChange = h / MyFonts(0).LineHeight
End If

End Sub

Private Sub Timer1_Timer()
Static Done As Boolean
Dim pc As Long

Dim st As Single
If Doc.Loaded Then
    Timer1.Interval = 0
    Label1.Caption = "Backgroud calcs: 100%"
Else
    If Done Then
       
        Do While Not Doc.Loaded
            LoadNextPara
            pc = pc + 1
            If pc > 100 Then Exit Do
        Loop
        Label1.Caption = "Backgroud calcs: " + CStr(Int(100 * Doc.LastParaLoaded / UBound(Doc.Paras()))) + "%"
    Else
   
        st = Timer
        Do While Not Doc.Loaded
            LoadNextPara
            pc = pc + 1
            If pc > 100 Then Exit Do
        Loop
        Label1.Caption = "Backgroud calcs: " + CStr(Int(100 * Doc.LastParaLoaded / UBound(Doc.Paras()))) + "%"
        st = Int((Timer - st) * 2000)
        If st < 2 Then st = 2
        Timer1.Interval = st
        Done = True
    End If
   
End If
End Sub

Private Sub VScroll1_Change()

VScroll1_Scroll
End Sub


Private Sub VScroll1_Scroll()
TLOS = VScroll1.Value
If Not Doc.Loaded Then
    If TLOS > Doc.ALPCount + 400 Then
        TLOS = Doc.ALPCount + 400
        VScroll1.Value = TLOS
    End If
End If
DisplayData

End Sub

Private Sub RepaginateDoc(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).startword = startword
            Doc.Paras(pc).Lines(lc).lastword = 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).startword = startword
    Doc.Paras(pc).Lines(lc).lastword = Doc.Paras(pc).WordCount - 1

Next pc

Set vs = VScroll1

vs.Value = 0
vs.Max = tlc

ReDim Preserve Doc.ALP(tlc - 1)

End Sub
0
 

Author Comment

by:Sukhwinder Singh
ID: 6926469
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.
0
 
LVL 17

Expert Comment

by:inthedark
ID: 6927405
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













0
 

Author Comment

by:Sukhwinder Singh
ID: 6929717
Once again thank you very much sir
0
 

Author Comment

by:Sukhwinder Singh
ID: 6929977
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
0
 

Author Comment

by:Sukhwinder Singh
ID: 6930196
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.foreColor = vbRed      or
     pictureBox.words(35).foreColor = 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.
0
 

Author Comment

by:Sukhwinder Singh
ID: 6964505
Control created using above code loads text very fast but scrolling speed isn't acceptable at all. Which means refreshing has a big problem.
0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

The debugging module of the VB 6 IDE can be accessed by way of the Debug menu item. That menu item can normally be found in the IDE's main menu line as shown in this picture.   There is also a companion Debug Toolbar that looks like the followin…
When designing a form there are several BorderStyles to choose from, all of which can be classified as either 'Fixed' or 'Sizable' and I'd guess that 'Fixed Single' or one of the other fixed types is the most popular choice. I assume it's the most p…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now