-
February 1st, 2009, 08:02 PM
#1
SendMessage Problem
I use the ShellExecute to execute notepad, and the return from that api is the HANDLE to the notepad, the handle is in a HMODULE, but after i try to use SendMessage, and give it the handle as the first argument, i get problems.
SendMessage wants a HWND but ShellExecute wants a HMODULE...
Code:
HMODULE hWnd;
//HWND hWnd;
hWnd = ShellExecute(NULL,"open","Notepad.exe",NULL,NULL,SW_MAXIMIZE);
//SendMessage(hWnd,WM_SETTEXT, 0, 0);
I just want to use SendMessage to "type" text on notepad.
-
February 1st, 2009, 10:47 PM
#2
Re: SendMessage Problem
I honestly don't know how you're going to make that code work. But anyway, here is another way to accomplish your task
Code:
#include <windows.h>
#include <stdio.h>
#define KEYEVENTF_UNICODE 0x0004
static void SendString(LPCTSTR str)
{
INPUT inp[2];
memset(inp,0,sizeof(INPUT));
inp[0].type = INPUT_KEYBOARD;
inp[0].ki.dwFlags = KEYEVENTF_UNICODE;
inp[1] = inp[0];
inp[1].ki.dwFlags |= KEYEVENTF_KEYUP;
for (LPCTSTR p=str; *p; p++) {
inp[0].ki.wScan = inp[1].ki.wScan = *p;
SendInput(2, inp, sizeof(INPUT));
}
}
int main(void)
{
HWND hWndMain = FindWindow(0, "test - Notepad");
if(hWndMain == NULL)
{
printf("Main window not found, terminating\n");
return -1;
}
HWND hWndChild = GetWindow(hWndMain,GW_CHILD);
if(hWndChild == NULL)
{
printf("Child window not found\n");
return -1;
}
SetForegroundWindow(hWndChild);
Sleep(1000);
SendString("Testing Testing Testing");
return 0;
}
Just open a text file in notepad entitled test.txt and execute the example.
-
February 1st, 2009, 11:30 PM
#3
Re: SendMessage Problem
You can use ShellExecute or ShellExecuteEx to launch the Notepad, then you can use FindWindow with the class name "Notepad":
Code:
ShellExecute(NULL,"open","Notepad.exe",NULL,NULL,SW_MAXIMIZE);
HWND hNotePad = FindWindow("Notepad", NULL);
You might have to wait a few milliseconds or so while notepad starts up to get the handle, you can just use the Sleep() function.
-
February 2nd, 2009, 05:00 AM
#4
Re: SendMessage Problem
- The value returned by ShellExecute can only be used to see if the function succeeds or fails.
MSDN
Returns a value greater than 32 if successful, or an error value that is less than or equal to 32 otherwise. The following table lists the error values. The return value is cast as an HINSTANCE for backward compatibility with 16-bit Windows applications. It is not a true HINSTANCE, however. The only thing that can be done with the returned HINSTANCE is to cast it to an int and compare it with the value 32 or one of the error codes below[...]
- The same think can be sayd about SHELLEXECUTEINFO::hInstApp retrieved by ShellExecuteEx. So, after launch an application using ShellExecute or ShellExecuteEx we lose the control on it.
- FindWindow is not the better approach because it's possible to have more (Notepad) application main windows with the same class name and text (e.g. "Notepad" and "Untitled - Notepad").
- Using Sleep it's also a not very good idea because we cannot know how long it takes to launch that application.
It's better to launch the application using CreateProcess. It takes an argument of type LPPROCESS_INFORMATION which in turn will give info about newly created process and its primary thread.
Further we can use these info to wait the until the application becomes active and get the main window handle.
For details and an example see this thread http://www.codeguru.com/forum/showth...90#post1801590
-
February 2nd, 2009, 05:11 AM
#5
-
February 2nd, 2009, 10:03 PM
#6
Re: SendMessage Problem
I tried the CreateProcess method and the only way I could get it to work reliably was to put a delay in between the CreateProcess call and the window enumeration proc. Otherwise, the window enumeration proc will never identify the target window.
Code:
#include <windows.h>
#include <stdio.h>
BOOL CALLBACK EnumProc(HWND hwnd,LPARAM lParam);
int main(void)
{
STARTUPINFO siStartupInfo;
PROCESS_INFORMATION piProcessInfo;
memset(&siStartupInfo, 0, sizeof(siStartupInfo));
memset(&piProcessInfo, 0, sizeof(piProcessInfo));
if(CreateProcess("c:\\windows\\notepad.exe",
"C:\\temp\\test.txt",
0,
0,
FALSE,
CREATE_DEFAULT_ERROR_MODE,
0,
0,
&siStartupInfo,
&piProcessInfo) == FALSE)
return 0;
if (WaitForInputIdle( piProcessInfo.hProcess, INFINITE ) == WAIT_FAILED )
printf("Console process\n");
else
printf("GUI process\n");
// Sleep(5000);
EnumWindows((WNDENUMPROC) EnumProc,NULL);
return 0;
}
BOOL CALLBACK EnumProc(HWND hwnd,LPARAM lParam)
{
char szBuff[MAX_PATH+1];
if(GetWindowText(hwnd,szBuff,MAX_PATH+1) <= 0)
printf("No window title\n");
else
printf("%s\n", szBuff);
return TRUE;
}
-
February 3rd, 2009, 12:03 PM
#7
Re: SendMessage Problem
Thats because CreateProcess just immediately returns, so the window isn't fully created yet when you call FindWindow.
If you look at CreateProcess on MSDN it stats in the 'Remarks' section that you can use WaitForIdleInput to wait until the process has completed loading.
-
February 5th, 2009, 04:30 AM
#8
Re: SendMessage Problem
Originally Posted by Notsosuperhero
If you look at CreateProcess on MSDN it stats in the 'Remarks' section that you can use WaitForIdleInput to wait until the process has completed loading.
Well, there are points to contemplate on:
1. The "launcher" application typically must be aware of regular "launchee" behavior.
2. The launcher has its own reasons for monitoring launchee window creation, and the reasons may vary from case to case.
3. Both applications may behave rather complex ways, so launcher must adapt itself as good as possible unless launchee was intentionally designed to communicate with launcher.
This gives us an idea that waiting for launchee idle input may be not acceptable for launcher (as long as the latter may want to communicate long before initialization finishes), and some other window-creation detection mechanism has to be used, like WH_CBT hook or something.
Well, the main idea of my speach is that such situation may have a number of solutions more than one, depending on particular requirements.
Last edited by Igor Vartanov; February 5th, 2009 at 04:40 AM.
Best regards,
Igor
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|