How to detect mouse click outside form

G

Glenn Lerner

Hi,

I have a form withtout titlebar. I want to close it if user clicks
anywhere outside the form.

I tried LostFocus() event but this event doesn't seem to get fired when
I click outside the form.

What is the best way to do this?

Thanks,
Glenn
 
G

Glenn Lerner

Gary said:
Hi Glenn,

You can use the form 'Deactivate()' event.

Gary
I just tried it but that didn't work. It seems like Deactivate() is
called when I click on the area of other app (therefore causing other
app to be active). I want to detect when I click outside of the current
form but inside the form (in the same app) that activated the current form.

The reason I need this is - I'm trying to create a control that mimics
DateTimePicker control (I don't like DateTimePicker because it doesn't
allow blank entries without having a checkbox). I have a plain text
control and a little button next to it - when clicked, I'm opening a
form that only contains MonthCalendar control. In order to mimic
DateTimePicker, I want to close the calendar when I click outside of
calendar area (but inside the parent form).

Can this be done?

Thanks,
Glenn
 
G

Gary Milton

Glenn,

Strangely enough, I actually wrote a datepicker control myself in VB6 a few
years ago and had exactly the same problem. The only way around it was to
subclass the dropdown calendar window and specifically post a close message
to that window when a user clicked somewhere outside of that window (so
exactly the same problem as you are getting in VB.NET). I have converted
the relevant subclassing code using the .NET classes and the code below
should hopefully do the trick. I have done some basic testing with forms in
a standard project and it does seem to work so I don't see why it shouldn't
also work inside a UserControl project.

Create a new class in your UserControl project called 'SubClassing' and then
paste in the following code...

\\\
Imports System.Windows.Forms

Public Class SubClassing
Inherits System.Windows.Forms.NativeWindow

Public Event CallBackProc(ByRef m As Message)

Public Sub New(ByVal intWindowHandle As IntPtr)
MyBase.AssignHandle(intWindowHandle)
End Sub

Protected Overrides Sub WndProc(ByRef m As Message)
RaiseEvent CallBackProc(m)

MyBase.WndProc(m)
End Sub

Protected Overrides Sub Finalize()
MyBase.Finalize()
End Sub
End Class
///

Then in your UserControl add the following code to your 'dropdown' month
calendar control form ...

\\\
Private Const WA_INACTIVE As System.Int32 = 0

Private Const WM_ACTIVATE As System.Int32 = &H6
Private Const WM_CLOSE As System.Int32 = &H10

Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" _
(ByVal hWnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer,
ByVal lParam As Integer) As Integer

Private WithEvents mobjSubclassing As SubClassing

Private Sub mobjSubclassing_CallBackProc(ByRef m As
System.Windows.Forms.Message) Handles mobjSubclassing.CallBackProc
If (m.Msg = WM_ACTIVATE) Then
If (m.WParam.ToInt32 = WA_INACTIVE) Then
Call PostMessage(m.HWnd.ToInt32, WM_CLOSE, 0, 0)
End If
End If
End Sub

Private Sub frmMonthCalendar_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
mobjSubclassing = New SubClassing(Me.Handle)
End Sub

frmMonthCalendar_Closing(ByVal sender As Object, ByVal e As
System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
mobjSubclassing.ReleaseHandle()
End Sub
///

What this will do is to force a windows 'Close' message to be posted to your
'dropdown' month calendar form whenever it is deactivated. Give it a go and
let me know if it works.

Gary
 
G

Gary Milton

Glenn,

Apologies, but I just realised that I've posted VB.NET code to the C#
newsgroup thinking I was in the VB.NET group. That said, there is no reason
that this code shouldn't be able to be converted to C# with a little extra
of work. At least it gives you the idea of what direction you need to be
heading in.

Gary
 
G

Glenn Lerner

Gary,

Thanks a lot for this post. I'm not too familiar with windows
subclassing but I'll give it a try. I'll first do some reading to learn
more about subclassing and then convert your code to C#. Looks like a
neat solution though.

Thanks again,
Glenn
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top