• 问题解决——MFC SDI程序 CFormView中控件随窗体缩放


    从来都是做对话框程序,这次想做个SDI的程序,想着用一下带Robbin界面的office2007风格。就不用使用那些花钱的商业控件/UI库了。

    假设你不想看我打的文字。能够直接拷走代码,自己声明上定义再略作改动就能够用了,不需大的改动。

    -------------------------------小尾巴首次登场-----------------------------------

    SDI程序,是要缩放的,假设是往里输入文字的话,这倒没什么,可是这次我使用的是CFormView类,里面加了控件。

    ———————————我才是切割线————————————

    大致上有3种方法

    方法1:

    1.记录原始的CFormView的RECT。在OnSize中获得当前Rect,求出放大比例。

    2.对每一个控件。在OnSize中获取当前RECT。然后乘以放大比例。作为新的RECT大小。

    3.对每一个控件。调用MoveWindow函数。完毕缩放。

    这样的方法对每一个控件,都编写代码进行操作,必定是缩放效果最好的。

    可是,当控件太多时,真的须要一个好脾气。并且要细心,善于调试。(复制粘贴,这么做有时候会让你编译链接过。可是就是一直错。

    方法2:

    这是对方法1的改进。须要一定的知识和技巧。

    全部控件的定义都是在*.rc文件里,可是这些控件的ID声明却都在resource.h中。假设你有足够的耐心和另外一块显示屏,那么你能够:

    1.更改这些控件的ID值,使它们顺序增长(减小),这样我们就能够在一个循环里完毕方法1中对控件的操作,仅仅需1套代码。

    (不要害怕改坏了,对于不同的控件,仅仅要在resource.h中ID值不反复即可了。)

    这样的方法看起来是对方法1的优化。可是实际上,对于代码的维护以及任务的交接都是不太好的。

    当控件较多时。手工的对ID进行记录更改排序,你须要例如法1还好的脾气。

    -------------------你不认为上面的切割线的风格怪怪的吗-------------------------

    方法3:

    我採用了这样的。主要是不想维护太多的代码。也不想在如此众多的宏中对ID值进行更改。

    先上代码吧,无码无真相。

    void CRealTimeFV::OnSize(UINT nType, int cx, int cy)
    {
    	CFormView::OnSize(nType, cx, cy);
    	// TODO: 在此处加入消息处理程序代码 http://blog.csdn.net/wlsgzl/article/details/34099313
    	RECT rc;
    	GetClientRect(&rc);
    	LPRECT lpClientRect=&rc;
    
    	m_dXRate=lpClientRect->right/(double)m_lastRect.right;
    	m_dYRate=lpClientRect->bottom/(double)m_lastRect.bottom;
    
    	if (lpClientRect->right!=0 && lpClientRect->bottom!=0)
    	{		
    		m_lastRect.bottom=lpClientRect->bottom;
    		m_lastRect.left=lpClientRect->left;
    		m_lastRect.right=lpClientRect->right;
    		m_lastRect.top=lpClientRect->top;
    
    		CWnd *pWnd=NULL;
    		pWnd=GetWindow(GW_CHILD);
    
    		while (pWnd)
    		{
    			CString strCaption;
    			pWnd->GetWindowTextW(strCaption);
    			OutputDebugString(TEXT("Caption:")+strCaption+TEXT("
    "));
    
    			CRect childRect;
    			pWnd->GetWindowRect(&childRect);
    			ScreenToClient(&childRect);
    
    			childRect.left=(LONG)(childRect.left*m_dXRate);
    			childRect.top=(LONG)(childRect.top*m_dYRate);
    			childRect.right=(LONG)(childRect.right*m_dXRate);
    			childRect.bottom=(LONG)(childRect.bottom*m_dYRate);
    
    			pWnd->MoveWindow(&childRect,TRUE);
    
    			pWnd=pWnd->GetWindow(GW_HWNDNEXT);
    		}
    	}
    }
    代码肯定有优化改进的余地。但这不是本文的主要意图。

    (可用于button、编辑框、GroupBox、ComboBox、静态文本框、Tab页。对其它控件未作尝试。)

    转载请注明出处http://blog.csdn.net/wlsgzl/article/details/34099313


    要注意的是:

    1.最好先限制下SDI程序界面的最小大小。

    2.在调用此函数之前,先获得一次m_lastRect。至于怎么获得,如何获得,便是仁者见仁智者见智的事情了。

    3.我加入了if,必定是有原因的。不相信能够自己跟消息跟便变量。至于原因,这属于如何学好MFC的问题,讲不了。我也不敢说自己学好了。


    4.定义了rc和lpClientRect,是由于我之前写错了位置,又不想改,就做了下小调整。

  • 相关阅读:
    数据字典/动态性能视图
    参数管理
    expdp实现oracle远程服务器导出到本地
    jquery 操作单选按钮
    vs2012加载T4MVC模板
    Asp.net Mvc 过滤器执行顺序
    oracle版本及字符集查询
    ora-01658: 无法为表空间*****中的段创建 INITIAL 区
    SmtpClient发送邮件
    盒模型padding和margin对滚动条位置的影响
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/8370564.html
Copyright © 2020-2023  润新知