2012-11-15 32 views
1

当一个线程更改为与AllocConsole()创建了一个不同的桌面新游戏机出现在原来的桌面。如预期的那样,创建的消息框和其他窗口显示在新桌面中,但控制台窗口不显示。下面的代码是一个Windows应用程序示例,但它的结果仍然是一样的,无论它是否是控制台应用程序。为什么MessageBox在我创建的桌面上显示窗口,但AllocConsole在前面显示它?

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

如何在第二个桌面创建控制台窗口?因为连接到进程的一个控制台通过该进程的所有线程共享,这是有道理的把那个控制台上的过程中推出,而不是动态地从桌面移动控制台在桌面上

+2

我怀疑的行为是因为控制台窗口创建和由[CSRSS.EXE]保持。而不是Windows控制台窗口,请考虑替代方法,如Console2或Cygwin中的方法。 –

+0

我怀疑这是因为控制台窗口与进程而不是与线程相关联。因此,如果您想更改创建控制台窗口的桌面,则必须设置主线程的桌面。它也可能与多个进程能够连接到单个控制台有关。 –

+0

设置主线程的桌面似乎不适用于我。 – chris

回答

2

这种行为是可以理解的作为控制台的桌面通过连接到不同桌面的线程分配和释放。如果允许控制台窗口的这种移动,那么当控制台在进程之间共享时,行为会更难理解。

为了回答关于如何使用控制台关联不同的桌面上的问题,我建议从目标台式机,其主要职责是将只保留控制台窗口活在一个空白的控制台应用程序窗口。所有这些都是需要做的就是做的

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

而不是调用AllocConsole,调用AttachConsole与新推出的进程的进程ID,然后调用GetStdHandle得到处理,为进一步呼吁WriteConsole控制台缓冲区。

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

+0

很奇怪...'dwProcessId'包含一个有效的PID,但'AllocConsole'失败什么的意思根据文件,这是不存在的过程。 – chris

+0

@chris您的意思是AttachConsole。可能是有效的PID在AttachConsole调用时没有控制台。 – nanda

+0

是的,我的意思是,谢谢。哦,嘿,'AttachConsole'前的一个'Sleep()'。我认为'????的输出Writ'只是我:P – chris

相关问题