I've been searching through the Windows API, looking for a way to intercept all WM_MOUSESCROLL messages before they hit their perspective message queues. After intercepting I need to change a few things about them and send them to a different [or the same] message queue.
I need to do this fairly efficiently as it will be running on top of a fairly large application.
Any Ideas on how I can achieve this? I've yet to find a way.
Your best bet is an unmanaged interception using a low level mouse event hook. see this MSKB article for more info.
When using MFC you can use PreTranslateMessage, or search for the WndProc function in a custom framework and see if it provides similar functionality. Otherwise the mouse hooking is good idea. Especially when you want to do it globally.
Related
I have been looking around and haven't really seen much information on why someone would override wndproc to handle messages.
So I wondering:
Why do it?
When to do it?
Whats its general purpose in C#?
I have tried using it when seeing a serial COM plugged and unplugged from the computer, but I felt like I managed better reliance on methods I have created myself.
Other messages I see are for key-presses, cursor settings, and other various actions. This being said most of these things already have built in methods in c# libraries. So again I am back to my three main questions. Any information, opinions, examples, etc would be awesome.
WndProc() is very, very core to the way a Windows window works. It is a managed wrapper method around the window procedure, a function that used to be written in C in the olden days. It is the way you customize the behavior of a window, making it respond differently to notifications generated by the operating system or other programs.
You don't normally have a need to override it, the WndProc() method in the base class handles most of the basic notifications. Turning them into friendly .NET events, like Click etc. But that isn't complete, either because the notification is too obscure or necessarily so because it cannot know anything about the messages used by a custom window. In which case you can fall back on overriding WndProc() to intercept the message. Best example I can think of is creating a borderless window to draw a custom window frame and still giving the window normal behavior. Most easily done by intercepting messages like WM_NCHITTEST, not wrapped by .NET.
Truly grokking WndProc() requires reading Petzold's seminal book "Programming Windows". Perhaps not that easy to grasp anymore today, it does assume a basic understanding of the C language. Which was the language targeted by the winapi 30 years ago, object oriented languages were not widely used or available back then. That also otherwise explains why writing code inside WndProc() is fairly painful, there is very little abstraction and you can't really ignore pointers.
Microsoft did make an effort to retire it, starting with Windows 8 and the WinRT api. Not exactly a slamdunk success, maybe Windows 10 will give it some traction. The foundational technology that makes WinRT work under the hood is COM, a big step up from C because it can support an object model. Albeit it well hidden in the friendly language projections, COM programming is something most programmers will try to avoid :)
I have found that it is useful for processing keypress events for a UserControl.
The keypress, keyDown, or KeyUp events are quite finicky at responding from a UserControl (even with KeyPreview set to true and all that). I found that if I override WndProc() I have much more reliability of the Control processing the command.
unfortunatly, when you listen to WM_QUERYENDSESSION, you do not get the information if the user has requested a reboot or a shutdown. This is really bad design, but it's the way Windows is, so I was thinking of hooking the call to NTShutdownSystem, which gets a parameter telling the system to perform a reboot or to shutdown.
The question is: how can this actually be achieved in C#? I want to get some kind of hook that I can use to determine the parameters passed to NTShutdownSystem, and then save that information. After that, I want to call the "real" NTShutdownSystem the way it was intended by the user.
Do you have any sample code illustrating this?
The reason why WM_QUERYENDSESSION does not give a shutdown reason is that the user may just be logging out at that time, rather than shutting down the system.
This generally falls under the category of kernel level hooking and has generally not been considered a good thing as it can influence stability of the system. Most of them are written in C or C++, and generally have to go to a lot of effort to perform the hook across all the programs that are executing - e.g. hooking the routines at program load-time.
This is not a trivial, but there are some frameworks that have been written to help with trying to hook routines like this using managed code (e.g. C#)
The next question to ask is why do you care?
edit NTShutdownSystem is invoked very late in the shutdown process - at that point you probably have no UI and no way of doing anything. I would recommend intercepting ExitWindowsEx, InitiateShutdown, InitiateSystemShutdown and InitiateSystemShutdownEx - I don't know if some of them are called by the other, but you should probably only record the reason and then react to the reason in the WM_QUERYENDSESSION code of your standard app.
I am trying to come up with a way to raise a public event that can be seen by more than one application. The first thing that comes to mind is SystemEvents.
Is there a way to "define" a new SystemEvent or even a public event that more than one application can see and listen for.
Do you really need to use SystemEvent? How about other methods for IPC
IpcChannel is an alternative technique that seems to fit your requirements.
I don't think there is an easy .Net built in way to do this. The only way I know of is to use PostMessage or SendMessage to the Windows Event Queue. You can read the details About Messages and Message Queues. There are TONS of resources for invoking these native commands on google, but one of the best to start with is pinvoke.net.
The underlying plumbing for SystemEvents are Windows messages that are broadcast to all top level windows. Messages like WM_SETTINGCHANGED. You too can broadcast messages, pinvoke SendMessageTimeout with HWND_BROADCAST. This is somewhat risky, you'll be sending messages to programs that have never seen the message number before. At the very least you'll need to use RegisterWindowMessage() to ensure you get a unique message number that's known to you and to the processes that you want to be aware of the notification and don't confuzzle the rest of them.
There are more reliable mechanisms with less risk, a named pipe server for example.
Is it possible to determine when window focus changes at the system level? I'm writing a time-tracking application, and I'd like to be able to listen for application switching (so that I can begin logging time in a given application). I've poked around the Process class for a good hour here, and while I learned quite a few useful things, I didn't find what I was looking for. I suspect I'll need to use hooks, but it's difficult finding clear documentation on the process, let alone documentation specific to what I'm asking.
See SetWindowHooksEx.
Good article, "Windows Hooks in the .NET Framework":
http://msdn.microsoft.com/en-us/magazine/cc188966.aspx
Suppose I have two applications written in C#. The first is a third party application that raises an event called "OnEmailSent".
The second is a custom app that I've written that I would like to somehow subscribe to the "OnEmailSent" even of the first application.
Is there any way that I could somehow attach the second application to an instance of the first application to listen for "OnEmailSent" event?
So for further clarification, my specific scenario is that we have a custom third party application written in c# that raises an "OnEmailSent" event. We can see the event exists using reflector.
What we want to do is have some other actions take place when this component sends an email.
The most efficient way we can think of would be to be able to use some form of IPC as anders has suggested and listen for the OnEmailSent event being raised by the third party component.
Because the component is written in C# we are toying with the idea of writing another C# application that can attach itself to the executing process and when it detect the OnEmailSent event has been raise it will execute it's own event handling code.
I might be missing something, but from what I understand of how remoting works is that there would need to be a server defining some sort of contract that the client can subscribe to.
I was more thinking about a scenario where someone has written a standalone application like outlook for example, that exposes events that I would like to subscribe to from another application.
I guess the scenario I'm thinking of is the .net debugger and how it can attach to executing assemblies to inspect the code whilst it's running.
In order for two applications (separate processes) to exchange events, they must agree on how these events are communicated. There are many different ways of doing this, and exactly which method to use may depend on architecture and context. The general term for this kind of information exchange between processes is Inter-process Communication (IPC). There exists many standard ways of doing IPC, the most common being files, pipes, (network) sockets, remote procedure calls (RPC) and shared memory. On Windows it's also common to use window messages.
I am not sure how this works for .NET/C# applications on Windows, but in native Win32 applications you can hook on to the message loop of external processes and "spy" on the messages they are sending. If your program generates a message event when the desired function is called, this could be a way to detect it.
If you are implementing both applications yourself you can chose to use any IPC method you prefer. Network sockets and higher-level socket-based protocols like HTTP, XML-RPC and SOAP are very popular these days, as they allow you do run the applications on different physical machines as well (given that they are connected via a network).
You can try Managed Spy and for programmatic access ManagedSpyLib
ManagedSpyLib introduces a class
called ControlProxy. A ControlProxy is
a representation of a
System.Windows.Forms.Control in
another process. ControlProxy allows
you to get or set properties and
subscribe to events as if you were
running inside the destination
process. Use ManagedSpyLib for
automation testing, event logging for
compatibility, cross process
communication, or whitebox testing.
But this might not work for you, depends whether ControlProxy can somehow access the event you're after within your third-party application.
You could also use Reflexil
Reflexil allows
IL modifications by using the powerful
Mono.Cecil library written by Jb
EVAIN. Reflexil runs as Reflector plug-in and
is directed especially towards IL code
handling. It accomplishes this by
proposing a complete instruction
editor and by allowing C#/VB.NET code
injection.
You can either use remoting or WCF. See http://msdn.microsoft.com/en-us/library/aa730857(VS.80).aspx#netremotewcf_topic7.
What's the nature of that OnEmailSent event from that third party application? I mean, how do you know the application is triggering such an event?
If you are planning on doing interprocess communication, the first question you should ask yourself is: Is it really necessary?
Without questioning your motives, if you really need to do interprocess communication, you will need some sort of mechanism. The list is long, very long. From simple WM_DATA messages to custom TCP protocols to very complex Web services requiring additional infrastructures.
This brings the question, what is it you are trying to do exactly? What is this third party application you have no control over?
Also, the debugger has a very invasive way of debugging processes. Don't expect that to be the standard interprocess mechanism used by all other applications. As a matter of fact, it isn't.
You can implement a similar scenario with SQL Server 2005 query change notifications by maintaing a persistent SqlConnection with a .NET application that blocks until data changes in the database.
See http://www.code-magazine.com/article.aspx?quickid=0605061.
also WM_COPYDATA might be possible, see https://social.msdn.microsoft.com/Forums/en-US/eb5dab00-b596-49ad-92b0-b8dee90e24c8/wmcopydata-event-to-receive-data-in-form-application?forum=winforms
I'm using it for similar Purose (to notify that options have been changed)
In our C++/Cli-scenario (MFC-)programs communicate vith WM_COPYDATA with Information-String in COPYDATASTRUCT-Member lpData
(Parameterlist like "Caller=xyz Receiver=abc Job=dosomething"). also a C#-App can receive WM_COPYDATA-messages as shown in the link. Sending WM_COPYDATA from C# (to known Mainframe-Handle) is done by a cpp/cli-Assembly, (I didnt proove how sending WMCOPYDATA can bei done in C#).
PS in Cpp/Cli we send AfxGetMainWnd()->m_hWnd as WPARAM of WMCOPYDATA-Message and in C# (WndProc) m.WParam can be used as adress to send WM_COPYDATA