zoukankan      html  css  js  c++  java
  • MFC只允许程序单开

       很多玩游戏的人都知道一般游戏客户端程序是不允许双开的,就是说在同一游戏在启动的时候,是无法打开多个窗口。很多其他软件如酷狗播放器等也是这样。如果把打开的窗口最小化,这时重新启动程序,最小化的窗口会被显示,而不是重新开一个窗口。
        今天突然想把我自己以前做的音乐播放器, 也加这么一个功能。查了点资料,主要用到了FindWindow这个函数。
        原型如下:

    HWND FindWindow
    (
     LPCSTR lpClassName,    //输入窗口的类名,其实需要是注册过的类名才行,否则是要报错或者查找失败的。
     LPCSTR lpWindowName, //输入窗口的名称,就是窗口上面蓝色的那行玩意儿写的字。
    );

    对于这个函数,如果按照窗口的名称查找,是很简单的,但是会有很多问题。
    一开始我就是按窗口的名称来查找,因为不知道类名。

    BOOL CMusicPlayerApp::InitInstance()
    { 
           CString strTitle = _T("MusicPlayer");
           HWND hwnd = ::FindWindow(NULL, strTitle);
            if (hwnd != NULL) {
                 ::SetActiveWindow(hwnd);
                  ShowWindow(hwnd, SW_NORMAL);
                  ::SetForegroundWindow(hwnd);
                  return FALSE; 
             }
    }

    发现这样有时候是可以运行成功的,有时候是不能运行成功的。为何? 
    运行失败的情况是这样的:
          (1)把编译好的程序,放在B文件夹(某个盘上的文件夹)
          (2)打开B文件夹,但不运行里面的程序 。
          (3)在桌面新建文件夹MusicPlayer ,并打开该文件夹。
          (4)运行B文件夹 里的程序,发现程序无法启动,MusicPlayer文件夹变成了当前活动窗口。
    出现这样的原因是:程序在用FindWindow来找窗口时,发现桌面上有一个文件夹叫MusicPlayer ,它以为这个就是你要找的程序窗口。于是把MusicPlayer 文件夹作为活动窗口给显示出来了。
    可见用窗口名称来查找有点不靠谱,虽然简单,但是不好控制。
         我就想把FindWindow的第一个参数也给它填上,用类名和窗口名同时查找,这样就不会出现上面的情况了。关键类名是什么,开始我猜是播放器界面这个对话框类,发现不是;我把程序用到的类都试了一下,发现也不行。查资料知道:
            MFC并没有一个一个帮我们派生的窗口类进行注册,而是使用的默认窗口类的方式,而默认的窗口类,一般类名都是“#32770(Dialog)”。就是说所有的MFC默认使用都是默认类,而且这个默认类是一样的,这样我在查找窗口的时候,不是很容易和别人写的程序进行撞车吗?
          可不可以自定义自己的类名呢?答案是可以的,但是必须先注册后,才能使用。

            比如我要注册的窗口类的对应句柄是IDD_MUSICPLAYER_DIALOG,

           那么打开XXX.rc文件后,稍微需找一下就会发现这个数据段:

       

    上面用框子框起来的就是要加的类名,这个名字可以随便起。

    然后再APP文件里这上这样的代码:

    BOOL CMusicPlayerApp::InitInstance()
    {  

      WNDCLASS wc;

      // Get the info for this class.
      // #32770 is the default class name for dialogs boxes.
      ::GetClassInfo(AfxGetInstanceHandle(), "#32770", &wc);

      / Change the name of the class.
      wc.lpszClassName = _T("CMusicPlayerDlg"); //这里请再次注意,一定要保证和rc资源文件里保存的类名相同!

      // Register this class so that MFC can use it.
      AfxRegisterClass(&wc);  HANDLE hObject = CreateMutex(NULL, FALSE, _T("MusicPlayer.exe")  if (ERROR_ALREADY_EXISTS == GetLastError())

      {
        CloseHandle(hObject);
        CString strTitle = _T("MusicPlayer");
        HWND hwnd = ::FindWindow(wc.lpszClassName, strTitle);
        if (hwnd != NULL)
        {

                      ::SetActiveWindow(hwnd);
                      if (IsIconic(hwnd))
                      {
                           ::ShowWindow(hwnd, SW_NORMAL);
                      }
                      else
                      {
                            ::ShowWindow(hwn  d, SW_RESTORE);
                      }
                       SetForegroundWindow(hwnd);

        }
        return FALSE;
      }

        .....

    }

      

    高山流水,海纳百川!
  • 相关阅读:
    103、服务器出现大量close_wait的连接的原因是什么?有什么解决方法?
    102、常见的HTTP状态码有哪些?
    rpm包管理、yum源及创建本地仓库(同步华为源)
    文件管理之:输出与重定向echo
    高级权限--acl, mask,文件属性权限;su切换用户,sudo提权
    基本权限;权限对⽂件or⽬录的意义;特殊权限;文件权限之umask
    权限管理--用户介绍;用户与组相关文件;用户管理命令之用户创建、查看、删除、修改
    文件管理之:打包、压缩
    字符处理命令-sort排序,uniq去重,cut剪切文件,tr删除或替换结果集,wc统计
    上传与下载wget、curl、r z、s z
  • 原文地址:https://www.cnblogs.com/ahcc08/p/6082558.html
Copyright © 2011-2022 走看看