# include<windows.h>; //包含windows.h头文件
# include <stdio.h>; //因为要使用大量C语言内容,包含C语言头文件
LRESULT CALLBACK WinSunProc( //回调函数声明,固定模版
_In_ HWND hwnd,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
);
int WINAPI WinMain( //winmain 函数,WINAPI就是_stdcal调用形式,由函 数自己清除栈中内容。
HINSTANCE hInstance, //当前窗口实例号
HINSTANCE hPrevInstance, //前一个窗口实例号
LPSTR lpCmdLine, //命令消息指针
int nCmdShow //代表窗口的主显示方式,如最大最小化之类,由一系列宏实现
)
{
WNDCLASS wdncls; //定义一个窗口类
wdncls.cbClsExtra = 0; //类额外字节数
wdncls.cbWndExtra = 0; //窗口 额外字节数
wdncls.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); //定义黑色背景(BLACK_BRUSH) ,使用画刷(HBRUSH)类型进行强制类型转换,因为GetStockObject函数会返回一个画刷句柄,但是这个句柄是HGDIOBJ类型的(为什么非要返还这种类型就不知道了,应该是在其他地方用的),与wdncls结构体所需的HBRUSH不同,所以要对他进行类型转换。
wdncls.hCursor = LoadCursor(NULL, IDC_CROSS); // 设置光标类型,如果使用自带光标,将第一个参数设为NULL;
wdncls.hIcon = LoadIcon(NULL, IDI_ERROR); //设置图标,选择自带图标error,因此前一个参数设为NULL;
wdncls.hInstance = hInstance; //应用程序实例号设置;
wdncls.lpfnWndProc = WinSunProc; //自定义窗口过程函数,在这里将回调函数名作为地址,复制给函数指针lpfnWndProc,表明这个窗口产生的消息会由操作系统调用WinSunProc函数来进行处理。
wdncls.lpszClassName = _T("Yang JL的类型"); //定义窗口类型;在这一步如果使用命令:wdncls.lpszClassName = "Yang JL的类型"会出现错误“不能将char*[]分配到LPCWSTR的实体中”,系数据类型兼容问题,可以包含头文件tchar.h,并在字符串前加_T,或者点击Visual Stuido菜单 项目-->配置属性-->常规-->字符集,将Unicode字符集改为使用多字节字符集。
wdncls.lpszMenuName = NULL; //菜单名称,因为无菜单,所以设为NULL;
wdncls.style = CS_HREDRAW | CS_VREDRAW; //水平重画和竖直重画。
RegisterClass(&wdncls); //注册窗口类,
//以上基本完成了一个窗口类的建立,下面创建这个窗口的一个实例
HWND hwnd; //定义一个句柄;
hwnd = CreateWindow( _T("Yang JL的类型"),_T("孙鑫C++第一课"),WS_OVERLAPPEDWINDOW,0,0,600,400,NULL,NULL,hInstance,NULL);//创建窗口命令,输入窗口类名称,窗口名称,WS_OVERLAPPEDWINDOW 提供标题栏、对话框,最小最大化等内容,0,0,600,400分别为窗口的坐标x,y和两个方向上的宽度。副窗口、菜单为NULL,实例为句柄,创建数据为NULL。
ShowWindow(hwnd, SW_SHOWNORMAL); //展示窗口
UpdateWindow(hwnd); //更新窗口
MSG msg; //用MSG结构体定义一个消息体以便在后续过程中进行消息循环;
while (GetMessage(&msg, NULL, 0, 0)) //GetMessage (四个参数):当收到消息时(除非收到的是WM_QUIT消息),返回true,否则返回false.最前面的&msg是第一个参数,意为给这个函数传入一个消息体的地址作为指针作为;第二个参数是一个窗口的句柄,意为GetMessage 将响应所在线程中对应窗口的消息,设为NULL意味着响应该线程中的所有窗口消息,后面的int分别为消息过滤的下限和上限,都设为0意味着不过滤消息,响应所有消息。
{
TranslateMessage(&msg); //将取到的消息对进行转换,例如,按下键盘这个动作会产生三个消息(1) WM_KEYDOWN (2) WM_KEYUP (3) 所按键的扫描码;这个消息翻译函数会将这三个消息转换为一个整体消息
DispatchMessage(&msg); //DispatchMessage函数可以理解为将消息传给操作系统,由操作系统调用回调函数进行处理。这个过程实际上有点复杂,建议进一步了解
}
return 0; //创建了一个窗口实例,下面是过程函数
}
LRESULT CALLBACK WinSunProc( //回调函数的定义
_In_ HWND hwnd,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
switch(uMsg)
{
case WM_CHAR:
char szChar[20]; //如果用户点击了键盘;
sprintf(szChar, "char is %d", wParam); //将这个字符串以一定格式放入字符数组;
MessageBox(hwnd, szChar, _T("OK"), 0); // 弹出一个窗口,显示出这个字符串
break;
case WM_LBUTTONDOWN:
MessageBox(hwnd, "mouse clicked", "OK", 0); //如果用户点了鼠标左键,弹出一个窗口
HDC hdc; //定义一个hdc,用来输出一个字符串,
hdc = GetDC(hwnd);
TextOut(hdc, 0, 50, "这是一个练习", strlen("这是一个练习"));
ReleaseDC(hwnd, hdc); //释放申请的hdc
break;
case WM_PAINT: //WM_PAINT函数
HDC hDC;
PAINTSTRUCT ps;
hDC = BeginPaint(hwnd, &ps);
TextOut(hDC, 0, 0, "WM_PAINT函数", strlen("WM_PAINT函数"));
EndPaint(hwnd, &ps);
break;
case WM_CLOSE: //如果点击了关闭
if (IDYES == MessageBox(hwnd, _T("确认退出?"), _T("询问"), MB_YESNO))
{
DestroyWindow(hwnd); //调用DestoryWindow函数,参数为当前窗口的句柄,销毁当前窗口,同时会消息队列中留下一个WM_DESTROY命令和一个WM_NCDESTORY消息,
}
break;
case WM_DESTROY: //响应消息队列中留下的一个WM_DESTROY命令,
PostQuitMessage(0); //执行PostQuitMessage函数,发送一个WM_QUIT指令在消息队列,GetMessage函数只有收到WM_QUIT指令时,才会返回0,线程中的无限循环结束循环,进而退出WinMain 函数,
break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}
摘自孙鑫C++教程第一课,建立一个窗口
最新推荐文章于 2022-08-09 18:58:39 发布