BlakeMcKenna
asked on
What event fires when "Normal" ControlBox is clicked on a form?
I need to check when a parent or child form's "normal" controlbox is clicked and I'm not sure which event to check. Is this possible?
Thanks!
Thanks!
ASKER
Actually it's the Maximize/Minimize button (the middle button) that I'm try to capture.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
If Blake is on the right track about what you meant "normal" ControlBox, then I need to change my answer.
And sorry to correct Blake, what you meant is more the Restore button. The Maximize and Minimize buttons (plural) are 2 different buttons that appear when the form is neither maximized or minimized. When the form is Maximized, the Maximize button is useless and replaced by a Restore button. However, some might see it as an alternate state of the Maximize button.
Anyway, there is a little problem. This one looks like a simple one, but when you start looking at it carefully, it's not so simple. Maybe someone will have a better idea than mine.
The resizing events (ResizeBegin, Resize and ResizeEnd) can be triggered in different ways:
1. Clicking either the Minimize, Maximize or Restore button.
2. Programmatically changing the Size property of the Form.
3. User resizing the Form by dragging its border.
There is no built-in way that I know to determine which of these 3 triggered the resizing, since these events do not pass any useful parameter.
A moderately complex algorithm could be written, but I started working on it and hit a problem after a few seconds, and do not have time to go further with it right now. So I'm just pushing my thoughts about it in case somebody has the time to work on it.
It would involve, between others, a variable that is incremented on each pass in the Resize event and a Timer that would be created on the first call. After a short while, the timer would look at the variable to determine if the event is called only once or repetitively. If called only once, then we eliminated item 3 in my list of triggers for the event.
The first problem I hit is to find a way to make the difference between a Restore by the user and a resize by the code.
The second one is that in order to know if the unique event call could be triggered as well by a Maximize, a Minimize or a Restore, which brings us back almost to square one. Knowing that the Restore button is available only when the form is Maximized, we would need to keep a constant status of the WindowState in order to know that the Resize started in that state.
There might be other hiccups I did not see.
@hes
Your answer shows your VB6 background, if I am not mislead.
Resize has its use sometimes, but most of the time I see it used in VB.NET, the wrong event was chosen. This probably due to the fact that this was the only resizing event in VB6, and "old hands" are used to it.
The problem is that it triggers many times when the user is resizing a form. In most situations where you want to react to a resizing, you do not need to "follow" the operation, you usually need to react once, either before the resizing begin, most often once the resizing is done. For that purpose the "new" (well, they've been there for 12 years but when you hear of them for the first time, they're kind of new) ResizeBegin and ResizeEnd as most of the time a better choice than Resize.
In your specific example, if the user was resizing manually, the If would be called repetitively without ever being useful, because you cannot minimize a Form while dragging it's border. Sure it would work if the user hit the Minimize button, but would be useless for a manual resize. And in some circumstances, if the code in the If is important, it make the manual resizing very jerky (not sure if it is the right word in English, excuse my French).
And sorry to correct Blake, what you meant is more the Restore button. The Maximize and Minimize buttons (plural) are 2 different buttons that appear when the form is neither maximized or minimized. When the form is Maximized, the Maximize button is useless and replaced by a Restore button. However, some might see it as an alternate state of the Maximize button.
Anyway, there is a little problem. This one looks like a simple one, but when you start looking at it carefully, it's not so simple. Maybe someone will have a better idea than mine.
The resizing events (ResizeBegin, Resize and ResizeEnd) can be triggered in different ways:
1. Clicking either the Minimize, Maximize or Restore button.
2. Programmatically changing the Size property of the Form.
3. User resizing the Form by dragging its border.
There is no built-in way that I know to determine which of these 3 triggered the resizing, since these events do not pass any useful parameter.
A moderately complex algorithm could be written, but I started working on it and hit a problem after a few seconds, and do not have time to go further with it right now. So I'm just pushing my thoughts about it in case somebody has the time to work on it.
It would involve, between others, a variable that is incremented on each pass in the Resize event and a Timer that would be created on the first call. After a short while, the timer would look at the variable to determine if the event is called only once or repetitively. If called only once, then we eliminated item 3 in my list of triggers for the event.
The first problem I hit is to find a way to make the difference between a Restore by the user and a resize by the code.
The second one is that in order to know if the unique event call could be triggered as well by a Maximize, a Minimize or a Restore, which brings us back almost to square one. Knowing that the Restore button is available only when the form is Maximized, we would need to keep a constant status of the WindowState in order to know that the Resize started in that state.
There might be other hiccups I did not see.
@hes
Your answer shows your VB6 background, if I am not mislead.
Resize has its use sometimes, but most of the time I see it used in VB.NET, the wrong event was chosen. This probably due to the fact that this was the only resizing event in VB6, and "old hands" are used to it.
The problem is that it triggers many times when the user is resizing a form. In most situations where you want to react to a resizing, you do not need to "follow" the operation, you usually need to react once, either before the resizing begin, most often once the resizing is done. For that purpose the "new" (well, they've been there for 12 years but when you hear of them for the first time, they're kind of new) ResizeBegin and ResizeEnd as most of the time a better choice than Resize.
In your specific example, if the user was resizing manually, the If would be called repetitively without ever being useful, because you cannot minimize a Form while dragging it's border. Sure it would work if the user hit the Minimize button, but would be useless for a manual resize. And in some circumstances, if the code in the If is important, it make the manual resizing very jerky (not sure if it is the right word in English, excuse my French).
Public Class Form1
Private Const WM_NCLBUTTONDOWN = &HA1
Private Enum HitTestResult
HTERROR = (-2)
HTTRANSPARENT = (-1)
HTNOWHERE = 0
HTCLIENT = 1
HTCAPTION = 2
HTSYSMENU = 3
HTGROWBOX = 4
HTMENU = 5
HTHSCROLL = 6
HTVSCROLL = 7
HTMINBUTTON = 8
HTREDUCE = HTMINBUTTON
HTMAXBUTTON = 9
HTZOOM = HTMAXBUTTON
HTLEFT = 10
HTRIGHT = 11
HTTOP = 12
HTTOPLEFT = 13
HTTOPRIGHT = 14
HTBOTTOM = 15
HTBOTTOMLEFT = 16
HTBOTTOMRIGHT = 17
HTBORDER = 18
HTOBJECT = 19
HTCLOSE = 20
HTHELP = 21
End Enum
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If m.Msg = WM_NCLBUTTONDOWN Then
Call ControlBoxClicked(m)
End If
MyBase.WndProc(m)
End Sub
Private Sub ControlBoxClicked(ByVal m As System.Windows.Forms.Message)
Dim hitTest As HitTestResult = m.WParam
Select Case hitTest
Case HitTestResult.HTMINBUTTON
Debug.Print("Min button down")
Case HitTestResult.HTMAXBUTTON
If Me.WindowState = FormWindowState.Maximized Then
Debug.Print("Restore button down")
Else
Debug.Print("Max button down")
End If
Case HitTestResult.HTCLOSE
Debug.Print("Close button down")
End Select
End Sub
End Class
<< if I am not mislead.>> Yes you are
ASKER
Hes,
You were the closest. I actually put the code in the Resize() event. Looks like this.
Wow, I don't why I made this so hard.
Thanks for the help guys!
You were the closest. I actually put the code in the Resize() event. Looks like this.
Private Sub frmMain_Resize(sender As Object, e As EventArgs) Handles Me.Resize
If Me.WindowState = FormWindowState.Normal Then
ResizeMDIParent(Me)
End If
End Sub
Wow, I don't why I made this so hard.
Thanks for the help guys!
Open in new window