8

我已经评论了我所知道的大部分内容。我相当有信心这个问题出现在 AttachThreadInput。我认为它仅设计为在 32 位下运行。相信我,如果我能自己解决这个问题,我会很高兴。我阅读了 Windows 中事件的完整文档(此处),但我离解决方案还差得远。如果您有任何想法,我很想听听。

#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);
}
4

1 回答 1

6

GetWindowThreadProcessId 接收一个窗口句柄作为输入。您正在传递一个完全不同的节拍的进程句柄。这自然会导致失败。随后对 SetFocus、SetForegroundWindow、PostMessage 和 SetWindowPos 的调用犯了同样的错误。

使用 EnumWindows 或 FindWindow 来获取记事本窗口句柄。

AttachThreadInput 使用线程 ID 进行操作。您尝试将句柄传递给函数,在 64 位进程中,句柄为 64 位宽,线程 ID 仍为 32 位宽。当然, AttachThreadInput 在 64 位下工作得很好。这里要吸取的教训是强制转换表示编程错误。如果您需要将参数转换为适当的类型,那么通常这意味着您将错误的东西传递给函数。避免铸造。

于 2012-06-06T08:19:12.397 回答