2012-06-06 4 views
7

나는 내가 아는 대부분의 것에 댓글을 달았다. 나는이 문제가 AttachThreadInput에서 발생한다고 확신한다. 32 비트에서 작동하도록 설계된 것 같습니다. 저를 믿어주십시오. 제가 이것을 스스로 해결할 수 있다면 행복 할 것입니다. Windows (here)의 이벤트에 대한 전체 설명서를 읽었으며 솔루션에 더 가깝지 않습니다. 당신이 어떤 아이디어라도 가지고 있다면 나는 그걸 듣고 싶어합니다.C - win32 : AttachThreadInput & SetFocus, 64 비트 : 단서 없음

#include <stdio.h> 
#include <windows.h> 

int main() 
{ 
    //Structure prereqs for CreateProcess 
    STARTUPINFO   siStartupInfo; 
    PROCESS_INFORMATION piProcessInfo; 
    memset(&siStartupInfo, 0, sizeof(siStartupInfo)); 
    memset(&piProcessInfo, 0, sizeof(piProcessInfo)); 
    siStartupInfo.cb = sizeof(siStartupInfo); 

    if(CreateProcess("c:\\windows\\notepad.exe", "", 0, 0, FALSE, CREATE_DEFAULT_ERROR_MODE, 0, 0, &siStartupInfo, &piProcessInfo) == FALSE) 
    { 
     GetLastError(); 
    } 
    Sleep(1000); 

    //Target thread, I can't seem to get this to return anything !0 
    DWORD dwTargetThread = GetWindowThreadProcessId(piProcessInfo.hProcess,NULL); 
    //For example: 
    //if(dwTargetThread == 0) return -1; 

    //Print debugging info 
    if (GetCurrentThreadId() == dwTargetThread) return -1; else printf("\nMy thread: %u\n\npiProcessInfo.hThread: %u\n\nDWORD dwTargetThread: %u\n\nunsigned int dwTargetThread: %u", GetCurrentThreadId(), piProcessInfo.hThread,dwTargetThread, GetWindowThreadProcessId(piProcessInfo.hProcess,NULL)); 

    //I've tried using piProcessInfo.hThread for AttachTo but I can't cast it to a DWORD as it's 64bit 
    AttachThreadInput(GetCurrentThreadId(),dwTargetThread,TRUE); 
    printf("\n\nAttached...\n"); 
    Sleep(1000); 

    //Set the focus & bring to foreground 
    SetFocus(piProcessInfo.hProcess); 
    printf("Focus set...\n"); 
    Sleep(1000); 
    SetForegroundWindow(piProcessInfo.hProcess); 
    printf("Brought to foreground...\n"); 
    Sleep(1000); 

    //I know I shouldn't use PostMessage for keyboard input but it's just for the example 
    PostMessage(piProcessInfo.hProcess, WM_CHAR, 'g', 0); 
    printf("Message queued\n"); 

    //No better than SetForegroundWindow: 
    //SetWindowPos(piProcessInfo.hProcess, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); 
} 
+0

'CreateProcess()'호출이 성공적입니까? 모든것이 이것에 달려 있고 코드는 ('GetLastError()'호출과 별개로 같은 방식으로 수행됩니다. – MatthewD

+0

'GetWindowThreadProcessId()'를 호출 한 후'GetLastError()'는 무엇을 반환합니까? 이 페이지의 아래쪽 주석을보십시오. http://msdn.microsoft.com/en-us/library/windows/desktop/ms633522%28v=vs.85%29.aspx – MatthewD

+0

예,'CreateProcess()'가 성공했습니다. 수동으로 메모장을 포 그라운드로 가져 오면 메모장이 완벽하게 열리고 SendInput 함수가 열립니다. 'GetLastError()'는'GetWindowThreadProcessId (piProcessInfo.hProcess, NULL); '뒤에 null을 반환합니다. – John

답변

6

GetWindowThreadProcessId는 입력 창 핸들을받습니다. 완전히 다른 비트 인 프로세스 핸들을 전달 중입니다. 당연히 이것은 실패로 끝납니다. SetFocus, SetForegroundWindow, PostMessage 및 SetWindowPos에 대한 후속 호출은 동일한 실수를 범합니다.

EnumWindows 또는 FindWindow를 사용하여 메모장 창 핸들을 확보하십시오.

AttachThreadInput은 스레드 ID로 작동합니다. 당신은 함수에 핸들을 넘기려고 노력했으며 64 비트 프로세스 핸들은 64 비트 폭이고 스레드 ID는 여전히 32 비트입니다. 물론 AttachThreadInput은 64 비트에서 완벽하게 작동합니다. 여기서 배우는 교훈은 프로그래밍 오류를 나타내는 것입니다. 매개 변수를 적절한 유형으로 변환해야하는 경우 일반적으로 함수에 잘못된 것을 전달하고 있음을 의미합니다. 전송하지 마십시오.

+0

정말 고마워요! 'HANDLE hTargetWindow = FindWindow (NULL, "제목 없음 - 메모장");' 이제 GetWindowThreadProcessId (hTargetWindow, NULL);는 아름답게 작동합니다. – John

+0

올바른 유형은 HAND 대신 HWND입니다. SetForegroundWindow에는 해당 설명서에 설명 된 제한 사항이 있습니다. 나는 당신이 물어 본 질문에 대답했다고 생각합니다. –

+0

즉시 게시 한 후 설명서를 확인한 후 지금 작업하고 있습니다. 여러분의 도움과 HANDLE/HWND 교정에 다시 한번 감사드립니다! – John