It is impossible to use SetThreadDesktop and the VCL at the same time because a thread can only show windows on one desktop at a time. However VCL is not written for the use with multiple threads, so there is no way to show Delphi forms of same process on two different desktops. SetThreadDesktop describes this issue as followed.
The SetThreadDesktop function will fail if the calling thread has any windows or hooks on its current desktop (unless the hDesktop parameter is a handle to the current desktop).
Though there is a workaround to make VCL work with SetThreadDesktop and SwitchDesktop. The Application variable defined in unit Forms must be freed and then renewed. Here is the correct order :
…follow the same way as described to get back to the original desktop and forms (in this order!). However this has to be done in the main project file (DPR) (except you’re going to source it out) because you cannot just free Application in the event method of a button click. You have to shutdown your application (not your process) and continue right after :
In this way the process does not shut down and you can use VCL on one desktop at a time.
A second possibility is to use VCL on one desktop and NonVCL on the other. However in this way you have to create a new thread and use your own message loop (located in the new thread). Then you can call SetThreadDesktop in this thread and show the NonVCL windows.
A third possibility is to execute another or the same application with CreateProcess. This function allows you to specify the target desktop name for the new process in lpDesktop of the TProcessInformation structure.
ProcInfo : TProcessInformation;
StartupInfo.cb := SizeOf(StartupInfo);
StartupInfo.lpDesktop := ‘winsta0\default’;
‘appname.exe’,//__in_opt LPCTSTR lpApplicationName,
nil,//__inout_opt LPTSTR lpCommandLine,
nil,//__in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes,
nil,//__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
true,//__in BOOL bInheritHandles,
CREATE_NEW_CONSOLE,//__in DWORD dwCreationFlags,
nil,//__in_opt LPVOID lpEnvironment,
nil,//__in_opt LPCTSTR lpCurrentDirectory,
StartInfo,//__in LPSTARTUPINFO lpStartupInfo,
ProcInfo,//__out LPPROCESS_INFORMATION lpProcessInformation