最大化、最小化和关闭按钮是窗口中最主要的元素。首先要说明,说他们是按钮其实是不准确的,按钮是一种窗口,而这三个组件根本就不是窗口,而是一个窗口常见的组成部分。出于习惯的原因,这里还是称呼他们为按钮。

这三个按钮是否显示似乎只能在窗口创建是决定。首先,要显示这三个按钮,窗口必须有标题条和系统菜单,没有标题条和系统菜单的窗口是不能显示这三个按钮的,也就是说,要想有这三个按钮,创建窗口时必须有WS_CAPTION和WS_SYSMENU风格。当窗口创建时有风格WS_MAXIMIZEBOX时,窗口显示最大化按钮,当有风格WS_MINIMIZEBOX时,窗口显示最小化按钮,而只要有标题条并且有系统菜单,关闭按钮就必然会显示出来。

对这三个按钮的操作往往都是系统菜单来进行的,这也解释了为什么要显示这三个按钮必须有系统菜单。一般而言,当一个窗口有最大化按钮时,在系统菜单里也会有对应的菜单项,对这个菜单项的操作一般都能反馈到这各按钮中。其中,最大化按钮在系统菜单中的ID为SC_MAXIMIZE,最小化按钮为SC_MINIMIZE,而关闭按钮为SC_CLOSE。当窗口处于最大化状态时,系统菜单SC_MAXIMIZE则变会并被禁止,而此时最大化按钮变为恢复按钮,ID对应为系统菜单中的SC_RESTORE。

变灰和使能
一般从功能上来讲,界面元素有使能(Enabled)和禁止(Disabled)两种状态,当界面元素处于使能状态时,用户可以使用它,否则用户不能使用它。而从外观的颜色角度讲,界面元素有灰色状态(Grayed)和普通状态两种状态,一般对于使能的界面元素,不应该是灰色的,而对于禁止的界面元素,则应该是灰色的。

这三个按钮也是如此。让人奇怪的是,虽然这三个按钮通过系统菜单操作,它的行为似乎并不和普通菜单项不完全一致。使能、禁止、变灰一个菜单项的操作都是通过EnableMenuItem,一般常见的使能一个菜单项ID_MY_MENU的代码为:

EnableMenuItem(hMenu,ID_MY_MENU,MF_BYCOMMAND|MF_ENABLED);
                          或者用CMenu的成员函数
       pMenu->EnableMenuItem(ID_MY_MENU,MF_BYCOMMAND|MF_ENABLED);

而禁止并同时使它变灰的代码则为:

EnableMenuItem(hMenu,ID_MY_MENU,MF_BYCOMMAND|MF_GRAYED|MF_DISABLED);
                          或者用CMenu的成员函数
       pMenu->EnableMenuItem(ID_MY_MENU,MF_BYCOMMAND|MF_GRAYED|MF_DISABLED);

注意:虽然从一般的视觉效果上变灰和禁止是一起起作用的,实际上在内部实现上,这两者并没有捆绑在一起,只有同时设置MF_GRAYED|MF_DISABLED,两个功能才同时作用。否则如果只使用MF_GRAYED,则只变灰不禁止,如果只使用MF_DISABLED,则只禁止不变灰。

这段代码对于菜单项总是很有效的,对关闭按钮也有作用,但是对于最大化和最小化按钮,则完全没有作用。对系统菜单应用上述代码后,系统菜单内的对应项的状态已经正确转变,但是窗口这两个按钮的功能和外观都未变化。

为了禁止并变灰两个按钮中的一个,唯一的方法是从系统菜单中删除这个菜单项,代码如下:

CMenu* pSysMenu = GetSystemMenu(FALSE);
         ASSERT_VALID(pSysMenu);
         if(NULL == pSysMenu)
         {
                return;
          }
          pSysMenu->DeleteMenu(SC_MINIMIZE,MF_BYCOMMAND);

为了使能一个按钮,则需要向系统菜单中添加这个按钮对应的项,代码为:

CMenu* pSysMenu = GetSystemMenu(FALSE);
         ASSERT_VALID(pSysMenu);
         if(NULL == pSysMenu)
         {
                return;
          }
          pSysMenu->AppendMenu(MF_STRING,SC_MINIMIZE,_T("最小化(&N)"));

消息处理
对于这三个消息的响应,也一样通过系统菜单的途径来处理的。系统菜单中的所有项都是通过消息WM_SYSCOMMAND来处理的,这个消息的wParam包含了需要处理的消息类型,其含义如下表:值含义
SC_CLOSE 关闭按钮
SC_MAXIMIZE 最大化按钮
SC_MINIMIZE 最小化按钮
SC_RESTORE 恢复按钮

这里只列出了和三个按钮的相关说明,其他值的说明请读者阅读MSDN。

为了自己截获这三个按钮的处理,需要处理WM_SYSCOMMAND消息。下面的代码示例就是处理SC_MINIMIZE消息并隐藏对话框到任务栏的常见操作。

void CTdDlg::OnSysCommand(UINT nID, LPARAM lParam)
{

if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else if(nID == SC_MINIMIZE)
{
NOTIFYICONDATA nid;
nid.cbSize = sizeof(nid);
nid.hIcon = m_hIcon;
nid.hWnd   = GetSafeHwnd();
GetWindowText(nid.szTip ,sizeof(nid.szTip ));
nid.uCallbackMessage = WM_NOTIFY_ICON_MESSAGE;
nid.uFlags = NIF_MESSAGE|NIF_TIP|NIF_ICON;
nid.uID = 1;
ShowWindow(SW_HIDE);
Shell_NotifyIcon(NIM_ADD,&nid);
}

else

{
   CDialog::OnSysCommand(nID, lParam);
}

}

对于对话框的SC_CLOSE按钮,缺省调用OnCancel,用户也可以仿照上面代码截获并不调用OnCancel

MFC的最大化,最小化,关闭的更多相关文章

  1. Electron 无边框窗口最大化最小化关闭功能

    Electron 无边框窗口最大化最小化关闭功能 目的 实现无边框窗口,并添加最大化最小化和关闭功能 前提 了解Electron 主进程和渲染进程的通讯 了解 BrowserWindow相关功能 操作 ...

  2. c# 窗体相关操作(最大化/最小化/关闭/标题栏)

    /// <summary> /// 窗体跟随鼠标移动的标记 /// </summary> private bool normalmoving = false; /// < ...

  3. Qt 窗口操作函数(置顶、全屏,最大化最小化按钮设置等)

    一.窗口置顶 与 取消置顶 void MainWindow::on_windowTopButton_clicked() { if (m_flags == NULL) { m_flags = windo ...

  4. 【转】ubuntu 12.04 LTS将关闭最大化最小化移动到右上角

    原文网址:http://www.4byte.cn/learning/114801.html ubuntu 12.04 LTS将关闭最大化最小化移动到右上角   还是按下“ALT +F2”组合键,输入g ...

  5. Q窗口操作函数(窗口最大化,全屏,隐藏最大化最小化按钮)

    //Qt主窗口没有最小化,最大化按钮且最大化显示  int main(int argc, char *argv[]) { QApplication a(argc, argv); TestQtForWi ...

  6. PyQt:无边框自定义标题栏及最大化最小化窗体大小调整

    环境 Python3.5.2 PyQt5 陈述 隐藏掉系统的控制栏,实现了自定义的标题控制栏,以及关闭/最大化/最小化的功能,自由调整窗体大小的功能(跟随一个大佬学的),代码内有详细注释 只要把Mai ...

  7. layer满屏/禁止最大化最小化 可以做选择框使用

    1.layer弹窗最大化 var index=layer.open(); layer.full(index); 2.layer禁止最大化最小化 layer.open( [ type:2, title: ...

  8. C#程序实现窗体的最大化/最小化

    C#程序实现窗体的最大化/最小化 http://blog.csdn.net/jiangqin115/article/details/41251215 private void button1_Clic ...

  9. delphi ,1)控件根据窗口大小,一直居中显示 2)显示最大化最小化按钮控件

    一.控件根据窗口大小,一直居中显示 1)onResize:当窗体尺寸改变时发生 例子:如何使控件随窗口的放大和缩小动态改变自己的大小,使控件“保存.返回”在窗口变大变小中随着变. 在Panel调用 p ...

  10. C#winform如何主窗口最大化最小化默认大小

    this.WindowState = FormWindowState.Minimized; bool b = true; private void button2_Click(object sende ...

随机推荐

  1. Candy----HDU4465----数学题

    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4465 题目意思: 有两个箱子,每个箱子装有N个糖果 打开第一个箱子的概率是P,另外一个就是1-P 当小 ...

  2. HDU ACM 1063 Exponentiation 大实数乘方

    分析:大实数乘方计算. #include<iostream> #include<string> using namespace std; struct BigReal //高精 ...

  3. 关于cvScalar的那些事

    CvScalar 可存放在1-,2-,3-,4-TUPLE类型的捆绑数据的容器 该函数包含4个浮点成员,可以用来表示B(Blue),G(Green),R(Red),Alpha(表示图像的透明度) ty ...

  4. 自定义通用Distinct去除重复数据的2中方式

    由于Lambda Distinct方法默认是按照集合里面的值比较的,所以当集合里面存放的是类的时候,我们一般是按照实体中的某一属性值比较,其实是用默认的Distinct也可以的,自己先定义一个实现了接 ...

  5. Android开发中出现cannot be resolved to a variable错误,也就是R文件不能生成。

    最近开始学过习Android开发,配置完成开发环境后,在创建第一个Android项目就出现了cannot be resolved to a variable错误,也就是R文件不能生成的问题. 以下是从 ...

  6. OSG项目经验2<在场景中添加文字面版>

    添加文字版需要用到osg的三个名字空间:                         osgText::Text,这个类用来添加文字和设置文字的一些属性:                     ...

  7. 解决64位系统下IIS 8下Asp+Access网站配置

    一.IIS7的安装 Windows 中IIS8是默认不安装的,所以在安装完windows 8,之后如果需要安装IIS8的话,就要自己动手了. 安装的步骤为:开始>控制面板>程序>打开 ...

  8. HDU2577:How to Type(DP)

    Problem Description Pirates have finished developing the typing software. He called Cathy to test hi ...

  9. 首页 导航栏隐藏 下一级页面显示,pop回来遇到的问题

    - (void)viewWillAppear:(BOOL)animated {    [super viewWillAppear:animated];    [self.navigationContr ...

  10. Eclipse快捷键 今天又学会了几个不常用的 收藏了

    1.Ctrl+e           打开所有已经打开的文件列表,当你使用Eclipse打开了N多文件的时候,需要找到一个你之前打开过                       的文件,是不是就很费 ...