我在网上寻找答案,我的问题是:GUI框架是如何工作的?例如Qt是如何工作的?有没有关于从头开始编写GUI框架的书籍或网站?框架是否必须从操作系统的GUI框架中调用方法?
-- 谢谢任何花时间尝试回答这个问题的人,并请原谅我拼错了任何单词。
我在网上寻找答案,我的问题是:GUI框架是如何工作的?例如Qt是如何工作的?有没有关于从头开始编写GUI框架的书籍或网站?框架是否必须从操作系统的GUI框架中调用方法?
-- 谢谢任何花时间尝试回答这个问题的人,并请原谅我拼错了任何单词。
现在您可以编写 主要事件收集函数。此函数将一直运行。它的目的是检测事件并向正确的窗口发送消息。什么是事件?当您启动程序时,请存储鼠标x和y坐标。然后在一个循环中检查它们是否发生了变化。如果它们发生了变化,请找到该位置的窗口...并向其发送WM_MOUSEMOVE事件。您的收集函数应处理: - 鼠标移动 - 鼠标单击 - 鼠标双击(记住最后一次单击和位置,测量时间并决定是否为双击) - 定时器事件 - 键盘缓冲区更改 ...
现在您应该能够向Windows发送事件。但是您真正需要的是一种机制。它是消息队列和窗口过程的组合。通常的工作方式是这样的:每个窗口都有一个窗口过程,它通常接受四个参数:消息ID(例如鼠标移动、绘画消息),窗口句柄,参数1和参数2。您可以使用类似于send_message函数直接调用此窗口过程,或者可以通过post_message函数向该窗口发送消息。这将将消息放入队列中,窗口将逐一处理消息,最终接收到这个消息。那么为什么要直接调用某些消息并将其他消息放入队列中呢?因为优先级。您知道,键盘点击可能需要等待一段时间才能被处理。但是窗口重绘必须立即完成,以防止屏幕闪烁和错误数据。
因此,您的harvest_events函数使用post_message和send_message向窗口发送消息。而您的窗口消息泵使用类似于以下的典型消息泵获取它们:
while (pmsg = get_message() != NULL) send_message(pmsg->id, pmsg->hwnd, pmsg->p1, pmsg->p2);
get_message 函数简单地从队列中获取消息并调用 send_message 函数。简单易懂,对吧?但事实并非如此。这样做只会接收到驱动程序发送的窗口消息,您还需要一些函数来重新绘制窗口、移动窗口等等。当您创建 move_window 函数、resize_window 函数、show_window 函数和 hide_window 函数时,窗口坐标将发生变化。其他窗口的某些部分将被覆盖(如果顶层窗口被移动或关闭)。您需要计算哪些窗口受到坐标更改的影响,并向这些窗口发送 paint 消息(仅重新绘制未被覆盖的部分——请记住,您拥有剪裁绘图函数,因此这样做是可行的)。
这些函数引入了消息 msg_paint、msg_move、msg_resize、msg_hide 等...
最后,你需要维护窗口的层次结构。你的顶层窗口应该是桌面。它应该有子窗口(应用程序顶层窗口)。这些窗口可能有更进一步的子窗口(按钮、编辑框等)。容纳这些窗口的明显结构是窗口树。当你检测到鼠标点击时,你必须遍历窗口树,并以聪明的方式(找出谁拥有焦点、谁是模态的等)向正确的窗口发送消息。当你绘制时,你也必须遍历所有的子窗口,看看谁被覆盖了,谁没有。最后但并非最不重要的是,你需要将鼠标矩形处理为顶层窗口,以防止在重新绘制窗口或(使用定时器和msg_paint事件)动画时闪烁鼠标。
大致就是这样。