建立一個簡易的虛擬桌面
阿新 • • 發佈:2019-01-06
文字性的描述留到後續文章再交代,還是先放一個小小的'大招',畢竟眼鏡看見的東西,比起抽象的東西,更能引起初學者的注意,
如果你對這個感興趣的話,這裡有個連結,你可以去看看,
1.用vs2013建立一個空專案,新增一個cpp檔案,
#include<windows.h> TCHAR szAppName[] = TEXT("TEST"); //視窗類名 #define DESTOP_NAME TEXT("MY_DESTOP") //定義我要建立的桌面名稱 ATOM m_HotKeyId1; //用於註冊ctrl+shift+F6 ,切換到原來的活動桌面 ATOM m_HotKeyId2; //用於註冊ctrl+shift+F7 ,將活動桌面切換到我們新建立的桌面, ATOM m_HotKeyId3; //用於正確退出程式,因為程式沒有相應介面且需要釋放一些資源 HDESK hDDesk; HWINSTA hWinStaThisProcess = GetProcessWindowStation( ); //程式執行起來,獲取系統為該程序設定的預設互動工作站 HDESK hDeskOriignInput = OpenInputDesktop(0,FALSE,GENERIC_ALL); //程式執行起來,獲取系統為該執行緒設定的預設活動桌面 void OnHotKey(WPARAM wParam,LPARAM lParam) { static LRESULT lRes = 0; if(wParam == m_HotKeyId1)//熱鍵1被按下 { // 該熱鍵按下時的處理 SwitchDesktop(hDeskOriignInput); //原活動桌面被顯現出來 //MessageBox(0,TEXT("F6"),0,0); } else if(wParam == m_HotKeyId2)//熱鍵2被按下 { SwitchDesktop(hDDesk); //我們建立的桌面顯現出來 //MessageBox(0,TEXT("F7"),0,0); } else if(wParam == m_HotKeyId3)//熱鍵2被按下 { MessageBox(0,TEXT("程式退出"),0,0); PostQuitMessage(0); //我們建立的桌面顯現出來 //MessageBox(0,TEXT("F7"),0,0); } return ; } LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) { switch(message) { case WM_HOTKEY: OnHotKey(wParam,lParam); return 0; } return DefWindowProc(hwnd,message,wParam,lParam); } int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow) { HWND hwnd; MSG msg; WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL,IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName; if(!RegisterClass(&wndclass)) { MessageBox(NULL,TEXT("視窗註冊失敗!"),NULL,0); return 0; } hwnd = CreateWindow( szAppName,szAppName, WS_OVERLAPPEDWINDOW, 0,0, 0,0, NULL,NULL,hInstance,NULL ); <span style="white-space:pre"> </span>//在程序 預設的互動式工作站中建立 桌面, hDDesk = CreateDesktop( DESTOP_NAME, 0,0,0, GENERIC_ALL, NULL ); //設定與本執行緒相聯絡的桌面為 我們建立的桌面 SetThreadDesktop(hDDesk); //填寫STARTUPINFO 結構體資訊,注意與平常建立程序的不同,這裡有了lpDesktop選項的設定, STARTUPINFO sti = { sizeof(sti) }; sti.lpDesktop = DESTOP_NAME; PROCESS_INFORMATION pi = {0}; CreateProcess( TEXT("C:\\Windows\\explorer.exe"),NULL,NULL,NULL,TRUE,0,NULL,NULL,&sti,&pi ); /**************************************************************** 註冊3個熱鍵 ******************************************************************/ //在全域性原子表中新增一項字串得到id一個,這一項跟 CTRL +SHIFT+F6 有關 m_HotKeyId1 = GlobalAddAtomW(TEXT("HotKey1")) - 0xc000; //註冊得到的id與 熱鍵CTRL+SHIFT+F6 關聯起來 RegisterHotKey(hwnd,m_HotKeyId1,MOD_CONTROL | MOD_SHIFT,VK_F6); //在全域性原子表中新增一項字串得到id一個,這一項跟 CTRL +SHIFT+F7 有關 m_HotKeyId2 = GlobalAddAtomW(TEXT("HotKey2")) - 0xc000; //註冊得到的id與 熱鍵CTRL+SHIFT+F7 關聯起來 RegisterHotKey(hwnd,m_HotKeyId2,MOD_CONTROL | MOD_SHIFT,VK_F7); //在全域性原子表中新增一項字串得到id一個,這一項跟 F7 有關 m_HotKeyId3 = GlobalAddAtomW(TEXT("HotKey3")) - 0xc000; //註冊得到的id與 熱鍵F7 關聯起來 RegisterHotKey(hwnd,m_HotKeyId3,0,VK_F7); /********************************************************** ***********************************************************/ //視窗訊息迴圈 while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } //F7 熱鍵按下,即退出,順便清理資源 UnregisterHotKey(hwnd,m_HotKeyId1); GlobalDeleteAtom(m_HotKeyId1); UnregisterHotKey(hwnd,m_HotKeyId2); GlobalDeleteAtom(m_HotKeyId2); UnregisterHotKey(hwnd,m_HotKeyId3); GlobalDeleteAtom(m_HotKeyId3); CloseHandle(hDDesk); return msg.wParam; }
2.可能會遇見的問題,
2.1SwitchDesktop失敗,GetLastError () 返回 error_access_dinied 這個錯誤通常跟管理員許可權沒提權有關,但是這裡不是這樣的,
而是, 1.你建立的桌面不在互動工作站中,
在這之前你得知道 你的程式, 系統預設給其對應的程序 關聯到 一個 互動式工作站,
2.怎樣將建立的桌面跟工作站產生 包含的邏輯關係 呢?
通過 給程序SetProcessWinstation()關聯工作站 ,(這裡省略了這一步,因為我已經知道,程序和工作站的關聯關係了)
給執行緒SetThreadDesktop() 關聯桌面,這樣一來, 二者的關係是不是可以想象出有了聯絡了呢?
這裡的兩個函式忽略了引數,要是你有興趣的話可以看看下面msdn連結的解釋
該頁面給出的是一族windows api,這些api都比較好理解
2.2, 64位系統下,用vs2013 64位編譯的方式編譯,32位系統下,程式用32位編譯方式
2.3
STARTUPINFO sti = {
sizeof(sti)
};
sti.lpDesktop = DESTOP_NAME;
若是第一次啟動了這個程式的話,將會生成一個explorer.exe程序,此時若是在工作管理員中檢視,有2個explorer程序,若是關閉我們的程式,這個2explorer程序個不會受到
影響,當第二次執行我們的程式時,(未關機),會發現視窗2中的東西和之前一樣,沒有變化