Quantcast
Channel: Windows Forms General forum
Viewing all articles
Browse latest Browse all 12583

How to move a windows form to another virtual desktop

$
0
0
Hello,
I am running Windows XP, SP2. .Net framework 3.5, Visual Studio 2008. C# is the language of coding, but will do VB if needed.

I am trying to move a running application\process from one desktop to another virtual desktop. Both desktops are running on the same windows station. The application is a windows form application. I want to start this application, create a new virtual desktop and select a radio button that switches me to the newly created desktop. All of these work fine, however, I want to transfer the current running windows form over to the newly created desktop. I can start new processes on the new desktop easily, but I need to move\transfer my running application to the newly created desktop.

I have downloaded Dexpot, which is a virtual desktop program. This application allows me to move a program over to another desktop no problem. I want to emulate this program.
I have even created a simple windows app that shows a messagebox when the app opens and closes. I then moved this app to another desktop using Dexpot and I didn't see any messageboxes pop up on any of the desktops...so I know that it isn't closing the original app and then reopening it.
Any ideas on how to do it...i have been drowning in the MSDN for the last 3 days.  
Thanks in advance,
Wayne

PS when the form switches to the other desktop. I start a timer that automatically switches back to the original desktop after 15 seconds.  Before I did this, I was stuck in the other newly created desktop >:)

I have posted the code below. I would be glad to zip the project and send it as well if needed. Thanks again.

WindowDesktop Class

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;

namespace New_Desktop
{

    public class WindowDesktop : IDisposable
    {
        #region DLLs

        [DllImport("user32.dll", EntryPoint = "CloseDesktop", CharSet = CharSet.Unicode, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool CloseDesktop(IntPtr handle);
        
        [DllImport("user32.dll")]
        private static extern IntPtr CreateDesktop(string lpszDesktop, IntPtr lpszDevice, IntPtr pDevmode,
                                                   int dwFlags, long dwDesiredAccess, IntPtr lpsa);

        [DllImport("kernel32.dll")]
        private static extern bool CreateProcess(
            string lpApplicationName,
            string lpCommandLine,
            IntPtr lpProcessAttributes,
            IntPtr lpThreadAttributes,
            bool bInheritHandles,
            int dwCreationFlags,
            IntPtr lpEnvironment,
            string lpCurrentDirectory,
            ref STARTUPINFO lpStartupInfo,
            ref PROCESS_INFORMATION lpProcessInformation
            );

        [DllImport("user32.dll")]
        private static extern bool EnumDesktops(IntPtr hwinsta, EnumDesktopProc lpEnumFunc, IntPtr lParam);

        [DllImport("user32.dll")]
        private static extern bool EnumDesktopWindows(IntPtr hDesktop, EnumDesktopWindowsProc lpfn, IntPtr lParam);

        [DllImport("kernel32.dll")]
        public static extern int GetCurrentThreadId();

        [DllImport("kernel32.dll")]
        public static extern int GetLastError();

        [DllImport("user32.dll",SetLastError=true)]
        private static extern bool GetUserObjectInformation(IntPtr hObj, int nIndex, [Out] byte [] pvInfo, uint nLength, out uint lpnLengthNeeded);

        [DllImport("user32.dll")]
        private static extern IntPtr GetProcessWindowStation();

        [DllImport("user32.dll")]
        public static extern IntPtr GetThreadDesktop(int dwThreadId);

        [DllImport("user32.dll")]
        private static extern IntPtr OpenDesktop(string lpszDesktop, int dwFlags, bool fInherit, int dwDesiredAccess);

        [DllImport("user32.dll")]
        internal static extern IntPtr OpenInputDesktop(int dwFlags, bool fInherit, int dwDesiredAccess);

        [DllImport("User32", CharSet = CharSet.Auto, ExactSpelling = true)]
        internal static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndParent);

        [DllImport("User32.dll")]
        internal static extern bool SetProcessWindowStation(IntPtr hWinSta);

        [DllImport("user32.dll")]
        public static extern bool SetThreadDesktop(IntPtr hDesktop);

        [DllImport("user32.dll")]
        private static extern bool SwitchDesktop(IntPtr hDesktop);
        
        #endregion

        #region Enumerator
        [Flags]
        internal enum DESKTOP_ACCESS_MASK : uint
        {
            DESKTOP_NONE = 0,
            DESKTOP_READOBJECTS = 0x0001,
            DESKTOP_CREATEWINDOW = 0x0002,
            DESKTOP_CREATEMENU = 0x0004,
            DESKTOP_HOOKCONTROL = 0x0008,
            DESKTOP_JOURNALRECORD = 0x0010,
            DESKTOP_JOURNALPLAYBACK = 0x0020,
            DESKTOP_ENUMERATE = 0x0040,
            DESKTOP_WRITEOBJECTS = 0x0080,
            DESKTOP_SWITCHDESKTOP = 0x0100,

            GENERIC_ALL = (DESKTOP_READOBJECTS | DESKTOP_CREATEWINDOW | DESKTOP_CREATEMENU |
                            DESKTOP_HOOKCONTROL | DESKTOP_JOURNALRECORD | DESKTOP_JOURNALPLAYBACK |
                            DESKTOP_ENUMERATE | DESKTOP_WRITEOBJECTS | DESKTOP_SWITCHDESKTOP),
        }
        #endregion

        # region Struct

        [StructLayout(LayoutKind.Sequential)]
        private struct STARTUPINFO
        {
            public int cb;
            public string lpReserved;
            public string lpDesktop;
            public string lpTitle;
            public int dwX;
            public int dwY;
            public int dwXSize;
            public int dwYSize;
            public int dwXCountChars;
            public int dwYCountChars;
            public int dwFillAttribute;
            public int dwFlags;
            public short wShowWindow;
            public short cbReserved2;
            public IntPtr lpReserved2;
            public IntPtr hStdInput;
            public IntPtr hStdOutput;
            public IntPtr hStdError;
        }

        public struct PROCESS_INFORMATION
        {
            public long hProcess;
            public long hThread;
            public long dwProcessId;
            public long dwThreadId;
        }

        # endregion //End of Strcut

        #region Dispose
        public void Dispose()
        {
            SwitchToOrginal();
            ((IDisposable)this).Dispose();
        }

        /// <summary>
        /// Implemented Dispose method from IDisposable
        /// </summary>
        /// <param name="fDisposing"></param>
        protected virtual void Dispose(bool fDisposing)
        {
            if (fDisposing)
            {
                // free up resources
                //BspVariable1 = null;
                CloseDesktop(DesktopPtr);
            }
        }

        void IDisposable.Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this); //Suppress garbage collector
        }
        #endregion

        #region Variables

        private const int UOI_FLAGS = 1;
        private const int UOI_NAME = 2;
        private const int UOI_TYPE = 3;
        private const int UOI_USER_SID = 4;

        private const int NORMAL_PRIORITY_CLASS = 0x00000020;
        IntPtr _hOrigDesktop;
        public IntPtr DesktopPtr;
        private string _sMyDesk;
        public string DesktopName
        {
            get
            {
                return (_sMyDesk);
            }
            set
            {
                _sMyDesk = value;
            }
        }

        private static StringCollection _sc;

        #endregion

        #region Constructors
        public WindowDesktop()
        {
            _sMyDesk = string.Empty;
        }

        public WindowDesktop(string sDesktopName)
        {
            _hOrigDesktop = GetCurrentDesktopPtr();
            _sMyDesk = sDesktopName;
            DesktopPtr = CreateMyDesktop();
        }
        #endregion

        # region Delegates

        private delegate bool EnumDesktopProc(string lpszDesktop, IntPtr lParam);

        private delegate bool EnumDesktopWindowsProc(IntPtr desktopHandle, IntPtr lParam);

        # endregion

        #region Methods
        public void show()
        {
            SetThreadDesktop(DesktopPtr);
            SwitchDesktop(DesktopPtr);
        }

        public void SwitchToOrginal()
        {
            SwitchDesktop(_hOrigDesktop);
            SetThreadDesktop(_hOrigDesktop);
        }

        private IntPtr CreateMyDesktop()
        {
            return CreateDesktop(_sMyDesk, IntPtr.Zero, IntPtr.Zero, 0, (long)DESKTOP_ACCESS_MASK.GENERIC_ALL, IntPtr.Zero);
        }

        public bool CreateProcess(string path, string desktopName)
        {
            // start the process.
            STARTUPINFO si = new STARTUPINFO();
            si.lpDesktop = DesktopName;
            //int hCurrentThread = GetCurrentThreadId();
            //IntPtr ptr = GetThreadDesktop(GetCurrentThreadId());
            PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
            

            return CreateProcess(null, path, IntPtr.Zero, IntPtr.Zero, true, NORMAL_PRIORITY_CLASS, IntPtr.Zero, null, ref si, ref pi);
        }

        private static bool DesktopProc(string lpszDesktop, IntPtr lParam)
        {
            // add the desktop to the collection.
            _sc.Add(lpszDesktop);

            return true;
        }

        public IntPtr GetCurrentDesktopPtr()
        {
            return GetThreadDesktop(GetCurrentThreadId());
        }

        public static StringCollection GetDesktops()
        {
            //define and initialize local variables
            IntPtr windowStation = GetProcessWindowStation();

            //be sure the handle is valid
            if (windowStation == IntPtr.Zero)
            { return null; }

            // lock the object. thread safety and all.
            lock (_sc = new StringCollection())
            {
                bool result = EnumDesktops(windowStation, new EnumDesktopProc(DesktopProc), IntPtr.Zero);

                //something went wrong.
                if (!result)
                { return null; }
            }

            return _sc;
        }

        public static StringCollection GetDesktopWindows(WindowDesktop wd)
        { 
            //define and intialize local variables
            //be sure the handle is valid
            if (wd.DesktopPtr == IntPtr.Zero)
            {
                return null;
            }

            //lock the object thread safety and all
            lock (_sc = new StringCollection())
            {
                bool result = EnumDesktopWindows(wd.DesktopPtr, new EnumDesktopWindowsProc(WindowProc), IntPtr.Zero);

                //an error ocurred
                if (!result)
                {
                    return null;
                }
            }

            return _sc;
        }

        private static bool WindowProc(IntPtr desktopHandle, IntPtr lParam)
        {
            // add the desktop to the collection.
            _sc.Add(desktopHandle.ToString());

            return true;
        }

        #endregion

    }

}


Form1 Class

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace New_Desktop
{
    public partial class Form1 : Form
    {
        WindowDesktop _d = null;
        IntPtr _ptrDefaultDesktopThread;
        WindowDesktop _wdDefault = new WindowDesktop("Default");

        public Form1()
        {
            InitializeComponent();

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //enable Timer
            tmrSwitchToDesktop.Interval = 15000;

        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            try
            {
                //switches back to the default desktop
                //check to see if another desktop is created besides the original three: Logon, Default, and ???
                if (_d != null)
                {
                    //switch back to the default desktop
                    _d.SwitchToOrginal();
                    
                }

                this.Close();
            }
            //handle exceptions
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("Error: {0}", ex.Message), "Form Closing Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void btnNewDesktop_Click(object sender, EventArgs e)
        {
            //Click Event for the New Desktop Button
            try
            {
                //make a new desktop 
                _d = new WindowDesktop("myDesktop");

                //get all the desktops for this Window Station
                StringCollection scDesktops = WindowDesktop.GetDesktops();
                if (scDesktops != null && scDesktops.Count > 0)
                {
                    for (int i = 0; i < scDesktops.Count; i++)
                    {
                        lstDesktops.Items.Add(scDesktops[i]);

                        //get all the windows for the specified Desktop
                        StringCollection scWindows = WindowDesktop.GetDesktopWindows(_d);
                        if (scWindows != null && scWindows.Count > 0)
                        {
                            for (int j = 0; j < scWindows.Count; j++)
                            {
                                lstWindows.Items.Add(scWindows[j]);
                            }
                        }
                    }
                }
            }
            //handle exceptions
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("New Desktop Error: {0}", ex.Message),
                    "New Desktop Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        
        private void tmrSwitchToDesktop_Tick(object sender, EventArgs e)
        {
            //switch back to default desktop
            if (_d != null)
            {
                //switch to default desktop
                _d.SwitchToOrginal();

            }

            tmrSwitchToDesktop.Enabled = false;
        }

        private void radDefaultDesktop_CheckedChanged(object sender, EventArgs e)
        {
            try
            {
                if (_d != null)
                {
                    _d.SwitchToOrginal();
                }
            }
            //handle exceptions
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("Switch Default Desktop Error: {0}", ex.Message),
                    "Switch Default Desktop Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void radOtherDesktop_CheckedChanged(object sender, EventArgs e)
        {
            try
            {
                //make a new desktop 
                if (_d == null)
                {
                    _d = new WindowDesktop("myDesktop");

                    //create new process to run on the new desktop
                    _d.CreateProcess(@"C:\WINDOWS\system32\cmd.exe",_d.DesktopName);
                }

                if (_d != null)
                {
                    //move application back to original desktop
            //        _d.CreateProcess(Application.ExecutablePath, "myDesktop");

                    _d.show();
                    
                }

                //enable timer
                tmrSwitchToDesktop.Enabled = true;
            }
            //handle exceptions
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("Switch Other Desktop Error: {0}", ex.Message),
                    "Switch Other Desktop Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            //destroy created desktop
            if (_d != null)
            {
                WindowDesktop.CloseDesktop(_d.DesktopPtr);
            }
        }
    }
}

Wayne Keadle

Viewing all articles
Browse latest Browse all 12583

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>