If a dialog registers some of its controls as drop-targets, will drag'n'drop messages intended for those controls pass through the dialog's message processing in a way that the dialog can register a message handler to be notified/intercept those messages?
In a similar fashion to this question, I want to catch drag'n'drop events at a higher level in certain circumstances, before individual drop-handlers are invoked. But That question's answers suggest this isn't really possible? How to disable drag/drop when a dialog box is open
If a dialog registers some of its controls as drop-targets, will drag'n'drop messages intended for those controls pass through the dialog's message processing in a way that the dialog can register a message handler to be notified/intercept those messages?
If the controls are using DragAcceptFiles(), WM_DROPFILES messages will go directly to the window procedures of the individual controls, not to the window procedure of the dialog. If you want to intercept the messages, you will have to subclass the individual controls using SetWindowLongPtr() or SetWindowSubClass(), or use a message hook from SetWindowsHookEx().
If the controls are using RegisterDragDrop() instead, drag&drop operations will not go through any window procedures at all, as OLE drag&drop does not use window messages.
In a similar fashion to this question, I want to catch drag'n'drop events at a higher level in certain circumstances, before individual drop-handlers are invoked. But That question's answers suggest this isn't really possible?
This would only be possible with DragAcceptFiles() and subclassing/hooking.
Related
I'm attempting to implement an auto-complete feature in a Word add-in, and consequently need a way to detect when the user is typing in the document. As this isn't an event offered by the Office API, my strategy is to monitor WM_CHAR messages on the document window. To do this I've determined the handle of the actual window within Word that receives keyboard input, and tried subclassing it using SetWindowSubclass.
However when testing this, WM_CHAR messages aren't seen by my WndProc. WM_KEYDOWN/UP messages are, but not WM_CHAR. Is it true that a subclassed WndProc necessarily receives all messages that the original WndProc would have? I can see in Spy++ that the window I subclassed is having WM_CHAR messages posted to it.
I believe this could be done with Hooks, but I've heard they are quite hungry as far as performance goes, and subclassing the specific windows seems a lot cleaner in this instance.
I have a shell extension that needs to reload its configuration when a specific window message (custom message registered with RegisterWindowMessage) is broadcasted by another application.
I tried several approaches to intercept the message:
Installing a window subclass callback on a window of Windows Explorer, using SetWindowSubclass. This works on Window 7, but not on Windows 8, because apparently DllMain is not called on the main thread, and SetWindowSubclass doesn't work from another thread. This is mentioned in the documentation:
You cannot use the subclassing helper functions to subclass a window across threads
Installing a hook for CALLWNDPROC, using SetWindowsHookEx. Because I don't want to slow down the whole system, I install the hook for a specific thread only (the explorer's main thread). This works on Windows 8, but not on Windows 7... I suspect this is because I'm hooking on the wrong thread, but I'm not sure. And anyway, this approach seems overly intrusive.
Creating a message-only window to handle the message. This doesn't work at all, because message-only windows don't receive broadcasted messages.
Is there a reliable way to receive a window message in a shell extension?
A window message initially seemed to be the easiest way to notify the shell extension, but if you think another mechanism would be more appropriate, I'm open to suggestions.
Create a hidden window and listen for the message in its window procedure.
Register a window class that has default values for all the fields apart from the window procedure and class name. You don't need to specify anything else in the window class since the window will never be visible.
When you create the window, pass 0 for the window style. Specifically exclude WS_VISIBLE.
Pass 0 for the WndParent when you create the window. This will make it a top level window and so eligible to receive broadcast messages.
I'm making an application that hooks itself in to a target application and, when activated by the user, prevents all keyboard and mouse window messages from reaching the target application's window proc. My application does this by translating the incoming input messages, such as WM_MOUSEMOVE, to WM_NULL, so that the window proc is unaware input happened.
The problem is that Windows also automatically sends WM_SETCURSOR and WM_NCHITTEST to the window proc (e.g. when the application calls PeekMessage) when mouse input occurs. These messages aren't posted to the window's message queue, so I can't change them to WM_NULL.
I initially worked around this by subclassing the window proc and simply ignoring WM_SETCURSOR and WM_NCHITTEST there, but subclassing seems to have compatibility issues with some of the applications I'm hooked in to.
My question is: How do I prevent WM_SETCURSOR and WM_NCHITTEST from being generated in the first place OR how do I prevent them from reaching the application's window proc.
Some Ideas to Try
I just finished implementing a global/system wide CallWndRetProc with a WH_CALLWNDPROCRET Windows Hook (like it describes in the past post of the link below).
http://help.lockergnome.com/windows2/Igor-SetCursor-SetWindowsHookEx--ftopict285504.html
Using that in combination with hiding all the system cursors using SetSystemCursor has effectively hidden the cursor for most applications.
If you wanted to continue hacking at this target application, you could try using API Monitor to diagnosis what is going on: http://www.rohitab.com/apimonitor
The guy at rohitab hints at releasing his source code eventually; his site seems to have some of the better forums about Hooking, Subclassing, Injecting, etc.
It sounds like you successfully used SetWindowLongPtr(), but there are a few different ways to get into the address space of the program you are working on...
Have you tried SetCapture()?
Other Links
Here are a few other links that may be useful:
http://support.microsoft.com/kb/31747
http://msdn.microsoft.com/en-us/library/windows/desktop/ms646262(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/ms633569%28v=vs.85%29.aspx#winproc_subclassing
http://msdn.microsoft.com/en-us/library/windows/desktop/ms648395(v=vs.85).aspx
Hope that helps. Good luck.
I have control, subclassed from CDialogBar, it has some buttons(like on toolbar). When I catch WM_LBUTTONDOWN in the CDialogBar class is it a simple way of getting know if mouse was clicked on one of the buttons that are on the control?
CDialogBar class normally hosts regular windowed controls, so when a button is clicked there, WM_LBUTTONDOWN message is sent to this control window, not the dialog window class. So if you want to intercept those messages (if you really do), you need to either subclass the windows and handle their messages, or install a message hook.
You can also use Spy++ tool to see what messages are effectively reaching your CDialogBar window of interest to see if handling them might be a solution to your challenge.
I need to send messages to the GUI thread which should be processed the next time the GUI thread is idle. This message can come from the GUI thread or background threads.
I tried a combination of a MachPort/Notification. But when i do a
[[NSNotificationQueue defaultQueue] enqueueNotification: my_notify postingStyle: NSPostASAP];
This is not dispatched if there is a modal dialog, i have to close the dialog before it is processed so this is not useable for me.
It's okay to not handle messages during menu selection or live resize, but modal dialogs is a little bit too much delay.
Short answer: Don't use modal dialogs.
Long answer: Modal dialogs are handled by a special run loop mode called NSModalPanelRunLoopMode, see here.
To schedule a call, one way is to use performSelectorOnMainThread:withObject:waitUntilDone:modes: explained in that document; don't forget to specify the modal mode and the default mode there.
You can also use NSNotificationCenter and specify the run loop modes, see the discussion here. But it's tricky to use NSNotificationCenter from the threaded environment to start with as described here, so I don't recommend it.
On 10.6, you can also use dispatch_async.