Thursday, December 27, 2007
sender or eventSender object, what is the point?
sender as System.Object (sometimes referred to as eventSender as System.Object).
What was the point of this this? We never used it in our code, so why was it being passed?
From this article - http://www.informit.com/articles/article.aspx?p=102148&seqNum=3 I realized that you can use that argument to figure out the who called the function. For example, if you have the MouseDown handle the call from 10 buttons, you can use the sender object to figure which button called the MouseDown routine. What you need to do is convert (cast) it to an Control or a Button, and then you can get the Button's text.
Another use I found for this is if you manually call MouseDown, or manually call MouseMove. In that past if we called a MouseMove event from the MouseDown routine, we just passed the sender from MouseDown to MouseMove. Sample code below:
Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseDown
Form1_MouseMove(sender, e)
End Sub
At first I thought in MouseMove, we could use the sender object to see if the routine was called by code or by the Form. But in MouseMove, when you look at the sender object, you cannot tell. So one way to tell is do something like this:
Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseDown
Form1_MouseMove("FromMouseDown", e)
End Sub
Then in MouseMove, you can do the following:
Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseMove
If TypeOf sender Is String Then
'Do Something, you can even test what the string value is
Dim aString as String = DirectCast(sender, String)
If aString = "FromMouseDown" Then
MsgBox("FromMouseDown")
End If
End If
End Sub
MouseMove put to rest
Wednesday, December 26, 2007
MouseMove oddity
MouseMove event is always fired
Wednesday, December 19, 2007
Textbox ignores the first character if you set the CharacterCasing property in the KeyPress event
To recreate this error, open a form, add a textbox to the form. Create a Keypress Event, and set the TextBox's CharacterCasing to True. If you run the program and click in the textbox, and enter a value, the first value will be ignored.
The solution was to move it to the TextBox.Enter subroutine.
Tuesday, December 18, 2007
Avoid Memory Leaks with FromHBitmap and GetHbitmap - Continued
'Just say you have the following Picture box (FImage)
'If you do the following, abmp will point to the Image of FImage (you don't make a copy)
Dim abmp as Bitmap = FImage.Image
'If you then supply abmp to the function I mentioned in the earlier post.
'Then all of a sudden FImage.Image does not have any data and you get an error when you try to use it.
So be careful when using the code below.
Stop stickykey hell
This is from my manager:
I don't know if you ever accidentally get into Windows "Filterkeys" mode, but if you press both shift keys at once, or one shift key for 8 seconds, you go into an accessibility mode in text is selected.
If like me, you never ever ever want this to happen, go into Control Panel>Accessibility options>Keyboard>Filterkeys settings button>Uncheck "keyboard shortcut"
I turn off the rest of them too – I have absent-mindedly tapped the shift key a few times and gone into "StickyKey" hell.
Task Manager doesn't have Menu Bar or Tabs
Monday, December 17, 2007
Avoid Memory Leaks with FromHBitmap and GetHbitmap
Public Function DoSomething(ByRef hbmp As Bitmap) As Integer
Dim returnVal As Integer
Dim hbmp1 As IntPtr
If Not hbmp Is Nothing Then
hbmp1 = hbmp.GetHbitmap 'Get a handle to the image
returnVal = DoSomethingInC(hbmp1.ToInt32) 'get an Integer Pointer to the Image which is passed to the C routine
hbmp = Bitmap.FromHbitmap(hbmp1)
Return returnVal
Else
Return MiscError
End If
End Function
Now when I did this, I had a memory leak with GetHBitmap and FromHBitmap. You solve that by calling .Dispose and DeleteObject. Highlighted below.
Public Function DoSomething(ByRef hbmp As Bitmap) As Integer
Dim returnVal As Integer
Dim hbmp1 As IntPtr
If Not hbmp Is Nothing Then
hbmp1 = hbmp.GetHbitmap 'Get a handle to the image
returnVal = DoSomethingInC(hbmp1.ToInt32) 'get an Integer Pointer to the Image which is passed to the C routine
If Not hbmp Is Nothing Then hbmp.Dispose()
hbmp = Nothing
hbmp = Bitmap.FromHbitmap(hbmp1)
DeleteObject(hbmp1)
Return returnVal
Else
Return MiscError
End If
End Function
A couple of thoughts:
1. Doing this slows down performance, as the calls to GetHbitmap and FromHBitmap is a lot slower than just calling Image.Handle (in VB6). I still haven't figured out how to solve the performance hit.
2. I still have issues with 8 bit images, as in VB.NET we do everything in 32 bit, and previously my C routines were working with 8 bits. I still haven't figured out a workaround to this.
Avoid Memory Leaks with PictureBox
Dim bm_out As New Bitmap(Width, Height)
Dim gr_out As Graphics = Graphics.FromImage(bm_out)
gr_out.DrawImage(...)
FullImage.Image = bm_out
Now everytime this block of code was called, when the New Bitmap was created we created a new block of memory. When I left this function, I was constantly losing memory. The reason for this is that FullImage.Image was pointing to a block of memory, and when I called FullImage.Image = bm_out, I pointed it to a new block of memory, and lost the pointer to the previous block of memory. But that previous block of memory was still allocated. So I had a memory leak. The solution was this one line, before FullImage.Image = bm_out
FullImage.Image.Dispose()
So the code like this did not have the memory leak.
Dim bm_out As New Bitmap(Width, Height)
Dim gr_out As Graphics = Graphics.FromImage(bm_out)
gr_out.DrawImage(...)
FullImage.Image.Dispose()
FullImage.Image = bm_out
Tuesday, November 27, 2007
Copy an ArrayList in VB.NET
You can't just do A = B to copy A to B. It will just create a
reference to B (so when you modify B, A will be modified as well).
In order to copy it, you need to do the following
A = new ArrayList(B)
Thursday, November 15, 2007
How to creating a larger arrowhead when drawing lines in VB.NET
the following:
Dim aPen as Pen = New Pen(Color.Red)
aPen.EndCap = LineCap.ArrowAnchor
Then when you draw the line, you specify the pen created above as the
pen for the line. The problem with this approach is that the size of
the arrow depends on the size of the line, in this case, our line is
of pixel width = 1, if we create a larger line we will have a larger
arrow, but what if you don't want a larger line, but do want a larger
arrowhead (the arrowhead with a line of 1 pixel is so small that its
hard to even see it).
Here we create a Custom Cap. Below is the code:
Dim aPen as Pen = New Pen(Color.Red)
Dim mycap As CustomLineCap = New AdjustableArrowCap(5, 5)
aPen.EndCap = LineCap.ArrowAnchor
aPen.CustomEndCap = mycap
Now the arrowhead will be 5 pixel by 5 pixels, which is a decent enough size.
Wednesday, November 14, 2007
What's New and Different in VB .NET
http://www.ondotnet.com/pub/a/dotnet/excerpt/vbnetnut_appa/index.html?page=1
Find the angle between two line segments - VB6 and VB.NET
segments. The code is in VB6, but to convert it to VB.NET all you
have to do is change "Abs" to System.Math.Abs and "atn" to
System.Math.ATAN