hook to win message (WM_WINDOWPOSCHANGING) of other process' windows - c#

I'm trying to hook directly into window size changes (before or while it is happening) to set other applications from changing its size.
If i use WinEvent hook (thanks pinvoke), I can receive EVENT_SYSTEM_MOVESIZESTART but only when user manually tries to resize them. If a program attempts to do it on itself (probably through SetWindowPos), it won't fire.
My hope is to hook into WM_WINDOWPOSCHANGING and deny it.
pwp->flags |= SWP_NOSIZE;
return FORWARD_WM_WINDOWPOSCHANGING(hwnd, pwp, DefWindowProc);
this is pretty much how I would do it if I can hook WM_WINDOWPOSCHANGING.

Related

How to disable mouse wheel event in another application(WM_MOUSEWHEEL) using Handler

I am able to close another application window (calculator) from my application by using the following code:
hwnd = FindWindow(null, "Calculator");SendMessage(hwnd,WM_CLOSE,0,IntPtr.Zero);
But I want to disable the mouse wheel in the same calculator application window. I tried the following way, but it doesn't work:
SendMessage(hwnd, WM_MOUSEWHEEL, 0, IntPtr.Zero);
You need to Hook Into the Event and catch the occurence if you want to disable it for specific hWnds.
Look into this:
https://msdn.microsoft.com/en-us/library/windows/desktop/dd373640(v=vs.85).aspx
If you define your callback function, it does need to take care about the correct distribution of the events to all Windows except the one you are searching for, despite that I'm not sure if this is just a clone of the Eventmessage or if they are only directed to your application if the hook is set.
Important is also that the code provided in the example is not complete,
it is missing a message-loop which actually does the grabbing from the message-queue.
Edit
the link mentioned below
http://null-byte.wonderhowto.com/how-to/create-simple-hidden-console-keylogger-c-sharp-0132757/

Sending paste message to active window's focused control

I want to intercept a hot-key (specifically CTRL V) which will interact with my application in a certain way. I am able to globally register the hotkey using the RegisterHotKey method. When I press CTRL V I want the focused window/control to also receive the WM_PASTE message. I've tried sending it trough SendMessage but it didn't seem to work. I eventually ended up Unregistering the HotKey, sending ^v to the current window, then re-Registering the hotkey.
private static void Hook_KeyPressed(object sender, KeyPressedEventArgs e)
{
_hook.KeyPressed -= Hook_KeyPressed;
_hook.Dispose();
SendKeys.Send("^v");
_hook = new KeyboardHook();
_hook.RegisterHotKey(global::ClipMaster.ModifierKeys.Control, Keys.V);
_hook.KeyPressed += Hook_KeyPressed;
}
This does the trick, but it blocks the mouse (and the window) for around half a second. I'm also afraid it won't work in certain applications, although I don't know what example I could give.
I'm not sure what you're trying to achieve with that hook since it's impossible to understand it from the code example.
Assuming you do it for auditing reasons (or monitoring of the sort), I'd suggest to review the return value of the WM_HOTKEY message. It can "say" that the message wasn't processed, hence allowing further processing of the Ctrl-V by other logic (e.g. other hooks).
Also, i'd advise to use alternative way to re-send Ctrl-V than SendKeys class which has know timing issues. Did you consider posting a message instead?
I've also found alternative approach to the hooking itself by using lower level key pressing for hooking.
Let me know if it helped.

Detect change of focus and find it C#

I need an underlying process to gather information about other applications used by Windows. I suspect this would be done using WAPI hooks. What I wish to do is for my program to detect when windows changes focus from one program to another and tell me which one currently has focus.
First I need an event that triggers each time Windows swaps focus between two applications. All events I've found so far only handles changes made from or to the program it's being used by, but I need to find all focus-changes, even if it's between two other programs.
I'll also need a function that gives me the window in focus. Would this work, or is this only internally (windows within the current application and not other programs)?
Cheers
Depending on how accurate you need your focus change detection system to be you might be able to get away with a service that polls for the foreground window using the API function you described GetForegroundWindow (yes this is system-wide, not process specific).
You can then use the handle of that function to determine which process is the current active/focused process. Then retrieve the focused element (child window) of that process..
HWND hwnd = GetForegroundWindow();
DWORD remoteThreadId = GetWindowThreadProcessId(hwnd, NULL);
DWORD currentThreadId = GetCurrentThreadId();
AttachThreadInput(rThreadId, curThreadId, TRUE);
HWND focusElement = GetFocus();
AttachThreadInput(rThreadId, curThreadId, FALSE);
Keep doing this.. and do whatever you need to do with focusElement
UPDATE
Well, apparently, as #Kenneth K. posted in a comment, there is a global EVENT_SYSTEM_FOREGROUND event that you can hook so that you application gets notified when the foreground (focused) window changes. This way you don't need to loop continuously to detect these changes.
EVENT_SYSTEM_FOREGROUND = 3;
WINEVENT_OUTOFCONTEXT = 0;
You can follow the example in this answer to see how to hook this event and get the notifications. Then whenever the foreground (focused) window changes you can hook that window's message loop and look form focus changed events withing that window using the SetWindowsHookEx function.
Another options is to consult the list of system events on MSDN and see if there is one you can use instead of the EVENT_SYSTEM_FOREGROUND, or along with it to detect control-level focus events. Perhaps the EVENT_OBJECT_FOCUS might be useful.
Please let me know if this is still unclear..

Unable to check a checkbox using C# WinAPI

I'm trying to check a checkbox inside a program called AviReComp and I'm unable to do it somehow. I've tried all sorts of code:
//Check the checkbox
IntPtr SubtitlesSection = FindWindowEx(MoreOptions, IntPtr.Zero, null, "Subtitles");
IntPtr AddSubtitlesCheckbox = FindWindowEx(SubtitlesSection, IntPtr.Zero, null, "Enable/Disable");
SendMessage(AddSubtitlesCheckbox, BM_SETSTATE, 1, IntPtr.Zero);
SendMessage(AddSubtitlesCheckbox, BM_SETCHECK, 1, IntPtr.Zero);
SendMessage(AddSubtitlesCheckbox, WM_PAINT, 0, IntPtr.Zero);
SendMessage(AddSubtitlesCheckbox, WM_LBUTTONDOWN, 1, MakeLParam(10, 10));
SendMessage(SubtitlesSection, WM_PARENTNOTIFY, (int)MakeLParam((int)AddSubtitlesCheckbox, WM_LBUTTONDOWN), MakeLParam(26, 31));
SendMessage(SubtitlesSection, WM_PARENTNOTIFY, (int)MakeLParam((int)AddSubtitlesCheckbox, WM_LBUTTONUP), MakeLParam(26, 31));
The checkbox is located within the Additions tab underneath the Subtitles section and is called Enable/Disable.
Am I doing something wrong?
Thanks for any help!
Edit: I now see that this code actually works and it does check the checkbox but I still have a problem since it does not change all the controls that are supposed to change when I check the checkbox manually and not inside my program. Is there a way to force the parent control to repaint itself or trigger the change event when I mark the checkbox as checked?
try to use spy++ to make sure of the location of the Check-box if all didn't work and this has to run on vista and above I Would use Windows Automation
When the state of a child control changes (in response to a user action), it sends some notification messages to it's parent window, and parent window by catching those messages, performs actions. Those notification messages are WM_COMMAND and WM_NOTIFY.
By monitoring messages sent to the parent window of your check box control (and checking the control by mouse), I noticed one WM_COMMAND message and two WM_NOTIFY messages. Those messages where not available when I programmatically sent a BM_SETCHECK message to the check box. So the magic revealed.
Sending WM_NOTIFY is a little difficult, because you have to allocate memory in the address space of the other process (using VirtualAllocEx, for NMHDR structure), fill the memory (using WriteProcessMemory), send the message, and then release the allocated memory.
Sending WM_COMMAND message is too much simpler. I tested it, and it worked!
Win32.SendMessage(SubtitlesSection, Win32.Message.WM_COMMAND, 0, AddSubtitlesCheckbox);
The message is sent to the parent control of the check box, using the handle of the control as the fourth parameter. Third parameter of the function should be the control ID, and the ID changes every time. But hopefully it seems that the program checks the control handle and not the ID.

Capture FlashWindowEx event of a running process

I have an app that is already running - every now and then it triggers a FlashWindowEx event (the windows 7 icon flashes). I would like to capture this event but I can't seem to find any good info on how.
My thoughts were that it would go like this:
Hook into running process using Process.GetProcessesByName
Set up event handler for FlashWindowEx
Catch it and do whatever
I guess my question is:
Is this possible?
Is there a way to get a list of available events from a running process?
How would I hook into FlashWindowEx?
The WH_SHELL hook notifies you when a window is flashing. According to the documentation:
nCode = HSHELL_REDRAW
wParam = the handle of the window
lParam = TRUE if the window is flashing, FALSE otherwise.

Categories

Resources