WinAPI入门: 第一个标准Win32窗口程序
//v1;WinAPI入门;第一个标准Win32窗口程序;[改进&详细注释版@HelloWin.c;]
/*/背景说明;
1.无论你编程使用的是MFC,还是DirectX,最终都是调用的WinAPI函数;其功能仅限于WinAPI的某个子集;
因此,WinAPI编程有时可以简单实现MFC某些看起来复杂的功能;还可以实现MFC编程无法实现的功能;
WinAPI定义了Windows编程所需的一切,直接使用WinAPI将无所不能;
2.通过学习WinAPI编程,有助于理解现代操作系统的工作原理,更能深入理解Windows应用程序的运行原理;
3.WinAPI编程作为一切Windows应用程序的基础,本程序的大部分语句都会出现在任何Windows程序中;
因此,本程序可以作为任何新程序的起点;或者通过复制作为一个模板来使用;
4.本例演示最简单的标准Win32应用程序的结构框架;更完整的Win32应用程序还应该包括菜单和鼠标响应;
因此,本例的每个部分都是必不可少的;包括窗口的类注册/创建/显示/消息循环/回调函数等;
//----------------------------------------------±-----------------------------------------------*/
//主程序;
//---------------------------------------------*/
//库引用;
#include <windows.h> //WinAPI基本库;
//<windows.h>主要包含有以下5部分: --但不包含winmm.lib;
//WINDEF.H 基本类型定义;
//WINNT.H 支持Unicode的类型定义;--支持中文&国际化;
//WINBASE.H Kernel函数;
//WINUSER.H 用户接口函数;
//WINGDI.H 图形设备接口函数; --即GDI编程;
#pragma comment(lib,"winmm.lib") //添加多媒体库;--可播放声音及视频;
//---------------------------------------------*/
//声明本地函数;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //回调函数CALLBACK;即窗口过程proc;
//---------------------------------------------*/
//主函数;--相当于main();
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] =TEXT("HelloWin"); //定义应用程序名称;--字符串;TCHAR兼容宽字符UNICODE;
//定义内部变量;
//句柄Handle;即32位的ID代号,在Windows编程中使用非常频繁,相当于资源对象的指针;
HWND hwnd; //窗口句柄;--即窗口ID代号;是创建窗口时Windows的返回值;
MSG msg ; //消息结构;--每个窗口都有一个消息循环,用它不断读取消息;然后转译分发处理;
WNDCLASS wndclass; //窗口类结构;--存放窗口类的特征信息;
//定义窗口;--用于注册,共需10个参数;[结构体初始化;]
wndclass.style = CS_HREDRAW | CS_VREDRAW; //窗口样式;旗标组合;--水平改变重绘REDRAW,垂直改变重绘REDRAW;
wndclass.lpfnWndProc = WndProc; //回调函数名称;--实际是函数指针pfn;
wndclass.cbClsExtra = 0; //为类对象预留的额外计数字节cb;[=couter byte;]
wndclass.cbWndExtra = 0; //为窗体预留的额外计数字节cb;
wndclass.hInstance = hInstance; //实例句柄;--当前窗口实例的ID代号;由Windows提供;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); //Icon图标句柄;--普通应用图标;
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); //Cursor光标句柄;--箭头鼠标指针;
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //HBRUSH背景画刷句柄;--选择预设的标准画刷--白色;
wndclass.lpszMenuName = NULL; //菜单名;--没有菜单为NULL;
wndclass.lpszClassName = szAppName; //窗口类别名=应用程序名称;[小程序可以同名;]
//注册窗口类;--如不成功则返回0;并立即跳出程序;
if (!RegisterClass (&wndclass)) //如果窗口类注册不成功,则给出提示;
{
MessageBox(NULL, TEXT("This program requires Windows NT!"),
szAppName, MB_ICONERROR); //对话框消息MB;[=Message Box;有时需要Windows NT环境兼容宽字符UNICODE;]
return 0;
}
//创建窗口;--共需11个参数;[函数实参说明;中英对照;]
hwnd =CreateWindow(
szAppName, // window class name; [窗口类别名=应用程序名称;同前;]
TEXT ("HelloWin_v1"), // window caption; [窗口标题;文本字符串;]
WS_OVERLAPPEDWINDOW, // window style; [窗口样式;同前;]
CW_USEDEFAULT, // initial x position; [x坐标位置;窗口左上角;]
CW_USEDEFAULT, // initial y position; [y坐标位置;窗口左上角;]
240, // initial x size; [窗口尺寸;单位=像素Pixel;默认CW_USEDEFAULT;]
120, // initial y size; [窗口尺寸;单位=像素Pixel;默认CW_USEDEFAULT;]
NULL, // parent window handle; [父窗口句柄;没有为NULL;]
NULL, // window menu handle; [窗口菜单句柄;没有为NULL;]
hInstance, // program instance handle; [App实例句柄;注册类时由Windows提供;]
NULL); // creation parameters; [*]
//显示窗口;
ShowWindow (hwnd, iCmdShow); //显示窗口;--决定窗口的显示方式iCmdShow--正常/最大化/最小化;[由程序安装或使用者决定;]
UpdateWindow (hwnd); //刷新窗口;--发送重绘消息WM_PAINT通知屏幕窗口区域自动刷新;
//消息循环;
while (GetMessage(&msg,NULL,0,0)) //(NULL,0,0)表示程式接收它自己建立的所有视窗的所有讯息;
{
TranslateMessage (&msg); //转译消息;--将消息结构传给Windows,进行一些键盘转换;
DispatchMessage (&msg); //分发消息;--消息各部分经由Windows传给窗口回调函数Proc接收并处理;[处理完原地返回继续读取下一条消息;]
}
//没有消息了;这时GetMessage()传回0;
return msg.wParam; //返回消息WM_QUIT;[WM =Window Message;]
}
//---------------------------------------------*/
/*/补充资料;–消息结构MSG;
//对消息msg的理解是Win32编程所必需的;因此这里列出MSG类型的结构;
typedef struct tagMSG
{
HWND hwnd ; //窗口句柄;–窗口ID代号32位整数;同前;
UINT message ; //消息标识;–无符号整型32位;
WPARAM wParam ; //消息短参数;–实际为32位;
LPARAM lParam ; //消息长参数;–实际为32位;
DWORD time ; //消息放入消息队列的时间;
POINT pt ; //消息放入消息队列时的鼠标位置坐标(x,y);
} MSG, * PMSG ;
//定义回调函数;
//---------------------------------------------*/
//定义回调函数;
//回调函数负责处理本窗口类所有实例的消息;因为专为Windows调用而设计,所以叫回调函数;
//注意,回调函数的4个形参,对应消息结构中的4个成员;
//当Windows向应用程序发送消息,其实质就是通过调用本回调函数实现的;
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
//定义内部变量;
HDC hdc; //设备环境句柄;
PAINTSTRUCT ps ; //保存绘图环境数据的结构体;
RECT rect; //客户区矩形;
//消息处理;--消息响应;
switch (message)
{
case WM_CREATE: //创建窗口;
PlaySound (TEXT ("HelloWin.wav"), NULL, SND_FILENAME | SND_ASYNC) ; //语音;
Sleep(2000); //等待语音结束,再开始音乐;
PlaySound(TEXT("bkmusic.wav"), NULL, SND_FILENAME | SND_ASYNC); //背景音乐;
break;
case WM_PAINT: //绘制窗口或重绘无效矩形区;--此处显示文本信息;
hdc =BeginPaint(hwnd, &ps); //获取设备环境句柄;--包括绘图环境数据;
GetClientRect (hwnd, &rect); //获取客户区矩形;
DrawText (hdc, TEXT("Hi,我是Win32窗口!"), -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER);
//@客户区rect;文本格式=(单行|水平居中|垂直居中);
EndPaint(hwnd, &ps);
break;
case WM_DESTROY: //销毁窗口;
PostQuitMessage(0); //将WM_QUIT放入消息队列;
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam); //默认;Windows内部消息处理;
}
return 0 ;
}
//----------------------------------------------+------------------------------------------------*/
//----------------------------------------------+------------------------------------------------*/