新建标准win32程序结构:
Visualc++项目类型->win32项目->输入名称确定->win32项目程序向导中点击“完成“->编译运行便可看到一个简易的win32窗口
注意:在应用程序界面中包含:标题栏、菜单栏、工具栏、状态栏、最小化按钮、最大化按钮/还原按钮、关闭按钮、滚动条、窗口边框、编辑区、控制菜单图标等。
窗口的概念:
窗口是Windows程序实现的基础,大多数Windows都是以窗口的方式运行。
Windows程序运行的基本的原理:
1.消息驱动
Windows程序设计是一种事件驱动方式的程序设计模式,主要是基于消息机制。
当用户完成对应用程序(窗口)的某种操作时会调用操作系统的某种支持,操作系统会将用户的操作包装成消息,并发送到一个应用程序可以访问的消息队列中,最后应用程序从消息队列中取走消息,并进行响应。
消息为应用程序和应用程序间、应用程序和操作系统间提供了信息传递的渠道。
2.预编译头文件
在程序的开始,代码引用了名为“Stdafx.h”的头文件,该文件主要用于进行预编译处理。
在文件stdafx.h头文件中包含了Windows.h头文件,在Windows.h头文件中包含了其他Windows头文件。
WINDED.H // 基本类型定义;
WINNT.H // 支持Unicode的类型定义;
WINBASE.H // 内核函数;
WINUSER.H // 用户接口函数;
WINGDI.H // 图形设备接口函数
3.程序入口函数
wWinMain是Windows程序的入口点函数。当wWinMain函数结束或返回时,Windows应用程序结束。
#define APIENTRY WINAPI
#define _tWinMain wWinMain
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,//hInstance表示该程序的当前运行的实例句柄
_In_opt_ HINSTANCE hPrevInstance,//hPrevInstance表示当前实例的上一个正在运行的,由同一个应用程序所产生的实例的句柄,即当前实例的句柄
_In_ LPTSTR lpCmdLine,//lpCmdLine是一个字符串,里面包含有传递给应用程序的参数
_In_ int nCmdShow)//nCmdShow指定的程序窗口应该如何显示,如最大化、最小化、隐藏等
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: 在此放置代码。
MSG msg;
HACCEL hAccelTable;
// 初始化全局字符串
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_WIN32PROJECTWQR, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// 执行应用程序初始化:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WIN32PROJECTWQR));
// 主消息循环:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
Win32程序执行流程:
程序入口函数(wWinMain函数)->注册窗口类(RegisterClass或RegisterClassEx)->创建主窗口类(CreateWindow或CreateWindowEx)->显示主窗口类(ShowWindow)->更新主窗口(UpdateWindow)->进入消息循环(GetMessage/TranslateMessage/DispatchMessage/处理各种Windows消息)->程序出口点(wWinMain返回)
1.注册窗口类
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;//wcex是个结构体变量
wcex.cbSize = sizeof(WNDCLASSEX);//cbSize描述整个wcex变量的大小
wcex.style = CS_HREDRAW | CS_VREDRAW;//Style描述类风格
wcex.lpfnWndProc = WndProc;//lpfnWndProc描述此类窗口的消息处理函数,在这里指定为WndProc函数
wcex.cbClsExtra = 0;//cbClsExtra为额外类空间,可以选择在其中存放窗口类所共有的数据
wcex.cbWndExtra = 0;//cbWndExtra描述额外窗口空间,可以选择在其中存放每个窗口所拥有的数据
wcex.hInstance = hInstance;//hInstance描述应用程序的实例句柄,标识这个窗口类和哪个应用程序的实例相关联
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32PROJECTWQR));//hIcon描述窗口类的正常图标,当窗口正常显示或被最大化时,窗口左上角会显示此图标
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);//hCursor描述窗口类的鼠标光标,可以根据需要将此光标设置成默认的鼠标指针形式或者特殊的十字光标形式
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);//hbrBackground描述缺省的窗口背景颜色
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_WIN32PROJECTWQR);//lpszMenuName为缺省的菜单名
wcex.lpszClassName = szWindowClass;//lpszClassName此窗口类的名称,和面向对象的类意义不一样,与创建窗口的类名保持一致
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));//hIconSm描述窗口类的小图标,当窗口被最小化时,在Windows任务栏中会显示此图标
return RegisterClassEx(&wcex);
}
2.创建主窗口类
实际窗口的创建是执行程序初始化Initlnstance函数保存实例句柄并通过CreateWindow函数来完成。
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // 将实例句柄存储在全局变量中
hWnd = CreateWindow(szWindowClass, //创建窗口,窗口类名
szTitle, //窗口实例的标题名
WS_OVERLAPPEDWINDOW,//窗口的风格
CW_USEDEFAULT, 0, //窗口左上角坐标为缺省值
CW_USEDEFAULT, 0, /窗口的高度和宽度为缺省值
NULL, //此窗口没有父窗口
NULL, //此窗口没有主菜单
hInstance, //应用程序当前句柄
NULL);//不使用该值技能归纳
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);//显示窗口类
UpdateWindow(hWnd);//更新窗口类
return TRUE;
}
如果窗口创建成功,那么此函数将返回一个窗口句柄存放在hWnd变量中。
3.显示窗口类以及更新窗口类
ShowWindow(hWnd, //hWnd指定要显示的窗口,即刚创建的窗口
nCmdShow);//nCmdShow决定窗口显示方式
UpdateWindow(hWnd);//调整窗口,使之完成一次窗口客户区的重绘
4.消息循环
// 主消息循环:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);//TranslateMessage主要做一些键盘翻译工作
DispatchMessage(&msg);//DispatchMessage负责将消息传递给该窗口的消息处理函数WndProc并调用WndProc完成对消息的处理,即分发消息。
}
}
GetMessage函数从窗口的消息队列中取出实际的消息,如果有消息需要处理,则GetMessage返回TRUE,如果调用时没有消息,则GetMessage函数不会返回,直到有消息需要处理时才返回。
5.处理消息过程的函数WndProc
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_COMMAND://菜单消息
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// 分析菜单选择:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: 在此添加任意绘图代码...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_LBUTTONDOWN://鼠标左键点击消息
MessageBox(hWnd, L"我爱编程!", L"Hello", MB_YESNO);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
纯手打 如有错 请指教!