UIManager.h 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846
  1. #ifndef __UIMANAGER_H__
  2. #define __UIMANAGER_H__
  3. #pragma once
  4. // 本头文件原本不含任何 include(符号由 StdAfx.h/UIlib.h 提供),
  5. // 但触屏相关的成员与状态里直接使用了 std::int64_t 与 std::vector,
  6. // 显式补齐以保证在 DuiLib 库工程(_WIN32_WINNT 兜底为 XP)里也能独立通过编译。
  7. #include <cstdint>
  8. #include <vector>
  9. namespace DuiLib {
  10. /////////////////////////////////////////////////////////////////////////////////////
  11. //
  12. class CControlUI;
  13. class CContainerUI;
  14. class CRichEditUI;
  15. class CIDropTarget;
  16. /////////////////////////////////////////////////////////////////////////////////////
  17. //
  18. enum UILIB_RESTYPE
  19. {
  20. UILIB_FILE=1, // 来自磁盘文件
  21. UILIB_ZIP, // 来自磁盘zip压缩包
  22. UILIB_RESOURCE, // 来自资源
  23. UILIB_ZIPRESOURCE, // 来自资源的zip压缩包
  24. };
  25. /////////////////////////////////////////////////////////////////////////////////////
  26. //
  27. typedef enum EVENTTYPE_UI
  28. {
  29. UIEVENT__FIRST = 1,
  30. UIEVENT__KEYBEGIN,
  31. UIEVENT_KEYDOWN,
  32. UIEVENT_KEYUP,
  33. UIEVENT_CHAR,
  34. UIEVENT_SYSKEY,
  35. UIEVENT__KEYEND,
  36. UIEVENT__MOUSEBEGIN,
  37. UIEVENT_MOUSEMOVE,
  38. UIEVENT_MOUSELEAVE,
  39. UIEVENT_MOUSEENTER,
  40. UIEVENT_MOUSEHOVER,
  41. UIEVENT_BUTTONDOWN,
  42. UIEVENT_BUTTONUP,
  43. UIEVENT_RBUTTONDOWN,
  44. UIEVENT_RBUTTONUP,
  45. UIEVENT_MBUTTONDOWN,
  46. UIEVENT_MBUTTONUP,
  47. UIEVENT_DBLCLICK,
  48. UIEVENT_CONTEXTMENU,
  49. UIEVENT_SCROLLWHEEL,
  50. UIEVENT__MOUSEEND,
  51. // 触摸事件(NIM Duilib 模型)。必须排在 __MOUSEEND 之后:
  52. // CContainerUI::DoEvent 开头对 UIEVENT__MOUSEBEGIN~__MOUSEEND 区间做了 IsMouseEnabled 早退分支,
  53. // 排在区间之外才能保证触摸事件始终走正常派发与冒泡。
  54. UIEVENT__TOUCHBEGIN,
  55. UIEVENT_TOUCHDOWN,
  56. UIEVENT_TOUCHMOVE,
  57. UIEVENT_TOUCHUP,
  58. UIEVENT__TOUCHEND,
  59. UIEVENT_KILLFOCUS,
  60. UIEVENT_SETFOCUS,
  61. UIEVENT_WINDOWSIZE,
  62. UIEVENT_SETCURSOR,
  63. UIEVENT_TIMER,
  64. UIEVENT__LAST,
  65. };
  66. /////////////////////////////////////////////////////////////////////////////////////
  67. //
  68. // 内部保留的消息
  69. typedef enum MSGTYPE_UI
  70. {
  71. UIMSG_TRAYICON = WM_USER + 1,// 托盘消息
  72. UIMSG_SET_DPI, // DPI
  73. WM_MENUCLICK, // 菜单消息
  74. UIMSG_USER = WM_USER + 100, // 程序自定义消息
  75. };
  76. /////////////////////////////////////////////////////////////////////////////////////
  77. //
  78. // Flags for CControlUI::GetControlFlags()
  79. #define UIFLAG_TABSTOP 0x00000001
  80. #define UIFLAG_SETCURSOR 0x00000002
  81. #define UIFLAG_WANTRETURN 0x00000004
  82. // Flags for FindControl()
  83. #define UIFIND_ALL 0x00000000
  84. #define UIFIND_VISIBLE 0x00000001
  85. #define UIFIND_ENABLED 0x00000002
  86. #define UIFIND_HITTEST 0x00000004
  87. #define UIFIND_UPDATETEST 0x00000008
  88. #define UIFIND_TOP_FIRST 0x00000010
  89. #define UIFIND_ME_FIRST 0x80000000
  90. // Flags used for controlling the paint
  91. #define UISTATE_FOCUSED 0x00000001
  92. #define UISTATE_SELECTED 0x00000002
  93. #define UISTATE_DISABLED 0x00000004
  94. #define UISTATE_HOT 0x00000008
  95. #define UISTATE_PUSHED 0x00000010
  96. #define UISTATE_READONLY 0x00000020
  97. #define UISTATE_CAPTURED 0x00000040
  98. /////////////////////////////////////////////////////////////////////////////////////
  99. //
  100. typedef struct UILIB_API tagTFontInfo
  101. {
  102. HFONT hFont;
  103. CDuiString sFontName;
  104. int iSize;
  105. bool bBold;
  106. bool bUnderline;
  107. bool bItalic;
  108. bool bStrikeout;
  109. TEXTMETRIC tm;
  110. } TFontInfo;
  111. typedef struct UILIB_API tagTImageInfo
  112. {
  113. tagTImageInfo();
  114. Gdiplus::Image* pImage;
  115. HBITMAP hBitmap;
  116. LPBYTE pBits;
  117. LPBYTE pSrcBits;
  118. int nX;
  119. int nY;
  120. bool bAlpha;
  121. bool bUseHSL;
  122. CDuiString sResType;
  123. DWORD dwMask;
  124. } TImageInfo;
  125. typedef struct UILIB_API tagTDrawInfo
  126. {
  127. tagTDrawInfo();
  128. void Parse(LPCTSTR pStrImage, LPCTSTR pStrModify, CPaintManagerUI *pManager);
  129. void Clear();
  130. CDuiString sDrawString;
  131. CDuiString sDrawModify;
  132. CDuiString sImageName;
  133. CDuiString sResType;
  134. RECT rcDest;
  135. RECT rcSource;
  136. RECT rcCorner;
  137. DWORD dwMask;
  138. UINT uFade;
  139. UINT uRotate;
  140. bool bHole;
  141. bool bTiledX;
  142. bool bTiledY;
  143. bool bHSL;
  144. bool bGdiplus;
  145. CDuiSize szImage;
  146. RECT rcPadding;
  147. CDuiString sAlign;
  148. } TDrawInfo;
  149. typedef struct UILIB_API tagTPercentInfo
  150. {
  151. double left;
  152. double top;
  153. double right;
  154. double bottom;
  155. } TPercentInfo;
  156. typedef struct UILIB_API tagTResInfo
  157. {
  158. DWORD m_dwDefaultDisabledColor;
  159. DWORD m_dwDefaultFontColor;
  160. DWORD m_dwDefaultLinkFontColor;
  161. DWORD m_dwDefaultLinkHoverFontColor;
  162. DWORD m_dwDefaultSelectedBkColor;
  163. TFontInfo m_DefaultFontInfo;
  164. CStdStringPtrMap m_CustomFonts;
  165. CStdStringPtrMap m_ImageHash;
  166. CStdStringPtrMap m_AttrHash;
  167. CStdStringPtrMap m_StyleHash;
  168. CStdStringPtrMap m_DrawInfoHash;
  169. } TResInfo;
  170. // Structure for notifications from the system
  171. // to the control implementation.
  172. typedef struct UILIB_API tagTEventUI
  173. {
  174. int Type;
  175. CControlUI* pSender;
  176. DWORD dwTimestamp;
  177. POINT ptMouse;
  178. TCHAR chKey;
  179. WORD wKeyState;
  180. WPARAM wParam;
  181. LPARAM lParam;
  182. } TEventUI;
  183. // Drag&Drop control
  184. const TCHAR* const CF_MOVECONTROL = _T("CF_MOVECONTROL");
  185. typedef struct UILIB_API tagTCFMoveUI
  186. {
  187. CControlUI* pControl;
  188. } TCFMoveUI;
  189. // Listener interface
  190. class INotifyUI
  191. {
  192. public:
  193. virtual void Notify(TNotifyUI& msg) = 0;
  194. };
  195. // MessageFilter interface
  196. class IMessageFilterUI
  197. {
  198. public:
  199. virtual LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, bool& bHandled) = 0;
  200. };
  201. class ITranslateAccelerator
  202. {
  203. public:
  204. virtual LRESULT TranslateAccelerator(MSG *pMsg) = 0;
  205. };
  206. class IDragDropUI
  207. {
  208. public:
  209. virtual bool OnDragDrop(CControlUI* pControl) { return false; }
  210. };
  211. /////////////////////////////////////////////////////////////////////////////////////
  212. //
  213. typedef CControlUI* (*LPCREATECONTROL)(LPCTSTR pstrType);
  214. class UILIB_API CPaintManagerUI : public CIDropTarget
  215. {
  216. public:
  217. CPaintManagerUI();
  218. ~CPaintManagerUI();
  219. public:
  220. void Init(HWND hWnd, LPCTSTR pstrName = NULL);
  221. // ------------------------------------------------------------------
  222. // 真模态(DialogBox)支持:把本 manager 从原 paint window 上摘下来 / 挂到新窗口上。
  223. //
  224. // 背景:Windows 的 DialogBox 机制不允许调用方指定 HWND,只能由系统创建对话框窗口。
  225. // 而调用方是「先 Create 再 ShowModal」,所以 ShowModal 里必须把已经 Init 好的 manager
  226. // 从旧 HWND 迁移到对话框的新 HWND —— 但**不能**重新走 Init(Init 会清空字体/图片/样式
  227. // 等已加载资源,且会重复 Add 到 m_aPreMessages)。因此这里提供一对轻量的挂载/摘除。
  228. //
  229. // DetachPaintWindow:释放旧 DC、从 m_aPreMessages 摘除,但**保留** m_hWndPaint 之外的
  230. // 全部状态(控件树、资源、定时器、字体…)。
  231. // AttachPaintWindow:绑定新 HWND 与 DC,重新加入 m_aPreMessages。
  232. // ------------------------------------------------------------------
  233. void DetachPaintWindow();
  234. void AttachPaintWindow(HWND hWnd);
  235. bool IsUpdateNeeded() const;
  236. void NeedUpdate();
  237. void Invalidate();
  238. void Invalidate(RECT& rcItem);
  239. LPCTSTR GetName() const;
  240. HDC GetPaintDC() const;
  241. HWND GetPaintWindow() const;
  242. HWND GetTooltipWindow() const;
  243. int GetHoverTime() const;
  244. void SetHoverTime(int iTime);
  245. POINT GetMousePos() const;
  246. SIZE GetClientSize() const;
  247. SIZE GetInitSize();
  248. void SetInitSize(int cx, int cy);
  249. RECT GetSizeBox();
  250. void SetSizeBox(RECT& rcSizeBox);
  251. RECT GetCaptionRect();
  252. void SetCaptionRect(RECT& rcCaption);
  253. SIZE GetRoundCorner();
  254. void SetRoundCorner(int cx, int cy);
  255. SIZE GetMinInfo();
  256. void SetMinInfo(int cx, int cy);
  257. SIZE GetMaxInfo();
  258. void SetMaxInfo(int cx, int cy);
  259. bool IsShowUpdateRect();
  260. void SetShowUpdateRect(bool show);
  261. bool IsNoActivate();
  262. void SetNoActivate(bool bNoActivate);
  263. BYTE GetOpacity() const;
  264. void SetOpacity(BYTE nOpacity);
  265. bool IsLayered();
  266. void SetLayered(bool bLayered);
  267. RECT& GetLayeredInset();
  268. void SetLayeredInset(RECT& rcLayeredInset);
  269. BYTE GetLayeredOpacity();
  270. void SetLayeredOpacity(BYTE nOpacity);
  271. LPCTSTR GetLayeredImage();
  272. void SetLayeredImage(LPCTSTR pstrImage);
  273. CShadowUI* GetShadow();
  274. void SetUseGdiplusText(bool bUse);
  275. bool IsUseGdiplusText() const;
  276. void SetGdiplusTextRenderingHint(int trh);
  277. int GetGdiplusTextRenderingHint() const;
  278. static HINSTANCE GetInstance();
  279. static CDuiString GetInstancePath();
  280. static CDuiString GetCurrentPath();
  281. static HINSTANCE GetResourceDll();
  282. static const CDuiString& GetResourcePath();
  283. static const CDuiString& GetResourceZip();
  284. static const CDuiString& GetResourceZipPwd();
  285. static bool IsCachedResourceZip();
  286. static HANDLE GetResourceZipHandle();
  287. static void SetInstance(HINSTANCE hInst);
  288. static void SetCurrentPath(LPCTSTR pStrPath);
  289. static void SetResourceDll(HINSTANCE hInst);
  290. static void SetResourcePath(LPCTSTR pStrPath);
  291. static void SetResourceZip(LPVOID pVoid, unsigned int len, LPCTSTR password = NULL);
  292. static void SetResourceZip(LPCTSTR pstrZip, bool bCachedResourceZip = false, LPCTSTR password = NULL);
  293. static void SetResourceType(int nType);
  294. static int GetResourceType();
  295. static bool GetHSL(short* H, short* S, short* L);
  296. static void SetHSL(bool bUseHSL, short H, short S, short L); // H:0~360, S:0~200, L:0~200
  297. static void ReloadSkin();
  298. static CPaintManagerUI* GetPaintManager(LPCTSTR pstrName);
  299. static CStdPtrArray* GetPaintManagers();
  300. static bool LoadPlugin(LPCTSTR pstrModuleName);
  301. static CStdPtrArray* GetPlugins();
  302. bool IsForceUseSharedRes() const;
  303. void SetForceUseSharedRes(bool bForce);
  304. // 注意:只支持简单类型指针,因为只释放内存,不会调用类对象的析构函数
  305. void DeletePtr(void* ptr);
  306. DWORD GetDefaultDisabledColor() const;
  307. void SetDefaultDisabledColor(DWORD dwColor, bool bShared = false);
  308. DWORD GetDefaultFontColor() const;
  309. void SetDefaultFontColor(DWORD dwColor, bool bShared = false);
  310. DWORD GetDefaultLinkFontColor() const;
  311. void SetDefaultLinkFontColor(DWORD dwColor, bool bShared = false);
  312. DWORD GetDefaultLinkHoverFontColor() const;
  313. void SetDefaultLinkHoverFontColor(DWORD dwColor, bool bShared = false);
  314. DWORD GetDefaultSelectedBkColor() const;
  315. void SetDefaultSelectedBkColor(DWORD dwColor, bool bShared = false);
  316. TFontInfo* GetDefaultFontInfo();
  317. void SetDefaultFont(LPCTSTR pStrFontName, int nSize, bool bBold, bool bUnderline, bool bItalic, bool bStrikeout, bool bShared = false);
  318. DWORD GetCustomFontCount(bool bShared = false) const;
  319. void AddFontArray(LPCTSTR pstrPath);
  320. HFONT AddFont(int id, LPCTSTR pStrFontName, int nSize, bool bBold, bool bUnderline, bool bItalic, bool bStrikeout, bool bShared = false);
  321. HFONT GetFont(int id);
  322. HFONT GetFont(LPCTSTR pStrFontName, int nSize, bool bBold, bool bUnderline, bool bItalic, bool bStrikeout);
  323. int GetFontIndex(HFONT hFont, bool bShared = false);
  324. int GetFontIndex(LPCTSTR pStrFontName, int nSize, bool bBold, bool bUnderline, bool bItalic, bool bStrikeout, bool bShared = false);
  325. void RemoveFont(HFONT hFont, bool bShared = false);
  326. void RemoveFont(int id, bool bShared = false);
  327. void RemoveAllFonts(bool bShared = false);
  328. TFontInfo* GetFontInfo(int id);
  329. TFontInfo* GetFontInfo(HFONT hFont);
  330. const TImageInfo* GetImage(LPCTSTR bitmap);
  331. const TImageInfo* GetImageEx(LPCTSTR bitmap, LPCTSTR type = NULL, DWORD mask = 0, bool bUseHSL = false, bool bGdiplus = false, HINSTANCE instance = NULL);
  332. const TImageInfo* AddImage(LPCTSTR bitmap, LPCTSTR type = NULL, DWORD mask = 0, bool bUseHSL = false, bool bGdiplus = false, bool bShared = false, HINSTANCE instance = NULL);
  333. const TImageInfo* AddImage(LPCTSTR bitmap, HBITMAP hBitmap, int iWidth, int iHeight, bool bAlpha, bool bShared = false);
  334. void RemoveImage(LPCTSTR bitmap, bool bShared = false);
  335. void RemoveAllImages(bool bShared = false);
  336. static void ReloadSharedImages();
  337. void ReloadImages();
  338. const TDrawInfo* GetDrawInfo(LPCTSTR pStrImage, LPCTSTR pStrModify);
  339. void RemoveDrawInfo(LPCTSTR pStrImage, LPCTSTR pStrModify);
  340. void RemoveAllDrawInfos();
  341. void AddDefaultAttributeList(LPCTSTR pStrControlName, LPCTSTR pStrControlAttrList, bool bShared = false);
  342. LPCTSTR GetDefaultAttributeList(LPCTSTR pStrControlName) const;
  343. bool RemoveDefaultAttributeList(LPCTSTR pStrControlName, bool bShared = false);
  344. void RemoveAllDefaultAttributeList(bool bShared = false);
  345. void AddWindowCustomAttribute(LPCTSTR pstrName, LPCTSTR pstrAttr);
  346. LPCTSTR GetWindowCustomAttribute(LPCTSTR pstrName) const;
  347. bool RemoveWindowCustomAttribute(LPCTSTR pstrName);
  348. void RemoveAllWindowCustomAttribute();
  349. // 样式管理
  350. void AddStyle(LPCTSTR pName, LPCTSTR pStyle, bool bShared = false);
  351. LPCTSTR GetStyle(LPCTSTR pName) const;
  352. BOOL RemoveStyle(LPCTSTR pName, bool bShared = false);
  353. const CStdStringPtrMap& GetStyles(bool bShared = false) const;
  354. void RemoveAllStyle(bool bShared = false);
  355. const TImageInfo* GetImageString(LPCTSTR pStrImage, LPCTSTR pStrModify = NULL);
  356. // 初始化拖拽
  357. bool EnableDragDrop(bool bEnable);
  358. void SetDragDrop(IDragDropUI* pDragDrop);
  359. virtual bool OnDrop(FORMATETC* pFmtEtc, STGMEDIUM& medium,DWORD *pdwEffect);
  360. bool IsValid();
  361. bool AttachDialog(CControlUI* pControl);
  362. bool InitControls(CControlUI* pControl, CControlUI* pParent = NULL);
  363. void ReapObjects(CControlUI* pControl);
  364. bool AddOptionGroup(LPCTSTR pStrGroupName, CControlUI* pControl);
  365. CStdPtrArray* GetOptionGroup(LPCTSTR pStrGroupName);
  366. void RemoveOptionGroup(LPCTSTR pStrGroupName, CControlUI* pControl);
  367. void RemoveAllOptionGroups();
  368. CControlUI* GetFocus() const;
  369. void SetFocus(CControlUI* pControl);
  370. void SetFocusNeeded(CControlUI* pControl);
  371. bool SetNextTabControl(bool bForward = true);
  372. bool SetTimer(CControlUI* pControl, UINT nTimerID, UINT uElapse);
  373. bool KillTimer(CControlUI* pControl, UINT nTimerID);
  374. void KillTimer(CControlUI* pControl);
  375. void RemoveAllTimers();
  376. void SetCapture();
  377. void ReleaseCapture();
  378. bool IsCaptured();
  379. bool IsPainting();
  380. void SetPainting(bool bIsPainting);
  381. bool AddNotifier(INotifyUI* pControl);
  382. bool RemoveNotifier(INotifyUI* pControl);
  383. void SendNotify(TNotifyUI& Msg, bool bAsync = false);
  384. void SendNotify(CControlUI* pControl, LPCTSTR pstrMessage, WPARAM wParam = 0, LPARAM lParam = 0, bool bAsync = false);
  385. bool AddPreMessageFilter(IMessageFilterUI* pFilter);
  386. bool RemovePreMessageFilter(IMessageFilterUI* pFilter);
  387. bool AddMessageFilter(IMessageFilterUI* pFilter);
  388. bool RemoveMessageFilter(IMessageFilterUI* pFilter);
  389. int GetPostPaintCount() const;
  390. bool IsPostPaint(CControlUI* pControl);
  391. bool AddPostPaint(CControlUI* pControl);
  392. bool RemovePostPaint(CControlUI* pControl);
  393. bool SetPostPaintIndex(CControlUI* pControl, int iIndex);
  394. int GetNativeWindowCount() const;
  395. RECT GetNativeWindowRect(HWND hChildWnd);
  396. bool AddNativeWindow(CControlUI* pControl, HWND hChildWnd);
  397. bool RemoveNativeWindow(HWND hChildWnd);
  398. void AddDelayedCleanup(CControlUI* pControl);
  399. void AddMouseLeaveNeeded(CControlUI* pControl);
  400. bool RemoveMouseLeaveNeeded(CControlUI* pControl);
  401. bool AddTranslateAccelerator(ITranslateAccelerator *pTranslateAccelerator);
  402. bool RemoveTranslateAccelerator(ITranslateAccelerator *pTranslateAccelerator);
  403. bool TranslateAccelerator(LPMSG pMsg);
  404. CControlUI* GetRoot() const;
  405. CControlUI* FindControl(POINT pt) const;
  406. CControlUI* FindControl(LPCTSTR pstrName) const;
  407. CControlUI* FindSubControlByPoint(CControlUI* pParent, POINT pt) const;
  408. CControlUI* FindSubControlByName(CControlUI* pParent, LPCTSTR pstrName) const;
  409. CControlUI* FindSubControlByClass(CControlUI* pParent, LPCTSTR pstrClass, int iIndex = 0);
  410. CStdPtrArray* FindSubControlsByClass(CControlUI* pParent, LPCTSTR pstrClass);
  411. static void MessageLoop();
  412. static bool TranslateMessage(const LPMSG pMsg);
  413. static void Term();
  414. CDPI* GetDPIObj();
  415. void ResetDPIAssets();
  416. void RebuildFont(TFontInfo* pFontInfo);
  417. void SetDPI(int iDPI);
  418. static void SetAllDPI(int iDPI);
  419. bool MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lRes);
  420. bool PreMessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lRes);
  421. void UsedVirtualWnd(bool bUsed);
  422. // 触屏支持(参考 NIM Duilib 模型,库级统一接管:主窗口 + 所有弹框通用)。
  423. //
  424. // 【重要】滑动逻辑与输入通道解耦(Begin/Update/End 三个共享函数):
  425. // Win10 上同一次触摸会在**两条互相独立**的通道上产生消息 ——
  426. // WM_TOUCH 与 WM_POINTER*(Win8+ 指针栈)。哪条通道驱动本次手势是运行时决定的
  427. // (本台收银机:主窗口常常 WM_TOUCH 先到;弹框 / 被指针抢走的手势只有指针)。
  428. //
  429. // 早期版本把"滑动"的全部实现(1:1 跟手平移 / 拖滚动条滑块 / Δy→滚轮)只写在
  430. // WM_TOUCH 通道里。于是指针通道一旦抢到手势,就出现两个症状:
  431. // · 「滑不动」—— 没有任何滑动逻辑被执行;
  432. // · 「滑动反倒触发点击」—— 指针把 UP 归一化成 WM_LBUTTONUP 走原生点击路径,
  433. // 而 tap/drag 判定所需的 m_bTouchMoved 从未被置真。
  434. // 现在抽成通道无关的 Begin/Update/End,两条通道都调用同一套 —— 行为必然一致。
  435. //
  436. // 派发给命中控件的事件语义(两通道统一):
  437. // DOWN → UIEVENT_TOUCHDOWN 滚动条据此抓滑块;容器据此记手势起点(其余控件忽略)
  438. // MOVE → UIEVENT_TOUCHMOVE CScrollBarUI 消费则拖滑块;否则冒泡给 CContainerUI 做 1:1 跟手平移
  439. // UP → UIEVENT_TOUCHUP 滚动条据此松开滑块;容器收尾(其余控件忽略)
  440. //
  441. // 按钮"点击"由 **End 的返回值(tap 判定)** 统一决定是否合成 BUTTONDOWN/BUTTONUP:
  442. // 位移超过 8px 阈值 ⇒ 判为拖拽 ⇒ **不**触发点击(这是"滑动误点"的防线);
  443. // 例外:位移虽大但抬起时仍落在同一控件上、且该控件不在可滚动容器内 ⇒ 仍算轻点
  444. // (吸收手指按下时的轻微抖动,否则弹框里的小按钮会点不动)。
  445. //
  446. // 注册在 Init 中完成,无需逐窗口样板。
  447. void InitTouchSupport();
  448. void OnTouchInput(WPARAM wParam, LPARAM lParam);
  449. // ------------------------------------------------------------------
  450. // [手势滑动] 与输入通道无关的"手指拖动"核心逻辑。
  451. //
  452. // 为什么需要把它单独抽出来:WM_TOUCH 与 WM_POINTER* 是两条**互相独立**的通道
  453. // (本台收银机上弹框只拿得到指针通道,主窗口有时也被指针抢先),而"滑动"的全部
  454. // 实现(1:1 跟手平移 / 拖滚动条滑块 / Δy→滚轮)原先只写在 WM_TOUCH 的
  455. // OnTouchInput 里。于是指针通道一旦抢到本次手势:
  456. // · WM_TOUCH 整条被 OnTouchInput 忽略 ⇒ 没有任何滑动逻辑被执行 ⇒ 「滑不动」;
  457. // · 指针通道把 UP 归一化成 WM_LBUTTONUP 走原生点击路径,
  458. // tap/drag 判定(m_bTouchMoved)从未被触摸链置真 ⇒「滑动反倒触发点击」。
  459. // 现在把这段逻辑抽成通道无关的公共函数,两条通道都调用它,行为立刻一致。
  460. //
  461. // 调用约定(两条通道都必须按这个顺序调):
  462. // BeginSlideGesture(pt) —— DOWN 时调一次:记起点、命中控件、找可滚动容器;
  463. // UpdateSlideGesture(pt) —— MOVE/UPDATE 时调:按 Δ 派发 UIEVENT_TOUCHMOVE(+合成滚轮);
  464. // EndSlideGesture(pt) —— UP 时调:派发 UIEVENT_TOUCHUP 并返回"是否算一次轻点"。
  465. // 详见各函数实现处的长注释。
  466. // ------------------------------------------------------------------
  467. void BeginTouchSlideGesture(POINT pt);
  468. void UpdateTouchSlideGesture(POINT pt);
  469. // 返回 true 表示"本次手势应当按轻点处理"(未越过拖拽阈值)。
  470. bool EndTouchSlideGesture(POINT pt);
  471. // [对标 nim_duilib] WM_POINTER*(Win8+ 指针栈)处理:把指针消息归一化成鼠标消息,
  472. // 与 WM_TOUCH 归一化形成互补通道。返回 true 表示已消费该消息。
  473. // 说明:本项目 _WIN32_WINNT=0x0601,WM_POINTER* 宏在编译期不可见,
  474. // 故 uMsg 用字面量常量比较(见 UIManager.cpp 的 PointerMsg 命名空间)。
  475. bool OnPointerInput(UINT uMsg, WPARAM wParam, LPARAM lParam);
  476. void ClearTouchHoverState(POINT pt);
  477. // ------------------------------------------------------------------
  478. // [WM_TOUCH 归属权] 未被文档化的关键机制与"补调 DefWindowProc"钩子。
  479. //
  480. // 机制(来源:The Witness 作者逆向结论 + MSDN Architectural Overview):
  481. // `WM_TOUCH` **不会**由系统直接投递。系统先发一条"特殊标记的"
  482. // `WM_MOUSEMOVE`(开了 raw input 时是 `WM_INPUT`);
  483. // **只有这条消息一路走到 `DefWindowProc` 里**,DefWindowProc 才会
  484. // 把驻留在窗口上的 `WM_TOUCH` "翻译"出来并派发。
  485. //
  486. // 推论:任何一层**吞掉**这条被标记的 `WM_MOUSEMOVE` 且不回落到
  487. // `DefWindowProc`,就会**永久掐断该窗口后续 WM_TOUCH 的派发链**。
  488. //
  489. // 本项目的两个真实断点(都在 MessageHandler 的 WM_MOUSEMOVE 分支):
  490. // · `if (bPromotedTouchMove && m_pEventTouch != NULL) { ... return true; }`
  491. // —— 触摸手势进行中,丢弃"提升出来的鼠标移动";
  492. // · `if (m_bSuppressHoverAfterTouch) { ... return true; }`
  493. // —— 触摸抬手后抑制悬浮态复活,丢弃合成移动。
  494. // 两者都 `return true`,顺着 MessageHandler → HandleMessage 直接返回,
  495. // **跳过了 DefWindowProc** ⇒ 弹框(#32770 对话框类就是靠 DefDlgProc→DefWindowProc
  496. // 这条链来"翻译"WM_TOUCH 的)永远收不到 WM_TOUCH。
  497. // 这与实测完全吻合:主窗口有 `WNDPROC-TOUCH`、弹框零条。
  498. //
  499. // 钩子用法:窗口过程(__WndProc / __DialogWndProc)在构造时把自己的
  500. // "原窗口过程调用入口"注册进来;MessageHandler 在**吞掉那条被标记的
  501. // WM_MOUSEMOVE 之前**调用一次 `RelayDefWindowProc(...)`,
  502. // 让系统的"翻译"链继续跑 —— 我们仍然吃掉消息、不破坏 DuiLib 状态机,
  503. // 只是补一次 DefWindowProc 的副作用。
  504. //
  505. // 默认**关闭**(见 UIManager.cpp 的 m_bRelayDefProcForTouchMove):这是一个
  506. // 尚未在本机验证的机制假设,先做成可开关 + 带日志,验证通过再考虑默认开启。
  507. // ------------------------------------------------------------------
  508. // 钩子签名:就是一个"把消息喂给原窗口过程"的调用入口。
  509. // 参数与普通 WNDPROC 一致;返回值同样是 LRESULT(本场景只关心副作用)。
  510. typedef LRESULT (CALLBACK* PFN_RELAY_DEFPROC)(HWND, UINT, WPARAM, LPARAM);
  511. void SetDefProcRelay(PFN_RELAY_DEFPROC pfnRelay, HWND hWndTarget);
  512. void ClearDefProcRelay(HWND hWndTarget);
  513. PFN_RELAY_DEFPROC GetDefProcRelay() const { return m_pfnDefProcRelay; }
  514. // 当前钩子绑定的窗口。窗口过程用它判断"是否需要为本窗口(重新)绑定"——
  515. // 真模态弹框复用的是同一个 manager 对象,必须靠这个判据在换 HWND 时重新绑定。
  516. HWND GetDefProcRelayBoundWindow() const { return m_hWndDefProcRelay; }
  517. // 让"被吞掉的那条触摸提升鼠标消息"补走一次原窗口过程(仅当开关开启)。
  518. void RelayDefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam, LPCTSTR pszWhy);
  519. bool IsDefProcRelayEnabled() const { return m_bRelayDefProcForTouchMove; }
  520. void SetDefProcRelayEnabled(bool bEnable) { m_bRelayDefProcForTouchMove = bEnable; }
  521. // 当前处于模态状态的弹框句柄(由 CWindowWnd::ShowModal 设置/清除)。
  522. // 目的是:万一 Windows 把 WM_TOUCH 错投给了被弹框挡住的 owner(主窗口),
  523. // 非模态窗口一律忽略触摸,避免“弹框还开着、主窗口却在响应手指”的穿透。
  524. static void SetModalWindow(HWND hWnd);
  525. static HWND GetModalWindow();
  526. private:
  527. CStdPtrArray* GetFoundControls();
  528. static CControlUI* CALLBACK __FindControlFromNameHash(CControlUI* pThis, LPVOID pData);
  529. static CControlUI* CALLBACK __FindControlFromCount(CControlUI* pThis, LPVOID pData);
  530. static CControlUI* CALLBACK __FindControlFromPoint(CControlUI* pThis, LPVOID pData);
  531. static CControlUI* CALLBACK __FindControlFromTab(CControlUI* pThis, LPVOID pData);
  532. static CControlUI* CALLBACK __FindControlFromShortcut(CControlUI* pThis, LPVOID pData);
  533. static CControlUI* CALLBACK __FindControlFromName(CControlUI* pThis, LPVOID pData);
  534. static CControlUI* CALLBACK __FindControlFromClass(CControlUI* pThis, LPVOID pData);
  535. static CControlUI* CALLBACK __FindControlsFromClass(CControlUI* pThis, LPVOID pData);
  536. static CControlUI* CALLBACK __FindControlsFromUpdate(CControlUI* pThis, LPVOID pData);
  537. static void AdjustSharedImagesHSL();
  538. void AdjustImagesHSL();
  539. void PostAsyncNotify();
  540. private:
  541. CDuiString m_sName;
  542. HWND m_hWndPaint; //所附加的窗体的句柄
  543. HDC m_hDcPaint;
  544. HDC m_hDcOffscreen;
  545. HDC m_hDcBackground;
  546. HBITMAP m_hbmpOffscreen;
  547. BYTE* m_pOffscreenBits;
  548. HBITMAP m_hbmpBackground;
  549. COLORREF* m_pBackgroundBits;
  550. // 提示信息
  551. HWND m_hwndTooltip;
  552. TOOLINFO m_ToolTip;
  553. int m_iHoverTime;
  554. bool m_bNoActivate;
  555. bool m_bShowUpdateRect;
  556. // 触屏状态(库级统一接管后,每个窗口的 CPaintManagerUI 各持一份)
  557. // 鼠标点击仍由 WM_LBUTTONDOWN/UP 维护 m_pEventClick;触摸期间则由
  558. // m_pEventTouch 和 m_bTouchMoved 独立维护,避免合成鼠标消息提前激活控件。
  559. CControlUI* m_pEventTouch = NULL; // 本次触摸命中的控件
  560. CContainerUI* m_pTouchScrollContainer = NULL; // 本次触摸对应的最近可滚动容器
  561. POINT m_ptLastTouchPos = { 0, 0 }; // 上一包触点:用于去重 + 计算跟手滚动的位移增量
  562. POINT m_ptTouchStart = { 0, 0 }; // 本次手势起点:用于判断是否发生位移(拖拽 vs 轻点)
  563. bool m_bTouchMoved = false; // 本次触摸是否发生位移(>阈值视为拖拽),松开时抑制点击
  564. bool m_bSuppressPromotedTouchMouse = false; // 触摸点击已由 TOUCHUP 处理,丢弃随后提升的鼠标点击
  565. // 本次 TOUCHDOWN 的时间戳。若 TOUCHUP 丢失(激活/前台被抢、手势被系统中断、窗口被遮挡等),
  566. // m_pEventTouch / m_bSuppressPromotedTouchMouse 会永久残留 → 之后所有提升的鼠标消息都被吞,
  567. // 该窗口表现为“突然完全点不动”。用这个时间戳做超时自愈(见 MessageHandler 开头)。
  568. DWORD m_dwTouchDownTick = 0;
  569. // m_bSuppressPromotedTouchMouse 被置真时的时刻。
  570. // 用途:该抑制位有可能在【没有 TOUCHDOWN】的情况下被置真(两条输入流交叉时),
  571. // 此时 m_dwTouchDownTick 仍为 0,若只按它计时则自愈永远不触发 → 点击永久失效。
  572. // 所以单独记一个时间戳,保证"只要有抑制位,就一定会被超时复位"。
  573. DWORD m_dwSuppressTick = 0;
  574. // 手指抬起后,Windows 仍会补发合成的 WM_MOUSEMOVE;且真实 WM_MOUSELEAVE 在
  575. // m_bMouseTracking 为真时会【自己给自己重发 WM_MOUSEMOVE】(UIManager.cpp WM_MOUSELEAVE 分支),
  576. // 导致刚清掉的悬浮态立刻被重新点亮 → “悬浮态不消失 / 多个控件同时悬浮”。
  577. // 抬起后置 true,丢弃随后这批“非真实”的 MOUSEMOVE 悬浮逻辑;一旦收到用户真实移动鼠标
  578. // (这里用“距上次触摸位置明显移动”判定)即解除。
  579. // 注:这是【第二道】保险。第一道(根治)在 WM_MOUSEMOVE 里:凡带 MOUSEEVENTF_FROMTOUCH
  580. // 标记的“触摸提升出来的鼠标消息”一律不参与悬浮 enter/leave —— 触摸没有“光标停留”语义,
  581. // 让这类消息参与必然出现“点过的控件一直高亮 / 多点几个后多个同时高亮”。
  582. bool m_bSuppressHoverAfterTouch = false;
  583. // [对标 nim_duilib] 竖向滑动 → WM_MOUSEWHEEL 的累加器。
  584. // 触摸只有位移增量,没有滚轮事件;把 TOUCHEVENTF_MOVE 的 Δy 累加,每满一个
  585. // WHEEL_DELTA(120) 就合成一次 UIEVENT_SCROLLWHEEL,让只认滚轮的控件在触摸下也能滚动。
  586. // 手势开始时(TOUCHDOWN)与手势结束时(TOUCHUP)都应清零,避免余量串到下一次手势。
  587. int m_nTouchWheelAccum = 0;
  588. // [通道无关滑动] 本次手势的滑动状态是否已由 BeginTouchSlideGesture 建立。
  589. //
  590. // 用途:指针通道(WM_POINTER*)在 DOWN 时也要走一遍 BeginTouchSlideGesture,
  591. // 才能在 UPDATE 里正确算出 Δ 并驱动容器/滚动条;UP 时也要走
  592. // EndTouchSlideGesture 来收尾并拿到"是否算轻点"。
  593. // 这个标志把"滑动状态机是否活着"与"本次手势由哪条通道驱动"解耦 ——
  594. // 两条通道都只是驱动者,滑动逻辑本身是共享的。
  595. bool m_bTouchSlideActive = false;
  596. // [通道混合] 是否启用 WM_POINTER*(Win8+ 指针栈)归一化。
  597. //
  598. // 为什么需要这个开关:Win10 上同一次触摸可能同时产生
  599. // ① 提升出来的鼠标消息 WM_LBUTTONDOWN/UP
  600. // ② 指针消息 WM_POINTERDOWN/UP
  601. // ③ legacy 触摸消息 WM_TOUCH
  602. // 如果把这些一起归一化成鼠标消息,同一次点击会驱动多套点击状态机 ⇒ 互相吞 →
  603. // 【所有窗口点击全失效】(含主窗口、含真实鼠标)。实测踩过这个坑。
  604. //
  605. // ⚠️ 历史教训(务必别再改回"二选一"):
  606. // 第一版策略是"默认关闭,收到真实 WM_TOUCH 就【永久】关闭本窗口的指针通道"。
  607. // 结果主窗口修好了,真模态弹框却彻底没救:
  608. // 本台收银机上 WM_TOUCH 的"贪婪归属权"(MSDN:收到第一条触摸消息后,
  609. // 后续所有触摸消息都发给该窗口,直到【另一个窗口获得焦点】)卡在主窗口身上,
  610. // 弹框(被程序 SetFocus,不是触摸点出来的焦点)永远拿不到 WM_TOUCH,
  611. // 只拿得到 WM_POINTER*(指针消息按窗口命中投递,不受贪婪归属权约束);
  612. // 而指针通道被永久关掉 ⇒ 弹框既无 WM_TOUCH 又无指针 ⇒ 完全点不动。
  613. //
  614. // 现在的策略:【始终开启 + 手势级让路(handover)】
  615. // · 指针通道永远开着(本开关默认 true),保证弹框这条"只有指针"的窗口有活路;
  616. // · 谁先驱动本次手势,谁就赢:指针先 DOWN ⇒ 本次手势内吃掉 WM_TOUCH;
  617. // WM_TOUCH 先 DOWN ⇒ 本次手势内拒绝指针;
  618. // · 手势结束(UP/超时/被夺)后立刻解禁 —— 下一个手势可以换通道。
  619. // 让路只加在**开始**(DOWN)上,因为同一手势两条通道的 DOWN 才是一对重复;
  620. // UP/MOVE 侧不做让路,避免某个通道的 UP 被误丢导致点一直悬着、成对状态卡死。
  621. // ⚠️ 这条规则是踩过坑之后补上的、不可省:曾经让路连 WM_POINTERUP 一起吞,
  622. // 而 UP 是唯一能解除 m_bPointerGestureActive 的消息 ⇒ 状态永久为真
  623. // ⇒ 之后每个 WM_POINTERDOWN 都被当"重复按下"挡掉 ⇒【整个窗口触摸点击全灭】。
  624. // 现在 UP 一律放行到 OnPointerInput,由它决定"只清状态"(让路中)还是"派发点击"。
  625. // 状态的"自愈"由 3 秒超时兜底(见下面的 m_dwPointerDownTick)。
  626. bool m_bPointerNormalizeEnabled = true;
  627. // ---- [NIM 风格] 通道归属:两个标记 + 一个计时器 ----
  628. //
  629. // 这套结构对照 nim_duilib Core/Window.cpp 的 OnPointerMsgs / HandleMessage:
  630. // · nim 用 m_pEventTouch(WM_TOUCH 占用)与 m_pEventPointer(指针占用)两个
  631. // **控件指针**做归属标记,谁先建立谁赢,另一条通道看到标记即退让;
  632. // · 本项目的等价物:m_pEventTouch(触摸占用)与 m_bPointerGestureActive(指针占用)。
  633. //
  634. // ⚠️⚠️ 最关键的教训:【不要让同一个字段同时表示"归属"和"计时"】⚠️⚠️
  635. // 曾经用一个 m_dwSuppressPointerUntilUpTick 时间戳身兼两职,结果
  636. // (GetTickCount() - 该值) < 3000 恒成立 ⇒ 指针通道自己驱动的手势被自己判定为
  637. // "让路中" ⇒ UP 走"只清状态、不合成点击"的早退路 ⇒ 点击全灭(真机日志可复现)。
  638. // 现在严格分离:归属用 bool 标记,计时用专用 tick 字段,互不干扰。
  639. //
  640. // m_bPointerGestureActive:
  641. // 本窗口当前正在由【指针通道】驱动一次手势(已 DOWN、还没 UP)。
  642. // 为真期间,进入 OnTouchInput 的 WM_TOUCH 一律忽略(含其 TOUCHDOWN/TOUCHUP)。
  643. bool m_bPointerGestureActive = false;
  644. //
  645. // m_dwActivePointerId:
  646. // m_bPointerGestureActive 为真时,对应的是哪个 pointerId(wParam 低 16 位)。
  647. // 多指时不相关的第二、三指消息直接放行/忽略,不会把状态机搅乱。
  648. DWORD m_dwActivePointerId = 0;
  649. //
  650. // m_dwPointerDownTick:
  651. // 指针手势的开始时刻,**仅**用于 3 秒超时自愈。
  652. // ⚠️ 与 m_dwActivePointerId 配套,只在指针 DOWN 时置、在 UP/CAPTURECHANGED/超时时清。
  653. // 绝不参与任何"归属判定"——归属只看 m_bPointerGestureActive。
  654. DWORD m_dwPointerDownTick = 0;
  655. // ---- "补调 DefWindowProc" 钩子(修复弹框收不到 WM_TOUCH)----
  656. // 见上方 SetDefProcRelay / RelayDefWindowProc 的长注释:
  657. // 被吞掉的触摸提升 WM_MOUSEMOVE 需要补走一次原窗口过程,
  658. // 否则系统的 WM_TOUCH "翻译"链会断掉,该窗口永远收不到 WM_TOUCH。
  659. PFN_RELAY_DEFPROC m_pfnDefProcRelay = NULL; // 由窗口过程注册(一般为 m_OldWndProc 的包装)
  660. HWND m_hWndDefProcRelay = NULL; // 该钩子绑定的窗口(换窗口时校验用)
  661. // 开关:**默认关闭**。开启后 MessageHandler 在吞掉那两条触摸提升
  662. // WM_MOUSEMOVE 前会补调一次原窗口过程,把系统的 WM_TOUCH 翻译链接上。
  663. //
  664. // 为什么默认关:这是一个"未经本机验证"的机制假设,贸然默认开启风险不可控
  665. // (最坏情况是主窗口本来正常的 WM_TOUCH 反而被干扰)。
  666. //
  667. // 如何开启(无需重新编译):
  668. // 设环境变量 `DUI_RELAY_DEFPROC=1` 再启动程序即可(见构造函数里的读取)。
  669. // 也可以在代码里调 SetDefProcRelayEnabled(true)。
  670. // 验证要点(看 touch_trace.log):
  671. // 开启后弹框里应出现 `DEFPROC-RELAY call` 与随后的 `WNDPROC-TOUCH`;
  672. // 若出现但点击异常,把环境变量去掉即可立刻回到当前已可用的行为。
  673. bool m_bRelayDefProcForTouchMove = false;
  674. // 诊断计数:补调发生了多少次、对应的窗口。便于在日志里确认机制是否生效。
  675. unsigned m_uDefProcRelayCount = 0;
  676. //
  677. CControlUI* m_pRoot;
  678. CControlUI* m_pFocus;
  679. CControlUI* m_pEventHover;
  680. CControlUI* m_pEventClick;
  681. CControlUI* m_pEventRClick;
  682. CControlUI* m_pEventKey;
  683. CControlUI* m_pLastToolTip;
  684. //
  685. POINT m_ptLastMousePos;
  686. SIZE m_szMinWindow;
  687. SIZE m_szMaxWindow;
  688. SIZE m_szInitWindowSize;
  689. RECT m_rcSizeBox;
  690. SIZE m_szRoundCorner;
  691. RECT m_rcCaption;
  692. UINT m_uTimerID;
  693. bool m_bFirstLayout;
  694. bool m_bUpdateNeeded;
  695. bool m_bFocusNeeded;
  696. bool m_bOffscreenPaint;
  697. BYTE m_nOpacity;
  698. bool m_bLayered;
  699. RECT m_rcLayeredInset;
  700. bool m_bLayeredChanged;
  701. RECT m_rcLayeredUpdate;
  702. TDrawInfo m_diLayered;
  703. bool m_bMouseTracking;
  704. bool m_bMouseCapture;
  705. bool m_bIsPainting;
  706. bool m_bUsedVirtualWnd;
  707. bool m_bAsyncNotifyPosted;
  708. //
  709. CStdPtrArray m_aNotifiers;
  710. CStdPtrArray m_aTimers;
  711. CStdPtrArray m_aTranslateAccelerator;
  712. CStdPtrArray m_aPreMessageFilters;
  713. CStdPtrArray m_aMessageFilters;
  714. CStdPtrArray m_aPostPaintControls;
  715. CStdPtrArray m_aNativeWindow;
  716. CStdPtrArray m_aNativeWindowControl;
  717. CStdPtrArray m_aDelayedCleanup;
  718. CStdPtrArray m_aAsyncNotify;
  719. CStdPtrArray m_aFoundControls;
  720. CStdPtrArray m_aFonts;
  721. CStdPtrArray m_aNeedMouseLeaveNeeded;
  722. CStdStringPtrMap m_mNameHash;
  723. CStdStringPtrMap m_mWindowCustomAttrHash;
  724. CStdStringPtrMap m_mOptionGroup;
  725. bool m_bForceUseSharedRes;
  726. TResInfo m_ResInfo;
  727. // 窗口阴影
  728. CShadowUI m_shadow;
  729. // DPI管理器
  730. CDPI* m_pDPI;
  731. // 是否开启Gdiplus
  732. bool m_bUseGdiplusText;
  733. int m_trh;
  734. ULONG_PTR m_gdiplusToken;
  735. Gdiplus::GdiplusStartupInput *m_pGdiplusStartupInput;
  736. // 拖拽
  737. bool m_bDragDrop;
  738. bool m_bDragMode;
  739. HBITMAP m_hDragBitmap;
  740. IDragDropUI *m_pDragDrop;
  741. //
  742. static HINSTANCE m_hInstance;
  743. static HINSTANCE m_hResourceInstance;
  744. static CDuiString m_pStrResourcePath;
  745. static CDuiString m_pStrResourceZip;
  746. static CDuiString m_pStrResourceZipPwd;
  747. static HANDLE m_hResourceZip;
  748. static BYTE* m_cbZipBuf;
  749. static bool m_bCachedResourceZip;
  750. static int m_nResType;
  751. static TResInfo m_SharedResInfo;
  752. static bool m_bUseHSL;
  753. static short m_H;
  754. static short m_S;
  755. static short m_L;
  756. static CStdPtrArray m_aPreMessages;
  757. static CStdPtrArray m_aPlugins;
  758. };
  759. } // namespace DuiLib
  760. #endif // __UIMANAGER_H__