Sometimes it seems that .NET has some obvious shortcomings. For example, all I want to do is have a MessageBox center in my application instead of the screen. This task shouldn't be that difficult; however, there is no way (that I have found) to set the StartPosition property for the MessageBox dialog. While there may be a functional and elegant solution to this problem (please post as a comment if you have one), the only solution I have found on the internet is to implement your own MessageBox class, and code it to do what you want. This isn't hard, but it doesn't seem like a lot of work for something so simple. Also, the Messagebox probably does more than you might first think. It does a lot of autosizing to hold whatever text you provide it.
Here is one implementation of a custom MessageBox I have found:
http://www.codeproject.com/KB/dialog/MessageBoxEx.aspx?fid=155440&df=90&mpp=25&noise=3&sort=Position&view=Quick&fr=76&select=1069708
I am sure there are more such implementations. Please post comments if you know of any.
This blog is a depository for things I have found regarding VB.NET and C#.NET development (and other things I may need to remember). This blog is primarily for my own reference, but if the information I found is useful to others, then that is great. If others want to contribute with comments or other information, then that is great too.
Friday, May 16, 2008
Wednesday, May 14, 2008
Finding VB.NET or C# Signatures for Interop/PInvoke
There are several places to find the Signatures in VB.NET and C# for Win32Api calls online. Here is one that is pretty good:
http://pinvoke.net
http://pinvoke.net
Defaulting to Thumbnail View when using OpenFileDialog
You would think that it would be very simple to default an OpenFileDialog to any view type you want via its properties. However, there is no property exposed for setting the view type. I simply want to browse for images with my OpenFileDialog instance, and I would prefer for the user not to have to manually set the view type to Thumbnail everytime.
I found a couple of solutions:
http://www.codeproject.com/cs/miscctrl/FileDialogExtender.asp (C#)
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2741273&SiteID=1&mode=1 (same as above only in VB.NET)
and the following offers even more functionality:
http://www.codeproject.com/KB/dialog/OpenFileDialogEx.aspx
If someone else has found or created a better solution, please let me know.
I found a couple of solutions:
http://www.codeproject.com/cs/miscctrl/FileDialogExtender.asp (C#)
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2741273&SiteID=1&mode=1 (same as above only in VB.NET)
and the following offers even more functionality:
http://www.codeproject.com/KB/dialog/OpenFileDialogEx.aspx
If someone else has found or created a better solution, please let me know.
Monday, May 12, 2008
Converting VB.NET to C# and C# to VB.NET
Here is a web site that will quickly converting VB.NET to C# or C# to VB.NET:
http://labs.developerfusion.co.uk/convert/csharp-to-vb.aspx
It is not perfect, but it does all of the grunt work and it is free.
http://labs.developerfusion.co.uk/convert/csharp-to-vb.aspx
It is not perfect, but it does all of the grunt work and it is free.
Thursday, May 8, 2008
Keeping a VB.NET Form Always on Top
In VB6, you used a Win32API call to SetWindowPos to get a form to always stay on top. This has been simplified somewhat in VB.NET. Put the following in Form_Load or other appropriate place:
Me.TopMost = True
Me.TopMost = True
Monday, April 21, 2008
DoEvents in VB.NET
I am not sure why this is so difficult to find, but if you need to do the equivalent to a VB6 DoEvents in VB.NET or even in C#:
or if you are in a form's code, it is simply:
System.Windows.Forms.Application.DoEvents()
or if you are in a form's code, it is simply:
Application.DoEvents()
Labels:
DoEvents
Thursday, April 17, 2008
Random Access with StreamReader - File Position and Seeking with ReadLine
I spent some time researching how to have dynamic access with StreamReader while using ReadLine and the solution turned out to more complicated that I would expect for .NET at this stage of its development.
My problem is that I have a text file I am reading with a StreamReader object and I am using ReadLine to get one line of text at a time. Nothing special here, but periodically I need to go back to a previous position in the file and read that part again.
If you use the BaseStream property of the StreamReader Object, then you can use the Position property and Seek method to get and set the current position in the file. These two items would appear to be all that you need to get the random access you need; however, when you use Position to get the offset of the file after the ReadLine, you don’t get the position of the file after the last line read, you get the position of the end of the buffer (usually 1024 bytes in size). So, when you use Seek to go back to that position, you will unlikely get back to the position you want unless the buffer boundary just happens to work out right.
I searched around for a simple solution to this problem (there may be and I haven’t found it yet). There were lots of posting about using FileStream, but it doesn't have ReadLine to read a line of text, so they were suggesting that you implement your own version of ReadLine for FileStream. I also found information on DiscardBufferedData that can be used with StreamReader, but it doesn’t help you get the correct offset after using ReadLine.
There were several suggestions on writing your own version of StreamReader:
http://bytes.com/forum/thread238508.html
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=6720&SiteID=1
I finally bit the bullet and created my own class to accomplish what I need (and only what I need). The previous two posts didn’t provide me with a working solution, so I am going to post what I have come up with. It may need some more refinement, but it appears to work okay. This is in VB.NET, but should be easily translatable into C# if necessary.
The first code snippet is an example of using the FileClass to read a file. In this example, I am looking for the string “*****StartOfData******”. When this string is found, I get the position and then call my PreprocessData function to read the rest of the data. I then go back to the position and run ProcessData from the same point:
The FileClass is shown below:
The FileClass is pretty simple, it just has to fill a buffer and look for the carriage returns and linefeeds itself to make generate the line it reads.
My problem is that I have a text file I am reading with a StreamReader object and I am using ReadLine to get one line of text at a time. Nothing special here, but periodically I need to go back to a previous position in the file and read that part again.
If you use the BaseStream property of the StreamReader Object, then you can use the Position property and Seek method to get and set the current position in the file. These two items would appear to be all that you need to get the random access you need; however, when you use Position to get the offset of the file after the ReadLine, you don’t get the position of the file after the last line read, you get the position of the end of the buffer (usually 1024 bytes in size). So, when you use Seek to go back to that position, you will unlikely get back to the position you want unless the buffer boundary just happens to work out right.
I searched around for a simple solution to this problem (there may be and I haven’t found it yet). There were lots of posting about using FileStream, but it doesn't have ReadLine to read a line of text, so they were suggesting that you implement your own version of ReadLine for FileStream. I also found information on DiscardBufferedData that can be used with StreamReader, but it doesn’t help you get the correct offset after using ReadLine.
There were several suggestions on writing your own version of StreamReader:
http://bytes.com/forum/thread238508.html
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=6720&SiteID=1
I finally bit the bullet and created my own class to accomplish what I need (and only what I need). The previous two posts didn’t provide me with a working solution, so I am going to post what I have come up with. It may need some more refinement, but it appears to work okay. This is in VB.NET, but should be easily translatable into C# if necessary.
The first code snippet is an example of using the FileClass to read a file. In this example, I am looking for the string “*****StartOfData******”. When this string is found, I get the position and then call my PreprocessData function to read the rest of the data. I then go back to the position and run ProcessData from the same point:
Dim list() As String
Dim sep() As Char = {""c}
Try
Dim s As New FileClass
s.Open(TextBoxDataFile.Text)
Dim buffer As String = ""
Do
If Not s.GetNextLine(buffer) Then
Exit Do
End If
list = buffer.Split(sep)
If buffer = "*****StartOfData*****" Then
Dim startOfData As Integer = s.GetCurrentOffset()
PreprocessData(s)
s.SetCurrentOffset(startOfData)
ProcessData(s)
End If
Loop Until s.EOF()
s.Close()
Catch ex As Exception
Return False
End Try
The FileClass is shown below:
Imports System.IO
Imports System.text
Public Class FileClass
Const BUFFER_SIZE As Integer = 1024
Private g_file As StreamReader = Nothing
Private g_line As Integer = 0
Private g_position As Integer = 0
Private g_buffer(BUFFER_SIZE) As Char
Private g_bufferSize As Integer = 0
Private g_offset As Integer = 0
Private g_eofFlag As Boolean = True
Private g_lineBuffer As New StringBuilder(BUFFER_SIZE)
Private g_bufferOffset As Integer = 0
Public Function Open(ByVal filename As String) As Boolean
If Not g_file Is Nothing Then Close()
g_file = New StreamReader(filename)
g_line = 0
g_position = 0
g_eofFlag = False
g_bufferSize = 0
g_bufferOffset = 0
LoadBuffer()
End Function
Public Function Close() As Boolean
g_file.Close()
g_file = Nothing
g_line = 0
g_position = 0
g_eofFlag = True
g_bufferSize = 0
Return True
End Function
Public Function GetCurrentOffset() As Integer
Return g_offset
End Function
Public Function SetCurrentOffset(ByVal offset As Integer) As Boolean
Dim pos As Long = g_file.BaseStream.Seek(offset, SeekOrigin.Begin)
g_file.DiscardBufferedData()
LoadBuffer()
Return offset = pos
End Function
Public Function GetNextLine(ByRef data As String) As Boolean
g_lineBuffer.Length = 0
Dim ch As Char
Dim flag As Boolean = False
While Not flag
ch = g_buffer(g_position)
If ch = vbCr Then
' do nothing - skip cr
ElseIf ch = vbLf Then
flag = True
Else
g_lineBuffer.Append(ch)
End If
g_position = g_position + 1
If g_position = g_bufferSize Then
If Not LoadBuffer() Then
Exit While
End If
End If
End While
If flag Then
g_offset = g_bufferOffset + g_position
data = g_lineBuffer.ToString
Return True
End If
Return False
End Function
Private Function LoadBuffer() As Boolean
g_bufferOffset = Convert.ToInt32(g_file.BaseStream.Position)
g_position = 0
g_bufferSize = g_file.Read(g_buffer, 0, BUFFER_SIZE)
If g_bufferSize = 0 Then
g_eofFlag = True
Return False
End If
Return True
End Function
Public Function EOF() As Boolean
Return g_eofFlag
End Function
End Class
The FileClass is pretty simple, it just has to fill a buffer and look for the carriage returns and linefeeds itself to make generate the line it reads.
Labels:
File Position,
Offset,
ReadLine,
Seeking,
StreamReader
Subscribe to:
Posts (Atom)