如果您想要编写一个图形界面的windows程序,您会用什么语言呢?
C#?VB?抑或是易语言?
哦不好意思。他们都有一个通病:经过深度封装,效率太差,稳定性也(可能)不太好。
那么我们应该选用什么呢?
C++!!!
没错,我们这个专栏,就是要讲讲最底层的Windows图形界面(GUI)程序。(当然您要用MFC,Qt什么的我也没意见,反正这些封装很浅的也挺好的,不过我就是喜欢绕远路)
那么C++的Win32程序有什么缺点呢:
纯代码编程(100%),不直观(编写时),难度较高,不好(自)学,代码比较臃肿,而且效果比较有限。
但是没办法,底层的东西,感觉还是最好的。(至少执行效率秒杀C#VB)
我不是最近在开发ClickIDE吗?然后我们786同学在开发C+++。我用C++,他用C#。结果打开同样的文件,我花了不到0.1秒,他花了10秒其中还有3~4秒处于未响应的状态。况且他的自适应也不怎么样。
好这下直观了吗?还犹豫吗?我们一起开始学习!
(PS这是我第一次写纯基础的教程,若有不好请见谅哈谢谢。)
本教程中的所有软件使用Dev-C++5.11编译通过,用VS也行,不过比较烦。还是用老古董吧。
废话不多说,现在我们开始今天的第一个程序。
第一步:选择文件->新建->项目,会弹出一个叫“新项目”的框框。根据图上的内容进行选择和填写。

第二步,选择好位置,进行保存。一个项目会有很多文件,建议单独建一个文件夹。
第三步,创建完成,可以看见添加了一堆示例代码。我们一会儿来解读一下。

然后我们修改第44行,把"Caption"改为"Hello, world!"。
第四步,编译运行(F11),来看看,结果如何!

与您想象的是否一致呢?
好了,这样我们的第一个Win32程序就完成了,之后我们朝这个空白窗口不断添加各种控件,然后就变成一个像模像样的软件了!
(顺便说一句,ClickIDE就完全使用Win32编写的,因此您看到的每一个按钮,每一个菜单,每一个图标,每一个编辑框,全部都是控件!)
哦差点忘了,我们先赶紧来解释一下这个示例代码吧。
#include <windows.h> //Windows编程都需要的一个头文件,有很多的内容
/* 处理窗口消息的函数 */
LRESULT CALLBACK WndProc(HWND hwnd/*窗口句柄*/, UINT Message/*消息代号*/, WPARAM wParam/*WPARAM类型参数,常见的有数字等*/, LPARAM lParam/*LPARAM类型参数,常见的有字符串等*/) {
switch(Message) {
/* 销毁窗口的时候发出WM_DESTROY消息 */
case WM_DESTROY: {
PostQuitMessage(0);//告诉Windows,你的程序要结束了
break;
}
default:
return DefWindowProc(hwnd, Message, wParam, lParam);//如果这个消息没有被您自己处理的话,交给Windows系统按照默认方式处理。如果之前您已经处理了这个消息,就相当于“拦截”了这个消息,就不会进default,也不会交给系统处理。
}
return 0;
}
/* WinMain函数是程序的入口点,exe文件从这里开始执行,相当于控制台程序的main() */
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
WNDCLASSEX wc; /* 暂时不用懂 */
HWND hwnd; /* 窗口的句柄("Handle"),是个很玄乎的东西,我自己还没完全搞懂。。。反正您要知道它代表着一个窗口 */
MSG msg; /* 暂时存储我们接收到的消息 */
/* 清空结构体中的内容(获取内存) */
memset(&wc,0,sizeof(wc));
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpfnWndProc = WndProc; /* 接收到了消息,交给这个函数处理 */
wc.hInstance = hInstance; /* 也是个玄乎玩意儿 */
wc.hCursor = LoadCursor(NULL, IDC_ARROW); /* 光标形状 */
/* COLOR_WINDOW,是一个宏,代表窗口颜色(背景色)是白色 */
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszClassName = "WindowClass"; /*要注册的窗口类名,就是像它的ID一样*/
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); /* 图标 */
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc)) {
MessageBox(NULL, "Window Registration Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
return 0;
}
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,"WindowClass","Hello, world!",WS_VISIBLE|WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, /* x */
CW_USEDEFAULT, /* y */
640, /* width */
480, /* height */
NULL,NULL,hInstance,NULL);
if(hwnd == NULL) {
MessageBox(NULL, "Window Creation Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
return 0;
}
//下面两行是我自己加的,模板里没有,但是应该有(虽然没有好像也没事?)
ShowWindow(hwnd, 1);//让窗口显示,如果是ShowWindow(hwnd, 0);就是隐藏窗口。现在知道hwnd是干什么用的了吗?就是窗口的”身份证"
UpdateWindow(hwnd);//更新窗口
/*整个软件的核心,就是不断接受消息并处理,这就是Windows程序的消息机制,后面有时间我会讲一讲。因为GetMessage是阻塞型函数,因此不会导致程序一直运转而导致CPU高消耗
*/
while(GetMessage(&msg, NULL, 0, 0) > 0) { /* 如果没有接收到错误信息 */
TranslateMessage(&msg); /* 翻译成消息代号 */
DispatchMessage(&msg); /* 翻译好了消息,交给WndProc处理 */
}
return msg.wParam;
}
虽然注释挺详细,但是原版都是英文的,我就用自己的话和大家讲一讲吧。因为没有行号显示,我只能全部放进注释了,请自行看代码!(哈哈,突然发现786的第一篇Apple开发也是这种思路,先新建一个模板项目,然后解说模板代码)。
好了今天就讲那么多,本文均有nth.ink原创,未经允许谢绝转载,感谢大家的支持,你们的支持是我更新的动力!
(还有,Win32我是纯靠自己理解一点点摸索出来的,不知道大家听不听得懂我讲,有问题欢迎评论区!同时看的同时,自己也一定要实践啊!!)