背景:
以前寫過類似TurboLaunch的WPF版快捷方式管理軟件,加入了3D動(dòng)畫,還集成了虛擬桌面,但是因?yàn)楸容^忙,自出了第一個(gè)版本后就不了了之了,Bug多多,也懶得改了,后來就漸漸忘記了。不巧的是,今天有位朋友向我要拖入可執(zhí)行文件或者快捷方式生成縮略圖的代碼,才把它翻了出來,想想又好久沒寫B(tài)log了,所以就單獨(dú)拎出虛擬桌面這塊做了個(gè)小Demo,和大家分享下。說到這個(gè)虛擬桌面,還是當(dāng)時(shí)剛學(xué)C#那會(huì)在Winform下實(shí)現(xiàn)的,Oh,扯遠(yuǎn)了,進(jìn)入正題。
設(shè)計(jì)思路:·
虛擬桌面說白了就是將窗體分組進(jìn)行顯示,操作窗體的顯隱藏,每個(gè)虛擬桌面可以包含多個(gè)窗體,考試@大提示只顯示該虛擬桌面所包含的窗體。當(dāng)然,桌面和任務(wù)欄是共享的,即所有的虛擬桌面都共用一個(gè)桌面和任務(wù)欄。
下面列出用到的API
private static class API
{
Import API#region Import API
/**////
/// 注冊(cè)熱鍵
///
///
///
///
///
///
[DllImport("user32")]
public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint control, Keys vk);
/**////
/// 取消熱鍵
///
///
///
///
[DllImport("user32")]
public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
/**////
/// 該函數(shù)枚舉所有屏幕上的頂層窗口
///
///
///
///
[DllImport("user32")]
public static extern bool EnumWindows(CallBack lpEnumFunc, int lParam);
//[DllImport("user32")]
//public static extern string GetWindowText(IntPtr hWnd, IntPtr lpString, int nMaxCount);//取得一個(gè)窗體的標(biāo)題(caption)文字,或者一個(gè)控件的內(nèi)容
/**////
/// 在指定的設(shè)備場(chǎng)景中描繪桌面墻紙圖案
///
///
///
[DllImport("user32", EntryPoint = "PaintDesktop")]
public static extern int PaintDesktop(
int hdc
);
/**////
/// 該函數(shù)返回桌面窗口的句柄
///
///
[DllImport("user32")]
public static extern IntPtr GetDesktopWindow();
/**////
/// 判斷窗口是否可見
///
///
///
[DllImport("user32")]
public static extern int IsWindowVisible(IntPtr hWnd);
/**////
/// 獲取指定窗體句柄
///
///
///
///
[DllImport("user32")]
public static extern IntPtr FindWindow(string LpClassName, string LpWindowName);
/**////
/// 該函數(shù)獲得一個(gè)窗口的句柄,該窗口的類名和窗口名與給定的字符串相匹配。這個(gè)函數(shù)查找子窗口,從排在給定的子窗口后面的下一個(gè)子窗口開始。在查找時(shí)不區(qū)分大小寫。
///
///
///
///
///
///
[DllImport("user32")]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
/**////
/// 該函數(shù)設(shè)置指定窗口的顯示狀態(tài)
///
/// 目標(biāo)窗口句柄
/// 狀態(tài)參數(shù)
///
[DllImport("user32")]
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
//[DllImport("user32")]
//public static extern int GetClassName(IntPtr hWnd, string sClassName, int nMaxCount);
#endregion
}
主要使用ShowWindow函數(shù)來設(shè)置窗體的顯隱藏,其狀態(tài)參數(shù)定義(API說明里是有10個(gè)的,不過我只定義了4個(gè)比較常用的)如下
WindowAction
private enum WindowAction
{
///
/// 隱藏窗口并激活其他窗口
///
Hide = 0x00,
///
/// 在窗口原來的位置以原來的尺寸激活和顯示窗口
///
Show = 0x04,
///
/// 激活并顯示窗口。如果窗口最小化或化,則系統(tǒng)將窗口恢復(fù)到原來的尺寸和位置。在恢復(fù)最小化窗口時(shí),應(yīng)用程序應(yīng)該指定這個(gè)標(biāo)志。
///
Restore = 0x03,
///
/// 以窗口最近一次的大小和狀態(tài)顯示窗口。激活窗口仍然維持激活狀態(tài)。
///
ShowNoActivate = 0x08
}
在虛擬桌面間切換時(shí),先清空當(dāng)前窗體組(一個(gè)虛擬桌面對(duì)應(yīng)一個(gè)窗體組),接著枚舉所有窗體,保存狀態(tài)為非隱藏的窗體句柄至當(dāng)前窗體組,然后置該組所有窗體(除了桌面、任務(wù)欄和本虛擬軟件程序)狀態(tài)為WindowAction.Hide,然后置目標(biāo)窗體組內(nèi)所有窗體狀態(tài)為WindowAction.ShowNoActivate。
當(dāng)然,不要忘記了在程序退出事件中加入顯示所有窗體組中的窗體的代碼,否則非當(dāng)前組的窗體可就看不到了。
源代碼在VS2008下編譯通過 。
以前寫過類似TurboLaunch的WPF版快捷方式管理軟件,加入了3D動(dòng)畫,還集成了虛擬桌面,但是因?yàn)楸容^忙,自出了第一個(gè)版本后就不了了之了,Bug多多,也懶得改了,后來就漸漸忘記了。不巧的是,今天有位朋友向我要拖入可執(zhí)行文件或者快捷方式生成縮略圖的代碼,才把它翻了出來,想想又好久沒寫B(tài)log了,所以就單獨(dú)拎出虛擬桌面這塊做了個(gè)小Demo,和大家分享下。說到這個(gè)虛擬桌面,還是當(dāng)時(shí)剛學(xué)C#那會(huì)在Winform下實(shí)現(xiàn)的,Oh,扯遠(yuǎn)了,進(jìn)入正題。
設(shè)計(jì)思路:·
虛擬桌面說白了就是將窗體分組進(jìn)行顯示,操作窗體的顯隱藏,每個(gè)虛擬桌面可以包含多個(gè)窗體,考試@大提示只顯示該虛擬桌面所包含的窗體。當(dāng)然,桌面和任務(wù)欄是共享的,即所有的虛擬桌面都共用一個(gè)桌面和任務(wù)欄。
下面列出用到的API
private static class API
{
Import API#region Import API
/**////
/// 注冊(cè)熱鍵
///
///
///
///
///
///
[DllImport("user32")]
public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint control, Keys vk);
/**////
/// 取消熱鍵
///
///
///
///
[DllImport("user32")]
public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
/**////
/// 該函數(shù)枚舉所有屏幕上的頂層窗口
///
///
///
///
[DllImport("user32")]
public static extern bool EnumWindows(CallBack lpEnumFunc, int lParam);
//[DllImport("user32")]
//public static extern string GetWindowText(IntPtr hWnd, IntPtr lpString, int nMaxCount);//取得一個(gè)窗體的標(biāo)題(caption)文字,或者一個(gè)控件的內(nèi)容
/**////
/// 在指定的設(shè)備場(chǎng)景中描繪桌面墻紙圖案
///
///
///
[DllImport("user32", EntryPoint = "PaintDesktop")]
public static extern int PaintDesktop(
int hdc
);
/**////
/// 該函數(shù)返回桌面窗口的句柄
///
///
[DllImport("user32")]
public static extern IntPtr GetDesktopWindow();
/**////
/// 判斷窗口是否可見
///
///
///
[DllImport("user32")]
public static extern int IsWindowVisible(IntPtr hWnd);
/**////
/// 獲取指定窗體句柄
///
///
///
///
[DllImport("user32")]
public static extern IntPtr FindWindow(string LpClassName, string LpWindowName);
/**////
/// 該函數(shù)獲得一個(gè)窗口的句柄,該窗口的類名和窗口名與給定的字符串相匹配。這個(gè)函數(shù)查找子窗口,從排在給定的子窗口后面的下一個(gè)子窗口開始。在查找時(shí)不區(qū)分大小寫。
///
///
///
///
///
///
[DllImport("user32")]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
/**////
/// 該函數(shù)設(shè)置指定窗口的顯示狀態(tài)
///
/// 目標(biāo)窗口句柄
/// 狀態(tài)參數(shù)
///
[DllImport("user32")]
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
//[DllImport("user32")]
//public static extern int GetClassName(IntPtr hWnd, string sClassName, int nMaxCount);
#endregion
}
主要使用ShowWindow函數(shù)來設(shè)置窗體的顯隱藏,其狀態(tài)參數(shù)定義(API說明里是有10個(gè)的,不過我只定義了4個(gè)比較常用的)如下
WindowAction
private enum WindowAction
{
///
/// 隱藏窗口并激活其他窗口
///
Hide = 0x00,
///
/// 在窗口原來的位置以原來的尺寸激活和顯示窗口
///
Show = 0x04,
///
/// 激活并顯示窗口。如果窗口最小化或化,則系統(tǒng)將窗口恢復(fù)到原來的尺寸和位置。在恢復(fù)最小化窗口時(shí),應(yīng)用程序應(yīng)該指定這個(gè)標(biāo)志。
///
Restore = 0x03,
///
/// 以窗口最近一次的大小和狀態(tài)顯示窗口。激活窗口仍然維持激活狀態(tài)。
///
ShowNoActivate = 0x08
}
在虛擬桌面間切換時(shí),先清空當(dāng)前窗體組(一個(gè)虛擬桌面對(duì)應(yīng)一個(gè)窗體組),接著枚舉所有窗體,保存狀態(tài)為非隱藏的窗體句柄至當(dāng)前窗體組,然后置該組所有窗體(除了桌面、任務(wù)欄和本虛擬軟件程序)狀態(tài)為WindowAction.Hide,然后置目標(biāo)窗體組內(nèi)所有窗體狀態(tài)為WindowAction.ShowNoActivate。
當(dāng)然,不要忘記了在程序退出事件中加入顯示所有窗體組中的窗體的代碼,否則非當(dāng)前組的窗體可就看不到了。
源代碼在VS2008下編譯通過 。