对话框全屏显示和自适应分辨率

 

一、简单对话框全屏显示方法
在OnInitDialog()中任意加入:
1、ModifyStyle(WS_CAPTION,0,0);   //如果不想去掉标题栏,去掉该句。
      SendMessage(WM_SYSCOMMAND,SC_MAXIMIZE,0);
2、ShowWindow(SW_SHOWMAXIMIZED);  

二、复杂一点的对话框全屏显示方法,随屏幕的分辩率而调节
void CMainFrame::OnFullScreen()    
{
 GetWindowPlacement(&m_OldWndPlacement);    
  CRect WindowRect;    
  GetWindowRect(&WindowRect);    
  CRect ClientRect;    
  RepositionBars(0, 0xffff, AFX_IDW_PANE_FIRST, reposQuery, &ClientRect);    
  ClientToScreen(&ClientRect);
   
  //获取屏幕的分辨率    
  int nFullWidth=GetSystemMetrics(SM_CXSCREEN);    
  int nFullHeight=GetSystemMetrics(SM_CYSCREEN);
    
  //将除控制条外的客户区全屏显示到从(0,0)到(nFullWidth, nFullHeight)区域,
    //将(0,0)和(nFullWidth, nFullHeight)两个点外扩充原窗口和除控制条之外的
 //客户区位置间的差值, 就得到全屏显示的窗口位置    
  m_FullScreenRect.left=WindowRect.left-ClientRect.left;    
  m_FullScreenRect.top=WindowRect.top-ClientRect.top;    
  m_FullScreenRect.right=WindowRect.right-ClientRect.right+nFullWidth;    
  m_FullScreenRect.bottom=WindowRect.bottom-ClientRect.bottom+nFullHeight;    
  m_bFullScreen=TRUE;   //设置全屏显示标志为TRUE
    
  //进入全屏显示状态    
  WINDOWPLACEMENT wndpl;    
  wndpl.length=sizeof(WINDOWPLACEMENT);    
  wndpl.flags=0;    
  wndpl.showCmd=SW_SHOWNORMAL;    
  wndpl.rcNormalPosition=m_FullScreenRect;    
  SetWindowPlacement(&wndpl);
}

三、对话框全屏及按钮控件移到相应位置
void CXXXDlg::OnLButtonDown(UINT nFlags, CPoint point)    
{                    
 int cx=::GetSystemMetrics(SM_CXSCREEN);  
 int cy=::GetSystemMetrics(SM_CYSCREEN);  
   
 CRect rtClient,rtBtn;  
 CWnd  *pWnd=GetDlgItem(IDC_BUTTON);  
   
 GetClientRect(&rtClient);             //获得对话框客户区屏幕坐标  
    ClientToScreen(&rtClient);            //映射为屏幕坐标  
 pWnd->GetWindowRect(&rtBtn);          //获得button屏幕坐标  
 
 int lx=rtBtn.Width();                 //button长度  
 int ly=rtBtn.Height();                //button高度  
 int dx=rtClient.right-rtBtn.right;    //离右边框的距离  
 int dy=rtClient.bottom-rtBtn.bottom;  //离底边框的距离  
 
 MoveWindow(CRect(0,0,cx,cy));                            //移动窗口  
 pWnd->MoveWindow(CRect(cx-dx-lx,cy-ly-dy,cx-dx,cy-dy));  //移动button  
 
 CDialog::OnLButtonDown(nFlags, point);  
}

四、设计状态下指定对话框以全屏显示
1、手工把它拽成比如1024×768, 然后Alt+V   U
2、在*.rc文件中修改,但是单位不一样。

五、用MoveWindow或SetWindowPos全屏对话框
首先计算出客户区的大小GetClientRect();
再计算出整个窗口的大小GetWindowRect();
然后再得到当前屏幕的大小GetSystemMetrics();
最后根据这三个数据进行换算,当客户区为屏幕大小时窗口的位置的大小;
计算完成后调用MoveWindow就可以了。

 

 

 

屏幕自适应修改方案
 
来     源:终端开发
关 键 词:分辨率  屏幕 布局
 
现象、问题描述
  为了适应不同分辨率屏幕上iRead的正常显示,在不替换图片的前提下,对画面进行缩放和位置调整是一种可以满足所有屏幕变化的方案。iRead原先的绘图方案是用Image::Draw方法来绘制png图片,这个方法是可以对图片进行拉伸,那么剩下的问题就是如何缩放和调整位置了。那么什么时候该缩放,什么时候该调整位置,这个怎么决定呢?下面对这些问题做几点描述。
 
关键过程、根本原因分析
 
1. 图片的缩放和位置的调整      
屏幕自适应是为了我们的程序画面能够满足不同的分辨率,如480x640,240x320,480x800等等。如果程序一开始是在480x640下写的程序,换到240x320屏幕,我们需要把图片长宽都缩小一半就可以了,胆识换到480x800下面就不同了,如果按x和y方向缩放比例拉伸的话,那么图片就会被拉长变形,画面就会失真。所以我们不能这么处理。因为我们的程序是在480x640开发的,那么就以这个为基准,来对其他分辨率的图片进行处理。在对图片进行缩放之前,先得出X方向和Y方向的两个缩放因子,dx=x/480,dy=y/640,并且取小的缩放因子,这样图片就能显示完整,画面不再失真。
图片缩放大小好了,还要考虑图片的位置,原先的对齐方式都是以左上角的点为原点,然后给出相对于这个点的位置坐标。需要考虑图片的对齐方式。
a. 置顶靠左对齐: 如果原先显示图片的区域是可以滚动的,那么就不需要更改,图片还是以左上角为原点,各个图片是从上往下,从左往右的顺序,间距也不用调整
b. 居中对齐: 如果原先的图片是要放在中间的,那么区域扩大后,中点也跟着要改变,在480x800下就是Y方向向下偏移1.25倍距离,比如PopDlg对话框。
c. 靠底对齐和靠右对齐:这种情况程序中很少出现,只有在我的设置里面的几个按钮才需要靠右对齐,处理的话和第一种情况一样。
下面给出调整图片位置和大小方案的代码
CRect CDataProcessCtrl::GetRect( const string& strWinName, int iRectId, int iAnchorType)
{
    CRect rcTemp;
    (void)GetRect( strWinName, iRectId, rcTemp);
    int cx = GetSystemMetrics(SM_CXSCREEN);
    int cy = GetSystemMetrics(SM_CYSCREEN);
    double iMaxCx = (double)cx/(double)STD_SCREEN_CX;
    double iMaxCy = (double)cy/(double)STD_SCREEN_CY; 
    double dScale = iMaxCy - iMaxCx;
    double iTemp = 0;
 
    int iSrcWidth = rcTemp.Width();
    int iSrcHeight = rcTemp.Height();
 
    if( cx > cy )
    {
       iTemp = (double)rcTemp.left * iMaxCx;
       rcTemp.left =(int)iTemp;
       iTemp = (double)rcTemp.right * iMaxCx;
       rcTemp.right =(int)iTemp;
       iTemp = (double)rcTemp.top * iMaxCy;
       rcTemp.top =(int)iTemp;
       iTemp = (double)rcTemp.bottom * iMaxCy;
       rcTemp.bottom =(int)iTemp;
 
       return rcTemp;
    }
 
    //比例相等
    if( dScale == 0 )
    {
       iTemp = (double)rcTemp.left * iMaxCx;
       rcTemp.left =(int)iTemp;
       iTemp = (double)rcTemp.right * iMaxCx;
       rcTemp.right =(int)iTemp;
       iTemp = (double)rcTemp.top * iMaxCy;
       rcTemp.top =(int)iTemp;
       iTemp = (double)rcTemp.bottom * iMaxCy;
       rcTemp.bottom =(int)iTemp;
    }
    //CY比例大于 CX,竖屏情况,以CX为基准
    else if( dScale > 0 )
    {
       // 居中对齐, Y坐标按Y方向做不等比缩放
       if( iAnchorType & ANCHOR_VCENTER )        {
           iTemp = (double)rcTemp.top * iMaxCy;
           rcTemp.top =(int)iTemp;
       }
       // 靠顶对齐, Y坐标按X方向做等比缩放
       else if( iAnchorType & ANCHOR_TOP )   
       {
           iTemp = (double)rcTemp.top * iMaxCx;
           rcTemp.top =(int)iTemp;
       }
       //X坐标做等比缩放
       iTemp = (double)rcTemp.left * iMaxCx;
       rcTemp.left =(int)iTemp;
       // 长宽做等比拉伸
       rcTemp.right = (int)(rcTemp.left + (double)(iSrcWidth * iMaxCx));
       rcTemp.bottom = (int)(rcTemp.top + (double)(iSrcHeight * iMaxCx));
    }
    //CY比例小于 CX,横屏情况,已CY为基准
    else
    {
       // 居中对齐, X坐标按X方向做不等比缩放
       if( iAnchorType & ANCHOR_HCENTER )        {
           iTemp = (double)rcTemp.left * iMaxCx;
           rcTemp.left =(int)iTemp;
       }
// 靠顶对齐, Y坐标按X方向做等比缩放
       else if( iAnchorType & ANCHOR_LEFT )  
       {
           iTemp = (double)rcTemp.left * iMaxCy;
           rcTemp.left =(int)iTemp;
       }
       // Y坐标只做等比拉伸
       iTemp = (double)rcTemp.top * iMaxCy;
       rcTemp.top =(int)iTemp;
       // 长宽做等比拉伸
       rcTemp.right = (int)(rcTemp.left + (double)(iSrcWidth * iMaxCy));
       rcTemp.bottom = (int)(rcTemp.top + (double)(iSrcHeight * iMaxCy));
    }
   
    return rcTemp;
}
 
2. 图片的嵌套关系和相对位置
因为程序中有许多图片都是有嵌套关系的,比如PopDlg是居中对齐的,而里面的元素却是置顶对齐,所以我们需要给出元素所在窗口的相对位置。原先的程序中很多都是以屏幕的右上点为原点给出的位置,那么就要改成使用相对父窗口为原点的位置。
 
3 浮点数计算的优化和横竖屏变换
在计算坐标时,需要使用到float类型数据运算,如果在OnPaint中执行的话,会耗去很多时间,而且是重复的过程,所以将区域提取出来作为成员变量,在OnSize中计算出些值,再在OnPaint中使用,同时OnSize也可以满足窗口发生变化的情况,如果横竖屏的切换。
另外进行float计算的过程可以用两个 long型来代替,通过一个函数来执行iLength*zoomX的运算 ZoomX(iLength),ZoomY(iWidth)。在屏幕缩放中使用到得值目前最大只是800,再多考虑点最大的值设为10,000也就够了,因为目前还没有这么大像素的显示屏,那么两个最大值相乘也就是100,000,000,long型也就足够了。
 
4. 字体的缩放
程序的字体中使用的是系统的,不同的屏幕的系统都各自设置了合适的字体,所以一半不需要考虑字体的变化,除非是一些特殊的情况,我们可以更改字体的高度来满足这种变化,当然字体最好要满足和屏幕的缩放比例一致,太小的话也会影响效果。
 
5. 计算的误区
       在显示文字的时候,经常要将文字放置在区域中间,而文字区域也需要根据文字的数量来确定,那么通过中心点来调整文字区域就很必要
    rcTip.left      = rc.CenterPoint().x - sizeTip.cx / 2;
    rcTip.top       = rc.CenterPoint().y - sizeTip.cy / 2;
    rcTip.right     = rc.CenterPoint().x + sizeTip.cx / 2;
    rcTip.bottom    = rc.CenterPoint().y + sizeTip.cy / 2;
 
上面的方法咋一看起来没什么问题,可要是sizeTip.cx和sizeTip.cy是个奇数就有问题了,算出来的区域会比原先会少了1个像素,在显示换行文字的时候就会有问题。而下面的方法就可以避免:       
    rcTip.left      = rc.CenterPoint().x - sizeTip.cx / 2;
    rcTip.top       = rc.CenterPoint().y - sizeTip.cy / 2;
    rcTip.right     = rcTip.left + sizeTip.cx;
    rcTip.bottom    = rcTip.top + sizeTip.cy;
 
  
结论、解决方案及效果
以上就是iRead中屏幕自适应修改方案的几点描述,在使用了上面的方案后,对原先的代码只需要更改部分基本上就可以满足所有屏幕分辨率的需求。如果您还有更好的方案,请不吝赐教!

本文出自 “飘~~~” 博客,请务必保留此出处http://xulin.blog.51cto.com/264387/410569

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值