Handling all mouse events in a central place

  • Thread starter Thread starter Mitko
  • Start date Start date
M

Mitko

Hello there

I am using Microsoft Visual .Net to develop a smart device
application.
The application has many forms and many controls on each form.
Is there any way to capture all click event in a central place?

As an example, in Delphi this is done with code like this:

...
Application.OnEvent := SomeHandler;
...
procedure TForm.SomeHandler(Sender: QObjectH; Event: QEventH; var
Handled: Boolean);
begin
Handled := False;
if (QEvent_isQMouseEvent(Event)) then begin
DoSomeThings(Sender);
end;
end;
...

Any suggestions will be appreciated.
 
You should be able to hook mouse events from multiple
control to one event procedure. Something like that:

pictureBox1.MouseDown+=new MouseEventHandler
(generic_MouseDown);
pictureBox2.MouseDown+=new MouseEventHandler
(generic_MouseDown);
pictureBox3.MouseDown+=new MouseEventHandler
(generic_MouseDown);

private void generic_MouseDown(object sender,
MouseEventArgs e)
{

}

HTH... Alex
 
Thanks for the reply Alex,

but the suggested solution will result in procedure with hundred of
lines.
Such a code will be very hard to maintain.
What I need is some more elegant way to do this.


Actually I want to intercept MouseEvents do some actions and then pass
control to the application logic.

e.g.

pictureBox1.MouseDown+=new MouseEventHandler(generic_MouseDown);
// what I need on every control in my app
....
pictureBox1.MouseDown+=new MouseEventHandler(pictureBox1_MouseDown);
// this is a handler added by me through WS UI

private void generic_MouseDown(object sender, MouseEventArgs e)
{
DoSomeProcessing(sender); // do the things
pictureBox1_MouseDown(sender,e); // continue to application logic
...
};
 
Mitko,

I previously worked with a development tool that automatically collected all
Windows events and handled them at the form level, so when I first started
working in .Net I tried to do the same. (I even succeeded by creating my own
TextBox subclass, etc., that forwarded events to the Form.) Then after I
worked with .Net forms for a while, I decided I really preferred having the
events handled at the control level.

Now if I want all textboxes to be blanked out when they receive focus, I
have a general event handler like this that I add to each TextBox in the
designer:

private void Textbox_GotFocus(object sender, System.EventArgs e)
{
TextBox tb = (TextBox)sender;
if(!tb.ReadOnly && tb.Enabled)
tb.Text = "";
}


I can still add specialized GotFocus event handlers (or whatever) for
specific controls as needed.

Is there some special reason you want to handle all events at the form
level?
 
Thanks Ginny
Is there some special reason you want to handle all events at the form
level?

Yes, I have a reason for that.

In process of working with the application an user may open many
overlapped forms.
After some interval of user inactivity I want to close all forms
opened by the user, until the main form reached.
The natural way to do this is by using a timer.
I was hopping to reset the timer Interval on every user click.
This is the reason for what I want a way to process events in a
central place.
In the same time I don't want to change the even handlers added by me
on the control level.

Another way to resolve my problem is to override the WndProc(), but
this seem to be not possible in CF :(
I didn't succeed to intercept the Windows message pump using
MessageWindow also.

May be there is another way to program the "user idle time" behavior,
but I didn't think of.
 
Mitko said:
Another way to resolve my problem is to override the WndProc(), but
this seem to be not possible in CF :(
I didn't succeed to intercept the Windows message pump using
MessageWindow also.
You CAN intercept an Application's message pump by creating your own. You
just have to do manually what Application.Run() does for you: creating a
form, making the form visible, initializing a message pump and destroying
the Application object when form is closed:

#region "API Calls for Message Pump"

[DllImport("Coredll.dll", SetLastError=true )]

private static extern Int32 GetMessage (

ref MSG lpMsg,

Int32 hwnd,

Int32 wMsgFilterMin,

Int32 wMsgFilterMax);

[DllImport("Coredll.dll", SetLastError=true )]

private static extern Int32 DispatchMessage(ref MSG lpMsg);

[DllImport("Coredll.dll", SetLastError=true )]

private static extern Int32 TranslateMessage(ref MSG lpMsg);

public struct POINTAPI

{



public Int32 x;



public Int32 y;

}



public struct MSG

{



public Int32 hwnd;



public WM message;



public Int32 wParam;



public Int32 lParam;



public Int32 time;

public POINTAPI pt;

}

#endregion



static void Main()

{

mainForm = new MainForm();



mainForm.Visible = true;

MSG msg = new MSG();

System.Exception exception = null;

while (GetMessage(ref msg, 0, 0, 0) == 1)

{

TranslateMessage(ref msg);

DispatchMessage(ref msg);

}

}



private void MainForm_Closed(object sender, System.EventArgs e)

{

Application.Exit();

}



This way we were able to handle accelerator keys which are not supported in
..NET CF. I think you can do the same for mouse events.



Marc
 
Hi Ginny,
I previously worked with a development tool that automatically collected all
Windows events and handled them at the form level, so when I first started
working in .

And wasn't that a bitch. Smart windows oh yeh!!

This way is much easier and a lot less code.

Graham
 
Hi Graham,

Yep. ;-) The code is also a lot cleaner than you get with one monolithic
event handler for that type of event form-wide. I really hate to look at
that old code.
 
You CAN intercept an Application's message pump by creating your own. You
just have to do manually what Application.Run() does for you: creating a
form, making the form visible, initializing a message pump and destroying
the Application object when form is closed:
Hi Mark,

tanks for the solution proposed! :))
In general it works great for my me.

But I have some questions
(1)
The message loop is not cycled for modal forms.
I guess this is a normal behavior.
Can You suggest me how to solve this case?

(2)
What is the purpose of the line: "System.Exception exception = null;" ?

(3)
And one more general question that is interesting to me.
Is it possible to catch unhandled application exception here?

e.g.
...
while (GetMessage(ref msg, 0, 0, 0) == 1) {
try {
if (msg.message == WM_LBUTTONUP) {
MyResetTimer();
};
TranslateMessage(ref msg);
DispatchMessage(ref msg);
} catch (Exception e) {
DealWithError(e);
// this works, but the next GetMessage() call returns 0
// and the application exits
};
}


Mitko
 
Mitko,


Mitko said:
The message loop is not cycled for modal forms.
I guess this is a normal behavior.
Can You suggest me how to solve this case?
This is the normal behaviour of a modal form. The code following ShowDialog
won't be executed unless the modal form is closed. Right now I have no
solution how to handle this. But on our side the behaviour not to have the
accelerator keys in modal forms is okay.
What is the purpose of the line: "System.Exception exception = null;" ?
And one more general question that is interesting to me.
Is it possible to catch unhandled application exception here?
exception = null was added for an exception handling mechanism I left out to
make the code more simple. The mechanism itself is similar to yours. If
GetMessage() returns 0, a WM_QUIT message was posted. I am not sure if you
can prevent the application from exiting if you catch unhandled exceptions
here.

Marc
 
Back
Top