MFC使用ShowWindow(SW_MAXIMIZE)任务栏消失的处理
- ShowWindow(SW_SHOWMAXIMIZED);//窗口最大化
问题:在写程序时,如果包含了标题栏,但是没有包含最大化按钮或者最小话按钮。
那么人工用ShowWindow(SW_MAXIMIZE),窗口会盖住任务栏,并且窗口最大化后还可以拖动!
解决方法:
1 窗口最大化可以拖动的问题就是在最大化时不让其拖动,
只要响应WM_NCLBUTTONDOWN时判断是否最大化 IsZoomed如果是则直接返回就OK!
2 解决遮住任务栏就是重载WM_GETMINMAXINFO:
- void CTabDlg::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
- {
- // TODO: Add your message handler code here and/or call default
- lpMMI-> ptMaxSize.y = GetSystemMetrics(SM_CYFULLSCREEN)+GetSystemMetrics(SM_CYCAPTION)+GetSystemMetrics(SM_CYDLGFRAME);
- CDialog::OnGetMinMaxInfo(lpMMI);
- }
针对这个问题,自己查了很久的资料:有一些问题再次拿出来讨论:
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是一个结构体指针,其中包含了有关窗口的最大化大小和位置以及最小、最大跟踪大小的信息。
使用这个函数控制窗口最小尺寸的示例的代码如下:
- void CXXXDlg::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
- {
- lpMMI->ptMinTrackSize.x = 500; //x宽度
- lpMMI->ptMinTrackSize.y = 100; //y高度
- CDialog::OnGetMinMaxInfo(lpMMI);
- }
以上代码可以使得窗口大小变化时,最小宽度为500px,最小高度为100px。
OnSizing
这个函数在窗口大小发生变化时被调用。在这个函数里,也可以控制窗口的最大最小尺寸,但是没有OnGetMinMaxInfo方便。
- void CXXXDlg::OnSizing(UINT fwSide, LPRECT pRect)
- {
- if ((pRect->right - pRect->left) < 500)
- {
- //return ; //直接return是无效的,窗口大小还是会改变
- pRect->right = pRect->left + 500;
- }
- CDialog::OnSizing(fwSide, pRect);
- }
用上面的方法,如果是从右边改变大小,可以达到想要的效果,但是从左边改变大小,虽然大小可以控制在最小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)任务栏消失的处理的更多相关文章
- windows任务栏消失
windows任务栏消失,快捷键打开任务管理器,新建任务explorer.exe
- TX2-入门坑点-Ubuntu16.04任务栏消失
问题:安装cuda过程中出现任务栏消失,快捷键失效的现象. 解决方法:重装桌面无法解决,使用cssm无法解决,最后删除home目录下的 .cache文件夹重启后解决
- mfc添加气球式提示栏
// TOOLTIPWND.H 添加气球式提示栏 #if !defined(AFX_TOOLTIPWND_H__2C52D3E4_2F5B_11D2_8FC9_000000000000__IN ...
- centos gnome面板菜单任务栏消失后的解决
今天终于下决心把我的电脑装成了centos,上网的时候感觉上边的那一行菜单栏碍事儿,就把他给删了 就是桌面最顶上这一行东西,然后百度无果,谷歌上不去,用bing好不容易才找到里解决方案! 症状:进入l ...
- win10常见问题-任务栏消失
问题描写叙述: O疼地尝鲜了win10,bug层出不穷,眼下遇到的最大的两个BUG是: 1.启动后高概率出现黑屏,仅仅有鼠标,无桌面,无法拯救 2.正常执行高概率出现任务栏丢失现象.无法拯救 问题一, ...
- ubuntu桌面变空白,或者只有壁纸,任务栏消失的解决办法
原因:因为打开了桌面特效的原因,但设置不合导致的. 解决方法:方法一:1.按住Ctrl+Alt+F1切换到字符终端下,输入用户名和密码登录2.输入以下命令删除出错的Compiz配置文件相关目录:rm ...
- 解决ubuntu16.04桌面左侧栏和顶部栏消失的问题
重要事情说三遍! 不要轻易重装系统! 不要轻易重装系统! 不要轻易重装系统! 问题所在:误删了unity桌面. 解决方法: $sudo apt-get install unity
- eclipse左边的项目栏消失的处理方法
window —–> Show View —–> other —–> package Explorer
- 【MFC】MFC技巧学习 当做字典来查
MFC技巧学习 摘自:http://www.cnblogs.com/leven20061001/archive/2012/10/17/2728023.html 1."属性页的添加:创建对话框 ...
随机推荐
- SqlDataAdapter用法
SqlDataAdapter和SqlCommand区别: SqlCommand就是是命令了,可以用它来执行SQL命令: SqlDataAdapter就是数据适配器了,它是用于在数据源和数据集之间通讯的 ...
- HTML5 增强的页面元素
一.HTML5 改良的 input 元素的种类 1.<input type="number" id="num1"> var n1 = documen ...
- esriFeatureType与esriGeometryType的区别与联系
esriFeatureType通常用来表示数据的存储结构,即物理层: esriGeometryType通常用来表示数据的几何形状,即表现层. esriGeometryType枚举类型详解 常量 值 对 ...
- 基于Struts2框架实现登录案例 之 使用Struts2标签库简化表单+继承ActionSupport完成输入交验
一,使用Struts2标签库简化表单 在文章[基于Struts2框架实现登录案例]的基础上,通过使用Struts标签库可以简化登录页面login2.jsp <%@ page language=& ...
- [Quick-x]cocos2dx下的彩色文本显示--RichLabel
部分关键代码与思路参考 http://www.cocoachina.com/bbs/read.php?tid=218977&page=1 感谢原作者 i7909 代码下载地址:https:// ...
- openfire的配置
Openfire 采用Java开发,开源的实时协作(RTC)服务器基于XMPP(Jabber)协议.Openfire安装和使用都非常简单,并利用Web进行管理.单台服务器可支持上万并发用户.所以常常被 ...
- hdu 4911 Inversion (分治 归并排序 求逆序数)
题目链接 题意:给n个数,求交换k次相邻的数之后的最小的逆序数对. 用分治的方法,以前在poj上做过这种题,昨天比赛的时候忘了.... 下面的归并排序还是以前的模板. #include <ios ...
- HDU 1166 敌兵布阵 (线段树 单点更新)
题目链接 线段树掌握的很差,打算从头从最简单的开始刷一波, 嗯..就从这个题开始吧! #include <iostream> #include <cstdio> #includ ...
- 制作SM2证书
前段时间将系统的RSA算法全部升级为SM2国密算法,密码机和UKey硬件设备大都同时支持RSA和SM2算法,只是应用系统的加解密签名验证需要修改,这个更改底层调用的加密动态库来,原来RSA用的对称加密 ...
- 文件大小转换成可显示的Mb,Gb和kb方法
public static String unitConversion(float resource) { String[] unit = new String[] { "B", ...