为什么MessageBox在我创建的桌面中显示窗口,但AllocConsole在之前显示它?

时间:2012-11-15 03:58:23

标签: c++ winapi console

当线程更改为其他桌面时,使用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;
}

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

1 个答案:

答案 0 :(得分:2)

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

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

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

而不是调用AllocConsole,使用新启动的进程的进程ID调用AttachConsole,然后调用GetStdHandle来获取控制台缓冲区的句柄以进一步调用WriteConsole。

要在目标桌面上启动一个新进程,该进程与进程(首先)连接的进程不同,您必须在STARTUPINFO结构中设置将传递给CreateProcess调用的桌面名称。