鱼C论坛

 找回密码
 立即注册
查看: 6444|回复: 7

[知识点备忘] 第007讲:Windows编程中的若干难点

[复制链接]
发表于 2014-7-23 15:56:02 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
知识点回顾:


1. 一个窗口的生与死

我们所有的代码分为两个部分:WinMain 函数和 WndProc 函数。

WinMain 函数只是包含一些常规的必要操作,如注册窗口类、创建窗口、从消息队列中检索和分发消息。这些都基本上是属于标配的内容,每个窗口程序我们都大致这么写,所以我之前给大家提供了模板。

关于窗口是如何诞生的,我们前几节课讲得很清楚了,再重复就显得小甲鱼磨叽,所以我们这里再谈谈窗口是如何“死”的。

【扩展阅读】系统如何销毁一个窗口(http://bbs.fishc.com/thread-48214-1-1.html


2. 究竟是谁调用了谁

在 Windows 编程有一句名言,叫:Don't call me, I will call you.其实讲的就是谁调用谁的道理。用户对窗口所有的操作都会触发相应的事件,而 Windows 把所有的事件转换为对应的消息,所有对窗口过程的调用都是以消息的形式触发,而我们写的大部分代码都是致力于对各种消息的处理和响应。

消息机制就是 Windows 的核心机制,那消息机制有多重要呢?这么说吧,以前C语言调用我们自己的函数,我们直接通过函数名调用即可,对吧?但是在 Windows 编程的做法可不是这样了。我们要调用自己写的函数,会选择通过发送消息给 Windows,然后由 Windows 再来通过消息间接调用我们的函数。初学 Windows 编程的童鞋可能觉得这样很没效率,但这样做恰恰是为了保证你的程序的高效实现,这就是 Windows 编程的游戏规则!


3. 队列消息和非队列消息

消息既可以是“队列消息”,也可以是“非队列消息”,队列消息是指那些由 Windows 放入消息队列的消息,主要由用户的输入产生,例如按键点击、鼠标移动、窗口重绘、还有定时器消息等。这些消息都是要经过消息循环,通过 GetMessage 检索消息,到 DisapatchMessage 将消息投递到窗口过程中处理。

队列消息以外的其他所有消息我们称之为非队列消息,他们通常是由调用特定的 Windows 函数引起的。例如上节课我们讲到的当 WinMain 调用 CreateWindow 函数时,Windows 就会创建窗口,并在创建过程中向窗口过程直接发送一条 WM_CREATE,注意,这条消息是不用进入消息队列的。

当然,消息机制的过程实际上是非常复杂的,目前我们只需要了解这么多就够了,在随后的学习中,我会不断地逐步展开来讲解,你会对此获得更深入的理解。


4. 速战速决

学习 Windows,我们还需要知道 Windows NT 是抢占式多任务环境,这就意味着当一个程序完成一项非常耗时的工作时,Windows 允许用户将控制权切换到其他程序上。

这本是一件非常棒的设计,但这种抢占式多任务模式未必总是会按照你期望的方式去工作。因此一定要注意,不要在处理某条消息上耗费太大的时间,这样的用户体验会很差!


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-7-23 17:00:49 | 显示全部楼层
第二个沙发来看看
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 2 反对 0

使用道具 举报

发表于 2014-7-23 17:27:16 | 显示全部楼层
强烈支持小甲鱼!顺便问下有打算出C#快速入门视频吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 2 反对 0

使用道具 举报

发表于 2014-7-27 16:40:57 | 显示全部楼层
小甲鱼,python快快更新啦
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 2 反对 0

使用道具 举报

发表于 2015-8-8 10:54:57 | 显示全部楼层
既然系统会自动调用WM_DESTROY消息,为什么代码中还要写呢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-8-8 10:56:08 | 显示全部楼层
发送WM_DESTROY的时候,窗口已经真正被销毁了吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-1-18 23:35:54 | 显示全部楼层
程序段1:
case WM_CLOSE:
        iResult = MessageBox(hwnd,TEXT("确定关闭窗口!"),TEXT("提示!"),MB_YESNO|MB_ICONWARNING);
        if(iResult == IDYES)
                DestroyWindow(hwnd);
        else
               return 0;

        case WM_DESTROY:
                PostQuitMessage(0);
                return 0;
程序段2:
case WM_CLOSE:
                iResult = MessageBox(hwnd,TEXT("关闭窗口!"),TEXT("提示!"),MB_YESNO|MB_ICONWARNING);
                if(iResult == IDYES)
                        DestroyWindow(hwnd);

                return 0;

        case WM_DESTROY:
                PostQuitMessage(0);
                return 0;

跟踪调试程序段2可以看出程序进入DestroyWindow(hwnd)后会继续执行WM_DESTROY,然后才退出DestroyWindow(hwnd),return 0。两段程序虽然运行结果相同,但是前者退出DestroyWindow(hwnd)后还会再次进入WM_DESTROY:中,先后进了2次,而第二次进入时其实窗口已经销毁了。请问程序段1的这种方式存在风险吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-11-28 13:12:00 From FishC Mobile | 显示全部楼层
windows 列队消息换来的是致辞中战略类型的攻击性系统基理,而非队列中的特殊性更加残酷,没有时间理的空间理论只有死亡和丢弃,而游戏里幼年的进程可以随时随地的干倒,没有天亮了
而UNIX的理念没有无用只有策略中心的偏移而已
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-22 09:57

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表