UIBase.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. #ifndef __UIBASE_H__
  2. #define __UIBASE_H__
  3. #pragma once
  4. namespace DuiLib {
  5. /////////////////////////////////////////////////////////////////////////////////////
  6. //
  7. #define UI_WNDSTYLE_CONTAINER (0)
  8. #define UI_WNDSTYLE_FRAME (WS_VISIBLE | WS_OVERLAPPEDWINDOW)
  9. #define UI_WNDSTYLE_CHILD (WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN)
  10. #define UI_WNDSTYLE_DIALOG (WS_VISIBLE | WS_POPUPWINDOW | WS_CAPTION | WS_DLGFRAME | WS_CLIPSIBLINGS | WS_CLIPCHILDREN)
  11. #define UI_WNDSTYLE_EX_FRAME (WS_EX_WINDOWEDGE)
  12. #define UI_WNDSTYLE_EX_DIALOG (WS_EX_TOOLWINDOW | WS_EX_DLGMODALFRAME)
  13. #define UI_CLASSSTYLE_CONTAINER (0)
  14. #define UI_CLASSSTYLE_FRAME (CS_VREDRAW | CS_HREDRAW)
  15. #define UI_CLASSSTYLE_CHILD (CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS | CS_SAVEBITS)
  16. #define UI_CLASSSTYLE_DIALOG (CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS | CS_SAVEBITS)
  17. /////////////////////////////////////////////////////////////////////////////////////
  18. //
  19. #ifndef ASSERT
  20. #define ASSERT(expr) _ASSERTE(expr)
  21. #endif
  22. #ifdef _DEBUG
  23. #ifndef DUITRACE
  24. #define DUITRACE DUI__Trace
  25. #endif
  26. #define DUITRACEMSG DUI__TraceMsg
  27. #else
  28. #ifndef DUITRACE
  29. #define DUITRACE
  30. #endif
  31. #define DUITRACEMSG _T("")
  32. #endif
  33. void UILIB_API DUI__Trace(LPCTSTR pstrFormat, ...);
  34. LPCTSTR UILIB_API DUI__TraceMsg(UINT uMsg);
  35. // 诊断日志出口已**统一到 `DuiLibDiag`**(Utils/UIDiag.h)。
  36. // 此处原先声明的 `namespace TouchTrace { void Log(LPCTSTR, ...); }` 已删除
  37. // —— UIManager.cpp 里的那份本地实现没了,声明留着只会让漏改的调用点
  38. // 变成"能编译但链接失败",反而不如让它直接在编译期报错。
  39. /////////////////////////////////////////////////////////////////////////////////////
  40. //
  41. class UILIB_API CNotifyPump
  42. {
  43. public:
  44. bool AddVirtualWnd(CDuiString strName,CNotifyPump* pObject);
  45. bool RemoveVirtualWnd(CDuiString strName);
  46. void NotifyPump(TNotifyUI& msg);
  47. bool LoopDispatch(TNotifyUI& msg);
  48. DUI_DECLARE_MESSAGE_MAP()
  49. private:
  50. CStdStringPtrMap m_VirtualWndMap;
  51. };
  52. class UILIB_API CWindowWnd
  53. {
  54. public:
  55. CWindowWnd();
  56. HWND GetHWND() const;
  57. operator HWND() const;
  58. void EnableUnicode();
  59. bool RegisterWindowClass();
  60. bool RegisterSuperclass();
  61. HWND Create(HWND hwndParent, LPCTSTR pstrName, DWORD dwStyle, DWORD dwExStyle, const RECT rc, HMENU hMenu = NULL);
  62. HWND Create(HWND hwndParent, LPCTSTR pstrName, DWORD dwStyle, DWORD dwExStyle, int x = CW_USEDEFAULT, int y = CW_USEDEFAULT, int cx = CW_USEDEFAULT, int cy = CW_USEDEFAULT, HMENU hMenu = NULL);
  63. HWND CreateDuiWindow(HWND hwndParent, LPCTSTR pstrWindowName,DWORD dwStyle =0, DWORD dwExStyle =0);
  64. HWND Subclass(HWND hWnd);
  65. void Unsubclass();
  66. void ShowWindow(bool bShow = true, bool bTakeFocus = true);
  67. UINT ShowModal();
  68. void ShowModalFake();
  69. void Close(UINT nRet = IDOK);
  70. void CenterWindow(); // 居中,支持扩展屏幕
  71. void SetIcon(UINT nRes);
  72. LRESULT SendMessage(UINT uMsg, WPARAM wParam = 0, LPARAM lParam = 0L);
  73. LRESULT PostMessage(UINT uMsg, WPARAM wParam = 0, LPARAM lParam = 0L);
  74. void ResizeClient(int cx = -1, int cy = -1);
  75. protected:
  76. virtual LPCTSTR GetWindowClassName() const = 0;
  77. virtual LPCTSTR GetSuperClassName() const;
  78. virtual UINT GetClassStyle() const;
  79. virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
  80. virtual void OnFinalMessage(HWND hWnd);
  81. static LRESULT CALLBACK __WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  82. static LRESULT CALLBACK __ControlProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  83. // 真模态(DialogBox)用的对话框过程。见 UIBase.cpp 里 ShowModal 的大段说明。
  84. // 参考 nim_duilib NativeWindow_Windows::__DialogProc。
  85. static INT_PTR CALLBACK __DialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
  86. // 对话框窗口的窗口过程:接管 GWLP_WNDPROC,把消息喂给 CWindowWnd::HandleMessage,
  87. // 从而既复用系统对话框的消息循环(模态/触摸投递语义),又保留 DuiLib 的自绘与路由。
  88. static LRESULT CALLBACK __DialogWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  89. protected:
  90. HWND m_hWnd;
  91. WNDPROC m_OldWndProc;
  92. bool m_bSubclassed;
  93. bool m_bUnicode;
  94. bool m_bFakeModal;
  95. // ---- 真模态(DialogBox)状态 ----
  96. bool m_bDoModal; // 当前正处在 DialogBoxIndirectParam 阻塞循环中
  97. UINT m_nModalRet; // 模态返回值(EndDialog 时写入)
  98. // 对话框窗口的原始窗口过程(WM_INITDIALOG 时保存、WM_NCDESTROY 时还原)
  99. WNDPROC m_pfnOldDlgWndProc;
  100. // 目标几何:left/top = 目标窗口左上角(屏幕坐标),right/bottom = left/top + 目标**客户区**尺寸。
  101. // 由 ShowModal 填写,__DialogProc 在 WM_INITDIALOG 里据此校正对话框的实际大小,
  102. // 保证迁移后客户区尺寸与原窗口逐像素一致(否则弹框会因边框换算而变大)。
  103. RECT m_rcModalTarget;
  104. };
  105. // ---------------------------------------------------------------------------
  106. // 真模态(DialogBox)辅助:按 paint window 句柄找到对应的 CPaintManagerUI。
  107. //
  108. // 定义在 UIBase.cpp。用途:ShowModal 要把 manager 从旧 HWND 迁到对话框新 HWND 时先找到它;
  109. // 也是 CPaintManagerUI::IsModalBackdropWindow 判定"本句柄是否就是弹框自己的 manager 窗口"
  110. // 的依据(透传闸门的一条关键判据)。
  111. //
  112. // 为什么必须在头文件里声明:它是 UIManager.cpp 要用的自由函数,此前只在 UIBase.cpp
  113. // 里定义、没有任何头文件声明 —— UIManager.cpp 引用它会报 C3861(找不到标识符)。
  114. // ---------------------------------------------------------------------------
  115. DuiLib::CPaintManagerUI* FindManagerByPaintWindow(HWND hWnd);
  116. // ---------------------------------------------------------------------------
  117. // [透传根治 · 全局代数] 跨模态边界的提升鼠标消息作废机制。
  118. //
  119. // 背景:一次触摸会被系统提升出一对原生鼠标消息(DOWN+UP,extra 带
  120. // MOUSEEVENTF_FROMTOUCH)。其中一条可能在 ShowModal() 的嵌套循环里被
  121. // 阻塞,等循环退出、模态归零之后才被投递 ⇒ 它带着"上一次手势"的身份
  122. // 干了"这一次交互"的活 = 透传。
  123. //
  124. // 为什么是**全局函数**而不是 CPaintManagerUI 的成员:
  125. // 弹框(如 CDiandanNatureWnd)与主窗口是**两个不同的 manager**,
  126. // 而泄漏是线程消息队列现象 —— 在弹框 manager 上记录,主窗口看不见。
  127. // 详见 UIManager.cpp 里 s_nPromotedMouseGeneration 处的长注释。
  128. // ---------------------------------------------------------------------------
  129. // ShowModal() 在进入 DialogBoxIndirectParam 之前调用,把代数 +1。
  130. // 此后"水位落后于当前代数"的提升鼠标消息一律作废。
  131. void BumpPromotedMouseGenerationGlobal();
  132. // 当前代数(仅日志/诊断用)。
  133. UINT PeekPromotedMouseGeneration();
  134. } // namespace DuiLib
  135. #endif // __UIBASE_H__