GUI框架如何工作?

时间:2010-05-24 05:33:44

标签: user-interface graphics frameworks

我一直在网上寻找答案,我的问题是: GUI框架如何工作?例如,Qt是如何工作的,是否有关于从头开始编写GUI框架主题的书籍或wibsites?并且框架还必须从操作系统GUI框架调用方法吗?

- 感谢任何一个花时间尝试回答这个问题的人,如果我拼错了任何东西,请原谅我。

3 个答案:

答案 0 :(得分:5)

像Qt这样的GUI框架通常可以通过获取现有操作系统的原始对象(窗口,字体,位图等),将它们包含在更加平台中立且不那么笨重的类/结构/句柄中,并为您提供功能。我需要操纵它们。是的,这几乎总是涉及使用操作系统自己的功能,但它没有 - 如果你正在设计一个API来绘制OpenGL UI,例如,大多数底​​层操作系统的GUI内容都无法工作,而且你将自己做所有事情。

无论哪种方式,都不适合胆小的人。如果你不得不问一下GUI框架是如何工作的,你甚至还没准备好设计它。你最好坚持使用现有的框架并将其扩展到做它已经没有做过的漂亮的东西。

答案 1 :(得分:4)

过去,我们从头开始进行许多GUI编程。这虽然看起来并不困难,但要花几周的时间才能得出结果。

首先,您需要一个好的绘图库。该库的最小功能是绘制剪切的矩形(使用图案),线条,位图和字体。您可以通过将字体创建为位图来作弊,并且剪切后的矩形只是一堆水平线。

现在至少需要鼠标,键盘和计时器驱动程序(如果操作系统尚未提供)。通常,您将需要检测键,符号键(例如Shift等),鼠标移动和鼠标单击。基本的计时器功能可让您检测双击。

然后,您需要创建一个窗口数据结构。该数据结构必须具有坐标(即矩形),链接到父窗口(如果不是顶部窗口)和窗口函数(即当该窗口应处理某些事件时将调用的函数)。

一旦可以在屏幕上绘制,就需要一些矩形代数函数。您至少需要一个好的函数来计算矩形的交点,并相对于绝对坐标的快速分辨率。例如-如果您的子窗口有父窗口,则应将其x和y递归添加到父x和y,直到到达顶部窗口。

此时,您拥有: -基本的图形功能, -窗户结构 -鼠标驱动程序,键盘驱动程序和计时器, -矩形算术。

现在,您可以编写主要事件收集功能。此功能将一直运行。目的是检测事件并将消息发送到正确的窗口。什么事好了,当您启动程序时,请存储鼠标的x和y坐标。然后循环检查它们是否已更改。如果它们已更改,请在该位置找到窗口...并向其发送WM_MOUSEMOVE事件。您的收割功能应处理: -鼠标移动 -鼠标点击 -鼠标双击(记住最后的点击和位置,测量时间并确定是否是双击) -计时器事件 -键盘缓冲区更改 ...

现在,您应该可以将事件发送到Windows了。但是您确实需要一种机制。它是消息队列和窗口过程的组合。通常它是这样工作的:每个窗口都有一个窗口过程,该过程通常接受四个参数:消息ID(即鼠标移动,是否绘制消息),窗口句柄,参数1和参数2。您可以使用直接调用此窗口过程类似于send_message函数。或者,您可以通过post_message函数向该窗口发送消息。这会将消息放入队列,窗口将一个接一个地处理消息,最终接收到该消息。那么,为什么要直接调用一条消息,然后将其他消息放入队列呢?因为优先。您会看到,键盘单击可能需要一段时间才能被处理。但是窗口重绘必须立即完成,以防止屏幕上出现闪烁和错误数据。

因此,您的Harvest_events函数使用post_message和send_message将消息发送到Windows。然后您的窗口消息泵使用典型的消息泵来获取它们,如下所示:

while(pmsg = get_message()!= NULL)send_message(pmsg-> id,pmsg-> hwnd,pmsg-> p1,pmsg-> p2);

get_message仅从队列中获取消息,然后调用发送消息。简单吧?好吧,事实并非如此。这样,您将只收到驱动程序消息到Windows,但是还需要一些函数来重绘窗口移动窗口,等等。当您创建move_window函数时,请重新调整窗口大小,显示窗口大小和hide_window函数,您的窗口坐标将改变。其他窗口的部分将被发现(如果顶部窗口被移动或关闭)。您需要计算哪些窗口受坐标更改的影响,并向这些窗口发送绘制消息(仅重新绘制那些被发现的部分-请记住,您已经裁剪了绘图功能,这样就可以了。

这些功能介绍了消息msg_paint,msg_move,msg_resize,msg_hide ...

最后,您需要维护窗口的层次结构。您的顶部窗口应该是桌面。它应该具有子窗口(应用程序顶部窗口)。这些窗口可能还有其他子窗口(按钮,编辑框等)。用于保存这些子窗口的明显结构是窗口树。当检测到鼠标单击时,您必须遍历窗口树并以一种聪明的方式(找出谁有焦点,谁是模态的,等等)进行操作,以将消息发送到右侧窗口。当您画画时,您还必须遍历所有孩子,看看谁被发现,谁未被发现。最后但并非最不重要的一点是,您需要将鼠标矩形作为顶部窗口处理,以防止在重新绘制窗口或(使用计时器和msg_paint事件)动画时使鼠标闪烁。

就是这样。

答案 2 :(得分:-1)

构建GUI框架不是1,2,3过程。

我只能说,看看其中一些开源IDE,比如Netbeans source code

查看代码,然后构建整个IDE。