96 lines
5.0 KiB
C++
96 lines
5.0 KiB
C++
/**
|
||
* Window(头文件)
|
||
*
|
||
* 设计目标:
|
||
* - 提供一个基于 Win32 + EasyX 的“可拉伸且稳定不抖”的窗口容器。
|
||
* - 通过消息过程子类化(WndProcThunk)接管关键消息(WM_SIZING/WM_SIZE/...)。
|
||
* - 将“几何变化记录(pendingW/H)”与“统一收口重绘(needResizeDirty)”解耦。
|
||
*
|
||
* 关键点(与 .cpp 中实现对应):
|
||
* - isSizing:处于交互拉伸阶段时,冻结重绘;松手后统一重绘,防止抖动。
|
||
* - WM_SIZING:只做“最小尺寸夹紧”,不回滚矩形、不做对齐;把其余交给系统。
|
||
* - WM_GETMINMAXINFO:按最小“客户区”换算到“窗口矩形”,提供系统层最小轨迹值。
|
||
* - runEventLoop:只记录 WM_SIZE 的新尺寸;真正绘制放在 needResizeDirty 时集中处理。
|
||
*/
|
||
//fuck windows fuck win32
|
||
#pragma once
|
||
|
||
#include "Control.h"
|
||
#include <string>
|
||
#include <vector>
|
||
#include <memory>
|
||
#include <windows.h>
|
||
|
||
class Window
|
||
{
|
||
// —— 尺寸状态 ——(绘制尺寸与待应用尺寸分离;收口时一次性更新)
|
||
int width; // 当前有效宽(已应用到画布/控件的客户区宽)
|
||
int height; // 当前有效高(已应用到画布/控件的客户区高)
|
||
int localwidth; // 基准宽(创建时的宽度)
|
||
int localheight; // 基准高(创建是的高度)
|
||
int pendingW; // 待应用宽(WM_SIZE/拉伸中记录用)
|
||
int pendingH; // 待应用高
|
||
int minClientW; // 业务设定的最小客户区宽(用于 GETMINMAXINFO 与 SIZING 夹紧)
|
||
int minClientH; // 业务设定的最小客户区高
|
||
int windowMode = NULL; // EasyX 初始化模式(EX_SHOWCONSOLE/EX_TOPMOST/...)
|
||
bool needResizeDirty = false; // 统一收口重绘标志(置位后在事件环末尾处理)
|
||
bool isSizing = false; // 是否处于拖拽阶段(ENTER/EXIT SIZEMOVE 切换)
|
||
|
||
// —— 原生窗口句柄与子类化钩子 ——(子类化 EasyX 的窗口过程以拦截关键消息)
|
||
HWND hWnd = NULL; // EasyX 初始化后的窗口句柄
|
||
WNDPROC oldWndProc = nullptr; // 保存旧过程(CallWindowProc 回落)
|
||
bool procHooked = false; // 避免重复子类化
|
||
static LRESULT CALLBACK WndProcThunk(HWND h, UINT m, WPARAM w, LPARAM l); // 静态过程分发到 this
|
||
|
||
// —— 绘制相关 ——(是否使用合成双缓冲、窗口标题、背景等)
|
||
bool useComposited = true; // 是否启用 WS_EX_COMPOSITED(部分机器可能增加一帧观感延迟)
|
||
std::string headline; // 窗口标题文本
|
||
COLORREF wBkcolor = BLACK; // 纯色背景(无背景图时使用)
|
||
IMAGE* background = nullptr; // 背景图对象指针(存在时优先绘制)
|
||
std::string bkImageFile; // 背景图文件路径(loadimage 用)
|
||
|
||
// —— 控件/对话框 ——(容器内的普通控件与非模态对话框)
|
||
std::vector<std::unique_ptr<Control>> controls;
|
||
std::vector<std::unique_ptr<Control>> dialogs;
|
||
|
||
public:
|
||
bool dialogClose = false; // 项目内使用的状态位,对话框关闭标志
|
||
|
||
// —— 构造/析构 ——(仅初始化成员;实际样式与子类化在 draw() 中完成)
|
||
Window(int width, int height, int mode);
|
||
Window(int width, int height, int mode, COLORREF bkcloc);
|
||
Window(int width, int height, int mode, COLORREF bkcloc, std::string headline);
|
||
~Window();
|
||
|
||
// —— 绘制与事件循环 ——(draw* 完成一次全量绘制;runEventLoop 驱动事件与统一收口)
|
||
void draw(); // 纯色背景版本
|
||
void draw(std::string pImgFile); // 背景图版本
|
||
int runEventLoop(); // 主事件循环(PeekMessage + 统一收口重绘)
|
||
|
||
// —— 背景/标题设置 ——(更换背景、背景色与标题;立即触发一次批量绘制)
|
||
void setBkImage(std::string pImgFile);
|
||
void setBkcolor(COLORREF c);
|
||
void setHeadline(std::string headline);
|
||
|
||
// —— 控件/对话框管理 ——(添加到容器,或做存在性判断)
|
||
void addControl(std::unique_ptr<Control> control);
|
||
void addDialog(std::unique_ptr<Control> dialogs);
|
||
bool hasNonModalDialogWithCaption(const std::string& caption, const std::string& message) const;
|
||
|
||
// —— 访问器 ——(只读接口,供外部查询当前窗口/标题/背景等)
|
||
HWND getHwnd() const;
|
||
int getWidth() const;
|
||
int getHeight() const;
|
||
std::string getHeadline() const;
|
||
COLORREF getBkcolor() const;
|
||
IMAGE* getBkImage() const;
|
||
std::string getBkImageFile() const;
|
||
std::vector<std::unique_ptr<Control>>& getControls();
|
||
|
||
// —— 尺寸调整 ——(供内部与外部调用的尺寸变化处理)
|
||
void pumpResizeIfNeeded(); // 执行一次统一收口重绘
|
||
void scheduleResizeFromModal(int w, int h);
|
||
private:
|
||
void adaptiveLayout(std::unique_ptr<Control>& c, const int finalH, const int finalW);
|
||
};
|