很多人都说windows编程凉了,实则不然,因为微软不倒,我们还在使用微软提供的winddows操作系统,windows编程就不会消亡,MFC也是一样,不可否认其他编程语言的方便,强大,但是windows编程也有它自己的优势,学习windows编程的人喜欢的就是DLL注入,钩子之类的东西,觉得很装逼
确实,曾经我也因为这个原因而学习这方面的知识,后来,现实打败了我,于是我老老实实的学着Linux内核
首先windows是不开源的,只给你提供了各种API接口,有上万个,但是我们只需要了解常用的就行
Easyx图形库是对windows的封装,使用简单,但也限制了代码的自由度
win32框架
目录
1、注册窗口类 RegisterClassEx
2、创建窗口 CreateWindowEx
3、在桌面显示窗口 ShowWindow
4、更新文本框 UpdateWindow
5、进入消息循环
-
获取消息 GetMessage
-
将消息发送到定义的MainWndProc函数处理 DispatchMessage
-
进入下一个循环
01
创建win32程序
VS2015下创建win32程序
在这一步的时候一般不会去掉空项目上面的√,创建的项目自带win32框架代码,不用自己去码那些重复的代码,但是因为要展现win32框架,加上√后代码太冗杂,容易代码劝退,所以选择空项目。
还有一个原因就是,如果可以,自己码一遍win32的框架,有助于理解和学习
02
编辑代码
#include <windows.h>
// 窗口函数的函数原形
LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
WCHAR szClassName[] = L"MainWClass";//窗口类的名称
WNDCLASSEX wndclass;
// 用描述主窗口的参数填充WNDCLASSEX结构
wndclass.cbSize = sizeof(wndclass); // 结构的大小
wndclass.style = CS_HREDRAW | CS_VREDRAW; // 指定如果大小改变就重画
wndclass.lpfnWndProc = MainWndProc; // 窗口函数指针
wndclass.cbClsExtra = 0; // 没有额外的类内存
wndclass.cbWndExtra = 0; // 没有额外的窗口内存
wndclass.hInstance = hInstance; // 实例句柄
wndclass.hIcon = LoadIcon(NULL,
IDI_APPLICATION); // 使用预定义图标
wndclass.hCursor = LoadCursor(NULL,
IDC_ARROW); // 使用预定义的光标
wndclass.hbrBackground = (HBRUSH)
::GetStockObject(WHITE_BRUSH); // 使用白色背景画刷
wndclass.lpszMenuName = NULL; // 不指定菜单
wndclass.lpszClassName = szClassName; // 窗口类的名称
wndclass.hIconSm = NULL; // 没有类的小图标
// 注册这个窗口类
RegisterClassEx(&wndclass);
// 创建主窗口
HWND hwnd = CreateWindowEx(
0, // dwExStyle,扩展样式
szClassName, // lpClassName,类名
L"My first Window!", // lpWindowName,标题
WS_OVERLAPPEDWINDOW, // dwStyle,窗口风格
CW_USEDEFAULT, // X,初始 X 坐标
CW_USEDEFAULT, // Y,初始 Y 坐标
CW_USEDEFAULT, // nWidth,宽度
CW_USEDEFAULT, // nHeight,高度
NULL, // hWndParent,父窗口句柄
NULL, // hMenu,菜单句柄
hInstance, // hlnstance,程序实例句柄
NULL); // lpParam,用户数据
if (hwnd == NULL)
{
MessageBox(NULL, L"创建窗口出错!", L"error", MB_OK);
return -1;
}
// 显示窗口
ShowWindow(hwnd, nCmdShow);
//更新这个窗口
UpdateWindow(hwnd);
// 从消息堆中取出消息
MSG msg;
while (::GetMessage(&msg, NULL, 0, 0))
{
// 转化键盘消息
TranslateMessage(&msg);
// 将消息发送到相应的窗口函数
DispatchMessage(&msg);
}
// 当GetMessage返回0时程序结束
return msg.wParam;
}
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
TCHAR szText[] = L"第一个win32程序!";
switch (message)
{
case WM_PAINT: // 窗口客户区需要重画
{
HDC hdc;
PAINTSTRUCT ps;
// 使无效的客户区变的有效,并取得设备环境句柄
hdc = BeginPaint(hwnd, &ps);
// 显示文字
TextOut(hdc, 10, 10, szText, wcslen(szText));
EndPaint(hwnd, &ps);
return 0;
}
case WM_DESTROY: // 正在销毁窗口
// 向消息队列投递一个WM_QUIT消息,促使GetMessage函数返回0,结束消息循环
PostQuitMessage(0);
return 0;
}
// 将我们不处理的消息交给系统做默认处理
return DefWindowProc(hwnd, message, wParam, lParam);
运行结果
这个就是简单地创建了一个win32程序,相比较于Easyx图形库来说,win32简直就是太复杂了
图形库的initgraph();closegraph();就解决了win32近100行的代码,其实也不能怪win32,它只是调用了这几个API函数RegisterClassEx、CreateWindowEx、ShowWindow、UpdateWindow、GetMessage、 DispatchMessage,不过函数的参数太多了而已。
事实也是如此,win32的绝大部分API函数参数都多的离谱。如果一上来就让你接触win32可能绝大部分人都会函数劝退。
而且那些变量自己一个都不认识,怎么搞!其实不是你不认识,只是这些个变量穿了一件外套。
例如:(VS下选中变量右键转到定义)
typedef unsigned int UINT;
在上面代码中需要注意的是注册的窗口类名必须和创建的窗口类名一致,否则创建窗口失败
例如将注册时的 szClassName 换成 DeRoy ,程序运行会弹出对话框。
然后就是那些函数的参数介绍了,在这里我就不介绍了,因为太多了,我告诉大家一个方法
在VS中,选中要查询的函数或者宏,按F1键,函数介绍和宏的相关信息就会出来了,特别全
例如我选中CS_HREDRAW,按下F1键
弹出界面
全英文看不懂怎么办,我不知道大家用的什么浏览器啊,下载一个翻译插件,
我用的是谷歌浏览器,自带翻译功能
win32就介绍到这里,其他的消息机制,GDI,控件什么的,个人建议
图书馆借本Windows编程的书自己看,图书馆有借阅期限的,想自己买个实体的可以看下这个链接,这本书仅介绍了消息机制,GDI绘图,控件一些基础的东西,然后做了几个小游戏,没有网络编程,钩子,内核之类的,适合入门学习。