#ifndef WIN_IMPL_BASE_HPP #define WIN_IMPL_BASE_HPP #include "stdafx.h" //add by Hong; #include #include namespace DuiLib { ////////////////////////////////////////////////////////////////////////// LPBYTE WindowImplBase::m_lpResourceZIPBuffer = NULL; DUI_BEGIN_MESSAGE_MAP (WindowImplBase, CNotifyPump) DUI_ON_MSGTYPE (DUI_MSGTYPE_CLICK, OnClick) DUI_END_MESSAGE_MAP () WindowImplBase::WindowImplBase () { } void WindowImplBase::OnFinalMessage (HWND hWnd) { m_PaintManager.RemovePreMessageFilter (this); m_PaintManager.RemoveNotifier (this); m_PaintManager.ReapObjects (m_PaintManager.GetRoot ()); } LPCTSTR WindowImplBase::GetWindowClassName () const { static wchar_t wszWndClassName[MAX_PATH] = {0}; _tcscpy (wszWndClassName, _tcsspnp (CA2W (typeid(*this).name ()), L"class ")); return wszWndClassName; } UINT WindowImplBase::DoModal (HWND hParent) { Create(hParent, GetWindowClassName(), WS_POPUP, 0); CenterWindow (); return ShowModal(); } LRESULT WindowImplBase::ResponseDefaultKeyEvent (WPARAM wParam) { if(wParam == VK_RETURN) { return FALSE; } else if(wParam == VK_ESCAPE) { //Close (); return TRUE; } return FALSE; } UINT WindowImplBase::GetClassStyle () const { return CS_DBLCLKS; } UILIB_RESOURCETYPE WindowImplBase::GetResourceType () const { return UILIB_FILE; } CDuiString WindowImplBase::GetZIPFileName () const { return _T (""); } LPCTSTR WindowImplBase::GetResourceID () const { return _T (""); } CControlUI* WindowImplBase::CreateControl (LPCTSTR pstrClass) { return NULL; } LRESULT WindowImplBase::MessageHandler (UINT uMsg, WPARAM wParam, LPARAM /*lParam*/, bool& /*bHandled*/) { if(uMsg == WM_KEYDOWN) { switch(wParam) { case VK_RETURN: case VK_ESCAPE: return ResponseDefaultKeyEvent (wParam); default: break; } } return FALSE; } LRESULT WindowImplBase::OnClose (UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) { bHandled = FALSE; return 0; } LRESULT WindowImplBase::OnDestroy (UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) { bHandled = FALSE; return 0; } #if defined(WIN32) && !defined(UNDER_CE) LRESULT WindowImplBase::OnNcActivate (UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) { if(::IsIconic (*this)) bHandled = FALSE; return (wParam == 0) ? TRUE : FALSE; } LRESULT WindowImplBase::OnNcCalcSize (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { LPRECT pRect = NULL; if(wParam == TRUE) { LPNCCALCSIZE_PARAMS pParam = (LPNCCALCSIZE_PARAMS)lParam; pRect = &pParam->rgrc[0]; } else { pRect = (LPRECT)lParam; } if(::IsZoomed (m_hWnd)) { // 最大化时,计算当前显示器最适合宽高度 MONITORINFO oMonitor = {}; oMonitor.cbSize = sizeof (oMonitor); ::GetMonitorInfo (::MonitorFromWindow (*this, MONITOR_DEFAULTTONEAREST), &oMonitor); CDuiRect rcWork = oMonitor.rcWork; CDuiRect rcMonitor = oMonitor.rcMonitor; rcWork.Offset (-oMonitor.rcMonitor.left, -oMonitor.rcMonitor.top); pRect->right = pRect->left + rcWork.GetWidth (); pRect->bottom = pRect->top + rcWork.GetHeight (); return WVR_REDRAW; } return 0; } LRESULT WindowImplBase::OnNcPaint (UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) { return 0; } LRESULT WindowImplBase::OnNcHitTest (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { POINT pt; pt.x = GET_X_LPARAM (lParam); pt.y = GET_Y_LPARAM (lParam); ::ScreenToClient (*this, &pt); RECT rcClient; ::GetClientRect (*this, &rcClient); if(!::IsZoomed (*this)) { RECT rcSizeBox = m_PaintManager.GetSizeBox (); if(pt.y < rcClient.top + rcSizeBox.top) { if(pt.x < rcClient.left + rcSizeBox.left) return HTTOPLEFT; if(pt.x > rcClient.right - rcSizeBox.right) return HTTOPRIGHT; return HTTOP; } else if(pt.y > rcClient.bottom - rcSizeBox.bottom) { if(pt.x < rcClient.left + rcSizeBox.left) return HTBOTTOMLEFT; if(pt.x > rcClient.right - rcSizeBox.right) return HTBOTTOMRIGHT; return HTBOTTOM; } if(pt.x < rcClient.left + rcSizeBox.left) return HTLEFT; if(pt.x > rcClient.right - rcSizeBox.right) return HTRIGHT; } RECT rcCaption = m_PaintManager.GetCaptionRect (); if(pt.x >= rcClient.left + rcCaption.left && pt.x < rcClient.right - rcCaption.right \ && pt.y >= rcCaption.top && pt.y < rcCaption.bottom) { CControlUI* pControl = static_cast(m_PaintManager.FindControl (pt)); if(pControl && _tcsicmp (pControl->GetClass (), _T ("ButtonUI")) != 0 && _tcsicmp (pControl->GetClass (), _T ("OptionUI")) != 0 && _tcsicmp (pControl->GetClass (), _T ("TextUI")) != 0) return HTCAPTION; } return HTCLIENT; } LRESULT WindowImplBase::OnGetMinMaxInfo (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { LPMINMAXINFO lpMMI = (LPMINMAXINFO)lParam; MONITORINFO oMonitor = {}; oMonitor.cbSize = sizeof (oMonitor); ::GetMonitorInfo (::MonitorFromWindow (*this, MONITOR_DEFAULTTONEAREST), &oMonitor); CDuiRect rcWork = oMonitor.rcWork; CDuiRect rcMonitor = oMonitor.rcMonitor; rcWork.Offset (-oMonitor.rcMonitor.left, -oMonitor.rcMonitor.top); // 计算最大化时,正确的原点坐标 lpMMI->ptMaxPosition.x = rcWork.left; lpMMI->ptMaxPosition.y = rcWork.top; lpMMI->ptMaxTrackSize.x = rcWork.GetWidth (); lpMMI->ptMaxTrackSize.y = rcWork.GetHeight (); lpMMI->ptMinTrackSize.x = m_PaintManager.GetMinInfo ().cx; lpMMI->ptMinTrackSize.y = m_PaintManager.GetMinInfo ().cy; bHandled = FALSE; return 0; } LRESULT WindowImplBase::OnMouseWheel (UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) { bHandled = FALSE; return 0; } LRESULT WindowImplBase::OnMouseHover (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { bHandled = FALSE; return 0; } #endif LRESULT WindowImplBase::OnSize (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { SIZE szRoundCorner = m_PaintManager.GetRoundCorner (); #if defined(WIN32) && !defined(UNDER_CE) if(!::IsIconic (*this) && (szRoundCorner.cx != 0 || szRoundCorner.cy != 0)) { CDuiRect rcWnd; ::GetWindowRect (*this, &rcWnd); rcWnd.Offset (-rcWnd.left, -rcWnd.top); rcWnd.right++; rcWnd.bottom++; HRGN hRgn = ::CreateRoundRectRgn (rcWnd.left, rcWnd.top, rcWnd.right, rcWnd.bottom, szRoundCorner.cx, szRoundCorner.cy); ::SetWindowRgn (*this, hRgn, TRUE); ::DeleteObject (hRgn); } #endif bHandled = FALSE; return 0; } LRESULT WindowImplBase::OnChar (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { bHandled = FALSE; return 0; } LRESULT WindowImplBase::OnSysCommand (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { if(wParam == SC_CLOSE) { bHandled = TRUE; PostMessage (WM_CLOSE); return 0; } #if defined(WIN32) && !defined(UNDER_CE) BOOL bZoomed = ::IsZoomed (*this); LRESULT lRes = CWindowWnd::HandleMessage (uMsg, wParam, lParam); if(::IsZoomed (*this) != bZoomed) { CControlUI* pbtnMax = static_cast(m_PaintManager.FindControl (_T ("maxbtn"))); // max button CControlUI* pbtnRestore = static_cast(m_PaintManager.FindControl (_T ("restorebtn"))); // restore button // toggle status of max and restore button if(pbtnMax && pbtnRestore) { pbtnMax->SetVisible (TRUE == bZoomed); pbtnRestore->SetVisible (FALSE == bZoomed); } } #else LRESULT lRes = CWindowWnd::HandleMessage(uMsg, wParam, lParam); #endif return lRes; } LRESULT WindowImplBase::OnCreate (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { LONG styleValue = ::GetWindowLong (*this, GWL_STYLE); styleValue &= ~WS_CAPTION; ::SetWindowLong (*this, GWL_STYLE, styleValue | WS_CLIPSIBLINGS | WS_CLIPCHILDREN); RECT rcClient; ::GetClientRect (*this, &rcClient); ::SetWindowPos (*this, NULL, rcClient.left, rcClient.top, rcClient.right - rcClient.left, \ rcClient.bottom - rcClient.top, SWP_FRAMECHANGED); m_PaintManager.Init (m_hWnd); m_PaintManager.AddPreMessageFilter (this); CDialogBuilder builder; CDuiString strResourcePath = m_PaintManager.GetResourcePath (); if(strResourcePath.IsEmpty ()) { strResourcePath = m_PaintManager.GetInstancePath (); strResourcePath += GetSkinFolder ().GetData (); } m_PaintManager.SetResourcePath (strResourcePath.GetData ()); auto ty = GetResourceType (); switch(GetResourceType ()) { case UILIB_ZIP: m_PaintManager.SetResourceZip (GetZIPFileName ().GetData (), true); break; case UILIB_ZIPRESOURCE: { HRSRC hResource = ::FindResource (m_PaintManager.GetResourceDll (), GetResourceID (), _T ("ZIPRES")); if(hResource == NULL) return 0L; DWORD dwSize = 0; HGLOBAL hGlobal = ::LoadResource (m_PaintManager.GetResourceDll (), hResource); if(hGlobal == NULL) { #if defined(WIN32) && !defined(UNDER_CE) ::FreeResource (hResource); #endif return 0L; } dwSize = ::SizeofResource (m_PaintManager.GetResourceDll (), hResource); if(dwSize == 0) return 0L; m_lpResourceZIPBuffer = new BYTE[dwSize]; if(m_lpResourceZIPBuffer != NULL) { ::CopyMemory (m_lpResourceZIPBuffer, (LPBYTE)::LockResource (hGlobal), dwSize); } #if defined(WIN32) && !defined(UNDER_CE) ::FreeResource (hResource); #endif m_PaintManager.SetResourceZip (m_lpResourceZIPBuffer, dwSize); } break; } CControlUI* pRoot = NULL; if(GetResourceType () == UILIB_RESOURCE) { STRINGorID xml (_ttoi (GetSkinFile ().GetData ())); pRoot = builder.Create (xml, _T ("xml"), this, &m_PaintManager); } else { auto str = GetSkinFile ().GetData (); pRoot = builder.Create (GetSkinFile ().GetData (), (UINT)0, this, &m_PaintManager); } ASSERT (pRoot); if(pRoot == NULL) { MessageBox (NULL, _T ("加载资源文件失败"), _T ("Duilib"), MB_OK | MB_ICONERROR); ExitProcess (1); return 0; } m_PaintManager.AttachDialog (pRoot); m_PaintManager.AddNotifier (this); InitWindow (); return 0; } LRESULT WindowImplBase::OnKeyDown (UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) { bHandled = FALSE; return 0; } LRESULT WindowImplBase::OnKillFocus (UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) { bHandled = FALSE; return 0; } LRESULT WindowImplBase::OnSetFocus (UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) { bHandled = FALSE; return 0; } LRESULT WindowImplBase::OnLButtonDown (UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) { bHandled = FALSE; return 0; } LRESULT WindowImplBase::OnLButtonUp (UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) { bHandled = FALSE; return 0; } LRESULT WindowImplBase::OnMouseMove (UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) { bHandled = FALSE; return 0; } LRESULT WindowImplBase::HandleMessage (UINT uMsg, WPARAM wParam, LPARAM lParam) { LRESULT lRes = 0; BOOL bHandled = TRUE; switch(uMsg) { case WM_CREATE: lRes = OnCreate (uMsg, wParam, lParam, bHandled); break; case WM_CLOSE: lRes = OnClose (uMsg, wParam, lParam, bHandled); break; case WM_DESTROY: lRes = OnDestroy (uMsg, wParam, lParam, bHandled); break; #if defined(WIN32) && !defined(UNDER_CE) case WM_NCACTIVATE: lRes = OnNcActivate (uMsg, wParam, lParam, bHandled); break; case WM_NCCALCSIZE: lRes = OnNcCalcSize (uMsg, wParam, lParam, bHandled); break; case WM_NCPAINT: lRes = OnNcPaint (uMsg, wParam, lParam, bHandled); break; case WM_NCHITTEST: lRes = OnNcHitTest (uMsg, wParam, lParam, bHandled); break; case WM_GETMINMAXINFO: lRes = OnGetMinMaxInfo (uMsg, wParam, lParam, bHandled); break; case WM_MOUSEWHEEL: lRes = OnMouseWheel (uMsg, wParam, lParam, bHandled); break; #endif case WM_SIZE: lRes = OnSize (uMsg, wParam, lParam, bHandled); break; case WM_CHAR: lRes = OnChar (uMsg, wParam, lParam, bHandled); break; case WM_SYSCOMMAND: lRes = OnSysCommand (uMsg, wParam, lParam, bHandled); break; case WM_KEYDOWN: lRes = OnKeyDown (uMsg, wParam, lParam, bHandled); break; case WM_KILLFOCUS: lRes = OnKillFocus (uMsg, wParam, lParam, bHandled); break; case WM_SETFOCUS: lRes = OnSetFocus (uMsg, wParam, lParam, bHandled); break; case WM_LBUTTONUP: lRes = OnLButtonUp (uMsg, wParam, lParam, bHandled); break; case WM_LBUTTONDOWN: lRes = OnLButtonDown (uMsg, wParam, lParam, bHandled); break; case WM_MOUSEMOVE: lRes = OnMouseMove (uMsg, wParam, lParam, bHandled); break; case WM_MOUSEHOVER: lRes = OnMouseHover (uMsg, wParam, lParam, bHandled); break; default: bHandled = FALSE; break; } if(bHandled) return lRes; lRes = HandleCustomMessage (uMsg, wParam, lParam, bHandled); if(bHandled) return lRes; if(m_PaintManager.MessageHandler (uMsg, wParam, lParam, lRes)) return lRes; return CWindowWnd::HandleMessage (uMsg, wParam, lParam); } LRESULT WindowImplBase::HandleCustomMessage (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { bHandled = FALSE; return 0; } LONG WindowImplBase::GetStyle () { LONG styleValue = ::GetWindowLong (*this, GWL_STYLE); styleValue &= ~WS_CAPTION; return styleValue; } void WindowImplBase::OnClick (TNotifyUI& msg) { CDuiString sCtrlName = msg.pSender->GetName (); if(sCtrlName == _T ("closebtn")) { Close (); return; } else if(sCtrlName == _T ("minbtn")) { SendMessage (WM_SYSCOMMAND, SC_MINIMIZE, 0); return; } else if(sCtrlName == _T ("maxbtn")) { SendMessage (WM_SYSCOMMAND, SC_MAXIMIZE, 0); return; } else if(sCtrlName == _T ("restorebtn")) { SendMessage (WM_SYSCOMMAND, SC_RESTORE, 0); return; } return; } void WindowImplBase::Notify (TNotifyUI& msg) { return CNotifyPump::NotifyPump (msg); } }