学习win32的编程,与DOS不同的是,实现的目标是一个具有你所需要的功能的窗口。这个窗口时时刻刻都在与操作系统之间,通过一个称之为消息队列的东西传送数据。因此处理好各种消息便成了win32编程的核心。
学习参考书:Windows程序设计(第五版珍藏版 )
学习窗口编程之前的几个概念:
- 实例(instance): 简单理解,就是类定义的对象,称为实例;
- 句柄(handle):和文件句柄一样,它实际上是一个整数,用来标识是哪一个实例也就是实例的标识符,通过句柄可以操作这个实例;
- 回调(CALLBACK):可以理解为函数指针;
- 窗口(Window):一个应用程序窗口上一般会在标题栏上显示程序的名称,紧挨着标题栏的菜单栏,或许还会有状态栏、滚动条等其他装饰品。
- 窗口类(WNDCLASSEX):这个类不同于C++的类,其实是结构体,包含了窗口的基本属性。 WNDCLASS是早期版本,WNDCLASSEX是现在版本
- 消息循环:当一个应用程序运行的时候,操作系统会为该应用程序创建一个消息队列,这个消息队列用来存放该程序(可能)创建的(各种)窗口的消息,当用户对应用程序进行操作时,此时Windows会立即把这一消息告诉应用程序,使应用程序能作出相应的动作。
- 窗口的过程函数:当一个窗口建立好之后,就可以从Windows那里不断的接收到Windows发来的消息,接到消息之后我们就需要一个函数来处理这些消息,可以简单的理解为,这个用来处理接收到的消息的函数称为窗口过程函数或回调函数。
一、WinMain( )函数
WinMain函数是窗口程序的入口函数,在这个函数中你就可以调用各种API来完成你的目标。
先不创建窗口,而是调用一下通用对话框,主要是了解WinMain()函数。
#include <windows.h>
int WINAPI WinMain( HINSTANCE hInstance, //当前窗口实例句柄
HINSTANCE hPrevInstance, //前一个实例句柄,Win32下为NULL
LPSTR lpCmdLine, //命令行参数字符
int nShowCmd )//窗口的显示方式
{
MessageBox (NULL, "窗口里的文字","窗口标题", MB_OK);//通用对话框
return 0;//函数返回值
}
WINAPI:先理解为函数的一种调用规则,是一个宏定义
HINSTANCE:实例句柄类型
LPSTR:字符串指针
MessageBox()函数是Win32的API函数,调用通用对话框,这不是我们要学习的窗口编程。
二、基本Win32程序
基本流程:
- 注册窗口类。先调用RegisterClassEx()函数,用当前窗口句柄去向操作系统申请将要创建一个什么样的窗口
- 创建窗口类。申请成功之后,再调用CreateWindowEx()函数创建一个窗口对象,这仅仅是一个外观
- 显示窗口类。调用ShowWindow()函数设置初期表示,即最大最小或普通。
- 更新窗口类。调用UpdateWindow()函数向窗口传送WM_PAINT消息来画出窗口的内容
- 消息循环。窗口创建完成后还只是一个静止的窗口,还需要创建消息循环,最后再return。
- 消息处理函数。WinMain()函数之后,还需要创建一个消息处理函数
真正编程的部分是消息处理函数。
#include <windows.h>
TCHAR szTitle[20] = TEXT("窗口的标题");//窗口的标题是最后窗口显示出来的
TCHAR szWindowClass[20] = TEXT("name");//窗口的名称,在后面用该窗口的一个标识
ATOM MyRegisterClass(HINSTANCE);//注册窗口函数
BOOL InitInstance(HINSTANCE, int);//初始化窗口函数
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);//消息处理函数
//窗口主程序
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow )
{
MSG msg;
MyRegisterClass(hInstance);//注册窗口类
if ( !InitInstance(hInstance, nCmdShow) ) { //包含窗口的创建、显示、更新)
return FALSE;
}
while ( GetMessage(&msg, NULL, 0, 0) ) { //消息循环
TranslateMessage(&msg); //消息解释
DispatchMessage(&msg); //消息发送
}
return msg.wParam;//return 0有非正常退出的可能性。
}
//注册窗口类
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wc; //定义一个窗口类,其实是一个结构体
wc.cbSize = sizeof(WNDCLASSEX); //结构体的字节长度
wc.style = CS_HREDRAW | CS_VREDRAW; //窗口式样
wc.lpfnWndProc = (WNDPROC)WndProc; //窗口处理函数
wc.cbClsExtra = 0; //分配给窗口类结构之后的额外字节数,一般为0
wc.cbWndExtra = 0; //分配给窗口实例之后的额外字节数,一般为0
wc.hInstance = hInstance; //实例句柄
wc.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW); //光标
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //背景
wc.lpszMenuName = NULL; //菜单
wc.lpszClassName = szWindowClass; //窗口名
wc.hIconSm = LoadIcon(wc.hInstance, (LPCTSTR)IDI_APPLICATION);
return RegisterClassEx(&wc);
}
//初始化窗口
BOOL InitInstance(HINSTANCE hInstance, int nCmdshow) {
HWND hWnd;
//创建窗口
hWnd = CreateWindow(szWindowClass,//窗口类名
szTitle,//窗口的标题
WS_OVERLAPPEDWINDOW,//窗口的风格
0,//窗口初始显示位置x
0,//窗口初始显示位置y
320,//窗口的宽度
180,//窗口的高度
NULL,//父窗口
NULL,//子菜单
hInstance,//该窗口应用程序的实例句柄
NULL );//创建参数
if (!hWnd) {
return FALSE;
}
ShowWindow(hWnd, nCmdshow);//显示窗口
UpdateWindow(hWnd); //立即显示
return TRUE;
}
//窗口消息处理
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY: //关闭窗口
PostQuitMessage(0); //发送关闭消息
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam); //缺省窗口处理函数
}
return 0;
}
这就是一个简单的win32窗口程序。
后续继续整个代码的介绍.