版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chen1083376511/article/details/89971015
在上一篇文章中(第一章:Windows程序内部机制(上)),核心的内容是介绍了最基本的Windows窗口创建的原理以及一些相关的API,主要依据楼主个人的理解,参考了 孙鑫MFC教程、深入浅出MFC以及网上相关的资料,进行精心整理而写作。
以下楼主便会根据孙鑫教程编写的代码,附加了一些详细的知识。伙伴们便可参考上一篇文章中提到的知识点,逐步研究以下各个代码的含义,将有助于加强个人的理解。
#include<windows.h>
#include<stdio.h>
LRESULT CALLBACK WinSunProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
);
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
WNDCLASS wndclass;
wndclass.hbrBackground = (HBRUSH)GetStockObject(DKGRAY_BRUSH);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wndclass.hInstance = hInstance;
wndclass.lpfnWndProc = WinSunProc;
wndclass.lpszClassName = "Weixin";
wndclass.lpszMenuName = NULL;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
RegisterClass(&wndclass);
HWND hwnd;
hwnd = CreateWindow("Weixin", "北京维新科学技术培训忠心",
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL
);
ShowWindow(hwnd, SW_SHOWNORMAL);
MSG msg;
while (GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WinSunProc(
HWND hwnd, // handle to window,接收消息的窗口句柄,
UINT uMsg, // message identifier,消息代码
WPARAM wParam, // first message parameter,消息代码的附加参数
LPARAM lParam // second message parameter,消息代码的附加参数
)//窗口过程函数的名字可以随便取,比如取名为:“WinSunProc”。
{
//dc是一个设备描述表,是包含设备(物理输出设备,如显示器,以及设备驱动程序)信息的结构体,
//所有图形操作都由DC完成。
HDC hdc;
PAINTSTRUCT ps;//用于接收绘制的信息
switch (uMsg)
{
/*
WM_PAINT消息的作用:更新指定窗口的绘画。发送WM_PAINT消息之前,窗口一直处于没有刷新绘图的
状态,所以即使写了一段文字, 也不会显示在窗口里,除非发送WM_PAINT消息。为得目的是程序由于
绘图的数据量大,减少内存占用率,等到绘图工作完成一次之后,再刷新一次来显示效果,又立即回到
了没有刷新的状态中,继续等待下次重新绘图的工作。
WM_PAINT消息处于低优先级:等到应用消息队列为空时才发送WM_PAINT消息,目的是有利于提高绘制
的效率,处理完各种相关的消息之后,在一个WM_PAINT消息中,一次性便得到更新。
*/
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);//该函数作用:为指定窗口进行绘图工作的准备,获取hdc
/*
调用BeginPaint函数,如果客户区的背景还没有被清除,那么BeginPaint函数会发送WM_ERASEBKGND
消息给窗口,系统就会使用WNDCLASS结构体的hbrBackground成员指定的画刷来擦除背景。
如果函数成功,返回值是“显示设备描述表”句柄。
如果函数失败,返回值为NULL,没有显示设备的内容。
含义:BeginPaint函数与WM_PAINT消息一定要紧紧相关联。因为如果没有BeginPaint函数,系统会接
连不断地接收到WM_PAINT消息,
导致进入死循环,使得CPU占用率极高。所以BeginPaint主要把该Update Region置为空(如果不为空,
就会发送WM_PAINT消息),然后用EndPaint终止绘画请求。
*/
TextOut(hdc, 0, 0, "北京维新科学技术", strlen("北京维新科学技术"));
EndPaint(hwnd, &ps);//终止绘画请求,释放hdc资源
break;
case WM_CHAR:
//(该消息通过TranslateNessage函数转换得到),wParam参数含有字符的ASCII码值
char szChar[20];
sprintf(szChar,"char is %d",wParam);
MessageBox(hwnd, szChar, "weixin", MB_OK);
break;
case WM_LBUTTONDOWN:
MessageBox(hwnd, "mouse click","weixin",MB_OK);
HDC hDc;
hDc = GetDC(hwnd);
TextOut(hDc, 0, 50, "计算机编程语言培训", strlen("计算机编程语言培训"));
ReleaseDC(hwnd,hDc);
break;
case WM_CLOSE:
if (IDYES == MessageBox(hwnd, "你是否要推出程序?", "weixin", MB_YESNO))
{
DestroyWindow(hwnd);
//销毁窗口,但是应用程序并不会退出,还在执行,在任务管理器中可知,其还依然存在。
}
break;
case WM_DESTROY:
PostQuitMessage(0);
//响应WM_QUIT消息,WM_QUIT为0,应用程序才会真正退出。
break;
default:
return DefWindowProc(hwnd,uMsg,wParam,lParam);
//如果WM_CLOSE没有响应,该函数调用DestroyWindow函数对WM_CLOSE消息进行响应
}
return 0;
}