窗口的本质
窗口的本质前置基础1虚拟内存● 每个进程 4GB 虚拟地址0x00000000 ~ 0xFFFFFFFF● 用户空间0x00000000 ~ 0x7FFFFFFF低 2GB进程私有● 内核空间0x80000000 ~ 0xFFFFFFFF高 2GB所有进程共享2模块划分● 内核模块内核空间○ ntoskrnl.exe进程、线程、内存管理核心○ win32k.sys图形界面、窗口消息、GDI 底层实现所有进程共享● 用户模块用户空间每个进程独立○ kernel32.dll进程线程内存基础 API○ user32.dll窗口、控件、消息○ gdi32.dll图形设备接口3API 调用链路用户程序 → DLL 接口 (kernel32/user32/gdi32) → 内核模块真正实现句柄对比HANDLE 与 HWND类型维护者句柄表跨进程生命周期用途HANDLE各个内核对象进程私有句柄表❌无效进程关闭自动销毁进程、线程、互斥体、事件等内核对象HWNDwin32k.sys全局共享句柄表✅全系统有效窗口销毁才失效窗口、控件重点HWND 是全局的A 进程拿到的窗口句柄B 进程可以直接使用4. GDI 绘图核心概念1设备对象 (HWND) 绘图目标代表 “画在哪里”可以是窗口、桌面Spy 可以抓取 HWND2设备上下文 HDCDevice Context内存绘图缓冲区所有 GDI 绘图必须依赖 HDC● 获取HDC GetDC(HWND hwnd)● 释放ReleaseDC(HWND hwnd, HDC hdc)● 双缓冲先内存绘图再输出到屏幕3GDI 图形对象选入 DC 使用对象作用创建函数Pen 画笔线条颜色、粗细、线型CreatePen()Brush 画刷区域填充颜色图案CreateSolidBrush() / GetStockObject()Font 字体文字样式CreateFont()Bitmap 位图图片CreateBitmap()SelectObject(HDC hdc, HGDIOBJ hgdiobj)● 将 GDI 对象选入 DC返回旧对象句柄● DC 同一时刻每类对象只能有一个生效● 绘图完成要恢复旧对象销毁自定义 GDI 对象否则发生GDI 资源泄漏5. 画笔 CreatePenHPENCreatePen(intstyle,intwidth,COLORREF color);线型○ PS_SOLID 实线○ PS_DASH虚线、PS_DOT点线、PS_DASHDOT点划线虚线 / 点线宽度必须≤1宽度逻辑像素填 0 代表强制 1 像素颜色COLORREF RGB(r,g,b)r/g/b 范围 0‑255FF示例CreatePen(PS_SOLID,5,RGB(255,0,0)); //5像素红色实线6. GetStockObject 获取系统预置 GDI 对象HGDIOBJGetStockObject(intnIndex);常用参数● BLACK_BRUSH黑色画刷、WHITE_BRUSH白色画刷● NULL_BRUSH / HOLLOW_BRUSH空心画刷● DC_BRUSH可动态改色的画刷配合SetDCBrushColor()系统预置对象不需要必须 DeleteObject写 DeleteObject 也无害7. 关键绘图 API1画线MoveToEx(hdc,x1,y1,NULL);//设置起点LineTo(hdc,x2,y2);//画到终点2绘制矩形Rectangle(hdc,left,top,right,bottom);● 边框由当前 DC 的画笔控制● 内部填充由当前 DC 的画刷控制坐标原点 (0,0)绘图目标窗口左上角标准 GDI 绘图完整示例代码#includewindows.hvoidDrawDemo(HWND hwnd){//1.获取DCHDC hdcGetDC(hwnd);//2.创建5像素红色实线画笔HPEN hPenCreatePen(PS_SOLID,5,RGB(255,0,0));//3.获取系统可变色画刷HBRUSH hBrush(HBRUSH)GetStockObject(DC_BRUSH);//4.把对象选入DC保存旧对象HGDIOBJ oldPenSelectObject(hdc,hPen);HGDIOBJ oldBrushSelectObject(hdc,hBrush);//修改画刷颜色为黄色SetDCBrushColor(hdc,RGB(255,255,0));//绘制400*400矩形Rectangle(hdc,0,0,400,400);//资源恢复与释放【重中之重】//恢复DC原来的对象SelectObject(hdc,oldPen);SelectObject(hdc,oldBrush);//销毁自定义GDI对象DeleteObject(hPen);//GetStockObject获取的对象可不删除//DeleteObject(hBrush);//释放设备上下文ReleaseDC(hwnd,hdc);}注意直接在窗口外部调用绘图窗口被遮挡、最小化再还原时绘制内容会消失原因窗口内容是实时绘制窗口重绘消息WM_PAINT到来会刷新界面真正绘图要写在 WM_PAINT 消息内部总结窗口本质窗口没有永久保存图像所有像素都是 GDI 实时绘制出来。窗口被遮挡后内容丢失需要响应WM_PAINT重绘HDC用完必须ReleaseDC自己 Create 出来的 GDI 对象必须DeleteObject否则 GDI 泄漏SelectObject一定要保存旧对象结束前还原回 DC不能直接选入新对象不管HWND全局有效普通HANDLE只属于本进程画笔控制线条边框画刷控制填充画矩形、椭圆这类闭合图形两者同时生效