效果:
#include<stdio.h>
#include<windows.h>
LPCTSTR clsName = "firstcls";
LPCTSTR wndTile = "第一个windows窗口";
//定义回调函数
LRESULT CALLBACK MyWinProc(
HWND hWnd,//用于接收消息的窗口过程的句柄。
UINT Msg,//消息
WPARAM wParam,//其他的消息特定信息。
LPARAM lParam//其他的消息特定信息。
)
{
int ret;
HDC hdc;
switch (Msg)
{
case WM_CHAR:
char szChar[20];
sprintf_s(szChar, "您刚才按下:%c", wParam);
MessageBox(hWnd, szChar, "char", NULL);
break;
case WM_LBUTTONDOWN:
MessageBox(hWnd, "左键按下", "msg",NULL);
break;
case WM_PAINT:
PAINTSTRUCT ps;
hdc = BeginPaint(hWnd, &ps);
TextOut(hdc, 0, 0, "www.baidu.com",NULL);
EndPaint(hWnd, &ps);
MessageBox(hWnd, "重绘", "msg",NULL);
break;
case WM_CLOSE:
ret = MessageBox(hWnd, "是否关闭窗口", "msg", MB_YESNO);
if (ret == IDYES)
{
DestroyWindow(hWnd);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance,//实例的句柄 或模块的句柄。 当可执行文件加载到内存中时,操作系统使用此值来标识可执行文件或 EXE。 某些 Windows 函数需要实例句柄,例如加载图标或位图。
HINSTANCE hPrevInstance,//这个是历史遗留问题,没有任何意义。 它在 16 位 Windows 中使用,但现在始终为零。
PSTR lpCmdLine, //以 Unicode 字符串的形式包含命令行参数。
int nCmdShow //窗口显示方式,是一个标志,指示主应用程序窗口是最小化、最大化还是正常显示。
) {
/*WINAPI简介:(这个可以暂时不用太理解,记住是一个函数调用约定就行)
#define WINAPI __stdcall
在Windows程序中,WINAPI是一个宏定义,用于标记函数的调用约定。
它的作用是告诉编译器和链接器如何在函数调用时处理参数传递、栈的管理以及返回值的处理。
在WINAPI调用约定下,函数的参数通常是从右到左依次入栈,由调用方负责清理栈空间。此外,返回值通常会以某种特定的寄存器传递。
WINAPI宏定义在Windows平台的头文件中定义为__stdcall,用于指定函数的调用约定。
在使用WINAPI宏定义修饰函数声明时,编译器和链接器将按照标准的Windows调用约定来处理该函数的调用和返回。
使用WINAPI宏定义有助于确保在不同的编译器和平台下,函数的调用方式保持一致,以便正确地与Windows操作系统进行交互。
这样可以避免函数调用时出现参数传递错误、堆栈不平衡等问题,提高代码的可移植性和稳定性。
*/
//WinMain是windows程序的入口函数和dos系统下的main函数一样
//1、定义,配置窗口对象
WNDCLASS wndcls;
wndcls.style = CS_HREDRAW | CS_VREDRAW;//窗口类样式 此成员可以是 类样式的任意组合
wndcls.lpfnWndProc=MyWinProc;//指向窗口过程的指针。 必须使用 CallWindowProc 函数调用窗口过程。 就是回调函数指针
wndcls.cbClsExtra = 0;//要根据窗口类结构分配的额外字节数。 系统将字节初始化为零。
wndcls.cbWndExtra = 0;//在窗口实例之后分配的额外字节数。 系统将字节初始化为零。
wndcls.hInstance = hInstance;//实例的句柄,该实例包含类的窗口过程。
wndcls.hbrBackground= (HBRUSH)GetStockObject(WHITE_BRUSH);//类背景画笔的句柄
wndcls.hCursor = NULL;//类游标的句柄。如果此成员为 NULL,则系统会提供默认图标。
wndcls.hIcon = NULL;//类图标的句柄。 此成员必须是图标资源的句柄。 如果此成员为 NULL,则系统会提供默认图标。
wndcls.lpszClassName = clsName;//指向以 null 结尾的字符串的指针或 是原子。
wndcls.lpszMenuName = NULL;//类菜单的资源名称,该名称显示在资源文件中。
//2、注册窗口类
RegisterClass(&wndcls);
//3、创建窗口
HWND hwnd;
hwnd = CreateWindow(
clsName,//窗口类名
wndTile,//窗口标题
WS_OVERLAPPEDWINDOW,//窗口样式
100,
100,//窗口左上角横纵坐标
800,
600,//窗口的宽高
NULL,//父窗口句柄
NULL,//菜单句柄
hInstance,//当前实例
NULL//自定义参数
);
//4、显示和刷新窗口
ShowWindow(hwnd, SW_SHOWNORMAL);
UpdateWindow(hwnd);
//消息循环
MSG msg;
while (GetMessage(&msg, NULL, NULL, NULL))
{
TranslateMessage(&msg);//翻译消息
DispatchMessage(&msg);//分派消息
}
return msg.wParam;
}