MFC使用ShowWindow(SW_MAXIMIZE)任务栏消失的处理

时间:2021-11-05 00:11:31
  1. ShowWindow(SW_SHOWMAXIMIZED);//窗口最大化

问题:在写程序时,如果包含了标题栏,但是没有包含最大化按钮或者最小话按钮。

那么人工用ShowWindow(SW_MAXIMIZE),窗口会盖住任务栏,并且窗口最大化后还可以拖动!

解决方法:

1 窗口最大化可以拖动的问题就是在最大化时不让其拖动,

只要响应WM_NCLBUTTONDOWN时判断是否最大化 IsZoomed如果是则直接返回就OK!

2 解决遮住任务栏就是重载WM_GETMINMAXINFO:

    1. void CTabDlg::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
    2. {
    3. // TODO: Add your message handler code here and/or call default
    4. lpMMI-> ptMaxSize.y   =   GetSystemMetrics(SM_CYFULLSCREEN)+GetSystemMetrics(SM_CYCAPTION)+GetSystemMetrics(SM_CYDLGFRAME);
    5. CDialog::OnGetMinMaxInfo(lpMMI);
    6. }

针对这个问题,自己查了很久的资料:有一些问题再次拿出来讨论:

1.afx_msg void OnGetMinMaxInfo( MINMAXINFO FAR* lpMMI );
参数:

lpMMI 指向一个MINMAXINFO结构,其中包含了有关窗口的最大化大小和位置以及最小、最大跟踪大小的信息。有关这个结构的更多信息参见MINMAXINFO结构。

说明:
每当Windows需要知道窗口的最大化位置或大小,或者最小、最大的跟踪大小时,框架就调用这个成员函数。最大化大小是指当窗口的边框被完全扩展时窗口的大小。窗口的最大跟踪大小是指用边框改变窗口的大小时可以达到的最大窗口大小。窗口的最小跟踪大小是指用边框改变窗口大小时可以达到的最小窗口大小。
Windows填充一个点组成的数组,为不同的位置和大小指定了缺省值。应用程序可以在OnGetMinMaxInfo中改变这些值。
注意 框架调用这个成员函数以允许你的应用程序处理一个Windows消息。传递给你的成员函数的参数反映了接收到消息时框架接收到的参数。如果你调用了这个函数的基类实现,则该实现将使用最初传递给消息的参数(而不是你提供给这个函数的参数)。

方法一:重载消息:WM_GETMINMAXINFO。
. 消息:ON_WM_GETMINMAXINFO
BEGIN_MESSAGE_MAP(COfflineSCDlg, CDialog)
//{{AFX_MSG_MAP(COfflineSCDlg)
ON_WM_GETMINMAXINFO() //申明方式
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
. 类定义:afx_msg void OnGetMinMaxInfo( MINMAXINFO FAR* lpMMI );
public:
// Dialog Data
//{{AFX_DATA(COfflineSCDlg)
enum { IDD = IDD_AAA_DIALOG };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(COfflineSCDlg)
public:
virtual BOOL DestroyWindow();
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual void OnSize(UINT nType, int cx, int cy);
afx_msg void OnGetMinMaxInfo( MINMAXINFO FAR* lpMMI );
//}}AFX_VIRTUAL
. 实现:OnGetMinMaxInfo
// 限制窗口的大小
void CAAADlg::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
{
lpMMI->ptMinTrackSize.x=; //限定最小宽度
lpMMI->ptMinTrackSize.y=; //限定最小高度
// lpMMI->ptMaxTrackSize.x=100; //限定最大宽度
// lpMMI->ptMaxTrackSize.y=100; //限定最大高度
CDialog::OnGetMinMaxInfo(lpMMI);
}
方法二、由于一般窗口大小的改变,都是用户拖动窗口边框而造成的。所以,我们可以截获主窗口消息WM_NCHITTEST在其响应函数中判断CWnd::OnNcHitTest()的返回值是否为HTRIGHT,HTLEFT,HTTOP,HTBOTTOM四个值之一,如果是,说明用户此时已点击了四个边框之一,此时我们应该返回HTCLIENT.那么,鼠标的形状就不会变成水平或垂直的双向箭头,用户就不可能依靠拖动边框来改变窗口大小了。
  另外,还应补上一个小漏洞,就是还要把系统菜单中的SC_SIZE去掉。

2.

最近用到窗口变化的一些东西,遇到几个相关的消息函数,简要分析,作为备忘。

3个消息分别是:WM_SIZE、WM_SIZING、WM_GETMINMAXINFO;分别对应相应的处理函数:OnSize、OnSizing、OnGetMinMaxInfo。

当窗口大小发生变化时,响应的顺序依次是:WM_GETMINMAXINFO-->WM_SIZING-->WM_SIZE。

OnGetMinMaxInfo

这个函数在窗口初始化的时候会被调用一次,当窗口大小发生改变的时候也会被调用。利用这个函数,可以比较方便的实现窗口最大最小尺寸的控制。

参数lpMMI是一个结构体指针,其中包含了有关窗口的最大化大小和位置以及最小、最大跟踪大小的信息。

使用这个函数控制窗口最小尺寸的示例的代码如下:

  1. void CXXXDlg::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
  2. {
  3. lpMMI->ptMinTrackSize.x = 500;   //x宽度
  4. lpMMI->ptMinTrackSize.y = 100;   //y高度
  5. CDialog::OnGetMinMaxInfo(lpMMI);
  6. }

以上代码可以使得窗口大小变化时,最小宽度为500px,最小高度为100px。

OnSizing

这个函数在窗口大小发生变化时被调用。在这个函数里,也可以控制窗口的最大最小尺寸,但是没有OnGetMinMaxInfo方便。

  1. void CXXXDlg::OnSizing(UINT fwSide, LPRECT pRect)
  2. {
  3. if ((pRect->right - pRect->left) < 500)
  4. {
  5. //return ;  //直接return是无效的,窗口大小还是会改变
  6. pRect->right = pRect->left + 500;
  7. }
  8. CDialog::OnSizing(fwSide, pRect);
  9. }

用上面的方法,如果是从右边改变大小,可以达到想要的效果,但是从左边改变大小,虽然大小可以控制在最小500,但是当达到最小宽度后,再缩小,会发现整个窗口往右移动了,原因是代码中的pRect->right = pRect->left + 500;这句是针对left来改变right的,所以left移动了,right也移动了,看上去就像是这个窗口右移了。所以针对这种情况又要另外做相应的处理。

OnSize

这个函数会在窗口大小改变结束后被调用,通常会在这个函数里重新摆放各个控件的位置及大小。用这个函数暂时没有找到什么办法可以控制窗口的最大最小大小。

3.SendMessage

SendMessage函數是阻塞的。PostMessage函數是非阻塞的。
SendMessage:
函数功能:该函数将指定的消息发送到一个或多个窗口。此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息再返回。而函数PostMessage不同,将一个消息寄送到一个线程的消息队列后立即返回。 函数原型:LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM IParam); 参数: hWnd:其窗口程序将接收消息的窗口的句柄。如果此参数为HWND_BROADCAST,则消息将被发送到系统中所有顶层窗口,包括无效或不可见的非自身拥有的窗口、被覆盖的窗口和弹出式窗口,但消息不被发送到子窗口。 Msg:指定被发送的消息。 wParam:指定附加的消息指定信息。 IParam:指定附加的消息指定信息。 返回值:返回值指定消息处理的结果,依赖于所发送的消息。 备注:需要用HWND_BROADCAST通信的应用程序应当使用函数RegisterWindowMessage来为应用程序间的通信取得一个唯一的消息。

参考:http://blog.csdn.net/tangaowen/article/details/5770816

在WM_LBUTTONDOWN里面处理
SendMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y));
或者
响应NCHITTEST消息,命中测试。

将会导致WM_LBUTTONDOWN响应阻塞,也就是按下鼠标,不会收到WM_LBUTTONDOWN消息,而要等到鼠标放开,才有WM_LBUTTONDOWN和WM_LBUTTONUP进行响应。

到这里很清楚了,就是由于我发送了SendMessage NCLBUTTONDOWN消息,SendMessage消息不能返回,导致WM_LBUTTTONDOWN响应不能返回,当我鼠标松开弹起的时候,系统接管结束,SendMessage返回,我的WM_LBUTTONDOWN返回,表面上看是响应延时。实际是SendMessage阻塞了。

有人提出,我处理拖动应该采用WM_NCHITTEST,经过测试,发现一旦采用对WM_NCHITTEST进行处理拖动,窗口将无法响应任何鼠标点击消息。应该是所有鼠标消息都被系统的拖动接管了。所有这个方法是不行的。

还有人提出,我应该将SendMessage改为PostMessage消息,测试结果就是,能够马上响应WM_LBUTTONDOWN,但是却基本不能响应WM_LBUTTONUP,原因猜测也是在执行拖动的时候,不能响应消息,消息被系统接管。

MFC使用ShowWindow(SW_MAXIMIZE)任务栏消失的处理的更多相关文章

  1. windows任务栏消失

    windows任务栏消失,快捷键打开任务管理器,新建任务explorer.exe

  2. TX2-入门坑点-Ubuntu16&period;04任务栏消失

    问题:安装cuda过程中出现任务栏消失,快捷键失效的现象. 解决方法:重装桌面无法解决,使用cssm无法解决,最后删除home目录下的 .cache文件夹重启后解决

  3. mfc添加气球式提示栏

    //    TOOLTIPWND.H  添加气球式提示栏 #if !defined(AFX_TOOLTIPWND_H__2C52D3E4_2F5B_11D2_8FC9_000000000000__IN ...

  4. centos gnome面板菜单任务栏消失后的解决

    今天终于下决心把我的电脑装成了centos,上网的时候感觉上边的那一行菜单栏碍事儿,就把他给删了 就是桌面最顶上这一行东西,然后百度无果,谷歌上不去,用bing好不容易才找到里解决方案! 症状:进入l ...

  5. win10常见问题-任务栏消失

    问题描写叙述: O疼地尝鲜了win10,bug层出不穷,眼下遇到的最大的两个BUG是: 1.启动后高概率出现黑屏,仅仅有鼠标,无桌面,无法拯救 2.正常执行高概率出现任务栏丢失现象.无法拯救 问题一, ...

  6. ubuntu桌面变空白&comma;或者只有壁纸,任务栏消失的解决办法

    原因:因为打开了桌面特效的原因,但设置不合导致的. 解决方法:方法一:1.按住Ctrl+Alt+F1切换到字符终端下,输入用户名和密码登录2.输入以下命令删除出错的Compiz配置文件相关目录:rm ...

  7. 解决ubuntu16&period;04桌面左侧栏和顶部栏消失的问题

    重要事情说三遍! 不要轻易重装系统! 不要轻易重装系统! 不要轻易重装系统! 问题所在:误删了unity桌面. 解决方法: $sudo apt-get install unity

  8. eclipse左边的项目栏消失的处理方法

    window —–> Show View —–> other —–> package Explorer

  9. 【MFC】MFC技巧学习 当做字典来查

    MFC技巧学习 摘自:http://www.cnblogs.com/leven20061001/archive/2012/10/17/2728023.html 1."属性页的添加:创建对话框 ...

随机推荐

  1. Mongo使用脚本更新数据

    SQL Server中我们经常要使用脚本来刷一些数据,在mongo中我们也可以使用mongo的脚本来刷mongo的数据 首先在命令窗口中链接到本地的mongo库 load("[脚本的地址]& ...

  2. php 执行外部命令exec&lpar;&rpar; system&lpar;&rpar; passthru&lpar;&rpar;

    php 执行部命令exec() system() passthru() 通常用c写一个外部小程序,然后使用上述命令可以在php中调用 1. exec() string exec ( string $c ...

  3. Chrome扩展与用户隐私

    转载自https://www.imququ.com/post/chrome-extensions-and-user-privacy.html   Google Chrome浏览器应该早就是大家的默认了 ...

  4. Linux用户管理的复习时间

    所谓三天不练手生,你还记得关于Linux用户管理的所有知识吗?现在就来跟我一起复习一下吧! 1.常用配置文件 用户信息文件: /etc/password 密码文件: /etc/shadow 用户组文件 ...

  5. JdbcTemplate源码解析

    先写一个测试代码 package jdbc; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Arr ...

  6. 在JSON中遇到的一些坑

    今天在进行压测的时候,由于需要使用到json进行传参,并且需要在JMeter中加入少量的JSON,由于JSON在java中呈现键值对的形式,并且需要使用到“”来修饰,导致只能使用\进行转义,在发送请求 ...

  7. Servlet基础知识点整理

    常用注解 官方文档:https://docs.oracle.com/javaee/7/api/toc.htm WebServlet @WebServlet用于定义一个Servlet,等价于下面的xml ...

  8. win7下安装node及出现的npm问题

    按照官网下载安装,选择 Windows Installer (.msi):,一直next安装,默认安装在C:\Program Files\nodejs下,环境变量会自动添加 如果安装后,打开cmd输入 ...

  9. 【Naive Splay Template】

    写小作业的时候重新复习了一下splay 只支持插入,删除,查k大,查节点数.没有迭代器. T类型需要重载==和<,要调用拷贝构造函数. template<class T> class ...

  10. 一款基于css3的动画按钮

    之前为大家分享了 推荐10款纯css3实现的实用按钮.今天给大家带来一款基于css3的动画按钮.实现的效果图如下: 在线预览   源码下载 实现的代码. html代码: <div class=& ...