C-win32:AttachThreadInput&;SetFocus,64位:没有线索

C-win32:AttachThreadInput&;SetFocus,64位:没有线索,c,winapi,64-bit,setfocus,C,Winapi,64 Bit,Setfocus,我已经对我所知道的大部分内容发表了评论。我很有信心这个问题是在AttachThreadInput出现的。我想,它的设计只能在32位以下工作。相信我,如果我能自己解决这个问题,我会很高兴的。我阅读了Windows()中事件的完整文档,但还没有找到解决方案。如果你有什么想法,我很想听听 #include <stdio.h> #include <windows.h> int main() { //Structure prereqs for CreateProcess

我已经对我所知道的大部分内容发表了评论。我很有信心这个问题是在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);
}
#包括
#包括
int main()
{
//CreateProcess的结构预需求
STARTUPINFO-siStartupInfo;
进程信息piProcessInfo;
memset(&siStartupInfo,0,sizeof(siStartupInfo));
memset(&piProcessInfo,0,sizeof(piProcessInfo));
siStartupInfo.cb=sizeof(siStartupInfo);
如果(CreateProcess(“c:\\windows\\notepad.exe”、“”、0、0、FALSE、创建默认错误模式、0、0、&siStartupInfo、&piProcessInfo)==FALSE)
{
GetLastError();
}
睡眠(1000);
//目标线程,我似乎无法使其返回任何内容!0
DWORD dwTargetThread=GetWindowThreadProcessId(piProcessInfo.hProcess,NULL);
//例如:
//if(dwTargetThread==0)返回-1;
//打印调试信息
if(GetCurrentThreadId()==dwTargetThread)返回-1;else printf(“\n我的线程:%u\n\npiProcessInfo.hThread:%u\n\nWord dwTargetThread:%u\n\n未签名的int-dwTargetThread:%u”,GetCurrentThreadId(),piProcessInfo.hThread,dwTargetThread,GetWindowThreadProcessId(piProcessInfo.hProcess,NULL));
//我曾尝试将piProcessInfo.hThread用于AttachTo,但无法将其转换为DWORD,因为它是64位的
AttachThreadInput(GetCurrentThreadId(),dwTargetThread,TRUE);
printf(“\n\n附加…\n”);
睡眠(1000);
//设置焦点并将其置于前景
SetFocus(piProcessInfo.hProcess);
printf(“焦点集…\n”);
睡眠(1000);
SetForegroundWindow(piProcessInfo.hProcess);
printf(“带到前台…\n”);
睡眠(1000);
//我知道我不应该使用PostMessage进行键盘输入,但这只是一个例子
PostMessage(piProcessInfo.hProcess,WM_CHAR'g',0);
printf(“消息队列\n”);
//不比SetForegroundWindow更好:
//SetWindowPos(piProcessInfo.hProcess,HWND_最顶层,0,0,0,SWP_NOMOVE | SWP_NOSIZE);
}

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

使用EnumWindows或FindWidow获取记事本窗口句柄


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

您确定
CreateProcess()
调用成功吗?一切似乎都取决于这一点,您的代码在这两种情况下都会做同样的事情(除了调用
GetLastError()
之外)。在调用
GetWindowThreadProcessId()
之后,
GetLastError()
返回什么?请参阅本页底部的注释:是,
CreateProcess()
成功。记事本可以完美打开,如果我手动将其置于前台,则可以发送输入功能
GetLastError()
GetWindowThreadProcessId(piProcessInfo.hProcess,null)之后返回null非常感谢!我做对了:
HANDLE-hTargetWindow=FindWindow(NULL,“Untitled-Notepad”)
现在
GetWindowThreadProcessId(hTargetWindow,NULL)工作得很好。正确的类型是HWND而不是HANDLE。SetForeGroundIndow在其文档中精确描述了其局限性。我想我回答了你问的问题。在我发布后,我立即检查了文档,现在它正在工作。再次非常感谢您的帮助和处理/纠正!