1

当线程更改为不同的桌面时,使用 AllocConsole() 创建的新控制台会出现在原始桌面中。如预期的那样,创建的消息框和其他窗口会出现在新桌面中,但控制台窗口不会。以下代码是一个 windows 应用程序示例,但是无论它是否是控制台应用程序,结果仍然是相同的。

#include <Windows.h>

HDESK hDesk;

DWORD WINAPI Testing(void *)
{
    SetThreadDesktop(hDesk);
    AllocConsole();
    MessageBox(NULL, TEXT("Test"), NULL, MB_OK); //This will show on the new desktop
    FreeConsole();
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    hDesk=CreateDesktop(TEXT("Testing"),NULL,NULL,NULL,GENERIC_ALL,NULL);
    SwitchDesktop(hDesk);

    DWORD thr;
    HANDLE thread = CreateThread (0, 0, Testing, 0, 0, &thr);

    WaitForSingleObject (thread, 10000); //Wait 10 seconds before automatically exiting.

    SwitchDesktop(GetThreadDesktop(GetCurrentThreadId())); //Return to previous desktop
    CloseDesktop(hDesk);
    return 0;
}

如何在第二个桌面中创建控制台窗口?

4

1 回答 1

2

这种行为是可以理解的,因为附加到进程的一个控制台由该进程的所有线程共享,并且将该控制台放在启动该进程的桌面上而不是像控制台那样动态地将控制台从桌面移动到桌面是有意义的由连接到不同桌面的线程分配和释放。如果允许控制台窗口的这种移动,那么当控制台在进程之间共享时,行为将更难理解。

要回答有关如何与不同桌面上的控制台关联的问题,我建议在目标桌面上启动一个空白控制台应用程序窗口,其主要职责是保持控制台窗口处于活动状态。所要做的就是做

int _tmain(int argc, _TCHAR* argv[])
{
Sleep(INFINITE);
return 0;
}

And instead of calling AllocConsole, call AttachConsole with the process id of the newly launched process, and then call GetStdHandle to get handle to the console buffer for further calls to WriteConsole.

To launch a new process in a target desktop different from the one the process (at first) is connected to you will have to set the desktop name in the STARTUPINFO structure that would be passed to CreateProcess call.

于 2012-11-15T06:13:37.003 回答