I have created a Tabbed Multi-Document-Interface Text Editor using just standard controls and custom modified controls.
See the screenshot:
In this post I will try to explain exactly how I managed to do it and I have attached the project source (VS2008 only, sorry). If I manage to find the time for it, I might post the code split up into individual files and explain how to add the code and to which file, so you can get it to work on older versions of Visual Studio as well.
As far as I know there is no way of creating a real tabbed MDI application with Visual Studio and its standard controls, although there are a large number of third party controls available which handle it really well, but are also really expensive and not really an option for any 'stand-alone' coder or hobbyist.
That's why I decided to try and 'fake' a tabbed MDI application using standard controls only, and that's also why I provide it for free here...
Now, instead of actually using MDI Forms, my application uses a custom control inheriting from a TabControl (although it is nearly the same using a standard TabControl) and custom TabPages which host a RichTextBox. This simulates the use of Tabbed MDI forms really well, although it makes it nearly impossible to switch between the tabbed and untabbed MDI look.
First, the custom TabControl (called cTabControl). This is simply a UserControl which inherits from the TabControl, making it behave exactly like a normal TabControl except for a few tiny things, which I thought were easier to do by creating a custom TabControl. As I've said I think it can be done easily using a normal TabControl.
The custom TabPage (called cTabPage) is also just a UserControl, this time inheriting from a TabPage. This TabPage differs from the standard TabPage because it already has a RichTextBox (called RTB) on it.
Most of the standard text-editor features are present:
- New, Open, Save, Save As features
- Cut, Copy, Paste, Select All features
And a few 'new' features which are useful for an MDI application have been added:
- The 'Open File' feature is able to open multiple files simultaneously
- Save All feature which saves every document
- Close All Documents feature which closes every document
- Close feature which closes the active document
There is also a StatusBar which hosts a label displaying the filepath of the active document and the current Line and Character positions ("Ln x, Ch y").
I have also added a handy little feature I got from Visual Studio itself: you can rightclick a tab header and a Contextmenu drops down where you can quickly Save or Close the selected tab.
One drawback of not using actual MDI Forms was that the 'Window' list of open documents could not be created automatically, so I had to list the windows manually.
I managed this by using the WindowToolStripMenuItem's "DropDownOpening" event which fires just before the dropdown menu is shown. First I clear the list. Then I add a ToolStripMenuItem for each open document. The document (tab) itself is stored in the Tag of this MenuItem so it can be handled accordingly when it is clicked.
But, enough talk. If you have VS2008 you can download my attachment which contains the complete project. You should be able to run it without making any changes. If this is not the case please let me know!
If you take a look at my signature, you can also have a look at the (non-tabbed) Extensive MDI Text Editor I have created. This contains a LOT more functions like document Splitting, synchronized scrolling etc etc... I don't think it will be very hard to translate features from that project to this Tabbed version, but if you want to try and cannot manage it, let me know and I'll try to help!
Lastly, there is still alot of work that can be done on this project and I might add things to it in time...
If anyone finds any errors or bugs please let me know and I'll try to fix them! Also, if anyone sees anything I shouldn't be doing please tell me. (I'm just a hobby coder so I'm sure I'm not doing much things the right way ).
Enjoy!
Last edited by Hack; Sep 24th, 2008 at 12:26 PM.
Reason: Edited Attachment And Removed Compiled Code
In this post and the next two posts I will try to explain how to rebuild this project exactly in older versions of Visual Studio. It's
also a chance to see all of the code without downloading my attachment.
Note that I have only ever used VS2005 and VS2008. If anything is different in older versions you will have to
decide for yourself how to overcome any difficulties!
1. Open a new Windows Forms Application project
2. Add a UserControl and call it cTabControl
3. Add another UserControl and call it cTabPage
4. Change the UserControl types to TabControl and TabPage:
Press the "Show All Files" button in the Solution Explorer (second button) and expand the [+] sign in front of the
'cTabControl.vb' usercontrol. Open the 'cTabControl.Designer.vb' file and find the following line somewhere at the
top:
vb.net Code:
Inherits System.Windows.Forms.UserControl
Change the word "UserControl" to "TabControl". There may be some errors popping up around the "AutoScaleMode"
property. If they do, comment out those line(s).
Do the same for the 'cTabPage' control, except change "UserControl" into "TabPage" this time.
You can now press the "Show All Files" button again to disable showing all files if you want to.
5. 'cTabControl' code:
Add the following code to the 'cTabControl.vb' usercontrol:
Code:
' Gets a tab from a location within the screen
' Works by checking if the 'loc' location is within the tab rectangle
Public Function GetTabFromLocation(ByVal loc As Point) As cTabPage
For i As Integer = 0 To Me.TabPages.Count - 1
If Me.GetTabRect(i).Contains(loc) Then
Return Me.TabPages(i)
Exit Function
End If
Next
Return Nothing
End Function
' Active tab changed
Private Sub cTabControl_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles MyBase.SelectedIndexChanged
Dim tab As cTabPage = frmMain.getTab()
If tab IsNot Nothing Then
frmMain.UpdateTitle()
frmMain.UpdateLineInfo(tab)
frmMain.UpdateWindowList()
Else
frmMain.lblLineInfo.Text = ""
frmMain.lblFilePath.Text = ""
End If
End Sub
Private Sub cTabControl_ControlAdded(ByVal sender As System.Object, ByVal e As
System.Windows.Forms.ControlEventArgs) Handles MyBase.ControlAdded
frmMain.UpdateWindowList()
End Sub
Private Sub cTabControl_ControlRemoved(ByVal sender As System.Object, ByVal e As
System.Windows.Forms.ControlEventArgs) Handles MyBase.ControlRemoved
frmMain.UpdateWindowList()
End Sub
6. 'cTabPage' controls and code:
Add a 'RichTextBox' control to your 'cTabPage.vb' usercontrol (drag it into the gray area) and name it 'RTB'. You
can choose which properties you want to set but most importantly is to set the 'Dock' property to 'Fill'.
Add the following code to your 'cTabPage.vb' usercontrol:
Code:
#Region " VARIABLES "
Dim _DocName, _DocPath As String
Dim _DocIndex As Integer
Dim _DocSaved, _DocChanged As Boolean
#End Region
Public Sub New()
' This call is required by the Windows Form Designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
frmMain.tabCtrl.SelectedTab = Me
RTB.Focus()
End Sub
#Region " PROPERTIES "
' Name of the document (including extension)
Public Property DocName() As String
Get
Return _DocName
End Get
Set(ByVal value As String)
_DocName = value
UpdateTitle()
End Set
End Property
' Filepath of the document
Public Property DocPath() As String
Get
Return _DocPath
End Get
Set(ByVal value As String)
_DocPath = value
End Set
End Property
' Index of the document (only for 'Untitled' documents)
' Example: Untitled 3 --> index = 3
Public Property DocIndex() As Integer
Get
Return _DocIndex
End Get
Set(ByVal value As Integer)
_DocIndex = value
End Set
End Property
' Whether or not the document already exists on the computer
' (has been saved before or not)
Public Property DocSaved() As Boolean
Get
Return _DocSaved
End Get
Set(ByVal value As Boolean)
_DocSaved = value
End Set
End Property
' Whether or not the document text has been changed since the last save action
Public Property DocChanged() As Boolean
Get
Return _DocChanged
End Get
Set(ByVal value As Boolean)
_DocChanged = value
End Set
End Property
#End Region
#Region " MISC FUNCTIONS "
' Updates the document title to reflect the Changed status
Public Sub UpdateTitle()
If DocChanged Then
Me.Text = Me.DocName & "*"
Else
Me.Text = Me.DocName
End If
End Sub
#End Region
#Region " DOCUMENT RELATED "
' Checks if the document has changed and asks whether or not to close
' If yes --> tab is saved then closed. If no --> tab is not saved then closed. If cancel --> tab is not closed
Public Sub Close()
Dim blnCancel As Boolean = False
If DocChanged Then
Dim str As String
If DocPath <> "" Then
str = "The following document has changed:" & ControlChars.CrLf & ControlChars.CrLf & DocName &
ControlChars.CrLf & "(" & DocPath & ")" & ControlChars.CrLf & ControlChars.CrLf & "Do you want to save before
closing?"
Else
str = "The following document has changed:" & ControlChars.CrLf & ControlChars.CrLf & DocName &
ControlChars.CrLf & ControlChars.CrLf & "Do you want to save before closing?"
End If
Dim msgBoxRes As MsgBoxResult = MessageBox.Show(str, "Document has changed",
MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question)
If msgBoxRes = MsgBoxResult.Cancel Then
blnCancel = True
ElseIf msgBoxRes = MsgBoxResult.Yes Then
If DocSaved Then
frmMain.SaveTab(Me)
Else
frmMain.SaveTabAs(Me)
End If
End If
End If
If Not blnCancel Then
Me.Dispose()
End If
End Sub
#End Region
#Region " RTB RELATED "
' Changes the LineInfo ("Ln x, Ch y")
Private Sub RTB_SelectionChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
RTB.SelectionChanged
frmMain.UpdateLineInfo(Me)
End Sub
Private Sub RTB_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RTB.TextChanged
If Not Me.DocChanged Then
Me.DocChanged = True
UpdateTitle()
frmMain.UpdateTitle()
End If
End Sub
' Loads a file into the RTB
' Throws error and returns False on error
Public Function LoadFile(ByVal path As String) As Boolean
Try
Dim richTb As RichTextBox = RTB
RTB.LoadFile(path, RichTextBoxStreamType.PlainText)
Return True
Catch ex As Exception
WriteError(ex.Message)
Return False
End Try
End Function
' Saves a file into the RTB
' Throws error and returns False on error
Public Function SaveFile(ByVal path As String) As Boolean
Try
RTB.SaveFile(path, RichTextBoxStreamType.PlainText)
Return True
Catch ex As Exception
WriteError(ex.Message)
Return False
End Try
End Function
#End Region
7. Build your application if there are no errors (Build - Build [solution name])
If you don't do this, you will not be able to use your usercontrols.
8. The Main Form:
There should already be a blank form called 'Form1'. Rename it to 'frmMain'.
Add the following controls, change the properties if it is mentioned:
- MenuStrip (right-click --> Insert Standard Items)
- ToolStrip (right-click --> Insert Standard Items)
- StatusStrip
- cTabControl (Change name to "tabCtrl", Dock = Fill, Remove all tabs)
(The custom tabcontrol can be found at the very top of your toolbox. If not, go back to step 7)
9. The main menus:
You need to edit a few of the menus if you wish:
- In the 'File' menu, add a ToolStripMenuItem called "SaveAllToolStripMenuItem". Give it a Text property of
something like "Save All". Also add a ToolStripMenuItem called "CloseToolStripMenuItem" with a Text property of
"Close".
- In the "Window" menu, add a ToolStripMenuItem called "CloseAllDocumentsToolStripMenuItem" and a Separator called
"WindowSeparator".
- In the ToolStrip, add a ToolStripButton called "SaveAllToolStripButton".
In the StatusStrip, add three labels:
- lblFilePath (left)
- lblSpring (middle, set the "Spring" property to true)
- lblLineInfo (right)
10. The ContextmenuStrip
Add a ContextMenuStrip with two items:
- CloseContextMenu
- SaveContextMenu
Set the 'ContextMenuStrip' property of the 'tabCtrl' tabcontrol to "ContextMenuStrip1".
11. Main form code:
The code for the "frmMain" form is:
Code:
#Region " VARIABLES "
Dim colWindowList As Collection
#End Region
#Region " MISC FUNCTIONS "
' Updates the Titlebar of the main form and label in the StatusBar to reflect the active document
Public Sub UpdateTitle()
If Me.tabCtrl.SelectedTab IsNot Nothing Then
Me.Text = Me.tabCtrl.SelectedTab.Text & " - [ Tabbed MDI Editor ]"
Me.lblFilePath.Text = CType(Me.tabCtrl.SelectedTab, cTabPage).DocPath
End If
End Sub
' Updates the LineInfo at the bottom-right corner
Public Sub UpdateLineInfo(ByVal tab As cTabPage)
Dim ln As Long = tab.RTB.GetLineFromCharIndex(tab.RTB.SelectionStart)
Dim ch As Integer = tab.RTB.SelectionStart - tab.RTB.GetFirstCharIndexFromLine(ln)
Me.lblLineInfo.Text = "Ln " & ln + 1 & ", Ch " & ch + 1
End Sub
' Returns the currently active Tabpage as a cTabPage custom tab
Public Function getTab() As cTabPage
If tabCtrl.SelectedTab IsNot Nothing Then
Return CType(tabCtrl.SelectedTab, cTabPage)
Else
Return Nothing
End If
End Function
' Returns the name only of the filepath
Public Function getName(ByVal path As String) As String
Return IO.Path.GetFileName(path)
End Function
' Kinda messy... Returns the first free 'index' for a New Document
Public Function getNextIndex() As Integer
Dim bln As Boolean = False
Dim n As Integer = tabCtrl.TabPages.Count - 1
Dim x As Integer
Dim arr(0 To 1000) As Integer
For i As Integer = 0 To 1000
arr(i) = -1
Next
For i As Integer = 0 To n
x = CType(tabCtrl.TabPages(i), cTabPage).DocIndex
If x > 0 And x <= 1000 Then arr(x) = x
Next
For i As Integer = 1 To 1000
If arr(i) < 0 Then
Return i
Exit Function
End If
Next
End Function
' Checks if the file 'path' is already open and return True if it is
Public Function checkExisting(ByVal path As String, Optional ByVal showError As Boolean = True) As Boolean
For Each cTab As cTabPage In tabCtrl.TabPages
If cTab.DocPath = path Then
If showError Then WriteError("The following document is already opened:" & vbNewLine & vbNewLine &
path, ErrorType.tError)
Return True
Exit Function
End If
Next
Return False
End Function
#End Region
#Region " MENU & TOOLSTRIP ITEMS "
Private Sub NewToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
NewToolStripMenuItem.Click
NewTab()
End Sub
Private Sub OpenToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
OpenToolStripMenuItem.Click
OpenTab()
End Sub
' Checks if the document already has a save-path and then save accordingly
Private Sub SaveToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
SaveToolStripMenuItem.Click
Dim tab As cTabPage = getTab()
If tab IsNot Nothing Then
If tab.DocSaved Then
SaveTab(tab)
Else
SaveTabAs(tab)
End If
End If
End Sub
Private Sub SaveAsToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
SaveAsToolStripMenuItem.Click
Dim tab As cTabPage = getTab()
If tab IsNot Nothing Then SaveTabAs(tab)
End Sub
' Loops through each tab and save it
Private Sub SaveAllToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
SaveAllToolStripMenuItem.Click
For Each tab As cTabPage In Me.tabCtrl.TabPages
If tab.DocSaved Then
SaveTab(tab)
Else
SaveTabAs(tab)
End If
Next
End Sub
' Closes the active tab
Private Sub CloseToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
CloseToolStripMenuItem.Click
Dim tab As cTabPage = getTab()
If tab IsNot Nothing Then
tab.Close()
End If
End Sub
Private Sub ExitToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
ExitToolStripMenuItem.Click
Me.Close()
End Sub
Private Sub UndoToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
UndoToolStripMenuItem.Click
Dim tab As cTabPage = getTab()
If tab IsNot Nothing Then
tab.RTB.Undo()
End If
End Sub
Private Sub RedoToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
RedoToolStripMenuItem.Click
Dim tab As cTabPage = getTab()
If tab IsNot Nothing Then
tab.RTB.Redo()
End If
End Sub
Private Sub CutToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
CutToolStripMenuItem.Click
Dim tab As cTabPage = getTab()
If tab IsNot Nothing Then
tab.RTB.Cut()
End If
End Sub
Private Sub CopyToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
CopyToolStripMenuItem.Click
Dim tab As cTabPage = getTab()
If tab IsNot Nothing Then
tab.RTB.Copy()
End If
End Sub
Private Sub PasteToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
PasteToolStripMenuItem.Click
Dim tab As cTabPage = getTab()
If tab IsNot Nothing Then
tab.RTB.Paste()
End If
End Sub
Private Sub SelectAllToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles SelectAllToolStripMenuItem.Click
Dim tab As cTabPage = getTab()
If tab IsNot Nothing Then
tab.RTB.SelectAll()
End If
End Sub
Private Sub CloseAllDocumentsToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles CloseAllDocumentsToolStripMenuItem.Click
For Each tab As cTabPage In tabCtrl.TabPages
If tab IsNot Nothing Then tab.Close()
Next
End Sub
Private Sub NewToolStripButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
NewToolStripButton.Click
NewToolStripMenuItem.PerformClick()
End Sub
Private Sub OpenToolStripButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
OpenToolStripButton.Click
OpenToolStripMenuItem.PerformClick()
End Sub
Private Sub SaveToolStripButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
SaveToolStripButton.Click
SaveToolStripMenuItem.PerformClick()
End Sub
Private Sub SaveAllToolStripButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
SaveAllToolStripButton.Click
SaveAllToolStripMenuItem.PerformClick()
End Sub
Private Sub CutToolStripButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
CutToolStripButton.Click
CutToolStripMenuItem.PerformClick()
End Sub
Private Sub CopyToolStripButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
CopyToolStripButton.Click
CopyToolStripMenuItem.PerformClick()
End Sub
Private Sub PasteToolStripButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
PasteToolStripButton.Click
PasteToolStripMenuItem.PerformClick()
End Sub
Private Sub CloseTabToolStripButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
CloseTabToolStripButton.Click
CloseToolStripMenuItem.PerformClick()
End Sub
' Changes the 'Save' and 'Close' captions to reflect the active document
Private Sub FileToolStripMenuItem_DropDownOpening(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles FileToolStripMenuItem.DropDownOpening
Dim tab As cTabPage = getTab()
If tab IsNot Nothing Then
SaveToolStripMenuItem.Text = "Save " & tab.DocName
CloseToolStripMenuItem.Text = "Close " & tab.DocName
End If
End Sub
' Changes the 'Save' and 'Close' captions to reflect the active document
Private Sub ContextMenuStrip1_Opening(ByVal sender As System.Object, ByVal e As
System.ComponentModel.CancelEventArgs) Handles ContextMenuStrip1.Opening
'Dim tab As cTabPage = getTab()
Dim loc As Point = tabCtrl.PointToClient(MousePosition)
Dim tab As cTabPage = tabCtrl.GetTabFromLocation(loc)
If tab IsNot Nothing Then
tabCtrl.SelectedTab = tab
CloseContextMenu.Text = "Close " & tab.DocName
SaveContextMenu.Text = "Save " & tab.DocName
End If
End Sub
Private Sub CloseContextMenu_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
CloseContextMenu.Click
Dim tab As cTabPage = getTab()
If tab IsNot Nothing Then
tab.Close()
End If
End Sub
#End Region
(This is continued from previous post, and still goes in the frmMain form!)
Code:
#Region " NEW/OPEN/SAVE ETC "
' Adds a new tab with a blank RTB
Public Sub NewTab()
Dim tab As New cTabPage
Dim i As Integer = getNextIndex()
tab.DocName = "Untitled " & i
tab.DocPath = ""
tab.Text = tab.DocName
tab.DocIndex = i
tab.DocChanged = False
tab.DocSaved = False
tabCtrl.TabPages.Add(tab)
UpdateTitle()
End Sub
' Shows an OpenFileDialog and opens the selected files in new Tabs
Public Sub OpenTab()
Using ofd As New OpenFileDialog
ofd.Title = "Open File"
ofd.Filter = "Text files (*.txt)|*.txt|All files|*.*"
ofd.Multiselect = True
If ofd.ShowDialog() = Windows.Forms.DialogResult.OK Then
For Each file As String In ofd.FileNames
If file <> "" Then OpenTab(file)
Next
End If
End Using
End Sub
' Opens 'path' file in a new Tab
Public Sub OpenTab(ByVal path As String)
If Not checkExisting(path) Then
Dim tab As New cTabPage
If tab.LoadFile(path) Then
tab.DocName = getName(path)
tab.DocPath = path
tab.Text = tab.DocName
tab.DocChanged = False
tab.DocSaved = True
tabCtrl.TabPages.Add(tab)
UpdateTitle()
End If
End If
End Sub
' Saves the document in the 'tab' tab
Public Sub SaveTab(ByVal tab As cTabPage)
If tab.SaveFile(tab.DocPath) Then
tab.DocSaved = True
tab.DocChanged = False
tab.UpdateTitle()
UpdateTitle()
End If
End Sub
' Shows a SaveFileDialog and saves the document in the 'tab' tab
Public Sub SaveTabAs(ByVal tab As cTabPage)
Using sfd As New SaveFileDialog
sfd.Title = "Save File: " & tab.DocName
sfd.Filter = "Text files (*.txt)|*.txt|All files|*.*"
If sfd.ShowDialog() = Windows.Forms.DialogResult.OK Then
If tab.SaveFile(sfd.FileName) Then
tab.DocSaved = True
tab.DocChanged = False
tab.DocPath = sfd.FileName
tab.DocName = getName(sfd.FileName)
tab.UpdateTitle()
UpdateTitle()
End If
End If
End Using
End Sub
' Saves the document in the 'tab' tab to 'path' file
Public Sub SaveTabAs(ByVal tab As cTabPage, ByVal path As String)
If tab.SaveFile(path) Then
tab.DocSaved = True
tab.DocChanged = False
tab.DocPath = path
tab.DocName = getName(path)
tab.UpdateTitle()
UpdateTitle()
End If
End Sub
#End Region
#Region " FORM RELATED "
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
NewTab()
End Sub
#End Region
#Region " WINDOW LIST "
' Generate the 'Window' list of active windows
' This is usually done automatically, but since the 'windows' are now not really MDI forms that is impossible
Public Sub UpdateWindowList()
colWindowList = New Collection 'Clear collection
Dim n As Integer = WindowToolStripMenuItem.DropDownItems.Count 'Store number of dropdown items
For i As Integer = n - 1 To 2 Step -1
WindowToolStripMenuItem.DropDownItems.RemoveAt(i) 'Remove every dropdownitem except the first
two (Close All and separator)
Next
If tabCtrl.TabPages.Count = 0 Then
WindowSeparator.Visible = False 'Hides the separator if no documents open
Exit Sub
End If
WindowSeparator.Visible = True
For Each tab As cTabPage In tabCtrl.TabPages
colWindowList.Add(tab) 'Adds the tab to the collection
Next
For i As Integer = 1 To colWindowList.Count
Dim windowMenuItem As New ToolStripMenuItem 'Creates a new ToolStripMenuItem
Dim tab As cTabPage = CType(colWindowList(i), cTabPage)
windowMenuItem.Text = i & ". " & tab.Text
windowMenuItem.Tag = tab
windowMenuItem.Checked = (tab Is tabCtrl.SelectedTab)
AddHandler windowMenuItem.Click, AddressOf OnWindowListItemClick
WindowToolStripMenuItem.DropDownItems.Add(windowMenuItem)
Next
End Sub
' WindowListItem Click Event Handler
Private Sub OnWindowListItemClick(ByVal sender As Object, ByVal e As System.EventArgs)
Dim ctrl As ToolStripItem = CType(sender, ToolStripItem)
Dim tab As cTabPage = CType(ctrl.Tag, cTabPage)
tabCtrl.SelectedTab = tab
UpdateWindowList()
End Sub
Private Sub WindowToolStripMenuItem_DropDownOpening(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles WindowToolStripMenuItem.DropDownOpening
UpdateWindowList()
End Sub
#End Region
12. Error handler module:
Add a new Module file and call it something like 'modErrorHandler'.
Add the following code:
Code:
Public Enum ErrorType As Integer
tError = 0
tWarning = 1
tInformation = 2
End Enum
' Fast way of handling errors. This way you don't have to type every little detail every time,
' you can often leave most parameters on default
Public Sub WriteError(ByVal msg As String, Optional ByVal ErrType As ErrorType = 0, Optional ByVal caption As
String = Nothing, Optional ByVal buttons As MessageBoxButtons = MessageBoxButtons.OK)
Select Case ErrType
Case 0
If caption = Nothing Then caption = "Error"
MessageBox.Show(msg, caption, buttons, MessageBoxIcon.Error)
Case 1
If caption = Nothing Then caption = "Warning"
MessageBox.Show(msg, caption, buttons, MessageBoxIcon.Warning)
Case 2
If caption = Nothing Then caption = "Information"
MessageBox.Show(msg, caption, buttons, MessageBoxIcon.Information)
End Select
End Sub
Whew, I think that's all.... If there is anything wrong (there's bound to be lol...) tell me and I'll fix it!
Nope sorry. I have never done that before and didn't want to go into the hassle of finding out how to do it, mainly because the program focuses on the tabbed mdi part and because I have no printer to test it on.... You may have noticed that there is also no Find/Replace, Goto, Options etc...
Most of these things however (except the printing again, sorry) are covered in the 'Very extensive MDI Text Editor' which can also be found in my signature.