人的心理有个奇妙的特性:一项知识一旦学会之后,学习过程中面临的困惑和不解很快就会忘得干干净净,似乎一切都是自然而然,本来就该这样的。因此,关于「如何入门」这类问题,找顶尖高手来回答,未必能比一个刚入门不久的人来回答要好。就譬如最高票的那个回答,是一个非常精通 Windows 编程的高人回答的,但这样的答案能给初学者带来多少帮助,我这里想先打一个问号。
本文只涉及 Win32 GUI 入门,不涉及其它 Windows 编程的话题,譬如网络操作、异步 IO、系统服务、线程同步什么的,不要因为我没有提到那些内容就跳出来说我「答非所问」,我相信题主想要问的也不会是那些话题。
要想学习 Windows 编程,首先最重要的一点是:C 语言必须入门。这个要求听上去像是废话,可是事实上目前国内大部分计算机专业的学生本科甚至硕士毕业都没能达到,因此我不得不单独提出来再次强调一遍。C 语言入门之后再学 Windows 编程,可以避免很多不必要的挫折,节约很多时间。固然,有很多人在 C 语言没有入门的情况下就开始了 Windows 编程的学习,到处碰壁撞得头破血流之后仍然学会了 Windows 编程,而且顺便把 C 语言也入门了的,譬如我,但我并不认为这样的经历是值得向所有人推崇的。我个人认为,先停留在黑框框下把 C 语言入门了再开始学习 Windows 编程,是性价比更高的做法。
至于 C++ 的学习,C++ 和 Windows 编程是两棵不相关的技能树,学习 C++ 并不要求你必须懂得 Windows 编程,写 Windows 程序也并非必须用 C++。熟悉 C++ 对于学习 Windows 编程或许有间接的帮助,但至少直接的联系是没有的,你完全可以在没学过 C++ 的情况下就开始学习 Windows 编程。
要入门 Windows 编程,最重要的不是阅读什么教材,使用什么工具,而是先必须把以下几个对于初学者来说非常容易困惑的重要概念搞清楚:
3. 了解句柄的大概原理和资源管理。这部分要求比较简单,一个 C 语言真正入门的学生,在之前的学习里应该早就已经涉及过动态内存分配和管理了,也在一些练习里自己实现过类似句柄的面向对象封装方式了,因此学到这里的时候只要把句柄和他之前学过的内容联系起来,这部分并不难学。但如果你遇到动态内存分配的时候还是搞得一塌糊涂,对于对象所有权转移、生命周期管理等还一头雾水,我个人建议你先回到「黑框框」把 C 语言入门了再来学 Windows 编程。
5. 理解窗体重绘机制。这点其实属于消息模型的一个子话题,但由于入门的时候会给初学者带来的困扰很大,因此我单独提出来作为一个点。在 Windows 9x 下,一个窗口出现在另外一个窗口上方的时候,是会把下面的窗口上的内容抹去的。当上面的窗口离开之后,下面的窗口需要重画自己被抹去的内容。更高版本的 Windows 虽然系统能够自动缓存被遮盖的窗体上的内容,但从编程的角度来看,程序员仍然需要遵从之前的窗口绘制机制来编写自己的程序,假定自己的程序被覆盖的时候会被擦除。为了能够正确处理擦除与重绘,绘制窗口内容必须通过监听重绘消息来进行,想改变窗口内容的时候不能随时往窗口上画,而是要先准备好要画的内容但不画,然后发消息触发重绘消息让系统通知你画。这些反直觉的行为的理解和掌握,是初学的时候必须迈过的坎。
上面这些概念都掌握之后,入门 Win32 GUI 编程就是一件相对容易的事情了。接下来只要找一份入门教程,按部就班把例题都过一遍,再自己亲手写几个 GUI 小程序,差不多也就上手了。这位学生在总结的时候提到说我推荐了一份非常有名的教程,很抱歉让他失望了,那份教程其实我自己都没看过,我只是在网上随手搜了一个教程,看了一下目录,发现他入门需要的知识点上面都有列举,于是就发给他了。总之,入门 Windows 编程,最重要的是理解并掌握上面提到的几个基本概念,概念掌握了,任何一份不要存在严重错误和硬伤的教材都可以用来入门,至于具体的 API 怎么用,用的时候现查手册就可以了,没必要把「学习 API 的使用」作为一个重点去攻克。