2#include "core/SNcPainter.h"
3#include "core/SHostWnd.h"
8 : SOsrPanel(pFrameHost, pItemContainer)
10 , m_crActiveTitle(RGBA(0, 0, 0, 255))
11 , m_crInactiveTitle(RGBA(128, 128, 128, 255))
18 ISkinObj *pSkin = m_bActive ? m_skinActive : m_skinInactive;
27 if (CR_INVALID != crBg)
41 COLORREF crTitle = bActive ? m_crActiveTitle : m_crInactiveTitle;
50 , m_bSysNcPainter(FALSE)
51 , m_bLButtonDown(FALSE)
52 , m_bMouseHover(FALSE)
54 m_root =
new SNcPanel(
this,
this);
72 m_bSysNcPainter = FALSE;
73 m_bLButtonDown = FALSE;
79 if (!xmlNode || m_pHost->IsTranslucent())
85 __baseCls::InitFromXml(pXmlNode);
86 m_root->InitFromXml(pXmlNode);
88 m_memLeft = m_memRight = m_memTop = m_memBottom = NULL;
89 GETRENDERFACTORY->CreateRenderTarget(&m_memRT, 0, 0);
90 GETRENDERFACTORY->CreateRenderTarget(&m_memLeft, 0, 0);
91 GETRENDERFACTORY->CreateRenderTarget(&m_memRight, 0, 0);
92 GETRENDERFACTORY->CreateRenderTarget(&m_memTop, 0, 0);
93 GETRENDERFACTORY->CreateRenderTarget(&m_memBottom, 0, 0);
105 return m_pHost->GetScale();
110 if (m_titleHeight.isZero() && m_borderWidth.isZero())
112 LPNCCALCSIZE_PARAMS pParam = (LPNCCALCSIZE_PARAMS)lParam;
114 if (bCalcValidRects && (pNative->
GetStyle() & WS_CHILDWINDOW))
116 if (SWP_NOSIZE & pParam->lppos->flags)
121 POINT point = { rcWindow.left, rcWindow.top };
122 ::ScreenToClient(::GetParent(pNative->
GetHwnd()), &point);
123 int w = rcWindow.Width();
124 int h = rcWindow.Height();
126 rcWindow.left = point.x;
127 rcWindow.top = point.y;
128 rcWindow.right = rcWindow.left + w;
129 rcWindow.bottom = rcWindow.top + h;
131 if (0 == (SWP_NOMOVE & pParam->lppos->flags))
133 rcWindow.left = pParam->lppos->x;
134 rcWindow.top = pParam->lppos->y;
137 rcWindow.right = rcWindow.left + pParam->lppos->cx;
138 rcWindow.bottom = rcWindow.top + pParam->lppos->cy;
139 pParam->rgrc[0] = rcWindow;
141 else if (bCalcValidRects)
143 if (SWP_NOSIZE & pParam->lppos->flags)
148 rcWindow = CRect(rcWindow.TopLeft(), CSize(pParam->lppos->cx, pParam->lppos->cy));
149 if (0 == (SWP_NOMOVE & pParam->lppos->flags))
151 rcWindow.MoveToXY(pParam->lppos->x, pParam->lppos->y);
153 pParam->rgrc[0] = rcWindow;
162 if (bCalcValidRects &&
IsDrawNc() && !m_pHost->IsIconic())
164 LPNCCALCSIZE_PARAMS pParam = (LPNCCALCSIZE_PARAMS)lParam;
165 CRect rcWnd = pParam->rgrc[0];
166 rcWnd.MoveToXY(0, 0);
167 CRect &rc = (CRect &)pParam->rgrc[0];
168 int nBorderWid = m_borderWidth.toPixelSize(
GetScale());
169 int nTitleHei = m_titleHeight.toPixelSize(
GetScale());
170 rc.DeflateRect(nBorderWid, nBorderWid);
173 CRect rcCaption(0, 0, rc.Width(), nTitleHei);
174 m_memRT->Resize(rcCaption.Size());
175 m_memRT->SetViewportOrg(CPoint(-nBorderWid, -nBorderWid));
177 m_root->Move(rcCaption);
178 m_root->UpdateLayout();
179 m_rcInvalid = rcCaption;
180 m_rcInvalid.OffsetRect(nBorderWid, nBorderWid);
182 m_memLeft->Resize(CSize(nBorderWid, rcWnd.Height()));
183 m_memLeft->BeginDraw();
184 m_skinBorder->DrawByIndex(m_memLeft, &rcWnd, 0);
185 m_memLeft->EndDraw();
187 m_memRight->Resize(CSize(nBorderWid, rcWnd.Height()));
188 m_memRight->SetViewportOrg(CPoint(-(rcWnd.right - nBorderWid), 0));
189 m_memRight->BeginDraw();
190 m_skinBorder->DrawByIndex(m_memRight, &rcWnd, 0);
191 m_memRight->EndDraw();
193 m_memTop->Resize(CSize(rcWnd.Width() - 2 * nBorderWid, nBorderWid));
194 m_memTop->SetViewportOrg(CPoint(-nBorderWid, 0));
195 m_memTop->BeginDraw();
196 m_skinBorder->DrawByIndex(m_memTop, &rcWnd, 0);
199 m_memBottom->Resize(CSize(rcWnd.Width() - 2 * nBorderWid, nBorderWid));
200 m_memBottom->SetViewportOrg(CPoint(-nBorderWid, -(rcWnd.bottom - nBorderWid)));
201 m_memBottom->BeginDraw();
202 m_skinBorder->DrawByIndex(m_memBottom, &rcWnd, 0);
203 m_memBottom->EndDraw();
207 SetMsgHandled(FALSE);
217 DWORD dwStyle = m_pHost->GetStyle();
218 if (dwStyle & WS_VISIBLE)
219 m_pHost->SetWindowLongPtr(GWL_STYLE, dwStyle & ~WS_VISIBLE);
220 m_pHost->DefWindowProc();
221 if (dwStyle & WS_VISIBLE)
222 m_pHost->SetWindowLongPtr(GWL_STYLE, dwStyle);
223 m_root->SetActive(bActive);
225 int nBorderWid = m_borderWidth.toPixelSize(
GetScale());
226 m_rcInvalid = m_root->GetClientRect();
227 m_rcInvalid.OffsetRect(nBorderWid, nBorderWid);
228 m_pHost->SendMessage(WM_NCPAINT, 1);
235 if (m_pHost->IsIconic())
237 UINT uRet = HTCLIENT;
242 CRect rcWnd = m_pHost->GetWindowRect();
243 CRect rcClient = m_pHost->GetClientRect();
244 m_pHost->ClientToScreen2(&rcClient);
245 if (rcClient.PtInRect(point))
250 CRect rcInner = rcWnd;
251 int nBorderWid = m_borderWidth.toPixelSize(
GetScale());
252 rcInner.DeflateRect(nBorderWid, nBorderWid);
253 CRect rcTitle = rcInner;
254 rcTitle.bottom = rcClient.top;
255 if (rcTitle.PtInRect(point))
257 point -= rcTitle.TopLeft();
258 SWND swnd = m_root->SwndFromPoint(point);
262 int nId = pWnd->
GetID();
263 if (nId == IDC_SYS_ICON)
273 if (m_pHost->m_hostAttr.m_bResizable)
282 htPart[0] = HTTOPLEFT;
283 rcParts[0] = CRect(rcWnd.left, rcWnd.top, rcInner.left, rcInner.top);
285 rcParts[1] = CRect(rcInner.left, rcWnd.top, rcInner.right, rcInner.top);
286 htPart[2] = HTTOPRIGHT;
287 rcParts[2] = CRect(rcInner.right, rcWnd.top, rcWnd.right, rcInner.top);
289 rcParts[3] = CRect(rcWnd.left, rcInner.top, rcInner.left, rcInner.bottom);
291 rcParts[4] = CRect(rcInner.left, rcInner.top, rcWnd.right, rcInner.bottom);
292 htPart[5] = HTBOTTOMLEFT;
293 rcParts[5] = CRect(rcWnd.left, rcInner.top, rcInner.left, rcWnd.bottom);
294 htPart[6] = HTBOTTOM;
295 rcParts[6] = CRect(rcInner.left, rcInner.bottom, rcInner.right, rcWnd.bottom);
296 htPart[7] = HTBOTTOMRIGHT;
297 rcParts[7] = CRect(rcInner.right, rcInner.bottom, rcWnd.right, rcWnd.bottom);
298 for (
int i = 0; i < 8; i++)
300 if (rcParts[i].PtInRect(point))
306 if (uRet == HTCLIENT)
315 else if (m_pHost->m_hostAttr.m_bResizable)
319 m_pHost->ScreenToClient(&point);
320 CRect rcMargin = m_pHost->m_hostAttr.GetMargin(
GetScale());
321 CRect rcWnd = m_pHost->GetRoot()->GetWindowRect();
322 if (point.x > rcWnd.right - rcMargin.right)
324 if (point.y > rcWnd.bottom - rcMargin.bottom)
326 uRet = HTBOTTOMRIGHT;
328 else if (point.y < rcMargin.top)
337 else if (point.x < rcMargin.left)
339 if (point.y > rcWnd.bottom - rcMargin.bottom)
343 else if (point.y < rcMargin.top)
352 else if (point.y > rcWnd.bottom - rcMargin.bottom)
356 else if (point.y < rcMargin.top)
370 CRect rcWnd = m_pHost->GetWindowRect();
371 if ((UINT_PTR)hRgn > 1 && !::RectInRegion(hRgn, &rcWnd))
373 m_pHost->DefWindowProc();
379 HDC hdc = ::GetWindowDC(m_pHost->m_hWnd);
380 CRect rcClient = m_pHost->GetClientRect();
381 m_pHost->ClientToScreen2(&rcClient);
382 rcClient.OffsetRect(-rcWnd.TopLeft());
383 ::ExcludeClipRect(hdc, rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);
384 rcWnd.MoveToXY(0, 0);
385 int nBorderWid = m_borderWidth.toPixelSize(
GetScale());
386 int nTitleHei = m_titleHeight.toPixelSize(
GetScale());
390 CRect rcDraw(0, 0, nBorderWid, rcWnd.bottom);
392 HDC memdc = m_memLeft->GetDC(0);
393 BitBlt(hdc, rcDraw.left, rcDraw.top, rcDraw.Width(), rcDraw.Height(), memdc, rcDraw.left, rcDraw.top, SRCCOPY);
394 m_memLeft->ReleaseDC(memdc, &rcDraw);
399 CRect rcDraw(nBorderWid, 0, rcWnd.right - nBorderWid, nBorderWid);
401 HDC memdc = m_memTop->GetDC(0);
402 BitBlt(hdc, rcDraw.left, rcDraw.top, rcDraw.Width(), rcDraw.Height(), memdc, rcDraw.left, rcDraw.top, SRCCOPY);
403 m_memTop->ReleaseDC(memdc, &rcDraw);
408 CRect rcDraw(rcWnd.right - nBorderWid, 0, rcWnd.right, rcWnd.bottom);
410 HDC memdc = m_memRight->GetDC(0);
411 BitBlt(hdc, rcDraw.left, rcDraw.top, rcDraw.Width(), rcDraw.Height(), memdc, rcDraw.left, rcDraw.top, SRCCOPY);
412 m_memRight->ReleaseDC(memdc, &rcDraw);
417 CRect rcDraw(nBorderWid, rcWnd.bottom - nBorderWid, rcWnd.right - nBorderWid, rcWnd.bottom);
419 HDC memdc = m_memBottom->GetDC(0);
420 BitBlt(hdc, rcDraw.left, rcDraw.top, rcDraw.Width(), rcDraw.Height(), memdc, rcDraw.left, rcDraw.top, SRCCOPY);
421 m_memBottom->ReleaseDC(memdc, &rcDraw);
426 if (m_root->IsLayoutDirty())
427 m_root->UpdateLayout();
428 m_memRT->BeginDraw();
429 m_memRT->PushClipRect(m_rcInvalid);
430 CRect rcTitle(nBorderWid, nBorderWid, rcWnd.Width() - nBorderWid, nTitleHei + nBorderWid);
431 m_root->Draw(m_memRT, rcTitle);
434 HDC memdc = m_memRT->GetDC(0);
435 ::BitBlt(hdc, rcTitle.left, rcTitle.top, rcTitle.Width(), rcTitle.Height(), memdc, rcTitle.left, rcTitle.top, SRCCOPY);
436 m_memRT->ReleaseDC(memdc, &rcTitle);
437 m_rcInvalid = CRect();
440 ::ReleaseDC(m_pHost->m_hWnd, hdc);
446 return !m_pHost->IsTranslucent() && !(m_borderWidth.isZero() && m_titleHeight.isZero());
453 return m_pHost->DefWindowProc();
457 DWORD dwStyle = m_pHost->GetStyle();
458 if (dwStyle & WS_VISIBLE)
459 m_pHost->SetWindowLongPtr(GWL_STYLE, dwStyle & ~WS_VISIBLE);
460 m_pHost->DefWindowProc();
461 if (dwStyle & WS_VISIBLE)
462 m_pHost->SetWindowLongPtr(GWL_STYLE, dwStyle);
476 return m_pHost->DefWindowProc();
493 SetMsgHandled(FALSE);
518 return m_pHost->OnFireEvent(e);
533 CRect rcItem = m_pHost->GetWindowRect();
534 rcItem.MoveToXY(0, 0);
535 int nBorderWid = m_borderWidth.toPixelSize(
GetScale());
536 int nTitleHei = m_titleHeight.toPixelSize(
GetScale());
537 rcItem.DeflateRect(nBorderWid, nBorderWid);
538 rcItem.bottom = rcItem.top + nTitleHei;
550 HRGN hRgn = CreateRectRgnIndirect(&m_rcInvalid);
551 m_pHost->SendMessage(WM_NCPAINT, (WPARAM)hRgn);
559 m_pHost->SendMessage(WM_NCPAINT, 1, 0);
577 HDC hdc = ::GetWindowDC(m_pHost->m_hWnd);
578 int nBorderWid = m_borderWidth.toPixelSize(
GetScale());
579 HDC memdc = m_memRT->GetDC(0);
580 ::BitBlt(hdc, rc->left, rc->top, RectWidth(rc), RectHeight(rc), memdc, rc->left, rc->top, SRCCOPY);
581 m_memRT->ReleaseDC(memdc, rc);
582 ::ReleaseDC(m_pHost->m_hWnd, hdc);
587 if (wp == HTCAPTION && msg != WM_NCLBUTTONDBLCLK)
589 m_bMouseHover = TRUE;
591 if (msg == WM_NCLBUTTONUP)
592 m_bLButtonDown = FALSE;
593 CPoint pt(GET_X_LPARAM(lp), GET_Y_LPARAM(lp));
594 CRect rcWnd = m_pHost->GetWindowRect();
595 pt -= rcWnd.TopLeft();
596 int nBorder = m_borderWidth.toPixelSize(
GetScale());
599 lp = MAKELPARAM(pt.x, pt.y);
600 msg += WM_MOUSEMOVE - WM_NCMOUSEMOVE;
601 m_root->DoFrameEvent(msg, wp, lp);
606 m_pHost->DefWindowProc();
617 m_root->DoFrameEvent(WM_MOUSELEAVE, 0, 0);
619 m_bMouseHover = FALSE;
621 return m_pHost->DefWindowProc();
626 if (nHitTest == HTCAPTION)
628 m_bLButtonDown = TRUE;
630 CRect rcWnd = m_pHost->GetWindowRect();
631 pt -= rcWnd.TopLeft();
632 int nBorder = m_borderWidth.toPixelSize(
GetScale());
637 SWND swnd = m_root->SwndFromPoint(pt2);
640 LPARAM lp = MAKELPARAM(pt.x, pt.y);
641 m_root->DoFrameEvent(WM_LBUTTONDOWN, 0, lp);
645 m_pHost->DefWindowProc();
650 m_pHost->DefWindowProc();
656 static struct SystemID
660 } systemID[] = { IDC_SYS_ICON, L
"sysid_icon", IDC_SYS_TITLE, L
"sysid_title", IDC_SYS_CLOSE, L
"sysid_close", IDC_SYS_MIN, L
"sysid_min", IDC_SYS_MAX, L
"sysid_max", IDC_SYS_RESTORE, L
"sysid_restore" };
665 for (
int i = 0; i < ARRAYSIZE(systemID); i++)
669 return systemID[i].id;
689 CRect rcWnd = m_pHost->GetWindowRect();
690 pt -= rcWnd.TopLeft();
693 BOOL bOK = m_root->UpdateToolTip(pt, tipInfo);
696 m_pHost->_SetToolTipInfo(&tipInfo, TRUE);
700 m_pHost->_SetToolTipInfo(NULL, TRUE);
707 int nBorderWid = m_borderWidth.toPixelSize(
GetScale());
708 int nTitleHei = m_titleHeight.toPixelSize(
GetScale());
709 szRet.cx = nBorderWid * 2;
710 szRet.cy = nBorderWid * 2 + nTitleHei;
736 HWND hHover = ::WindowFromPoint(pt);
737 if (hHover != m_pHost->m_hWnd)
744 SetMsgHandled(FALSE);
752 if (pMax && pRestore)
754 if (nResizeMode == SIZE_MAXIMIZED)
759 else if (nResizeMode == SIZE_RESTORED)
virtual BOOL IsHostUpdateLocked() const
Checks if host updates are locked.
LRESULT OnSetText(LPCTSTR pszText)
Handles the WM_SETTEXT message.
void OnSize(UINT nType, CSize size)
Handles the WM_SIZE message.
void OnLButtonUp(WPARAM wp, LPARAM lp)
Handles the WM_LBUTTONUP message.
virtual BOOL OnHostFireEvent(IEvtArgs *e)
Called when an event is fired on the host.
virtual ISwndContainer * GetHostContainer()
Gets the host container.
virtual void OnLayoutDirty()
Called when layout is dirty.
virtual CRect GetHostRect() const
Gets the rectangle of the host.
void OnNcLButtonDown(UINT flag, CPoint pt)
Handles the WM_NCLBUTTONDOWN message.
BOOL IsDrawNc() const
Checks if non-client area should be drawn.
CSize GetNcSize() const
Gets the size of the non-client area.
static void updateSystemButton(SWindow *pRoot, UINT nResizeMode)
Updates system buttons in the non-client area.
LRESULT OnNcMouseLeave(UINT msg, WPARAM wp, LPARAM lp)
Handles the WM_NCMOUSELEAVE message.
virtual BOOL IsItemRedrawDelay() const
Checks if item redraw is delayed.
static int toNcBuiltinID(const SStringW &str)
Converts a string to a built-in non-client ID.
void Reset()
Resets the non-client painter.
void OnTimer(UINT_PTR tid)
Handles the WM_TIMER message.
virtual void OnReleaseHostRenderTarget(IRenderTarget *pRT, LPCRECT rc, GrtFlag gdcFlags)
Called to release the host render target.
LRESULT OnRepaint(UINT msg, WPARAM wp, LPARAM lp)
Handles repaint messages.
virtual IRenderTarget * OnGetHostRenderTarget(LPCRECT rc, GrtFlag gdcFlags)
Called to get the host render target.
void OnMouseMove(WPARAM wp, LPARAM lp)
Handles the WM_MOUSEMOVE message.
void OnNcDestroy()
Handles the WM_NCDESTROY message.
virtual void OnItemSetCapture(SOsrPanel *pItem, BOOL bCapture)
Called when an item sets capture.
LRESULT OnNcCalcSize(BOOL bCalcValidRects, LPARAM lParam)
Handles the WM_NCCALCSIZE message.
BOOL OnNcActivate(BOOL bActive)
Handles the WM_NCACTIVATE message.
virtual BOOL OnItemGetRect(const SOsrPanel *pItem, CRect &rcItem) const
Called to get the rectangle of an item.
int GetScale() const
Gets the scale factor.
SNcPainter(SHostWnd *pHost)
Constructor for SNcPainter.
virtual void InvalidateHostRect(LPCRECT pRc, BOOL bClip)
Invalidates a rectangle in the host.
IWindow * GetRoot() OVERRIDE
Gets the root window.
UINT OnNcHitTest(CPoint point)
Handles the WM_NCHITTEST message.
virtual IObject * GetHost()
Gets the host object.
void OnNcPaint(HRGN hRgn)
Handles the WM_NCPAINT message.
~SNcPainter(void)
Destructor for SNcPainter.
virtual BOOL IsHostVisible() const
Checks if the host is visible.
void UpdateToolTip()
Updates the tooltip.
BOOL InitFromXml(IXmlNode *pXmlNode) OVERRIDE
Initializes the non-client painter from an XML node.
LRESULT OnNcMouseEvent(UINT msg, WPARAM wp, LPARAM lp)
Handles non-client mouse events.
BOOL OnEraseBkgnd(IRenderTarget *pRT)
Erases the background of the panel.
SNcPanel(IHostProxy *pFrameHost, IItemContainer *pItemContainer)
Constructor for SNcPanel.
void SetActive(BOOL bActive)
Sets the active state of the panel.
int GetID() SCONST OVERRIDE
Retrieves the object's ID.
A class representing an ASCII string.
int CompareNoCase(const wchar_t *psz) SCONST
Compares the string with another string, ignoring case.
BOOL IsEmpty() SCONST
Checks if the string is empty.
SStringW Left(int nCount) const
Extracts the leftmost part of the string.
Base class for SOUI DUI windows.
void SetVisible(BOOL bVisible, BOOL bUpdate=FALSE) OVERRIDE
Sets the visibility of the window.
virtual CRect GetClientRect() const
Retrieves the client rectangle of the window.
void SetWindowText(LPCTSTR lpszText) OVERRIDE
Sets the window text.
COLORREF GetBkgndColor() SCONST OVERRIDE
Retrieves the background color of the window.
const SwndStyle & GetStyle() const
Retrieves the style of the window.
SWindow * FindChildByID(int nID, int nDeep=-1)
Finds a child window by its ID.
static SWindow * GetWindow(SWND swnd)
Retrieves the SWindow pointer from a given handle.
Class representing an XML node.
void SetTextColor(int iState, COLORREF cr)
Sets the text color for a specific state.
Interface for Native Window Operations.
HWND GetHwnd() PURE
Retrieves the handle to the window.
BOOL GetWindowRect(LPRECT lpRect) SCONST PURE
Retrieves the window rectangle.
DWORD GetStyle() SCONST PURE
Retrieves the window style.
Interface for rendering target objects.
HRESULT PushClipRect(LPCRECT pRect, UINT mode=RGN_AND) PURE
Push a rectangular clip region.
HRESULT FillSolidRect(LPCRECT pRect, COLORREF cr) PURE
Fill a rectangle with a solid color.
Interface for Skin Objects.
void DrawByIndex(IRenderTarget *pRT, LPCRECT rcDraw, int iState) SCONST PURE
Draws the skin object to the specified render target with a given index.
SOUI Window Container Interface.