简体   繁体   中英

Why does MessageBox show the window in my created desktop, but AllocConsole show it in the previous?

When a thread is changed to a different desktop new consoles created with AllocConsole() appear in the original desktop. Message boxes and other windows created appear in the new desktop as would be expected, but console windows do not. The following code is a windows application example, however it still the result is the same whether or not it is a console application.

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

How can I make the console window be created in the second desktop?

This behavior is understandable because the one console attached to a process is shared by all threads of that process and it makes sense to put that console on the desktop on which the process was launched rather than dynamically moving the console from desktop to desktop as consoles are allocated and freed by threads that are attached to different desktops. And if such movement of console window is allowed the behavior would be tougher to understand when consoles are shared between processes.

To answer the question on how to associate with a console on a different desktop, I would suggest starting a blank console application window on the target desktop, whose primary responsibility would be to just keep the console window alive. All is has to do is do as

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM