改变窗口最大化的尺寸

来源:互联网 发布:socket编程是什么意思 编辑:程序博客网 时间:2024/05/17 03:05

背景:单文档程序,由于数据使用的是非模态对话框(不要问我为什么没有使用view),然后希望给数据展示对话框加一个最大最小化按钮,希望最大化的时候能适应view视图的大小,这样看起来比较合理。问题来了:如果对话框使用child风格,将其父窗口设为view即可实现最大化时想要的尺寸,但是我的数据展示窗口会不只一个,它们会叠加,发现在child风格下对话框被同级对话框盖住后怎么也无法激活到最前页来,这显然不符合要求。于是上网查,说是可以通过控制z-order来实现窗口最前显示,但水平所限,没有尝试成功。。。

于是打算截获数据对话框的最大化按钮的消息,这个简单,在WM_SYSCOMMAND消息响应中检查nID是否为SC_MAXIMIZE即可,然后获取view的位置和尺寸,使用MoveWindow将对话框的尺寸设为view的尺寸,即可做到最大化尺寸跟着view走,看起来很棒!

然额,最大化后的最大化按钮还是最大化按钮,不是应该出现的还原按钮?这一点也不奇怪,毕竟最大化的处理不是真的“最大化”的操作,而只是自己调用了一次MoveWindow函数而已。

于是,不学无术的我又开始想别的烂招了:能不能在最大化操作后自己把最大化按钮改为还原按钮?这里参考里一篇文章:[转载]MFC 系统自带菜单中的最大化、最小化和关闭按钮于是尝试以下代码:

void CDlgXXX::OnSysCommand(UINT nID, LPARAM lParam)

{

//TODO:在此添加消息处理程序代码和/或调用默认值

if(nID == SC_MAXIMIZE)

{

CMenu* menu = GetSystemMenu(0);

menu->DeleteMenu( SC_MAXMIZE,MF_BYCOMMAND);//删除最大化菜单项,最后只是删掉了右键菜单项,按钮还在只是没反应了

menu->AppendMenu(SC_RESTORE, MF_BYCOMMAND);//添加还原菜单项,右键菜单里添加成功,但没有成功

//也试过以下几个函数,都没实现,可能是我不会用

RemoveMenu(...);

EnableMenu(...);

}

}

后来偶然发现一篇文章:http://blog.csdn.net/u012578046/article/details/45418679,,才知道可以换个思路,设置最大化和最小化的尺寸,在消息WM_GETMAXMININFO的响应中添加如下代码,这里直接照搬:

  1. void CMainFrame::OnGetMinMaxInfo(MINMAXINFO* lpMMI)  
  2. {  
  3.     // TODO: 在此添加消息处理程序代码和/或调用默认值  
  4.          
  5.     lpMMI->ptMinTrackSize.x = 500;   //x宽度      
  6.     lpMMI->ptMinTrackSize.y = 300;   //y高度    
  7.     lpMMI ->ptMaxPosition.x = 150;   //最大化x坐标  
  8.     lpMMI ->ptMaxPosition.y = 150;       //最大化y坐标  
  9.     lpMMI ->ptMaxTrackSize.x = 800;      //最大宽度  
  10.     lpMMI ->ptMaxTrackSize.y = 500;      //最大高度  
  11.     CFrameWnd::OnGetMinMaxInfo(lpMMI);  
  12. }  
具体查了msn对MINMAXINFO的描述,如下:

Contains information about a window's maximized size and position and its minimum and maximum tracking size. 

Syntax

C++
typedef struct tagMINMAXINFO {  POINT ptReserved;  POINT ptMaxSize;  POINT ptMaxPosition;  POINT ptMinTrackSize;  POINT ptMaxTrackSize;} MINMAXINFO, *PMINMAXINFO, *LPMINMAXINFO;

Members

ptReserved

Type: POINT

Reserved; do not use.

ptMaxSize

Type: POINT

The maximized width (x member) and the maximized height (y member) of the window. For top-level windows, this value is based on the width of the primary monitor.

ptMaxPosition

Type: POINT

The position of the left side of the maximized window (x member) and the position of the top of the maximized window (y member). For top-level windows, this value is based on the position of the primary monitor.

ptMinTrackSize

Type: POINT

The minimum tracking width (x member) and the minimum tracking height (y member) of the window. This value can be obtained programmatically from the system metrics SM_CXMINTRACK and SM_CYMINTRACK (see the GetSystemMetrics function).

ptMaxTrackSize

Type: POINT

The maximum tracking width (x member) and the maximum tracking height (y member) of the window. This value is based on the size of the virtual screen and can be obtained programmatically from the system metrics SM_CXMAXTRACK and SM_CYMAXTRACK (see the GetSystemMetrics function).

Remarks

For systems with multiple monitors, the ptMaxSize and ptMaxPosition members describe the maximized size and position of the window on the primary monitor, even if the window ultimately maximizes onto a secondary monitor. In that case, the window manager adjusts these values to compensate for differences between the primary monitor and the monitor that displays the window. Thus, if the user leaves ptMaxSize untouched, a window on a monitor larger than the primary monitor maximizes to the size of the larger monitor.


说实话MaxTrackSide是什么没理解,不过已经能达到目标了,遂在对话框中响应WM_GETMAXMININFO消息并添加如下代码:

void CDlgXXX::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CView* pView = ((CMainFrame*)AfxGetMainWnd())->GetActiveView();
CRect rc;
pView->GetWindowRect(rc);
lpMMI->ptMaxSize.x = rc.Width();
lpMMI->ptMaxSize.y = rc.Height();
lpMMI->ptMaxPosition.x = rc.left;;
lpMMI->ptMaxPosition.y = rc.top;
CDialog::OnGetMinMaxInfo(lpMMI);
}

终于让对话框跟着view的尺寸最大化最小化了。

这个问题的处理再一次感到自己渣的有深度,MFC学的很不到位,特此记录,一来怕以后忘掉,二来警醒自己。

0 0
原创粉丝点击