创建一个看起来很专业(和表现!)的表单设计器

时间:2011-04-03 23:05:19

标签: c++ windows winapi mfc form-designer

当我开始编程(大约10年前)时,有三件事令我惊讶:

  • 编译器/口译员(当时我认为它们是“使我的程序有效的程序”,通常后面跟着限定词“无论它们是什么”)
  • 代码编辑
  • 表单设计师

那时候,我接受了所有这些作为生活的事实。我能够制作我自己的专用程序,但是“让我的程序工作的程序”,代码编辑和表单编辑都是由神创造的,我无法用它们搞砸。

然后我上大学,参加了正式的语言处理课程。学习了正式语法,解析器,抽象语法树等后;关于编译器,口译员和代码编辑的所有魔力很快就消失了。编译器和解释器可以用合理且简单的方式编写,而语法突出显示代码编辑器可能需要的唯一不合理的东西是Windows API黑客。

然而,直到今天,表格编辑对我来说仍然是一个谜。要么我缺乏制作表单设计师所需的技术知识,要么我掌握了这些知识,但却找不到使用它来实现表单设计器的方法。

使用Visual C ++和MFC,我想实现一位受到最佳表单设计师启发的表单设计师:

Visual Basic 6's form designer

特别是,我想模仿我最喜欢的两个功能:

  • 正在设计的表单位于容器内。因此,通过简单地将容器的大小调整到合适的大小,可以设计任意大的形式而不会浪费太多的屏幕空间。

  • “与网格对齐”选项使设计专业的用户界面更少 令人沮丧的。事实上,我会说使用Visual Basic的表单设计器创建具有专业外观的用户界面实际上是简单,有趣和愉快。即便是像我这样的左脑程序员。

所以,我有以下问题:

  1. 如何制作表单设计器,其中正在设计的表单位于容器内?被设计的表单是否包含在另一个窗口中的实际窗口?或者它只是由表单设计者“手动”绘制的模型?

  2. Windows API和/或MFC是否包含函数,类,以及任何可以轻松创建“可选”项目的内容(选中时用小白框或蓝框包围,当它们被“抓取”时可调整大小“通过其中一个”边缘“)?

  3. 如何实现“与网格对齐”功能?

3 个答案:

答案 0 :(得分:30)

答案 1 :(得分:6)

您实现的表单设计器几乎就像普通的GUI一样。你有可以拖动的东西(你的小部件),你有可以点击的东西(你的按钮),你有你可以选择的东西(你放置的小部件),这就是它。


问:现在,如何在GUI中显示窗口?
A:你画它,就这么简单。

问:你如何把东西放在那个窗口里?
答:您检查“父”对象的边界。你几乎可以说表单设计师就像一个小游戏,你有一个场景图,包含所有你的小部件,由父子关系连接。

问:那么,如何在GUI中选择内容?
答:检查当前鼠标位置是否点击所有(近)小部件的边界(场景图仅对此有帮助,如四叉树)。

问:如何在网格上对齐小部件?
答:对于网格对齐,我们有一个简单的例子:假设您的实际分辨率在x轴上为100px,但您希望网格在x上的分辨率为10px。现在假设您以实际分辨率移动小部件28px。要获得网格分辨率,只需除以10,得到2.8,然后对其进行舍入,最后在x上移动小部件3切片。四舍五入是关键。仅当网格移动为>= ?.5时,才会捕捉到下一个图块。否则你只需留在旧的。


希望这可以为您提供有关如何启动表单设计器的一般提示。玩得开心。 :)
(PS:不知道任何特定的WinAPI / MFC功能/类可以帮助你,抱歉。)

答案 2 :(得分:2)

只需在@Xeo已经说过的内容中添加一两点:

首先,不,你不总是自己绘制所有内容。在正常设计阶段,你基本上只是绘制一些看起来像控件的东西,但是(至少是IIRC)它还允许你在测试模式下“运行”一个表单(当然VC ++对话框设计器也是如此),尽管VB更加原始,我认为它确实具有这种特殊能力)。测试模式是指您在(必要)附加任何代码之前可以“运行”表单 - 即使单击按钮(例如)在周围程序中没有执行任何操作,控件本身也能正常工作 - 按钮正常点击,编辑控件可让您编辑等

这是通过实际实例化一个控件,告诉它正确的位置,大小和属性来完成的。 ActiveX控件做了相当多的工作来支持这一点,而之前的“Windows自定义控件”也做得很好,尽管复杂程度要低得多。从控制的角度来看,它的工作方式与通常情况完全一样,接收输入,向其父级发送通知等。唯一改变的是父级最忽略它收到的大多数通知,但是控件没有真的很清楚。

有两种基本方法可以做到这一点。一种是自己创建一组控件,以及它们的位置,大小等,并使用CreateWindow(或CreateWindowEx等)来创建正确类的窗口。虽然相对容易处理,但它的缺点是它会将所有标签处理留给您。

另一种可能性是创建一个DLGTEMPLATE结构来保存关于对话框的数据,并创建一些DLGITEMTEMPLATES用于各个控件,最后使用CreateDialogIndirect创建一个对话框有这些规格,持有这些控制。这很乏味,但它确实有效,当你完成它时,它会自动处理控件之间的标签(并且与任何其他对话框的工作方式相同,因为它是以相同方式创建它的Windows代码)。

其次,既然你已经标记了这个C ++,你可能想看看CodeProject上实际实现对话框编辑器的一些code。虽然它不像某些商业软件那么复杂,但它是一个合理的完整的表单/对话框编辑器,完成了你所询问的大部分内容。

相关问题