您的位置:首页 > 编程语言 > C语言/C++

Framework4.5,vs下系统自动生成的C++ win32应用程序的详细解释

2016-07-29 21:46 411 查看
在vs2013下,Framework4.5创建win32应用程序时,和以前有些不同,很多书中也很少提到,我整理了一下,对每一句代码都做了解释,

希望对初次学习win32应用程序的同学有帮助。

#include "stdafx.h"
#include "FirstWin32.h"
#define MAX_LOADSTRING 100
// 全局变量:
HINSTANCE hInst; // 当前实例
TCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本 TCHAR 是wchar_t的宏,表示是宽字符,使用unicode编码,可以写入中文等。
TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名
TCHAR szMyTest[MAX_LOADSTRING];
// 此代码模块中包含的函数的前向声明:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);

//#define APIENTRY WINAPI而又#define WINAPI __stdcall 说明这是系统回调函数
//_In_调用函数传值前必须赋予参数的值,系统调用main之前,就已经确定了这个应用程序的句柄。
//_In_opt_调用函数传值前必须赋予参数的值并且不可改,不能修改上一个应用程序的句柄,以免产生错误。
//hInstance实例句柄,当前应用程序进程的句柄,是操作系统为你分配,在当前程序里只能有一个,如果你打开多程序则有多个
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,//上一个实例句柄
_In_ LPTSTR    lpCmdLine,
_In_ int       nCmdShow)
{
//unreferenced_parameter(不用的变量) 告诉编译器,这个变量不使用也不要报警告。
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);

// TODO:  在此放置代码。
MSG msg;
HACCEL hAccelTable;//快捷键表

// 初始化全局字符串从.rc资源文件中获取字符串信息
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_FIRSTWIN32, szWindowClass, MAX_LOADSTRING);
LoadString(hInstance, MYTEST, szMyTest, MAX_LOADSTRING);
MyRegisterClass(hInstance);//注册

// 执行应用程序初始化:
if (!InitInstance (hInstance, nCmdShow))//初始化以及显示窗口
{
return FALSE;
}
//获取用户在.rc资源文件中配置的快捷键信息表
//make int resource,将数字类型的宏定义转化成字符串,#define IDC_FIRSTWIN32 109转化为字符串109
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_FIRSTWIN32));

// 主消息循环:
while (GetMessage(&msg, NULL, 0, 0))//不停的获取消息,但只是获取可能属于自己的消息,如在控件里点击或者按下键盘
{
//TranslateAccelerator翻译快捷键消息,如果消息存在于快捷键表里,就将消息的类型转化为WM_COMMAND或者WM_SYSCOMMAND
//如果输入的快捷键不存在于快捷键信息表里,就当作非快捷键消息做处理,这里只需要快捷键消息的处理
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);//如果是键盘消息就转化为字符信息
DispatchMessage(&msg);//将消息派送之系统,系统会自动调用lpfnWndProc函数
}
}

return (int) msg.wParam;
}

//
//  函数:  MyRegisterClass()
//
//  目的:  注册窗口类。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;//和WNDCLASS区别在于新增了cbSize指明自己的大小和hIconSm小图标。

wcex.cbSize = sizeof(WNDCLASSEX);

wcex.style = CS_HREDRAW | CS_VREDRAW;//
wcex.lpfnWndProc= WndProc;
wcex.cbClsExtra= 0;//新增
wcex.cbWndExtra= 0;
wcex.hInstance= hInstance;
//第二个参数就是图标的路径,在.rc的资源文件中添加了一个ID为IDI_FIRSTWIN32的图片,在Resource.h会有自动的宏定义
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_FIRSTWIN32));//最小化时在任务栏的图标
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);//鼠标光标的形状
wcex.hbrBackground= (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName= MAKEINTRESOURCE(IDC_FIRSTWIN32);
wcex.lpszClassName= szWindowClass;//注册时必须保证窗口类名lpszClassName没有被注册过,否则注册新窗口失败
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));//新增

return RegisterClassEx(&wcex);
}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;

hInst = hInstance; // 将实例句柄存储在全局变量中

//szWindowClass这个字符数组就是在Register窗口时的窗口名字wcex.lpszClassName=szWindowClass;
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;
}

//当消息被DispatchMessage处理时就运行这个方法
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;
default:
return DefWindowProc(hWnd, message, wParam, lParam);//对于不想要的消息,必须使用DefWindowProc交给系统处理,不然的话,该消息一直等待被处理,程序卡死不动
}
return 0;
}

// “关于”框的消息处理程序。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;

case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: