We can set window text with:
BOOL WINAPI SetWindowText(
__in HWND hWnd,
__in_opt LPCTSTR lpString
);
and this windows text by another application
int WINAPI GetWindowText(
__in HWND hWnd,
__out LPTSTR lpString,
__in int nMaxCount
);
I don't want to change my forms caption but I want to keep a custom text in window and get this text by another instance of same program. How can I achieve this?
A simple way to do this is:
Define your own WM_APP message, which instance A of your app will use to tell instance B's window "send me your private text".
When instance B receives this message, it can use WM_COPYDATA to send a reply to instance A's window.
Instance A receives the data from WM_COPYDATA and does what it wants with it.
This scheme allows you to send arbitrary data (as long as it doesn't include pointers) provided that the data is reasonably small (say a few KB tops). It's also easy to implement. What it does lack is security controls, so if you have to prevent the bad guys from retrieving this data from your application you will need to use something more heavy-duty.
I am not sure, but I think you will have to open the other process using openProcess and then use some function on the process handle to get the title text. Once you have the text, you can very well use that in your application. For getting the process if of the required process, you can use EnumProcess, here is a complete example: http://msdn.microsoft.com/en-us/library/ms686701%28v=vs.85%29.aspx
Probably the easiest way to do this is to define a windows message in the WM_APP range and send it from one instance to the other. You'd have to do your own marshalling though with something like GlobalAlloc.
Related
In our Program we have a Dialog from a separate dll open to display infomation. I need to close this dialog when our system timer causes the system to lock.
I send information to the dll by registering a system message in both my MainFrm and EditDisplayDll
SYSTEMLOCK = RegisterWindowMessage("SystemLock");
When I sent the message via
::PostMessage(GetActiveWindow()->m_hWnd,SYSTEMLOCK,0,0);
The message correctly sends to my EditDisplayDll and closes the dialog when the system locks; however, if I alt tab while waiting for the timeout and use another program(firefox, outlook, etc.) the message never correctly calls to the EditDisplayDll. The MainFrm and other windows inside of the MainFrm correctly lockout and hide themselves in either case.
I have tried also using HWND_BROADCAST with PostMessage and SendNotifyMessage. I have also tried to use FindWindow() and FindWindowEx() to specifically call the EditDisplayDll.
I cannot use something like GetDlgItem() because my MainFrm.cpp doesn't have access to this dll.
My decision to use GetActiveWindow() was because I believe it looks to windows specific to my program no matter what window I am in as seen in the imagery in Foreground Vs Active window
Finally, my question is, is there a way to call all Windows in my program no matter what program I am currently in or is there another way I could get access to the specific IDD of the EditDisplayDll in order to send the SYSTEMLOCK message to it?
CWnd *cWndED = FindWindow(_T("EditDisplay"),_T("EditDisplay")); HWND
hwnd = (HWND)cWndED;
You should use win32 API ::FindWindow with proper class, window name. And do not cast CWnd pointer to HWND. Your code should look like:
HWND hWnd = ::FindWindow(_T("ProperClass"), _T("ProperNmae"));
if (hWnd != NULL)
{
::PostMessage(hWnd, YOUR_MESSAGE, ....);
}
I will suggest you to find your Dll window class and name using Spy++ and then try to find that using above method. Remember it's always better to use native API for this kind of tasks.
FindWindow is a good solution if you know both, name of the window and the element.
If you want to get the HWND of your window - no element inside the window -, you can pass as first parameter NULL.
::FindWindow(NULL, _T("WindowName"));
Back to your code: If you are lucky your PostMessage does nothing, otherwise the active window may catch your message. Who knows how/if it is handled in the active window ? Use the PostMessage if you have a valid IsWindow(HWND) from FindWindow or FindWindowEx.
In case you want a CWnd from your HWND take a look at this. (The call may be slow)
HWND hWnd = ::FindWindow(_T("ClassName"), _T("WindowName"));
if (hWnd && IsWindow(hWnd))
{
::PostMessage(hWnd, MESSAGE_TO_BE_SEND, lParam_or_Flags);
}
I have worked with the win32 API and the DirectX API for interpreting input from the user, but haven't found much in the way of generating input that matches original user input.
My goal is to make a program that will run transparently in the background, minimized, or in the quicklaunch area and have that program artificially implant keyboard and mouse input for a third party, full screen application.
I've found some commands for verifying which window has focus, and some code samples for checking the process name or ID of said application, but not as much on generating input via directx or anything else, to simulate legitimate input.
Any suggestions would be much appreciated, I want it to register as close to real input as possible to help facilitate automated testing.
My apologies in advance if this question is too general or "under-researched", I'm just not quite sure where to start on this one!
The program will be in either C++ or C# due to my familiarity with those languages.
I have done this:
One app to act as an global keyboard_hock, and then i did send matching patterns to an second app, direct in memory - i used examples from All-in-one code framework examples you can download, lock for CSFileMappingServer & CSFileMappingClient (get / set) to memory from two separete processes. And CSWindowsHook project to catch global keyboard events
I was a litle quick, but to send virtual keyboard you can use:
BOOL
WINAPI
PostMessageA(
__in_opt HWND hWnd,
__in UINT Msg,
__in WPARAM wParam,
__in LPARAM lParam);
But the winow you send to has to be in focus, you can use:
BOOL
WINAPI
BringWindowToTop(
__in HWND hWnd);
And to get HWIND to the running app, you can use:
HWND
WINAPI
FindWindowA(
__in_opt LPCSTR lpClassName,
__in_opt LPCSTR lpWindowName);
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
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.
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);