程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C語言實現的虛擬桌面程序代碼

C語言實現的虛擬桌面程序代碼

編輯:關於C語言

虛擬一個桌面,然後在虛擬桌面啟動explorer進程,用戶可以用"ALT+Q"來切換現有桌面與這個虛擬桌面,用戶需要運行什麼軟件,自己在虛擬桌面打開就是了。原理很簡單,實現同樣也很簡單,下面是代碼:

#include<afxwin.h>
HINSTANCE hInst; //當前實例
TCHAR szAppName[] = TEXT ("VirtualDesk") ; //程序名稱
HWND  hwnd ; //主窗體句柄
HDESK hVirtualDesk; //虛擬桌面句柄
HDESK hCurrent; //當前桌面句柄
PROCESS_INFORMATION piExplor; //Explorer進程的PROCESS_INFORMATION結構
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
//每次運行首先檢測注冊表相關項,如果未發現,則設置開機自動運行
void SetStartup(HINSTANCE hInst)
{
    HKEY hKey;
    DWORD DataType = REG_SZ;
    PCSTR data_run = "Software\Microsoft\Windows\CurrentVersion\Run";
    long ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,data_run,0,KEY_ALL_ACCESS,&hKey);
    if(ret != ERROR_SUCCESS)
    {
        MessageBox(NULL,"無法打開注冊表鍵","Error",0);
        return;
    }
    CString ProcessName;
    int len = GetModuleFileName(hInst,ProcessName.GetBuffer(256),256);
      if(len == 0)
    {
        MessageBox(NULL,"無法獲取進程的當前目錄","Error",0);
          return;
      }
    ProcessName.ReleaseBuffer(len);
      DWORD direcLen = ProcessName.GetLength() + 1;
      LPBYTE direc = new BYTE[direcLen];
    ZeroMemory(direc,direcLen);
      ret = RegQueryValueEx(hKey,"VirtualDesk",0,0,direc,&direcLen);
        //如果鍵不存在或者鍵長度與目前的值長度不匹配則添加新鍵
      if((ret != ERROR_SUCCESS )|| (direcLen != ProcessName.GetLength()+1))
    {
SetValue:
          DWORD KeyLength = ProcessName.GetLength() + 1;
          LPBYTE KeyValue = new BYTE[KeyLength];
          ZeroMemory(KeyValue,KeyLength);
          for(int i=0;i<ProcessName.GetLength();i++)
              KeyValue[i] = ProcessName[i];
          KeyValue[ProcessName.GetLength()] = 0;
          ret = RegSetValueEx(hKey,"VirtualDesk",0,REG_SZ,KeyValue,KeyLength);
          delete []KeyValue;
      }
      else
    {
        //如果鍵的內容與當前值不匹配同樣進行更改
        for(int i=0;i<ProcessName.GetLength();i++)
       {
            if(direc[i] != ProcessName[i])
                goto SetValue;
        }
    }
    delete []direc;
    return;
}
//創建explorer進程的函數,如果創建了一個虛擬桌面,那麼最好調用該函數

void StartExplorer()
{
    STARTUPINFO si;
    ZeroMemory( &si, sizeof(si) );
    si.cb = sizeof(si);
    si.lpDesktop = "Virtual";
    ZeroMemory( &piExplor, sizeof(piExplor) );
    if( !CreateProcess( NULL,                    // No module name (use command line).

    "explorer",                                       // Command line.
    NULL,                       // Process handle not inheritable.
    NULL,                       // Thread handle not inheritable.
    FALSE,                      // Set handle inheritance to FALSE.
    0,                      // No creation flags.
    NULL,                       // Use parent's environment block.
    NULL,                       // Use parent's starting directory.
    &si,                        // Pointer to STARTUPINFO structure.
    &piExplor )                     // Pointer to PROCESS_INFORMATION structure.
    )
    {
        MessageBox(NULL,"無法初始化Explorer","Error",0);
        ExitProcess(1);
    }
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = (WNDPROC)WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(hInstance, (LPCTSTR)IDI_APPLICATION);
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = NULL;
    wcex.lpszClassName  = szAppName;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_APPLICATION);
    return RegisterClassEx(&wcex);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   hInst = hInstance; // 將實例句柄存儲在全局變量中
   hwnd = CreateWindow(szAppName, TEXT ("SunBear"), WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInst, NULL);
   if (!hwnd)
   {
      return FALSE;
   }
   return TRUE;
}
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,PSTR szCmdLine, int iCmdShow)
{
    static TCHAR szAppName[] = TEXT ("SunBear") ;
    MSG          msg ;
    SetStartup(hInstance);
    hVirtualDesk = CreateDesktop(
            "Virtual",
            NULL,
            NULL,
            DF_ALLOWOTHERACCOUNTHOOK,
              GENERIC_ALL,
            NULL);
    hCurrent = GetThreadDesktop(GetCurrentThreadId());
    MyRegisterClass(hInstance);
    if (!InitInstance (hInstance, iCmdShow))
    {
        return FALSE;
    }
    StartExplorer(); //啟動Explorer進程
    if(!RegisterHotKey(hwnd, 0x0001,MOD_ALT ,'Q'))
    {
        //處理切換虛擬桌面
        return TRUE;
    }
    if(!RegisterHotKey(hwnd, 0x0002, 0,VK_F8))
    {
        //處理退出進程
        return TRUE;
    }
     while (GetMessage (&msg, NULL, 0, 0))
     {
          TranslateMessage (&msg) ;
          DispatchMessage (&msg) ;
     }
     return 0;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     HDC         hdc ;
     PAINTSTRUCT ps ;
     static HDESK hNow = hCurrent;
     switch (message)
     {
     case WM_PAINT:
            hdc = BeginPaint (hwnd, &ps) ;
            EndPaint (hwnd, &ps) ;
            return 0 ;
     case WM_DESTROY:
            //在關閉虛擬桌面前要切換回當前桌面
            SwitchDesktop(hCurrent);
            PostQuitMessage (0) ;
            return 0 ;
     case WM_HOTKEY:
            if(0x0001 == wParam)
            {
                if(hNow == hCurrent)
                {
                    SwitchDesktop(hVirtualDesk);
                    hNow = hVirtualDesk;
                }
                else
                {
                    SwitchDesktop(hCurrent);
                    hNow = hCurrent;
                }
            }
            if(0x0002 == wParam)
            {
                  //用TerminateProcess終止explorer進程的時候,如果傳遞第二個參數為1
                //那麼操作系統不會在終止後自動喚醒explorer,如果為0,會重新啟動
                //explorer
                TerminateProcess(piExplor.hProcess,1);
                //關閉虛擬桌面
                CloseDesktop(hVirtualDesk);
                SendMessage(hwnd,WM_CLOSE,0,0);
            }
            return 0;
     }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
}

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,PSTR szCmdLine, int iCmdShow)
{
    static TCHAR szAppName[] = TEXT ("SunBear") ;
    MSG          msg ;
    SetStartup(hInstance);
    hVirtualDesk = CreateDesktop(
            "Virtual",
            NULL,
            NULL,
            DF_ALLOWOTHERACCOUNTHOOK,
              GENERIC_ALL,
            NULL);
    hCurrent = GetThreadDesktop(GetCurrentThreadId());
    MyRegisterClass(hInstance);
    if (!InitInstance (hInstance, iCmdShow))
    {
        return FALSE;
    }
    StartExplorer(); //啟動Explorer進程
    if(!RegisterHotKey(hwnd, 0x0001,MOD_ALT ,'Q'))
    {
        //處理切換虛擬桌面
        return TRUE;
    }
    if(!RegisterHotKey(hwnd, 0x0002, 0,VK_F8))
    {
        //處理退出進程
        return TRUE;
    }
     while (GetMessage (&msg, NULL, 0, 0))
     {
          TranslateMessage (&msg) ;
          DispatchMessage (&msg) ;
     }
     return 0;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     HDC         hdc ;
     PAINTSTRUCT ps ;
     static HDESK hNow = hCurrent;
     switch (message)
     {
     case WM_PAINT:
            hdc = BeginPaint (hwnd, &ps) ;
            EndPaint (hwnd, &ps) ;
            return 0 ;
     case WM_DESTROY:
            //在關閉虛擬桌面前要切換回當前桌面
            SwitchDesktop(hCurrent);
            PostQuitMessage (0) ;
            return 0 ;
     case WM_HOTKEY:
            if(0x0001 == wParam)
            {
                if(hNow == hCurrent)
                {
                    SwitchDesktop(hVirtualDesk);
                    hNow = hVirtualDesk;
                }
                else
                {
                    SwitchDesktop(hCurrent);
                    hNow = hCurrent;
                }
            }
            if(0x0002 == wParam)
            {
                  //用TerminateProcess終止explorer進程的時候,如果傳遞第二個參數為1
                //那麼操作系統不會在終止後自動喚醒explorer,如果為0,會重新啟動
                //explorer
                TerminateProcess(piExplor.hProcess,1);
                //關閉虛擬桌面
                CloseDesktop(hVirtualDesk);
                SendMessage(hwnd,WM_CLOSE,0,0);
            }
            return 0;
     }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved