// Learn_01_CreateWindow.cpp : Defines the entry point for the application.
// #include "stdafx.h"
#include < windows.h>
#include "resource.h" //--------------------------------------------------------------------------------------
// 全局变量
//-------------------------------------------------------------------------------------- //HINSTANCE 是“句柄型”数据类型。相当于装入到了内存的资源的ID。
//HINSTANCE对应的资源是instance.句柄实际上是一个无符号长整数。
//但它是“句柄型”,所以你不能把它当成真的无符号长整数,拿来派别的用处,例如,不能拿来做四则运算。
HINSTANCE g_hInst = NULL;
//h是类型描述,表示句柄(handle),Wnd 是变量对象描述,表示窗口,所以hWnd 表示窗口句柄
HWND g_hWnd = NULL; //--------------------------------------------------------------------------------------
// 函数声明
//-------------------------------------------------------------------------------------- //HRESULT=h+result(句柄结果)。如果这个函数是执行完返回的话将包含具有实际意义的数据,
//如果立即返回则包含状态信息--发送成功与否,并不能说明执行的如何。
HRESULT InitWindow(HINSTANCE hInstance, int nCmdShow);
//LRESULT就是longresult,也就是长整型
//之所以取名类LRESULT, 是因为L即long
//result表示结果, 说明这个函数的返回值是某个结果
//CALLBACK,回调函数就是一个通过函数指针调用的函数
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //--------------------------------------------------------------------------------------
// 程序入口。初始化,并进入消息循环。空闲时间用来绘制场景。
//--------------------------------------------------------------------------------------
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);//UNREFERENCED_PARAMETER 未引用的参数
UNREFERENCED_PARAMETER(lpCmdLine); if (FAILED(InitWindow(hInstance, nCmdShow))) //FAILED失败
return ; // 消息循环 /*
MSG是Windows程序中的结构体,
在Windows程序中,消息是由MSG结构体来表示的。MSG结构体的定义如下(参见MSDN):
typedef struct tagMSG {
HWND hwnd; //表示消息所属的窗口
UINT message; //制定了消息的标示符,在Windows中,消息是由一个数值来表示的,不同的消息对应不同的数值。
//但是由于数值不便于记忆,所以Windows将消息对应的数值定义为WM_XXX宏(WM是Windows message的缩写)的形式
//XXX对应某种消息的英文拼写的大写形式。例如,鼠标左键按下的消息是WM_LBUTTONDOWN,键盘按下消息是WM_KEYDOWN
//字符消息是WM_CHAR,等等。在程序中我们通常都是以WM_XXX宏的形式来使用消息的。
WPARAM wParam;
LPARAM lParam; //wParam和lParam,用于指定消息的附加信息。例如,当我们收到一个字符消息的时候,message成员变量的值就是WM_CHAR
//但是用户到底输入的是什么字符,那么就由wParam和lParam来说明。
DWORD time;
POINT pt; //time和pt分别表示消息投递到消息队列中的时间和鼠标的当前位置
} MSG;
*/
MSG msg = { };
while (GetMessage(&msg, NULL, , ))
{
TranslateMessage(&msg); //TranslateMessage将虚拟键消息转换为字符消息。字符消息被寄送到调用线程的消息队列里
//当下一次线程调用函数GetMessage或PeekMessage时被读出,函数原型BOOL TranslateMessage( CONST MSG*lpMsg );
DispatchMessage(&msg); //DispatchMessage表示分发一个消息给窗口程序。通常消息从GetMessage函数获得。消息被分发到回调函数(过程函数)
//作用是消协传递给操作系统,然后操作系统去操作我们的回调函数,也就是说我们在窗体的过程中处理消息
} return (int)msg.wParam;
} //--------------------------------------------------------------------------------------
// 注册窗口类并创建窗口
//--------------------------------------------------------------------------------------
HRESULT InitWindow(HINSTANCE hInstance, int nCmdShow)
{
/* WNDCLASSEX的原型如下:
typedef struct WNDCLASSEX {
UINT cbSize; //WNDCLASSEX的大小,我们可以用sizeof(WNDCLASSEX)来获得准确的值
UINT style; //从这个窗口类派生的窗口具有的风格。可以用“or”操作符来把几个风格或到一起
WNDPROC lpfnWndProc; //窗口处理函数的指针,lpfn前缀表示该成员是一个指向函数的长指针
int cbClsExtra; //指定紧跟在窗口结构后的附加字节数
int cbWndExtra; //指定紧跟在窗口实例的附加字节数。如果一个应用程序在资源中用CLASS伪指令注册一个对话框类是,
//则必须把这个成员设成DLGWINDOWEXTRA
HINSTANCE hInstance; //本模块的实例句柄
HICON hIcon; //图标的句柄
HCURSOR hCursor; //光标的句柄
HBRUSH hbrBackground; //背景画刷的句柄
LPCTSTR lpszMenuName; //指向菜单的指针
LPCTSTR lpszClassName; /指向类名的指针
HICON hIconSm; //和窗口类关联的小图标。如果该值为MULL。则把hlcon中的图标转换成大小合适的小图标
} WNDCLASSEX, *PWNDCLASSEX;
*/
// 注册窗口类
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX); //sizeof,判断数据类型长度符关键字,返回值为内存所占字节数
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = ;
wcex.cbWndExtra = ;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, nullptr);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + );
wcex.lpszMenuName = NULL;
wcex.lpszClassName = L"TutorialWindowClass";
wcex.hIconSm = LoadIcon(wcex.hInstance, nullptr);
if (!RegisterClassEx(&wcex))
return E_FAIL; // 创建窗口
g_hInst = hInstance;
RECT rc = { , , , }; //RECT用于储存成对出现的参数,原型为 typedef struct _RECT {LONG left;LONG top;LONG right;LONG bottom;} RECT, *PRECT /*AdjustWindowRect依据所需客户矩形的大小,计算需要的窗口矩形的大小,计算出的窗口矩形随后可以传递给CreateWindows函数,
用于创建一个客户区所需大小的窗口
函数原型:BOOL AdjustWindowRect(LPRECT lpRect ,DWORD dwStyle,BOOL bMENU);
参数说明:
lpRect:指向RECT结构的指针,该结构包含所需客户区域的左上角和右下角的坐标。函数返回时,该结构容纳所需客户区域的窗口的左下角和右下角的坐标
dwStyle:指定将被计算尺寸的窗口的窗口风格
bMENU:指示窗口是否有菜单
*/
AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE); /*CreateWindow
HWND CreateWindow(
LPCTSTR lpClassName, //指向一个空结束的字符串或整型数atom。如果该参数是一个整型量,
//它是由此前调用theGlobalAddAtom函数产生的全局量。
//这个小于0xC000的16位数必须是lpClassName参数字的低16位,该参数的高位必须是0。
//如果lpClassName是一个字符串,它指定了窗口的类名。
//这个类名可以是任何用函数RegisterClass注册的类名,或是任何预定义的控制类名。
LPCTSTR lpWindowName,//指向一个指定窗口名的空结束的字符串指针。
//如果窗口风格指定了标题条,由lpWindowName指向的窗口标题将显示在标题条上。
//当使用Createwindow函数来创建控制例如按钮,选择框和静态控制时,可使用lpWindowName来指定控制文本。 DWORD dwStyle, //窗口的风格,如WS_BORDER:创建一个带边框的窗口,WS_HSCROLL:创建一个有水平滚动条的窗口。
int x, //指定窗口的初始水平位置,如果该参数被设为CW_USEDEFAULT则系统为窗口选择缺省的左上角坐标并忽略Y参数
int y, //指定窗口的初始垂直位置
int nWidth, //以设备单元指明窗口的宽度
int nHeight,//以设备单元指明窗口的高度
HWND hWndParent, //指向被创建窗口的父窗口或所有者窗口的句柄
HMENU hMenu, //菜单句柄,或依据窗口风格指明一个子窗口标识。对于层叠或弹出式窗口,
//hMenu指定窗口使用的菜单:如果使用了菜单类,则hMenu可以为NULL。
//对于子窗口,hMenu指定了该子窗口标识(一个整型量),一个对话框使用这个整型值将事件通知父类。
//应用程序确定子窗口标识,这个值对于相同父窗口的所有子窗口必须是唯一的。
HANDLE hlnstance, //与窗口相关联的模块实例的句柄。
LPVOID lpParam //指向一个值的指针,该值传递给窗口WM_CREATE消息。该值通过在IParam参数中的CREATESTRUCT结构传递。
//如果应用程序调用CreateWindow创建一个MDI客户窗口,则lpParam必须指向一个CLIENTCREATESTRUCT结构。
);
//返回值:如果函数成功,返回值为新窗口的句柄:如果函数失败,返回值为NULL。若想获得更多错误信息,请调用GetLastError函数。
*/
g_hWnd = CreateWindow(L"TutorialWindowClass", L"Direct3D Learning 01: Create Window", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance,
NULL);
if (!g_hWnd)
return E_FAIL; ShowWindow(g_hWnd, nCmdShow); return S_OK;
} //--------------------------------------------------------------------------------------
// 每次当应用程序接收消息时调用这个方法
//--------------------------------------------------------------------------------------
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps; //PAINTSTRUCT包含了某种应用程序用来绘制它所拥有的窗口客户区所需要的信息
HDC hdc; switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break; case WM_DESTROY:
PostQuitMessage();
break; default:
return DefWindowProc(hWnd, message, wParam, lParam);
} return ;
}