Re: How to Access Window Messages
- From: andrerus@xxxxxxxxx
- Date: 7 Sep 2006 10:47:24 -0700
I could try, but the problem is that the rest of application into which
this component must be included is written in C#.
Andrea
Paul G. Tobey [eMVP] ha scritto:
I think you're just working too far outside the box. Forget about managed
code and use native code. That will allow you to figure out if it's
possible to do what you want to do in the way that I've suggested. If it's
not, you won't be able to do it in managed code, either. Right now, you're
battling both the structure of your code and trying to get delegates to
work, etc., as well as the real problem of trying to capture the messages.
Concentrate on answering the main question: will subclassing tell me what I
need to know!
Paul T.
<andrerus@xxxxxxxxx> wrote in message
news:1157617396.201023.165080@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Sorry but I don't understood your last post, however I do other
observation:
I understood that the MainWindowHandle is never set if the process
doesn't have any form, or, otherwise, until the process finish starting
(in Framework is present an apposit function to wait for it, but it
hasn't een included in CF), so I decided to sleep for a time (ughly
solution, but it does);
I also test the IntPtr values and here you the results:
MainWindowHandle is now correct, in fact if I use it in
GetWindowThreadProcessId I get the same processId of launched appl;
After the call to SetWindowLong the pointer to my procedure is
different than the set procedure, and this last is also different than
the baseProcedure.
Obviuosly I continue to get Error 87 (invalParam).
Andrea
Paul G. Tobey [eMVP] ha scritto:
Yea, so?! All you've proven is that, yes, MainWindowHandle is never set.
So what? Pass the handle retrieved by GetCapture(). That's *why* I went
to
the trouble to give you the code.
Paul T.
<andrerus@xxxxxxxxx> wrote in message
news:1157563951.061803.197920@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
I replace in my code the line
IntPtr baseHwnd = tracedApp.MainWindowHandle;
with your code, and now the setWindowLong call return error 87
InvalParam
Andrea
Paul G. Tobey [eMVP] ha scritto:
Do something like this, which is used all over the place to get a
handle
to
a window from managed code in .NET CF:
some method of the main form:
{
...
this.Capture = true;
IntPtr hWnd = GetCapture();
this.Capture = false;
...
}
you have to P/Invoke GetCapture, of course.
Paul T.
<andrerus@xxxxxxxxx> wrote in message
news:1157562094.109746.164080@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
With some modifies I'm now able to avoid any exception. But there's
another problem: the call of tracedApp.MainWindowHandle return a
Zero
IntPtr. Here is the code:
delegate IntPtr proc(IntPtr hwnd, uint uMsg, IntPtr wParam,
IntPtr lParam);
IntPtr baseWndProc;
private IntPtr MyWndProc(IntPtr hwnd, uint uMsg, IntPtr wParam,
IntPtr lParam){
MessageBox.Show("ricevuto messaggio " + uMsg);
/*switch (uMsg)
{
case WM_LBUTTONDOWN: MessageBox.Show("ricevuto
messaggio
di click"); break;
}*/
return CallWindowProc(baseWndProc, hwnd, uMsg, wParam,
lParam);
}
private void launchApp_Click(object sender, EventArgs e)
{
System.Diagnostics.Process tracedApp =
System.Diagnostics.Process.Start("/Windows/Calc.exe", "");
IntPtr baseHwnd = tracedApp.MainWindowHandle;
proc superWndProc = MyWndProc;
IntPtr baseWndProc = new IntPtr(SetWindowLong(baseHwnd,
GWL_WNDPROC,
Marshal.GetFunctionPointerForDelegate(superWndProc).ToInt32()));
}
[DllImport("coredll")]
private static extern int SetWindowLong(IntPtr hWnd, int
nIndex,
int dwNewLong);
[DllImport("coredll")]
private static extern IntPtr CallWindowProc(IntPtr wProc,
IntPtr
hWnd, uint uMsg, IntPtr wParam, IntPtr lParam);
private const int GWL_WNDPROC = -4;
Andrea
Paul G. Tobey [eMVP] ha scritto:
I'm not sure. The exception is thrown where? If you end up using
subclassing, managed code is not a good choice for this.
Paul T.
<andrerus@xxxxxxxxx> wrote in message
news:1157558125.555300.262360@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Well, after have digested the concept, I formulated this
solution:
delegate int proc(IntPtr hwnd, uint uMsg, IntPtr wParam,
IntPtr
lParam);
proc baseWndProc;
private int MyWndProc(IntPtr hwnd, uint uMsg, IntPtr wParam,
IntPtr lParam){
switch (uMsg)
{
case WM_LBUTTONDOWN: MessageBox.Show("ricevuto
messaggio
di click"); break;
}
return CallWndProc(baseWndProc, hwnd, uMsg, wParam,
lParam);
}
private void launcApp_Clicked(object sender, EventArgs e){
System.Diagnostics.Process tracedApp =
System.Diagnostics.Process.Start("/Windows/Calc.exe", "");
IntPtr baseHwnd = tracedApp.MainWindowHandle; //Obtain
handle
to window of process launched
proc superWndProc = MyWndProc; //define a reference to
the
newWndProc to install
baseWndProc = SetWindowLong(baseHwnd, GWL_WNDPROC,
superWndProc); //install
}
[DllImport("coredll")]
private static extern proc SetWindowLong(IntPtr hWnd, int
nIndex,
proc dwNewLong);
[DllImport("coredll")]
private static extern int CallWndProc(proc wProc, IntPtr
hWnd,
uint uMsg, IntPtr wParam, IntPtr lParam);
private const int GWL_WNDPROC = -4;
I tried to write in managed form concepts of unmanaged, so
probably
I
make some mistake, and in fact install line throws an
NotSupportedException.
Where is/are the mistake/s?
Andrea
Paul G. Tobey [eMVP] ha scritto:
No, you can subclass an instance of an EDIT control, which you
don't
have
the source for, obviously, quite easily, maybe to exclude some
characters
from being entered, for example. I think that, if you look up
subclassing
and Win32 you'll find various examples. You're effectively
inserting
your
own window procedure for the window, in place of the one that
the
guy
who
wrote the code for the window type originally used. You then
can
see
all
messages before they're processed and pass along those that you
want
to
the
original procedure.
Paul T.
<andrerus@xxxxxxxxx> wrote in message
news:1157189677.676418.124180@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
It's some similar to that.
I've a doubt, to subclass windows of other application I need
to
have
its sources, or not?
I've never done anything similar, could you explain in detail,
or
or
redirect me where i can find them?
Thanks,
Andrea
Paul G. Tobey [eMVP] ha scritto:
I think I see what you're saying. It would be the equivalent
of
an
automated test application which might record a set of user
actions,
then
later replay them to verify that the result is the same (or
whatever).
I
don't know of any way to do this, however, other than, maybe,
subclassing
all of the windows in the other application. You know, the
old
SetWindowLong( GWL_WNDPROC... ) to set your own window
procedure
for
the
window and then CallWindowProc() to call the original one
after
you've
seen
each message. The help for SetWindowLong() says that you
shouldn't
do
this
for other process' windows, but I can't think of another way.
Paul T.
<andrerus@xxxxxxxxx> wrote in message
news:1157096623.384833.195030@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
As I wrote in other posts, what I'm looking for is a
mechanism
to
record all the interaction activities between a user and a
defined
application (in other words input activities and most
relevant
changes
to the application occurred), where the recording is
controlled
be
my
appl.
The best thing should be to have the abitity to treat
compiled
applications.
The hooking mechanism could be the best, but, as we saw, ic
CF
it
is
limited to input recording, so an alternative could be the
Pre-filtering of messages, but how can I controll it by my
appl?
I hope to have been clear.
Andrea
Paul G. Tobey [eMVP] ha scritto:
No. I don't understand why you'd want to do that, anyway.
OpenNETCF was there first, before there was such a thing
in
.NET
CF.
I
haven't used the .NET CF 2.0 version from MS, but I'd
guess
that
it's
the
same.
Please tell us *what* you're trying to do, not *how*
you've
decided
to
go
about it.
Paul T.
<andrerus@xxxxxxxxx> wrote in message
news:1157040502.606821.52320@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
If I decide to launch an external application by a link
in
my
appl,
is
there a system to catch messages delivered to the
external
appl?
I tried to attach a messagefilter to my appl, and then
to
launch
the
external with a link (using
System.Diagnostics.Process.Start(ApplPath,
""), but the filter acts only on messages delivered to
my
appl.
Am I able to attach a messagefilter ONLY to an
application
or
does
it
exist a way to attach it ALSO to processes?
I noticed that IMessageFilter is also present inside CF
and
that
Application inside CF provide a method to add a
messageFilter,
what
is
the difference with those declared in OpenNetCF?
Thanks,
Andrea
Paul G. Tobey [eMVP] ha scritto:
The only option for processing all messages sent to the
message
queue
of
the
application would be something like
ApplicationEx/IMessageFilter
from
the
OpenNETCF Smart Device Framework, which you can get
from
www.opennetcf.org.
I don't see any reason to go that way here, since
you're
just
trying
to
get
a notification of a custom event that it seems to me
could
be
sent
to
any
window you want, but it works if you need it.
Paul T.
<andrerus@xxxxxxxxx> wrote in message
news:1156875345.653614.297300@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
And if I would process the message sent to that
specific
window
handle?
Remember that my propose was to override WndProc of
my
appl,
but
that
this is unpermitted under CF.
Andrea
Paul G. Tobey [eMVP] ha scritto:
Remember that not every message sent to every window
will
go
through
the
MessageWindow!!! Your other program must be posting
the
message
to
*that
specific window handle*!
Paul T.
<andrerus@xxxxxxxxx> wrote in message
news:1156873476.597249.64620@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Even if remove the creaton of a messageBox and put
a
breakpoint
on
the
fist useful line on WndProc, nothig change, the
appl
seems
to
not
receive any message (no access to WndProc
noticed).
What I don't understand is why the WndProc doesn't
receive
any
standard
message, such as tap, keystroke, ecc...
Into the appl I declare an instance of
MyMessageWindow
passing
a
ref
to
the appl (this), and implement the method to use
to
treat
the
message,
according to the sample aforesaid.
Andrea
Paul G. Tobey [eMVP] ha scritto:
MessageWindow *does* work. Maybe you are not
posting
the
message
to
that
window, though. You don't want to be popping up
message
boxes
during
processing of other messages. Set a breakpoint
in
the
procedure
and
you
should see your custom message, if you're posting
it
to
the
right
place.
Paul T.
<andrerus@xxxxxxxxx> wrote in message
news:1156868088.650797.256570@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Hi,
I'd like to process costumized window messages
receiver
by
my
appl.
Il
developing in C#, and this avoid me to override
WndProc.
I
tried
to
use
MessageWindow, following the how to available
on
MSDN
(http://msdn2.microsoft.com/en-us/library/5143xwd8.aspx),
but
it
seems
to not intercept any message, neither cusomized
nor
standards
(I
tried
to monitor which message I received showing it
into
a
MessageBox,
before processing the switch block).
Why this happening? Can anybody suggest me
another
solution?
Here is my code:
private class MyMsgWin : MessageWindow
{
private FrmMain Frm;
public MyMsgWin(FrmMain frm)
{
this.Frm = frm;
// Register the unique message
for
this
application.
THIS_MSG =
RegisterWindowMessage(
"MESSAGE_55B71366_F217_4061_9FBE_F601FE4EB920");
}
#region Message Registration
// Used to register the special
Windows
messages
// used for this application.
[DllImport("coredll")]
public static extern UInt32
RegisterWindowMessage(
String Msg);
// Three variables used to store the
unique
message
values.
UInt32 THIS_MSG;
#endregion
protected override void WndProc(ref
Message
m)
{
MessageBox.Show("received message
"
+
m.Msg);
// switch (m.Msg)
{
// If message is of interest,
invoke
the
method
on
the form that
// functions as a callback to
perform
actions
in
response to the message.
if(m.Msg == THIS_MSG)//
Detect
my
message.
//TODO: HandleMessage
}
// Default processing. Don't
touch
this
or
you
could
cause the
// system to freeze (among other
things).
base.WndProc(ref m);
}
}
}
}
The message registered is also registered into
an
unmanaged
portion,
used be the appl, ad usually is sent by the
unmanaged
portion
to
the
appl.
Andrea
.
- Follow-Ups:
- Re: How to Access Window Messages
- From: Paul G. Tobey [eMVP]
- Re: How to Access Window Messages
- References:
- Re: How to Access Window Messages
- From: andrerus
- Re: How to Access Window Messages
- From: Paul G. Tobey [eMVP]
- Re: How to Access Window Messages
- From: andrerus
- Re: How to Access Window Messages
- From: Paul G. Tobey [eMVP]
- Re: How to Access Window Messages
- From: andrerus
- Re: How to Access Window Messages
- From: Paul G. Tobey [eMVP]
- Re: How to Access Window Messages
- From: andrerus
- Re: How to Access Window Messages
- From: Paul G. Tobey [eMVP]
- Re: How to Access Window Messages
- From: andrerus
- Re: How to Access Window Messages
- From: Paul G. Tobey [eMVP]
- Re: How to Access Window Messages
- From: andrerus
- Re: How to Access Window Messages
- From: Paul G. Tobey [eMVP]
- Re: How to Access Window Messages
- Prev by Date: Re: VS2005 compatibility
- Next by Date: Re: How to Access Window Messages
- Previous by thread: Re: How to Access Window Messages
- Next by thread: Re: How to Access Window Messages
- Index(es):
Loading