How Can I pass message from DLL to Application - c++

I have a ATLCOM Shell Extension which adds Right Click Extension to Windows Explorer. How Can I pass a message from my DLL to another MFC application.
To Sumarize, I want to pass a Message from DLL to MFC application.

You can use Windows API SendMessage or PostMessage.

Have you tried using Windows messages?
You can define you own custom messages like this:
const UINT WM_YOUR_CUSTOM_MESSAGE = ::RegisterWindowMessage(_T("Your_custom_message"));
You receive the message in a standard WindowProc() function:
WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
You can add one by overriding the CWnd::WindowProc() function in your receiving application (use classwizard in either the dialog in an MFC dialog app, or the MainFrm in a Single / Multiple Document MFC app)
You send the message to all windows like this:
ULONG ulRC = BSM_APPLICATIONS;
BroadcastSystemMessage(BSF_IGNORECURRENTTASK | BSF_FORCEIFHUNG, // do not send message to this process and don't hang
&ulRC, // broadcast only to applications
WM_YOUR_CUSTOM_MESSAGE, // message registered in previous step
0, // wParam message-specific value
0); // lParam message-specific value
If you need to pass some information with the message, you can also make use of the wParam and lParam values in the message.

There is one big assumption in the current answers. You normally send messages to processes, not applications. This is a huge difference. There could be zero, one or more instances of the MFC application running.
In the case of zero applications, the DLL will have to call CreateProcess. CreateProcess allows the DLL to pass command-line arguments to your MFC app.
In the case of one MFC application, the message-based solutions offered above will work.
In the case of more than one running MFC application, they'll have different HWNDs. THe DLL picks the application(s) by picking which HWND to send the message to. The logic by which an HWND is picked is outside the scope of this question. One common solution is to just send the message to the HWND's of all running instances.
Finding out how many instances of your application are running is achieved by Process Enumeration

Related

In MFC, in wizard-generated WindowProc, how do I determine message sender window handle?

I have a legacy MFC application originally written in Visual C++ 6. I need to do some minor changes to it but MFC is a black box to me.
There is this apparently wizard-generated function that processes messages
LRESULT CMainFrame::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// TODO: Add your specialized code here and/or call the base class
switch (message)
{
case WM_CLOSE:
...;
...
etc.
}
For some messages I need to get the sender window handle (which is from a different process). In Windows API a standard WindowProc has this handle as the first argument, but where is it in MFC?
Edit: Thank you Raymond and Mark. I see that I misunderstood how it works.
This information isn't available. The first parameter in a standard window procedure is the receiver, not the sender. This makes sense, too, since SendMessage and PostMessage identify the receiver by window handle. The sender, on the other hand, can be any thread, including a thread that doesn't own any windows.
If you need to identify the sender of a message in the code receiving a message you will have to explicitly pass an ID along. When crossing process boundaries you're going to have to marshal any referenced memory. The system won't do that for custom messages.

Intercept mouse input

I was wondering if there is a way to intercept and modify mouse input before it gets to windows?
What I'm wanting to do is intercept mouse motion events, apply some custom scaling and acceleration to the values, and then continue passing them along. I'd need something that can do this before the inputs get to the raw input API or DirectInput.
In order to affect all mouse input, including DirectInput, during logon and the SAS screen, etc., you'll need to load a filter driver into the mouse driver stack.
Other people have done it, for example http://www.maf-soft.de/mafmouse/
There should be a moufiltr sample in the Windows DDK which you can use as a starting point. You will most likely want to use a virtual machine for development since errors in a driver on your development machine could be difficult to recover from.
Have you seen this method of intercepting mouse and keyboard input without having to make a filter driver or hook?
http://oblita.com/Interception.html
There is a LowLevelMouseProc hook procedure that you can use to get information on any mouse input entering the system, although I doubt if you can actually change this information (and the docs are silent on this).
If this fails, GetMsgProc is an alternative that lets you intercept all messages posted to any window. Though this hook does let you modify the message, it's probably too late to have any effect on APIs such as DirectInput.
You could try a windows hook - which are functions you set to receive windows messages before they get passed through to the rest of the system - a CBT hook (for computer based training) is what might get you best results.
I don't know Whether this will work with DirectInput or the other new stuff MS has added to break all the old internal consistency. Its easy to set up though, so try it and see.
As far as I know the best way is to hook to windows message loop, In your case you should pass HWND 0 (If I remember correctly this the HWND of the desktop) so all the messages will pass though your function first.
http://msdn.microsoft.com/en-us/library/ms633591%28VS.85%29.aspx
More on hooks : http://msdn.microsoft.com/en-us/library/ms644959%28VS.85%29.aspx
Use it as follows:
m_nOldWindowProc = ::SetWindowLong(0 /I think.../, GWL_WNDPROC, (LPARAM)(WNDPROC)WindowProcCallback);
and the callback:
LRESULT CALLBACK CStubWindow::WindowProcCallback(HWND hwnd,
UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_WINDOWPOSCHANGING:
((WINDOWPOS*)lParam)->cx = STATUS_BAR_WIDTH;
((WINDOWPOS*)lParam)->flags = SWP_NOOWNERZORDER | SWP_NOMOVE;
break;
default:
break;
}
return ::CallWindowProc(m_nOldWindowProc, hwnd, message, wParam, lParam);
}

Windows/C++: detect when focus has changed between windows (globally)

I'm trying to find a way to detect when focus is changed to another window (without having to poll every X ms).
I've already figured out a way to detect when focus is switched between applications using WH_SHELL and HSHELL_ACTIVATESHELLWINDOW.
The problem is I want to detect when focus is switched between dialog/windows within the same app.
ie. In Notepad, I can determine when the app switches to Notepad, but I cannot detect when the "Open" or "Save" dialogs appear because the focus is still within the same application.
You can use SetWindowsHookEx with a WH_CBT hook type. If you just want to detect focus changes within an application, pass GetCurrentThreadId() as the last parameter, otherwise the hook will be for all threads on the current desktop.
Note that using windows hooks can have an adverse effect on system performance, so the hook should only be installed when necessary and you should do a minimum amount of work in the hook procedure.
Sorry for the delay, I don't have VS installed on this computer so it's a bit hard to find the code.
Use this to hook your code into the system.
HHOOK oldShellHook = SetWindowsHookEx(WH_SHELL, BCK_WndShellProc, hDll, NULL);
if (!info->oldShellHook) {
MessageBox(m_hwnd, L"Failed to load global hook.", strTitle, MB_OK | MB_ICONERROR);
return;
}
And this your hook. Depending on what you're doing, use nMsg to figure out when you want to apply your custom logic.
LRESULT CALLBACK BCK_WndShellProc(int nMsg, WPARAM wParam, LPARAM lParam) {
...
}
Read the MSDN docs for SetWindowsHookEx() to make sure you return the expected values, otherwise you can lock up the whole system.
I use code similar to this on my Breadcrumb Killer and Spasm (Show all programs on Start menu) programs and it seems to work fine.
How about the "Computer Based Training API"; SetWindowsHookEx with WH_CBT which will enable you to receive HCBT_SETFOCUS (among others)

Notification when Windows Dialog is opened

I want to do some processing when a particular dialog is opened but I am not able to find any way to get notification when that dialog is opened.
Is there any way to get notification in application for opening of a particular windows dialog?
The only available information about the dialog is its title and its unique.
The general solution is to use windows hooks, filter to WH_CBT, filter to WM_CREATE, or something like that, get the window text and see if it is the one of your interest.
One more important point: in hook you should use SetWindowLongPtr() to set window process to your own function, that will actually receive WM_CREATE event. In all calls this function should call the original window procedure.
You can also use a CBT Hook to watch window creation messages. You'll have access to the CREATSTRUCT used to create the actual window, eg, the title and class name. You can prevent the window from being created in your hook, modify the size, etc.
EDIT: sorry didn't notice that you don't have the code yourself but only the title. So I think the other posts solution is what you need
The event handling in win32 applications is done via a so called windows procedure which is a callback function with the following signature:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
This callback gets called by windows every time there is a message for windows which are registered with this callback function. One of the first messages send to a new window is the WM_CREATE message.
If you are creating your windows "by hand" with win32 API, then there should be a static callback function like the one below where you can filter for the WM_CREATE message.
LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
{
switch( message )
{
case WM_CREATE:
// do what ever you want
return 0;
case default:
return DefWndProc( hwnd, message, wParam, lParam );
}
}
If you use MFC dialogs (CDialog) then you can overwrite the function CDialog::OnInitDialog().
OK, the way to do this is to use SetWindowsHookEx(WH_SYSMSGFILTER,...)
You'll be getting a lot more callbacks than you really need. and global hooks are a real drain on system performance (they can force the system to serialize things that would normally run independently)
be sure to read the Remarks, especially this part:
SetWindowsHookEx can be used to inject a DLL into another process. A 32-bit DLL cannot be injected into a 64-bit process, and a 64-bit DLL cannot be injected into a 32-bit process. If an application requires the use of hooks in other processes, it is required that a 32-bit application call SetWindowsHookEx to inject a 32-bit DLL into 32-bit processes, and a 64-bit application call SetWindowsHookEx to inject a 64-bit DLL into 64-bit processes. The 32-bit and 64-bit DLLs must have different names.
Your hook must live in a dll, and the dll will end up loaded into other process's address space, so you won't it won't have access to your procees's address space, you will have to set up some sort of interprocess communication between your hook and your app.
On the whole I'd say this sounds like a really bad idea.

Getting control of the main thread in windows c++ app

I'm writing some code that id like to be able to work with any window, such as a window created through the windows API, MFC, wxWidgets, etc.
The problem is that for some things I need to use the same thread that created the window, which in many cases is just sat in a message loop.
My first thought was to post a callback message to the window, which would then call a function in my code when it recieves the message using one of the params and a function pointer of some sorts. However there doesnt seem to be a standard windows message to do this, and I cant create my own message since I dont control the windows code, so cant add the needed code to the message handler to implement the callback...
Is there some other way to get the thread that created the window to enter my function?
EDIT:
John Z sugessted that I hooked the windows messages. If I do that is there some way to get "ids" for custom messages without the risk of conflicting with any custom messages the window already has?
eg I might do
WM_CALLBACK = WM_APP+1
But if the window I'm hooking has already done something with WM_APP+1 I'm gonna run into problems.
EDIT2:
just found RegisterWindowMessage :)
If you are in the same process as the window you can hook its messages by subclassing it. Check out http://msdn.microsoft.com/en-us/library/ms633570(VS.85).aspx
The key API is SetWindowLong.
// Subclass the edit control.
wpOrigEditProc = (WNDPROC) SetWindowLong(hwndEdit, GWL_WNDPROC, (LONG)EditSubclassProc);
// Remove the subclass from the edit control.
SetWindowLong(hwndEdit, GWL_WNDPROC, (LONG)wpOrigEditProc);
Alternatively to subclassing, you can use SetTimer to call a function in the window thread.
VOID CALLBACK Function(
HWND hwnd,
UINT uMsg,
UINT_PTR idEvent,
DWORD dwTime
)
{
// stuff
}
SetTimer(hWnd, event, 0, Function);