博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MFC实现虚拟桌面(桌面切换)
阅读量:6089 次
发布时间:2019-06-20

本文共 4620 字,大约阅读时间需要 15 分钟。

博文来源:http://www.cnbolgs.com/ZzzZzz ,转载请注明出处

一直用桌面切换,总觉得程序退出后创建的explorer无法退出感到很不爽,就想DIY一个,结果网上找的不是VB(我是VB白痴)就是直接VC++API的,看到头疼不已,代码又是那么长(不要喷哦,我讨厌看团在一起的代码,这就是为什么我喜欢用MFC而不是Win32 WinApp的原因 囧TZ)。

程序截图(有图有真相):

下面开始贴上分析:(源码后面给出)

//定义

PROCESS_INFORMATION ProcessInfo;

STARTUPINFO StartupInfo;
HDESK hDesktop;
HDESK hOriginalThread;
HDESK hOriginalInput;

//核心代码:

//创建名称为“Virtual”的虚拟桌面

hDesktop = CreateDesktop("Virtual", NULL, NULL, 0, GENERIC_ALL , NULL);

//初始化创建进程必须的结构体

ZeroMemory(&StartupInfo, sizeof(StartupInfo));
ZeroMemory(&ProcessInfo, sizeof(ProcessInfo));
StartupInfo.cb = sizeof(StartupInfo);
StartupInfo.lpDesktop = "Virtual";

//记录原始桌面的句柄

hOriginalThread = GetThreadDesktop(GetCurrentThreadId());
hOriginalInput = OpenInputDesktop(0, FALSE, DESKTOP_SWITCHDESKTOP);

//创建桌面外壳进程

CreateProcess(NULL, "explorer", NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcessInfo);

//下面是桌面切换代码:

SetThreadDesktop(hDesktop); //设置桌面活动焦点是虚拟桌面

SwitchDesktop(hDesktop); //切换到虚拟桌面

 

SetThreadDesktop(hOriginalThread);

SwitchDesktop(hOriginalInput);
CloseDesktop(hDesktop); //关闭虚拟桌面

//核心代码就是这些,然后加入热键,设置程序切换时的特效什么的就自由添加好了

 

附上程序源代码:

//stdafx.h

//由于用到渐显渐隐的效果,需要加入AnimateWindow,由于VC6的限制,要在最上面加入

#undef WINVER

#define WINVER 0X500

 

//VitualDesktopDlg.h

public:

  PROCESS_INFORMATION ProcessInfo;
  STARTUPINFO StartupInfo;
  HDESK hDesktop;
  HDESK hOriginalThread;
  HDESK hOriginalInput;
  BOOL IsOriginalDesktopActive; //是否在原始桌面rz
  BOOL IsInitialDesktop; //是否初始化桌面,防止灰色按钮克星造成不可估计的后果
  BOOL IsWindowShow; //程序是否可见

protected:

  afx_msg LRESULT OnHotKey(WPARAM wParam, LPARAM lParam);//自定义热键消息

 

//VitualDesktopDlg.cpp

#include <WINUSER.H>

#pragma comment(lib, "user32.lib")  //这两个是AnimateWindow要的头和库

BEGIN_MESSAGE_MAP(CVitualDesktopDlg, CDialog)

//{
{AFX_MSG_MAP(CVitualDesktopDlg)
  ON_MESSAGE(WM_HOTKEY, OnHotKey) //链接热键消息
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

BOOL CVitualDesktopDlg::OnInitDialog()

{
  CDialog::OnInitDialog();
  ModifyStyleEx(WS_EX_APPWINDOW, WS_EX_TOOLWINDOW); //设置窗体样式为工具样式,这样任务栏就没有图标了

  SetIcon(m_hIcon, TRUE); // Set big icon

  SetIcon(m_hIcon, FALSE); // Set small icon
  IsOriginalDesktopActive = FALSE;
  IsInitialDesktop = TRUE;
  IsWindowShow = TRUE;
  RegisterHotKey(m_hWnd, 521, MOD_WIN, 'X'); //设置显示程序热键为 Win+X
  return TRUE; // return TRUE unless you set the focus to a control
}

void CVitualDesktopDlg::OnOK()

{
  if (IsInitialDesktop) //第一次运行时初始化程序,加上判断防止灰色按钮克星
  {
    //创建名称为“Virtual”的虚拟桌面
    hDesktop = CreateDesktop("Virtual", NULL, NULL, 0, GENERIC_ALL , NULL);

    //初始化创建进程必须的结构体

    ZeroMemory(&StartupInfo, sizeof(StartupInfo));
    ZeroMemory(&ProcessInfo, sizeof(ProcessInfo));
    StartupInfo.cb = sizeof(StartupInfo);
    StartupInfo.lpDesktop = "Virtual";

    //记录原始桌面的句柄

    hOriginalThread = GetThreadDesktop(GetCurrentThreadId());
    hOriginalInput = OpenInputDesktop(0, FALSE, DESKTOP_SWITCHDESKTOP);

    //创建桌面外壳进程

    CreateProcess(NULL, "explorer", NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcessInfo);

    //完成初始化,以后不会再次被调用,防止打开虚拟桌面出现资源管理器

    IsInitialDesktop = !IsInitialDesktop;

    SetThreadDesktop(hDesktop); //设置桌面活动焦点是虚拟桌面

    SwitchDesktop(hDesktop); //切换到虚拟桌面
    GetDlgItem(IDOK)->EnableWindow(FALSE); //设置初始化按钮失效,只允许热键操作
    RegisterHotKey(m_hWnd, 1314, MOD_ALT, 'Z'); //设置热键为 Alt+Z
  }

  return;

  CDialog::OnOK();
}

void CVitualDesktopDlg::OnClose()

{
  //注销热键
  UnregisterHotKey(m_hWnd, 1314);
  UnregisterHotKey(m_hWnd, 521);

  //关闭创建的explorer

  if (!IsInitialDesktop)
  {
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessInfo.dwProcessId); //获取虚拟桌面的explorer句柄
    if(hProcess)
    {
    TerminateProcess(hProcess, 1); //结束虚拟桌面的explorer
    }
    CloseHandle(hProcess);
  }
  exit(0);
  CDialog::OnClose();
}

LRESULT CVitualDesktopDlg::OnHotKey(WPARAM wParam, LPARAM lParam)

{
  if (wParam == 1314) //消息为 Alt+Z 时
  {
    if (IsOriginalDesktopActive) //是否在原始桌面
    {
      hDesktop = CreateDesktop("Virtual", NULL, NULL, 0, GENERIC_ALL , NULL); //创建虚拟桌面(与CloseDesktop相对应)
      SetThreadDesktop(hDesktop);
      SwitchDesktop(hDesktop);
    }
    else
    {
      SetThreadDesktop(hOriginalThread);
      SwitchDesktop(hOriginalInput);
      CloseDesktop(hDesktop); //关闭虚拟桌面
    }
    IsOriginalDesktopActive = !IsOriginalDesktopActive;
  }
  if (wParam == 521)
  {
    if (IsWindowShow)
    {
      AnimateWindow(m_hWnd, 521, AW_BLEND|AW_HIDE);  //隐藏窗口
    }
    else
    {
      AnimateWindow(m_hWnd, 521, AW_BLEND);    //显示窗口
    }
    IsWindowShow = !IsWindowShow;
  }

  return TRUE;

}

好了,程序就是那么多了,可以自行修改哦,不满意的点击右上方的X键,满意的握个抓留个言。

终于看完了,发个源码地址:

http://d.1tpan.com/tp2058548247

转载于:https://www.cnblogs.com/ZzzZzz/archive/2011/12/31/2308973.html

你可能感兴趣的文章
linux设置LD_LIBRARY_PATH变量
查看>>
整理:java定时器。
查看>>
Objective C 快速入门学习一
查看>>
移动互联网实战--社交游戏的排行榜设计和实现(1)
查看>>
瘋子C语言笔记 (string)
查看>>
PHP-四种解析XML文件的方法
查看>>
连HTTPS都有漏洞,这么不安全的互联网我们还要继续用吗?
查看>>
MySQL的各种join
查看>>
微信支付开发(2) 扫码支付模式一
查看>>
java.lang.Runnable接口
查看>>
jQuery cssHook的经典例子
查看>>
HDU 5052 Yaoge’s maximum profit 光秃秃的树链拆分 2014 ACM/ICPC Asia Regional Shanghai Online...
查看>>
Java Date API demo
查看>>
转multicast vs broadcast
查看>>
ASP.NET MVC权限验证 封装类
查看>>
表单数据相关
查看>>
安卓动画基础讲解
查看>>
继承中參数传递及调用顺序
查看>>
tnt_esri.dat Arcgis8.1安装license
查看>>
springboot 配置文件 .properties和.yml的写法区别
查看>>