CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8
  1. #1
    Join Date
    Jan 2009
    Posts
    4

    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.

  2. #2
    Join Date
    Apr 2004
    Posts
    102

    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.

  3. #3
    Join Date
    Dec 2003
    Location
    Syracuse, NY
    Posts
    400

    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.
    "Windows programming is like going to the dentist: You know it's good for you, but no one likes doing it."
    - Andre LaMothe

    DLL For Beginners(UPDATED)
    Please use CODE tags
    Rate me if I've helped.

  4. #4
    Join Date
    Feb 2003
    Location
    Iasi - Romania
    Posts
    8,234

    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
    Ovidiu
    "When in Rome, do as Romans do."
    My latest articles: https://codexpertro.wordpress.com/

  5. #5
    Join Date
    Jan 2009
    Posts
    4

    Re: SendMessage Problem

    Thank you all

  6. #6
    Join Date
    Apr 2004
    Posts
    102

    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;
    }

  7. #7
    Join Date
    Dec 2003
    Location
    Syracuse, NY
    Posts
    400

    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.
    "Windows programming is like going to the dentist: You know it's good for you, but no one likes doing it."
    - Andre LaMothe

    DLL For Beginners(UPDATED)
    Please use CODE tags
    Rate me if I've helped.

  8. #8
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: SendMessage Problem

    Quote Originally Posted by Notsosuperhero View Post
    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
  •  





Click Here to Expand Forum to Full Width

Featured