I am going to be checking if the user is moving any window around (my application does not have an interface) and respond accordingly. What do you think is the best way to do this? Can I determine if the user is clicking on a titlebar? Can I determine if a window is being moved? I then need to grab the hWnd of the window after I know it's being moved.
To get notifications for all windows, not just Windows Forms ones, you'll need to use a hook set by the SetWindowsHookEx() API function. You'll need a WH_CALLWNDPROC hook so you can see the WM_MOVE message that Windows sends to the window.
Unfortunately, that's a global hook. The code that implements the hook callback needs to be packaged into a DLL so that it can be injected into all target processes. That shoots a hole into your plans to use C# for this, you can't inject the CLR. The DLL must be written in unmanaged code.
This code project offers an approach, including the unmanaged injectable DLL you'll need.
here is a technique to spy on window handles. You can inspect all the handles which are open and wait for the move messages.
EDIT
.NET spy code.
Related
I keep getting multiple verification prompt from a 3rd party application where on many instances I have to select the prompt window, type my password and click on Ok. I thought of writing a simple application in WHITE framework which can capture the window, enter my password and deliver a click automatically.
I need to detect whenever a new window has popped up in Windows environment. I don't want to use either a timer or a loop. Can I get an event when ever a new window appears (registers) ?
-- Regards
Akshay Mishra
Outside of managed code you could use global WindowHooks, however this involves injecting a DLL into another process space.
This is not easily done with managed DLLs (read: assemblies). (It can be done, see here)
I wrote an article on CodeProject a while ago on how to create a sort of managed global hook for WM_CREATE and WM_DESTROY messages.
It includes full source code and it probably has what you need. Your application will need administrator privileges for this!
Assuming I have a valid hWnd to an active window (it was retrieved using ‘GetForegroundWindow’ or FindWindow, for example), can I register to windows message of this hWnd, from another application, of course? Is there any Win32 API for this, or a built-in C# method?
Example: In my console application I have a hWnd to the ‘Notepad’ window (running in the background). Can I register somehow to messages indicating the ‘Notepad’ window had moved, changed size, minimized, closed, etc.?
Thanks,
Elad
You have to inject a DLL into the process that owns the window. Use SetWindowsHookEx(), WH_CALLWNDPROC hook. You cannot write such a DLL using the C# language, the process won't have a CLR initialized and ready to run your code. Native code is required. Check this project.
If you just need to know about it moving or closing, then check out SetWinEventHook. You'll have to write a P/Invoke wrapper for this, since there's no equivalent in the .Net API. You can use this without needing to inject a DLL (use the WINEVENT_OUTOFCONTEXT
flag), so can keep everything in C# (and it also avoids the hassle of having to communicate between a separate DLL and your main process).
You'll likely want the events EVENT_OBJECT_LOCATIONCHANGE and EVENT_OBJECT_DESTROY. Note that you get these for all HWNDs on the thread you are listening to, so you'll need to filter by HWND in your callback.
Note that when you use WINEVENT_OUTOFCONTEXT, your own code will need to have a message loop running on the thread that calls SetWinEventHook. Also, the notifications that you receive are not delivered instantly, but with a slight delay (similar to PostMessage), but that may still be fast enough for your purposes that you can avoid doing an in-proc hook.
You can use the Accessible Event Watcher app (AccEvent) that's part of the Windows SDK to see what messages are available from notepad before you start writing code.
I am developing a (in-process) plug-in to application and as part of my plug-in I want to replace the application's tool-tips with my own. However, there is no API available for me to do so, so I've decided to go low-level.
I know the window class of the tool tip, but the question is, how do I detect it being created and how do I close it afterward?
Here's what I thought to do so far:
Create a system-wide hook on WM_CREATE
When caught, check the class and the process of the WM_CREATE target
Verify it is indeed the window I care about:
If the process is the one my plug-in is sitting in
And if the class is of the correct type
And if the correct application is in focus (in case of multiple applications)
Send a WM_DESTROY to the created window and create my own window at its position instead
How does it sound? Assuming there is indeed no API to handle the tooltips, is there a simpler way for what I need?
Thanks!
P.S Tagged as C++/C# as I intend to write it in these 2 languages (C++ for system-wide hook, C# for everything else)
If you know the type of the window you want to block, you can simply subclass it and handle the destruction in your own WndProc. Use GetClassLongPtr() with GCL_WNDPROC on the tooltip class, use SetClassLongPtr() with GCL_WNDPROC to set your own WndProc and have it call DestroyWindow() on WM_CREATE and call the old WndProc for the rest..
This won't work. Consider the view of the application that you're replacing the tooltips of and assuming that you could tell it to destroy windows. What will happen when the app decides that it needs to close the tooltip? It doesn't have the handle of your new window, it has the handle of the old window, which you've destroyed. Time for things to go wrong.
Your plugin system needs to explicitly support replacing the tooltips if you want this to work smoothly. Perhaps an optional part of the plugin framework could be a RequestTooltip function. If it doesn't exist, or returns null, or whatever then the default tooltips are used, otherwise your plugin provided ones are used.
I have a program that has a MDI host and I would like to be able to get which of it children just got focus, bassiclly I would like to make a window focus changed event for this application.
The application is a 3rd party and I don't have the source, I have the window handle to the main program and the MDI host part.
I know I'll have to use Win32 API just not sure which ones.
I am writing my application in C#
Thanks.
I guess what you're looking for is intercepting WM_SETFOCUS and WM_KILLFOCUS messages
The real problem is how are you going to do this. I guess the easiet way is to install a hook which is a subroutine to monitor the message traffic in the system and process certain types of messages before they reach the target window procedure. You're doing it by using SetWindowsHookEx winapi function with WH_CALLWNDPROC or WH_CALLWNDPROCRET types of hooks. There some are examples posted on codeproject; also there is one on msdn: How to set a Windows hook in Visual C# .NET
What is not really clear in your post is where your code running: in the same process with the MDI windows or is it a separate application\service? In case it is you would also need to inject your code into the remote process. Check this link for details on how you can do it: Three Ways to Inject Your Code into Another Process
hope this helps, regards
Is there a way in C# to globally add a menu item to all the system menus on all active windows? Perhaps under the "Maximize" command?
This can't be done in managed code. And it would be remarkably difficult even in unmanged code. Basically you would have to inject your code into every process, and then insert items into the local system menus, and then hook the main window proc to intercept the WM_SYSCOMMAND messages so that you could make the menu items do something.
You CAN write code that will add the WS_TOPMOST style to (most) windows (security permitting) just by using FindWindow to get the window handle and then SetWindowLong to change the window style.
But you won't be able to put the UI for this into other process's system menus.
You can do it by writing all the logic in C# in an exe file. You will also have to write some code in C/C++ as a hook, which will send events from the menu items to your exe file. You can find an example here https://github.com/AlexanderPro/SmartSystemMenu