VC基于对话框的应用程序如何实现自适合显示器分辨率,有什么简单的办法大家分享一下吧。

2011-02-17 03:24:33

6 Answers

先做一个标准的界面,
启动时记录下每个控件的位置和大小和窗口大小,
当产生WM_SIZE消息时,
用新的窗口大小和原始窗口大小算出变化比例,
用这个比例乘以系数再调整所有控件的位置和大小,
每个控件有独自的系数,这是预先计算好的,
比如以下一个窗口有四个控件:
[A][B]
[C][D]
A在高度上的系数是1,在窗口有高度变化时它的高度也以100%的比例变化,
B在宽度上的系数是1,在窗口有宽度变化时它的宽度也以100%的比例变化,
C在坐标Y上的系数是1,在窗口有高度变化时它的坐标Y也以100%的比例变化,
D在宽度和高度上的系数是1,在窗口有高度和宽度变化时它的高宽也以100%的比例变化.
如果窗口的大小增加了50%,控件的位置和大小变化如下:
[A][B][B]
[A][D][D]
[C][D][D]

2011-02-17 07:13:14

根据显示器自适应,需要通过DPI来控制

概念比较多,难以一两句话说清楚,请参考如下解决方案:
开发能够识别 DPI 的应用程序

2011-02-17 08:33:16

调整分辨率的代码: 

DEVMODE dm; dm.dmSize = sizeof(DEVMODE) ; EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&dm); if(dm.dmPelsHeight!=1024||dm.dmPelsWidth!=1280){ if(AfxMessageBox("为了达到最好的显示效果,建议您使用1280*1024的分辨率,确定吗?",MB_YESNO)==IDYES){ LONG result; dm.dmBitsPerPel = 32; dm.dmPelsHeight = 1024; dm.dmPelsWidth = 1280; dm.dmFields = DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; result = ChangeDisplaySettings(&dm,0); } }

如果要在程序启动时自动调整到合适的分辨率,可以将上面的调整分辨率代码加入到app的InitInstance()中,并记录下dm.dmPelsHeight和dm.dmPelsWidth的值。
要在程序结束时自动调整回原有分辨率,可在APP的ExitInstance中用以上代码将其改回原值

2011-02-17 10:03:47

如果你是用MFC写的,可以在建立对话框的时候,也就是OnInitDialog里面加上这名话。ShowWindow(SW_MAXIMIZE);如果不是的话,可以ShowWindow(m_hWnd,SW_MAXMINZE);

你还可以获取屏幕的尺寸。

GetSystemMetrics(int nIndex);参数用SM_CXFULLSCREEN,SM_CYFULLSCREEN 全屏幕窗口的窗口区域的宽度和高度。就可以运用MoveWindow();方法比较多

也可以改变自已程序的界面,将每个控件的位置都计算出来,看下面这个例子,在窗口大小改变时,窗口里的控件也跟着调整位置.

  
void CEmail::OnSize(UINT nType, int cx, int cy) { CFormView::OnSize(nType, cx, cy); // TODO: Add your message handler code here if(nType==SIZE_RESTORED && cx>=522 && cy>=386) { CWnd *pwnd; CRect rect; pwnd=(CWnd *)GetDlgItem(IDC_COMBO_CATALOG); if(pwnd==NULL)return; pwnd->GetWindowRect(&rect); ScreenToClient(&rect); rect.right=cx-15; rect.left=rect.right - 90; pwnd->MoveWindow(&rect,TRUE); pwnd=(CWnd *)GetDlgItem(IDC_LIST); if(pwnd==NULL)return; pwnd->GetWindowRect(&rect); ScreenToClient(&rect); rect.right=cx-10; rect.bottom=rect.top+cy/3+20; pwnd->MoveWindow(&rect,TRUE); ((CListCtrl *)pwnd)->SetColumnWidth(1, rect.Width()-274); pwnd=(CWnd *)GetDlgItem(IDC_RICHEDIT); if(pwnd==NULL)return; rect.top=rect.bottom+5; rect.bottom=cy-10; pwnd->MoveWindow(&rect,TRUE); } }
2011-02-17 11:16:21

 做一套基准的界面,其他分辨率的界面通过和基准界面的长宽比例进行缩放。这个做起来还是比较省事。不过适应范围和实际效果很一般。因为不仅要考虑分辨率,还要考虑屏幕的密度问题也就是dpi.如果涉及到具体图片,除非图片本身是设计成可以自由缩放的特殊格式,比如android上使用的控件图片格式.9,否则均会出现图片失真的问题。界面变丑了,可能你会考虑用一个非常的大的图片去适应所有分辨率,但也行不通,长宽比不一样缩放肯定失真,大图片占空间,运行时缩小又要重采样的,耗时间啊!!因此,还是要准备不同分辨率的图片来平衡时间和空间上的开销。类似于android里面那种自适应的机制。
例如
(1)drawable-hdpi里面存放高分辨率的图片,如WVGA (480x800),FWVGA (480x854)
(2)drawable-mdpi里面存放中等分辨率的图片,如HVGA (320x480)
(3)drawable-ldpi里面存放低分辨率的图片,如QVGA (240x320)
甚至界面的布局也可以分成不同dpi的目录。

2011-02-17 13:15:21

自己来实现的话需要处理WM_DISPLAYCHANGE,根据分辨率比例算出控件的大小、位置,有点繁锁, 一个开源类库ResizableLib

2011-02-17 05:22:30
您不能回答该问题或者回答已经关闭!

相关文章推荐

  • C#中using指令的几种用法

    using + 命名空间名字,这样可以在程序中直接用命令空间中的类型,而不必指定类型的详细命名空间,类似于Java的import,这个功能也是最常用的,几乎每个cs的程序都会用到

  • C#实例解析适配器设计模式

    将一个类的接口变成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够一起工作

  • 使用托管C++粘合C#和C++代码(二)

    本文实现一下C++代码调用C#代码的过程。我构造一个简单并且直观的例子:通过C++ UI 触发C# UI.

  • C#开发高性能Log Help类设计开发

    项目中要在操作数据库的异常处理中加入写Log日志,对于商业上有要求,写log时对其它操作尽可能影响小,不能因为加入log导致耗时太多

  • Async和Await使异步编程更简单

    C#5.0中async和await两个关键字,这两个关键字简化了异步编程,之所以简化了,还是因为编译器给我们做了更多的工作

  • C#开发中的反射机制

    反射的定义:审查元数据并收集关于它的类型信息的能力。元数据(编译以后的最基本数据单元)就是一大堆的表,当编译程序集或者模块时,编译器会创建一个类定义表,一个字段定义表,和一个方法定义表等

  • C#运行时相互关系

    C#运行时相互关系,包括运行时类型、对象、线程栈和托管堆之间的相互关系,静态方法、实例方法和虚方法的区别等等

  • C#协变和逆变

    “协变”是指能够使用与原始指定的派生类型相比,派生程度更大的类型,“逆变”则是指能够使用派生程度更小的类型

  • C#基础概念之延迟加载

    延迟加载(lazy load)是Hibernate3关联关系对象默认的加载方式,延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作

  • 使用托管C++粘合C#和C++代码(一)

    C#在xml读写,数据库操纵,界面构造等很多方面性能卓越;C++的效率高,是底层开发的必备武器

  • C#中的索引器的简单理解和用法

    C#中的类成员可以是任意类型,包括数组和集合。当一个类包含了数组和集合成员时,索引器将大大简化对数组或集合成员的存取操作

  • 深入C# 序列化(Serialize)、反序列化(Deserialize)

    C#中的序列化和反序列化,序列化是.NET运行时环境用来支持用户定义类型的流化的机制