Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
User interface GUI框架是如何工作的?_User Interface_Graphics_Frameworks - Fatal编程技术网

User interface GUI框架是如何工作的?

User interface GUI框架是如何工作的?,user-interface,graphics,frameworks,User Interface,Graphics,Frameworks,我一直在网上寻找答案,我的问题是: GUI框架是如何工作的?例如,Qt是如何工作的,是否有关于从头开始编写GUI框架的书籍或wibsite?框架是否也必须从操作系统GUI框架调用方法 --感谢所有花时间回答这个问题的人,如果我拼错了什么,请原谅我 像Qt这样的GUI框架通常是通过使用现有操作系统的基本对象(窗口、字体、位图等),将它们封装在与平台无关、不那么笨重的类/结构/句柄中,并为您提供操作它们所需的功能来工作的。是的,这几乎总是涉及到使用操作系统自己的函数,但不一定——例如,如果您正在设计

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


--感谢所有花时间回答这个问题的人,如果我拼错了什么,请原谅我

像Qt这样的GUI框架通常是通过使用现有操作系统的基本对象(窗口、字体、位图等),将它们封装在与平台无关、不那么笨重的类/结构/句柄中,并为您提供操作它们所需的功能来工作的。是的,这几乎总是涉及到使用操作系统自己的函数,但不一定——例如,如果您正在设计一个API来绘制OpenGL UI,那么大多数底层操作系统的GUI内容甚至都不起作用,而您几乎可以自己做每件事


不管怎样,这都不是为胆小的人准备的。如果你不得不问GUI框架是如何工作的,你甚至还没有准备好设计一个。您最好还是坚持使用现有的框架并扩展它,以完成它尚未完成的漂亮工作。

在过去,我们从头开始做了很多GUI编程。这并不像看上去那么难,但需要几周时间才能有结果

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

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

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

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

在这一点上,您有: -原始图形函数, -窗口结构, -鼠标驱动程序、键盘驱动程序和计时器, -矩形运算

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

现在,您应该能够将事件发送到windows。但你真的需要一个机制。它是消息队列和窗口过程的组合。它通常是这样工作的:每个窗口都有一个窗口过程,该过程通常接受四个参数:消息id(即,它是否移动鼠标,它是否绘制消息)、窗口句柄、参数1和参数2。您可以使用诸如send_message函数之类的函数直接调用此窗口过程。或者您可以通过post_消息功能向此窗口发送消息。这将把消息放入队列,窗口将逐个处理消息,最终接收到这条消息。那么,为什么要直接调用一条消息,然后将其他消息放入队列?因为优先权。你看,键盘点击在被处理之前可能要等待一段时间。但窗口重画必须立即完成,以防止屏幕上出现闪烁和错误数据

因此,您的harvest_events函数使用post_消息和send_消息向windows发送消息。您的窗口消息泵使用以下典型消息泵获取它们:

而(pmsg=get_message()!=NULL)发送_message(pmsg->id,pmsg->hwnd,pmsg->p1,pmsg->p2)

get_message只是从队列中获取消息,并调用send message。简单,嗯?嗯,不完全是这样。这样,您将只接收到windows的驱动程序消息,但您还需要一些函数来重新绘制窗口移动窗口,等等。。创建“移动窗口”、“调整窗口大小”、“显示窗口”和“隐藏窗口”功能时,窗口坐标将更改。其他窗口的部分将被覆盖(如果顶部窗口被移动或关闭)。您需要计算哪些窗口受到坐标更改的影响,并向这些窗口发送绘制消息(要仅重新绘制被覆盖的部分,请记住,您具有剪裁绘图功能,因此这将起作用)

这些函数介绍消息msg\u paint、msg\u move、msg\u resize、msg\u hide

最后,您需要维护windows的层次结构。您的顶部窗口应该是桌面。它应该有子窗口(应用程序顶部窗口)。这些窗口可能有更多的子窗口(按钮、编辑框等)。保存这些子窗口的明显结构是窗口树。当您检测到鼠标点击时,您必须遍历窗口树并以一种智能的方式(找出谁有焦点、谁是模态等)将消息发送到正确的窗口。当你画画的时候,你也必须穿越