之前一直学习的是控制台程序设计,后来接触MFC程序设计,中间忽略了Windows程序设计的学习,所以在开始接触MFC的时候非常迷茫,不知道MFC框架下的各个函数的意义,不明白其内部的原理及机制,只大概了解使用了函数的封装,现在将这部分知识重拾起来。
使用c语言,调用WIN32 API进行Windows程序设计,首先要包含windows.h头文件,入口函数是WinMain函数,这点不同于控制台程序的main函数入口,WINAPI是一个宏定义,实际就是__stdcall调用Windows函数的意思。
句柄概念:一个对象的值(32位int数值),通过句柄可以找到对应的对象,具体又分为窗口句柄、实例句柄、设备环境句柄、图标光标句柄等。
这个简单的Windows程序实现了以下功能:创建一个窗口,在窗口内输出“Hello,Windows 98!”文本,同时播放音乐。
具体步骤包括:创建窗口类,注册窗口类,创建窗口,更新窗口,循环等待窗口消息。
处理窗口消息需要调用窗口过程函数,LRESULT是宏定义long,CALLBACK类似于WINAPI,传参包括窗口句柄及消息类型等,每个窗口有自己的窗口过程函数。
除了自定义消息响应,也可使用缺省的窗口响应DefWindowProc。
#include <windows.h>
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);//回调函数声明
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR szCmdLine,
int iCmdShow)//WinMain入口函数
{
static TCHAR szAPPName[]=TEXT("HelloWin");
HWND hwnd;//窗口句柄
MSG msg;//消息结构体
WNDCLASS wndclass;//窗口类
//窗口类成员变量赋值
wndclass.style =CS_HREDRAW |CS_VREDRAW;//窗口类型水平重画和竖直重画
wndclass.lpfnWndProc=WndProc;//窗口过程函数
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=szAPPName;//窗口名称
//注册窗口类
if(!RegisterClass(&wndclass))
{
MessageBox(NULL,TEXT("This program requires Windows NT!"),szAPPName,MB_ICONERROR);//若注册失败,则弹出消息对话框
return 0;
}
//创建窗口
hwnd=CreateWindow(szAPPName,
TEXT("The Hello Program"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
//显示窗口
ShowWindow(hwnd,iCmdShow);//WinMain传递给iCmdShow的为SW_SHOWNORMAL
UpdateWindow(hwnd);//更新窗口或者重画窗口,通过调用WM_PAINT消息
//循环获取消息队列
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);//翻译键盘消息
DispatchMessage(&msg);//发送消息
}
return msg.wParam;
}
//窗口过程函数
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
HDC hdc;//设备句柄
PAINTSTRUCT ps;//PAINT结构体
RECT rect;//RECT结构体
switch(message)//判断消息类型
{
case WM_CREATE://创建窗口消息
PlaySound(TEXT("1.mp3"),NULL,SND_FILENAME|SND_ASYNC);//播放声音
return 0;
case WM_PAINT://PAINT消息
hdc=BeginPaint(hwnd,&ps);//开始PAINT
GetClientRect(hwnd,&rect);//获得客户区域
DrawText(hdc,TEXT("Hello,Windows 98!"),-1,&rect,
DT_SINGLELINE|DT_CENTER|DT_VCENTER);//绘制字符串
EndPaint(hwnd,&ps);//结束绘制
return 0;
case WM_DESTROY://销毁消息
PostQuitMessage(0);//将结束消息加入消息队列
return 0;
}
return DefWindowProc(hwnd,message,wParam,lParam);//返回缺省的窗口过程函数
}