UIBase.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  1. #include "StdAfx.h"
  2. #ifdef _DEBUG
  3. #include <shlwapi.h>
  4. #pragma comment(lib, "shlwapi.lib")
  5. #endif
  6. namespace DuiLib {
  7. namespace {
  8. typedef BOOL (WINAPI* PFN_REGISTER_TOUCH_WINDOW)(HWND, ULONG);
  9. void RegisterTouchWindowIfAvailable(HWND hWnd)
  10. {
  11. if (hWnd == NULL) return;
  12. HMODULE hUser32 = ::GetModuleHandle(_T("user32.dll"));
  13. if (hUser32 == NULL) return;
  14. PFN_REGISTER_TOUCH_WINDOW pfnRegister =
  15. reinterpret_cast<PFN_REGISTER_TOUCH_WINDOW>(::GetProcAddress(hUser32, "RegisterTouchWindow"));
  16. if (pfnRegister != NULL)
  17. pfnRegister(hWnd, 0);
  18. }
  19. }
  20. /////////////////////////////////////////////////////////////////////////////////////
  21. //
  22. //
  23. void UILIB_API DUI__Trace(LPCTSTR pstrFormat, ...)
  24. {
  25. #ifdef _DEBUG
  26. TCHAR szBuffer[2048] = {0};
  27. va_list args;
  28. va_start(args, pstrFormat);
  29. _vsntprintf(szBuffer, 2048, pstrFormat, args);
  30. va_end(args);
  31. CDuiString strMsg = szBuffer;
  32. strMsg += _T("\n");
  33. OutputDebugString(strMsg.GetData());
  34. #endif
  35. }
  36. LPCTSTR DUI__TraceMsg(UINT uMsg)
  37. {
  38. #define MSGDEF(x) if(uMsg==x) return _T(#x)
  39. MSGDEF(WM_SETCURSOR);
  40. MSGDEF(WM_NCHITTEST);
  41. MSGDEF(WM_NCPAINT);
  42. MSGDEF(WM_PAINT);
  43. MSGDEF(WM_ERASEBKGND);
  44. MSGDEF(WM_NCMOUSEMOVE);
  45. MSGDEF(WM_MOUSEMOVE);
  46. MSGDEF(WM_MOUSELEAVE);
  47. MSGDEF(WM_MOUSEHOVER);
  48. MSGDEF(WM_NOTIFY);
  49. MSGDEF(WM_COMMAND);
  50. MSGDEF(WM_MEASUREITEM);
  51. MSGDEF(WM_DRAWITEM);
  52. MSGDEF(WM_LBUTTONDOWN);
  53. MSGDEF(WM_LBUTTONUP);
  54. MSGDEF(WM_LBUTTONDBLCLK);
  55. MSGDEF(WM_RBUTTONDOWN);
  56. MSGDEF(WM_RBUTTONUP);
  57. MSGDEF(WM_RBUTTONDBLCLK);
  58. MSGDEF(WM_SETFOCUS);
  59. MSGDEF(WM_KILLFOCUS);
  60. MSGDEF(WM_MOVE);
  61. MSGDEF(WM_SIZE);
  62. MSGDEF(WM_SIZING);
  63. MSGDEF(WM_MOVING);
  64. MSGDEF(WM_GETMINMAXINFO);
  65. MSGDEF(WM_CAPTURECHANGED);
  66. MSGDEF(WM_WINDOWPOSCHANGED);
  67. MSGDEF(WM_WINDOWPOSCHANGING);
  68. MSGDEF(WM_NCCALCSIZE);
  69. MSGDEF(WM_NCCREATE);
  70. MSGDEF(WM_NCDESTROY);
  71. MSGDEF(WM_TIMER);
  72. MSGDEF(WM_KEYDOWN);
  73. MSGDEF(WM_KEYUP);
  74. MSGDEF(WM_CHAR);
  75. MSGDEF(WM_SYSKEYDOWN);
  76. MSGDEF(WM_SYSKEYUP);
  77. MSGDEF(WM_SYSCOMMAND);
  78. MSGDEF(WM_SYSCHAR);
  79. MSGDEF(WM_VSCROLL);
  80. MSGDEF(WM_HSCROLL);
  81. MSGDEF(WM_CHAR);
  82. MSGDEF(WM_SHOWWINDOW);
  83. MSGDEF(WM_PARENTNOTIFY);
  84. MSGDEF(WM_CREATE);
  85. MSGDEF(WM_NCACTIVATE);
  86. MSGDEF(WM_ACTIVATE);
  87. MSGDEF(WM_ACTIVATEAPP);
  88. MSGDEF(WM_CLOSE);
  89. MSGDEF(WM_DESTROY);
  90. MSGDEF(WM_GETICON);
  91. MSGDEF(WM_GETTEXT);
  92. MSGDEF(WM_GETTEXTLENGTH);
  93. static TCHAR szMsg[10];
  94. ::wsprintf(szMsg, _T("0x%04X"), uMsg);
  95. return szMsg;
  96. }
  97. /////////////////////////////////////////////////////////////////////////////////////
  98. //
  99. //
  100. //////////////////////////////////////////////////////////////////////////
  101. //
  102. DUI_BASE_BEGIN_MESSAGE_MAP(CNotifyPump)
  103. DUI_END_MESSAGE_MAP()
  104. static const DUI_MSGMAP_ENTRY* DuiFindMessageEntry(const DUI_MSGMAP_ENTRY* lpEntry,TNotifyUI& msg )
  105. {
  106. CDuiString sMsgType = msg.sType;
  107. CDuiString sCtrlName = msg.pSender->GetName();
  108. const DUI_MSGMAP_ENTRY* pMsgTypeEntry = NULL;
  109. while (lpEntry->nSig != DuiSig_end)
  110. {
  111. if(lpEntry->sMsgType==sMsgType)
  112. {
  113. if(!lpEntry->sCtrlName.IsEmpty())
  114. {
  115. if(lpEntry->sCtrlName==sCtrlName)
  116. {
  117. return lpEntry;
  118. }
  119. }
  120. else
  121. {
  122. pMsgTypeEntry = lpEntry;
  123. }
  124. }
  125. lpEntry++;
  126. }
  127. return pMsgTypeEntry;
  128. }
  129. bool CNotifyPump::AddVirtualWnd(CDuiString strName,CNotifyPump* pObject)
  130. {
  131. if( m_VirtualWndMap.Find(strName) == NULL )
  132. {
  133. m_VirtualWndMap.Insert(strName.GetData(),(LPVOID)pObject);
  134. return true;
  135. }
  136. return false;
  137. }
  138. bool CNotifyPump::RemoveVirtualWnd(CDuiString strName)
  139. {
  140. if( m_VirtualWndMap.Find(strName) != NULL )
  141. {
  142. m_VirtualWndMap.Remove(strName);
  143. return true;
  144. }
  145. return false;
  146. }
  147. bool CNotifyPump::LoopDispatch(TNotifyUI& msg)
  148. {
  149. const DUI_MSGMAP_ENTRY* lpEntry = NULL;
  150. const DUI_MSGMAP* pMessageMap = NULL;
  151. #ifndef UILIB_STATIC
  152. for(pMessageMap = GetMessageMap(); pMessageMap!=NULL; pMessageMap = (*pMessageMap->pfnGetBaseMap)())
  153. #else
  154. for(pMessageMap = GetMessageMap(); pMessageMap!=NULL; pMessageMap = pMessageMap->pBaseMap)
  155. #endif
  156. {
  157. #ifndef UILIB_STATIC
  158. ASSERT(pMessageMap != (*pMessageMap->pfnGetBaseMap)());
  159. #else
  160. ASSERT(pMessageMap != pMessageMap->pBaseMap);
  161. #endif
  162. if ((lpEntry = DuiFindMessageEntry(pMessageMap->lpEntries,msg)) != NULL)
  163. {
  164. goto LDispatch;
  165. }
  166. }
  167. return false;
  168. LDispatch:
  169. union DuiMessageMapFunctions mmf;
  170. mmf.pfn = lpEntry->pfn;
  171. bool bRet = false;
  172. int nSig;
  173. nSig = lpEntry->nSig;
  174. switch (nSig)
  175. {
  176. default:
  177. ASSERT(FALSE);
  178. break;
  179. case DuiSig_lwl:
  180. (this->*mmf.pfn_Notify_lwl)(msg.wParam,msg.lParam);
  181. bRet = true;
  182. break;
  183. case DuiSig_vn:
  184. (this->*mmf.pfn_Notify_vn)(msg);
  185. bRet = true;
  186. break;
  187. }
  188. return bRet;
  189. }
  190. void CNotifyPump::NotifyPump(TNotifyUI& msg)
  191. {
  192. ///遍历虚拟窗口
  193. if( !msg.sVirtualWnd.IsEmpty() ){
  194. for( int i = 0; i< m_VirtualWndMap.GetSize(); i++ ) {
  195. if( LPCTSTR key = m_VirtualWndMap.GetAt(i) ) {
  196. if( _tcsicmp(key, msg.sVirtualWnd.GetData()) == 0 ){
  197. CNotifyPump* pObject = static_cast<CNotifyPump*>(m_VirtualWndMap.Find(key, false));
  198. if( pObject && pObject->LoopDispatch(msg) )
  199. return;
  200. }
  201. }
  202. }
  203. }
  204. ///
  205. //遍历主窗口
  206. LoopDispatch( msg );
  207. }
  208. //////////////////////////////////////////////////////////////////////////
  209. ///
  210. CWindowWnd::CWindowWnd() : m_hWnd(NULL), m_OldWndProc(::DefWindowProc), m_bSubclassed(false), m_bUnicode(false), m_bFakeModal(false)
  211. {
  212. }
  213. HWND CWindowWnd::GetHWND() const
  214. {
  215. return m_hWnd;
  216. }
  217. UINT CWindowWnd::GetClassStyle() const
  218. {
  219. return 0;
  220. }
  221. LPCTSTR CWindowWnd::GetSuperClassName() const
  222. {
  223. return NULL;
  224. }
  225. CWindowWnd::operator HWND() const
  226. {
  227. return m_hWnd;
  228. }
  229. void CWindowWnd::EnableUnicode()
  230. {
  231. m_bUnicode = true;
  232. }
  233. HWND CWindowWnd::CreateDuiWindow( HWND hwndParent, LPCTSTR pstrWindowName,DWORD dwStyle /*=0*/, DWORD dwExStyle /*=0*/ )
  234. {
  235. return Create(hwndParent,pstrWindowName,dwStyle,dwExStyle,0,0,0,0,NULL);
  236. }
  237. HWND CWindowWnd::Create(HWND hwndParent, LPCTSTR pstrName, DWORD dwStyle, DWORD dwExStyle, const RECT rc, HMENU hMenu)
  238. {
  239. return Create(hwndParent, pstrName, dwStyle, dwExStyle, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, hMenu);
  240. }
  241. HWND CWindowWnd::Create(HWND hwndParent, LPCTSTR pstrName, DWORD dwStyle, DWORD dwExStyle, int x, int y, int cx, int cy, HMENU hMenu)
  242. {
  243. if( GetSuperClassName() != NULL && !RegisterSuperclass() ) return NULL;
  244. if( GetSuperClassName() == NULL && !RegisterWindowClass() ) return NULL;
  245. if(m_bUnicode) {
  246. #ifndef UNICODE
  247. LPWSTR lpClassName = a2w((char*)GetWindowClassName());
  248. LPWSTR lpName = a2w((char*)pstrName);
  249. #else
  250. LPWSTR lpClassName = (LPWSTR)GetWindowClassName();
  251. LPWSTR lpName = (LPWSTR)pstrName;
  252. #endif
  253. m_hWnd = ::CreateWindowExW(dwExStyle, lpClassName, lpName, dwStyle, x, y, cx, cy, hwndParent, hMenu, CPaintManagerUI::GetInstance(), this);
  254. #ifndef UNICODE
  255. delete []lpClassName;
  256. delete []lpName;
  257. #endif
  258. }
  259. else {
  260. m_hWnd = ::CreateWindowEx(dwExStyle, GetWindowClassName(), pstrName, dwStyle, x, y, cx, cy, hwndParent, hMenu, CPaintManagerUI::GetInstance(), this);
  261. }
  262. ASSERT(m_hWnd!=NULL);
  263. RegisterTouchWindowIfAvailable(m_hWnd);
  264. return m_hWnd;
  265. }
  266. HWND CWindowWnd::Subclass(HWND hWnd)
  267. {
  268. ASSERT(::IsWindow(hWnd));
  269. ASSERT(m_hWnd==NULL);
  270. m_OldWndProc = SubclassWindow(hWnd, __WndProc);
  271. if( m_OldWndProc == NULL ) return NULL;
  272. m_bSubclassed = true;
  273. m_hWnd = hWnd;
  274. ::SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LPARAM>(this));
  275. RegisterTouchWindowIfAvailable(m_hWnd);
  276. return m_hWnd;
  277. }
  278. void CWindowWnd::Unsubclass()
  279. {
  280. ASSERT(::IsWindow(m_hWnd));
  281. if( !::IsWindow(m_hWnd) ) return;
  282. if( !m_bSubclassed ) return;
  283. SubclassWindow(m_hWnd, m_OldWndProc);
  284. m_OldWndProc = ::DefWindowProc;
  285. m_bSubclassed = false;
  286. }
  287. void CWindowWnd::ShowWindow(bool bShow /*= true*/, bool bTakeFocus /*= false*/)
  288. {
  289. ASSERT(::IsWindow(m_hWnd));
  290. if( !::IsWindow(m_hWnd) ) return;
  291. ::ShowWindow(m_hWnd, bShow ? (bTakeFocus ? SW_SHOWNORMAL : SW_SHOWNOACTIVATE) : SW_HIDE);
  292. }
  293. UINT CWindowWnd::ShowModal()
  294. {
  295. ASSERT(::IsWindow(m_hWnd));
  296. UINT nRet = 0;
  297. HWND hWndParent = GetWindowOwner(m_hWnd);
  298. RegisterTouchWindowIfAvailable(m_hWnd);
  299. ::ShowWindow(m_hWnd, SW_SHOWNORMAL);
  300. ::EnableWindow(hWndParent, FALSE);
  301. MSG msg = { 0 };
  302. while( ::IsWindow(m_hWnd) && ::GetMessage(&msg, NULL, 0, 0) ) {
  303. if( msg.message == WM_CLOSE && msg.hwnd == m_hWnd ) {
  304. nRet = (int)msg.wParam;
  305. ::EnableWindow(hWndParent, TRUE);
  306. ::SetFocus(hWndParent);
  307. }
  308. if( !CPaintManagerUI::TranslateMessage(&msg) ) {
  309. ::TranslateMessage(&msg);
  310. ::DispatchMessage(&msg);
  311. }
  312. if( msg.message == WM_QUIT ) break;
  313. }
  314. ::EnableWindow(hWndParent, TRUE);
  315. ::SetFocus(hWndParent);
  316. if( msg.message == WM_QUIT ) ::PostQuitMessage((int)msg.wParam);
  317. return nRet;
  318. }
  319. void CWindowWnd::ShowModalFake()
  320. {
  321. ASSERT(::IsWindow(m_hWnd));
  322. auto p_hwnd = GetWindowOwner(m_hWnd);
  323. ASSERT(::IsWindow(p_hwnd));
  324. ASSERT(p_hwnd);
  325. ::EnableWindow(p_hwnd, FALSE);
  326. ShowWindow();
  327. m_bFakeModal = true;
  328. }
  329. void CWindowWnd::Close(UINT nRet)
  330. {
  331. if (m_bFakeModal)
  332. {
  333. auto parent_hwnd = GetWindowOwner(m_hWnd);
  334. ASSERT(::IsWindow(parent_hwnd));
  335. ::EnableWindow(parent_hwnd, TRUE);
  336. ::SetFocus(parent_hwnd);
  337. m_bFakeModal = false;
  338. }
  339. ASSERT(::IsWindow(m_hWnd));
  340. if (!::IsWindow(m_hWnd)) return;
  341. PostMessage(WM_CLOSE, (WPARAM)nRet, 0L);
  342. }
  343. void CWindowWnd::CenterWindow()
  344. {
  345. ASSERT(::IsWindow(m_hWnd));
  346. ASSERT((GetWindowStyle(m_hWnd)&WS_CHILD)==0);
  347. RECT rcDlg = { 0 };
  348. ::GetWindowRect(m_hWnd, &rcDlg);
  349. RECT rcArea = { 0 };
  350. RECT rcCenter = { 0 };
  351. HWND hWnd=*this;
  352. HWND hWndParent = ::GetParent(m_hWnd);
  353. HWND hWndCenter = ::GetWindowOwner(m_hWnd);
  354. if (hWndCenter!=NULL)
  355. hWnd=hWndCenter;
  356. // 处理多显示器模式下屏幕居中
  357. MONITORINFO oMonitor = {};
  358. oMonitor.cbSize = sizeof(oMonitor);
  359. ::GetMonitorInfo(::MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST), &oMonitor);
  360. rcArea = oMonitor.rcWork;
  361. if( hWndCenter == NULL )
  362. rcCenter = rcArea;
  363. else
  364. ::GetWindowRect(hWndCenter, &rcCenter);
  365. int DlgWidth = rcDlg.right - rcDlg.left;
  366. int DlgHeight = rcDlg.bottom - rcDlg.top;
  367. // Find dialog's upper left based on rcCenter
  368. int xLeft = (rcCenter.left + rcCenter.right) / 2 - DlgWidth / 2;
  369. int yTop = (rcCenter.top + rcCenter.bottom) / 2 - DlgHeight / 2;
  370. // The dialog is outside the screen, move it inside
  371. if( xLeft < rcArea.left ) xLeft = rcArea.left;
  372. else if( xLeft + DlgWidth > rcArea.right ) xLeft = rcArea.right - DlgWidth;
  373. if( yTop < rcArea.top ) yTop = rcArea.top;
  374. else if( yTop + DlgHeight > rcArea.bottom ) yTop = rcArea.bottom - DlgHeight;
  375. ::SetWindowPos(m_hWnd, NULL, xLeft, yTop, -1, -1, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
  376. }
  377. void CWindowWnd::SetIcon(UINT nRes)
  378. {
  379. HICON hIcon = (HICON)::LoadImage(CPaintManagerUI::GetInstance(), MAKEINTRESOURCE(nRes), IMAGE_ICON,
  380. (::GetSystemMetrics(SM_CXICON) + 15) & ~15, (::GetSystemMetrics(SM_CYICON) + 15) & ~15, // 防止高DPI下图标模糊
  381. LR_DEFAULTCOLOR);
  382. ASSERT(hIcon);
  383. ::SendMessage(m_hWnd, WM_SETICON, (WPARAM) TRUE, (LPARAM) hIcon);
  384. hIcon = (HICON)::LoadImage(CPaintManagerUI::GetInstance(), MAKEINTRESOURCE(nRes), IMAGE_ICON,
  385. (::GetSystemMetrics(SM_CXICON) + 15) & ~15, (::GetSystemMetrics(SM_CYICON) + 15) & ~15, // 防止高DPI下图标模糊
  386. LR_DEFAULTCOLOR);
  387. ASSERT(hIcon);
  388. ::SendMessage(m_hWnd, WM_SETICON, (WPARAM) FALSE, (LPARAM) hIcon);
  389. }
  390. bool CWindowWnd::RegisterWindowClass()
  391. {
  392. WNDCLASS wc = { 0 };
  393. wc.style = GetClassStyle();
  394. wc.cbClsExtra = 0;
  395. wc.cbWndExtra = 0;
  396. wc.hIcon = NULL;
  397. wc.lpfnWndProc = CWindowWnd::__WndProc;
  398. wc.hInstance = CPaintManagerUI::GetInstance();
  399. wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
  400. wc.hbrBackground = NULL;
  401. wc.lpszMenuName = NULL;
  402. wc.lpszClassName = GetWindowClassName();
  403. ATOM ret = ::RegisterClass(&wc);
  404. ASSERT(ret!=NULL || ::GetLastError()==ERROR_CLASS_ALREADY_EXISTS);
  405. return ret != NULL || ::GetLastError() == ERROR_CLASS_ALREADY_EXISTS;
  406. }
  407. bool CWindowWnd::RegisterSuperclass()
  408. {
  409. if(m_bUnicode) {
  410. #ifndef UNICODE
  411. LPWSTR lpSuperClassName = a2w((char*)GetSuperClassName());
  412. LPWSTR lpClassName = a2w((char*)GetWindowClassName());
  413. #else
  414. LPWSTR lpSuperClassName = (LPWSTR)GetSuperClassName();
  415. LPWSTR lpClassName = (LPWSTR)GetWindowClassName();
  416. #endif
  417. // Get the class information from an existing
  418. // window so we can subclass it later on...
  419. WNDCLASSEXW wc = { 0 };
  420. wc.cbSize = sizeof(WNDCLASSEXW);
  421. if( !::GetClassInfoExW(NULL, lpSuperClassName, &wc) ) {
  422. if( !::GetClassInfoExW(CPaintManagerUI::GetInstance(), lpSuperClassName, &wc) ) {
  423. ASSERT(!"Unable to locate window class");
  424. return NULL;
  425. }
  426. }
  427. m_OldWndProc = wc.lpfnWndProc;
  428. wc.lpfnWndProc = CWindowWnd::__ControlProc;
  429. wc.hInstance = CPaintManagerUI::GetInstance();
  430. wc.lpszClassName = lpClassName;
  431. ATOM ret = ::RegisterClassExW(&wc);
  432. #ifndef UNICODE
  433. delete []lpClassName;
  434. delete []lpSuperClassName;
  435. #endif
  436. ASSERT(ret!=NULL || ::GetLastError()==ERROR_CLASS_ALREADY_EXISTS);
  437. return ret != NULL || ::GetLastError() == ERROR_CLASS_ALREADY_EXISTS;
  438. }
  439. else {
  440. // Get the class information from an existing
  441. // window so we can subclass it later on...
  442. WNDCLASSEX wc = { 0 };
  443. wc.cbSize = sizeof(WNDCLASSEX);
  444. if( !::GetClassInfoEx(NULL, GetSuperClassName(), &wc) ) {
  445. if( !::GetClassInfoEx(CPaintManagerUI::GetInstance(), GetSuperClassName(), &wc) ) {
  446. ASSERT(!"Unable to locate window class");
  447. return NULL;
  448. }
  449. }
  450. m_OldWndProc = wc.lpfnWndProc;
  451. wc.lpfnWndProc = CWindowWnd::__ControlProc;
  452. wc.hInstance = CPaintManagerUI::GetInstance();
  453. wc.lpszClassName = GetWindowClassName();
  454. ATOM ret = ::RegisterClassEx(&wc);
  455. ASSERT(ret!=NULL || ::GetLastError()==ERROR_CLASS_ALREADY_EXISTS);
  456. return ret != NULL || ::GetLastError() == ERROR_CLASS_ALREADY_EXISTS;
  457. }
  458. }
  459. LRESULT CALLBACK CWindowWnd::__WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  460. {
  461. CWindowWnd* pThis = NULL;
  462. if( uMsg == WM_NCCREATE ) {
  463. LPCREATESTRUCT lpcs = reinterpret_cast<LPCREATESTRUCT>(lParam);
  464. pThis = static_cast<CWindowWnd*>(lpcs->lpCreateParams);
  465. pThis->m_hWnd = hWnd;
  466. ::SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LPARAM>(pThis));
  467. }
  468. else {
  469. pThis = reinterpret_cast<CWindowWnd*>(::GetWindowLongPtr(hWnd, GWLP_USERDATA));
  470. if( uMsg == WM_NCDESTROY && pThis != NULL ) {
  471. LRESULT lRes = ::CallWindowProc(pThis->m_OldWndProc, hWnd, uMsg, wParam, lParam);
  472. ::SetWindowLongPtr(pThis->m_hWnd, GWLP_USERDATA, 0L);
  473. if( pThis->m_bSubclassed ) pThis->Unsubclass();
  474. pThis->m_hWnd = NULL;
  475. pThis->OnFinalMessage(hWnd);
  476. return lRes;
  477. }
  478. }
  479. if( pThis != NULL ) {
  480. return pThis->HandleMessage(uMsg, wParam, lParam);
  481. }
  482. else {
  483. return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
  484. }
  485. }
  486. LRESULT CALLBACK CWindowWnd::__ControlProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  487. {
  488. CWindowWnd* pThis = NULL;
  489. if( uMsg == WM_NCCREATE ) {
  490. LPCREATESTRUCT lpcs = reinterpret_cast<LPCREATESTRUCT>(lParam);
  491. pThis = static_cast<CWindowWnd*>(lpcs->lpCreateParams);
  492. ::SetProp(hWnd, _T("WndX"), (HANDLE) pThis);
  493. pThis->m_hWnd = hWnd;
  494. }
  495. else {
  496. pThis = reinterpret_cast<CWindowWnd*>(::GetProp(hWnd, _T("WndX")));
  497. if( uMsg == WM_NCDESTROY && pThis != NULL ) {
  498. LRESULT lRes = ::CallWindowProc(pThis->m_OldWndProc, hWnd, uMsg, wParam, lParam);
  499. if( pThis->m_bSubclassed ) pThis->Unsubclass();
  500. ::SetProp(hWnd, _T("WndX"), NULL);
  501. pThis->m_hWnd = NULL;
  502. pThis->OnFinalMessage(hWnd);
  503. return lRes;
  504. }
  505. }
  506. if( pThis != NULL ) {
  507. return pThis->HandleMessage(uMsg, wParam, lParam);
  508. }
  509. else {
  510. return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
  511. }
  512. }
  513. LRESULT CWindowWnd::SendMessage(UINT uMsg, WPARAM wParam /*= 0*/, LPARAM lParam /*= 0*/)
  514. {
  515. ASSERT(::IsWindow(m_hWnd));
  516. return ::SendMessage(m_hWnd, uMsg, wParam, lParam);
  517. }
  518. LRESULT CWindowWnd::PostMessage(UINT uMsg, WPARAM wParam /*= 0*/, LPARAM lParam /*= 0*/)
  519. {
  520. ASSERT(::IsWindow(m_hWnd));
  521. return ::PostMessage(m_hWnd, uMsg, wParam, lParam);
  522. }
  523. void CWindowWnd::ResizeClient(int cx /*= -1*/, int cy /*= -1*/)
  524. {
  525. ASSERT(::IsWindow(m_hWnd));
  526. RECT rc = { 0 };
  527. if( !::GetClientRect(m_hWnd, &rc) ) return;
  528. if( cx != -1 ) rc.right = cx;
  529. if( cy != -1 ) rc.bottom = cy;
  530. if( !::AdjustWindowRectEx(&rc, GetWindowStyle(m_hWnd), (!(GetWindowStyle(m_hWnd) & WS_CHILD) && (::GetMenu(m_hWnd) != NULL)), GetWindowExStyle(m_hWnd)) ) return;
  531. ::SetWindowPos(m_hWnd, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
  532. }
  533. LRESULT CWindowWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
  534. {
  535. return ::CallWindowProc(m_OldWndProc, m_hWnd, uMsg, wParam, lParam);
  536. }
  537. void CWindowWnd::OnFinalMessage(HWND /*hWnd*/)
  538. {
  539. }
  540. } // namespace DuiLib