https://git.reactos.org/?p=reactos.git;a=commitdiff;h=73ba03add1ccf725b85c5…
commit 73ba03add1ccf725b85c55b4d0532ed640993d6d
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Thu Jan 18 19:25:46 2024 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Thu Jan 18 19:25:46 2024 +0900
[SDK] cicuif.h: Add CUIFBalloonButton and CUIFBalloonWindow (#6384)
Supporting TIPs...
JIRA issue: CORE-19360
- Implement CUIFBalloonButton class.
- Half-implement CUIFBalloonWindow class.
---
sdk/include/reactos/cicero/cicuif.h | 700 +++++++++++++++++++++++++++++++++---
1 file changed, 660 insertions(+), 40 deletions(-)
diff --git a/sdk/include/reactos/cicero/cicuif.h b/sdk/include/reactos/cicero/cicuif.h
index c5f4bfcc845..fc05fb72f33 100644
--- a/sdk/include/reactos/cicero/cicuif.h
+++ b/sdk/include/reactos/cicero/cicuif.h
@@ -23,12 +23,15 @@ class CUIFTheme;
class CUIFWindow;
class CUIFToolTip;
class CUIFShadow;
+ class CUIFBalloonWindow;
+ class CUIFButton;
+ class CUIFButton2;
+ class CUIFToolbarMenuButton;
+ class CUIFToolbarButtonElement;
+ class CUIFBalloonButton;
class CUIFToolbarButton;
- class CUIFButton;
- class CUIFButton2;
- class CUIFToolbarMenuButton;
- class CUIFToolbarButtonElement;
- class CUIFGripper;
+ class CUIFWndFrame;
+ class CUIFGripper;
class CUIFObjectArray;
class CUIFColorTable;
class CUIFColorTableSys;
@@ -203,7 +206,7 @@ protected:
CUIFWindow *m_pWindow;
CUIFScheme *m_pScheme;
CUIFObjectArray m_ObjectArray;
- DWORD m_dwUnknown3; //FIXME: name and type
+ DWORD m_nObjectID;
DWORD m_style;
RECT m_rc;
BOOL m_bEnable;
@@ -214,9 +217,10 @@ protected:
DWORD m_dwUnknown4[2]; //FIXME: name and type
friend class CUIFWindow;
friend class CUIFToolTip;
+ friend class CUIFBalloonWindow;
public:
- CUIFObject(CUIFObject *pParent, DWORD dwUnknown3, LPCRECT prc, DWORD style);
+ CUIFObject(CUIFObject *pParent, DWORD nObjectID, LPCRECT prc, DWORD style);
virtual ~CUIFObject();
void StartCapture();
@@ -544,7 +548,6 @@ protected:
CUIFToolTip *m_pToolTip;
CUIFShadow *m_pShadow;
BOOL m_bShowShadow;
- CUIFWindow *m_pShadowOrToolTipOwner;
friend class CUIFObject;
friend class CUIFShadow;
friend class CUIFToolTip;
@@ -574,7 +577,7 @@ public:
static LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM
lParam);
STDMETHOD_(LPCTSTR, GetClassName)();
- STDMETHOD_(LPCTSTR, GetWndText)();
+ STDMETHOD_(LPCTSTR, GetWndTitle)();
STDMETHOD_(DWORD, GetWndStyle)();
STDMETHOD_(DWORD, GetWndStyleEx)();
STDMETHOD_(HWND, CreateWnd)(HWND hwndParent);
@@ -620,6 +623,7 @@ public:
class CUIFToolTip : public CUIFWindow
{
protected:
+ CUIFWindow *m_pToolTipOwner;
CUIFObject *m_pToolTipTarget;
LPWSTR m_pszToolTipText;
BOOL m_bShowToolTip;
@@ -662,6 +666,7 @@ public:
class CUIFShadow : public CUIFWindow
{
protected:
+ CUIFWindow *m_pShadowOwner;
COLORREF m_rgbShadowColor;
DWORD m_dwUnknown11[2];
INT m_xShadowDelta;
@@ -722,7 +727,7 @@ protected:
void DrawTextProc(HDC hDC, LPCRECT prc, BOOL bPressed);
public:
- CUIFButton(CUIFObject *pParent, DWORD dwUnknown3, LPCRECT prc, DWORD style);
+ CUIFButton(CUIFObject *pParent, DWORD nObjectID, LPCRECT prc, DWORD style);
~CUIFButton() override;
void SetIcon(HICON hIcon);
@@ -748,7 +753,7 @@ protected:
SIZE m_BitmapSize;
public:
- CUIFButton2(CUIFObject *pParent, DWORD dwUnknown3, LPCRECT prc, DWORD style);
+ CUIFButton2(CUIFObject *pParent, DWORD nObjectID, LPCRECT prc, DWORD style);
~CUIFButton2() override;
DWORD MakeDrawFlag();
@@ -763,7 +768,7 @@ class CUIFToolbarMenuButton : public CUIFButton2
public:
CUIFToolbarButton *m_pToolbarButton;
- CUIFToolbarMenuButton(CUIFToolbarButton *pParent, DWORD dwUnknown3, LPCRECT prc,
DWORD style);
+ CUIFToolbarMenuButton(CUIFToolbarButton *pParent, DWORD nObjectID, LPCRECT prc, DWORD
style);
~CUIFToolbarMenuButton() override;
STDMETHOD_(void, OnLButtonUp)(LONG x, LONG y) override;
@@ -777,7 +782,7 @@ class CUIFToolbarButtonElement : public CUIFButton2
public:
CUIFToolbarButton *m_pToolbarButton;
- CUIFToolbarButtonElement(CUIFToolbarButton *pParent, DWORD dwUnknown3, LPCRECT prc,
DWORD style);
+ CUIFToolbarButtonElement(CUIFToolbarButton *pParent, DWORD nObjectID, LPCRECT prc,
DWORD style);
STDMETHOD_(LPCWSTR, GetToolTip)() override;
STDMETHOD_(void, OnLButtonUp)(LONG x, LONG y) override;
@@ -796,7 +801,7 @@ public:
CUIFToolbarButton(
CUIFObject *pParent,
- DWORD dwUnknown3,
+ DWORD nObjectID,
LPCRECT prc,
DWORD style,
DWORD dwToolbarButtonFlags,
@@ -876,6 +881,88 @@ public:
/////////////////////////////////////////////////////////////////////////////
+class CUIFBalloonButton : public CUIFButton
+{
+protected:
+ UINT m_nCommandID;
+ friend class CUIFBalloonWindow;
+
+public:
+ CUIFBalloonButton(CUIFObject *pParent, DWORD nObjectID, LPCRECT prc, DWORD style);
+
+ STDMETHOD_(void, OnPaint)(HDC hDC) override;
+ void DrawTextProc(HDC hDC, LPCRECT prc, BOOL bPressed);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+// m_style flags for CUIFBalloonWindow
+enum
+{
+ UIF_BALLOON_WINDOW_OK = 0x10000,
+ UIF_BALLOON_WINDOW_YESNO = 0x20000,
+ UIF_BALLOON_WINDOW_TYPE_MASK = 0xF0000,
+};
+
+class CUIFBalloonWindow : public CUIFWindow
+{
+protected:
+ LPWSTR m_pszBalloonText;
+ HRGN m_hRgn;
+ RECT m_rcMargin;
+ DWORD m_dwUnknown6;
+ BOOL m_bHasBkColor;
+ BOOL m_bHasTextColor;
+ COLORREF m_rgbBkColor;
+ COLORREF m_rgbTextColor;
+ POINT m_ptTarget;
+ RECT m_rcExclude;
+ POINT m_ptBalloon;
+ DWORD m_dwUnknown7;
+ UINT m_nBalloonType;
+ DWORD m_dwUnknown8[2];
+ UINT m_cButtons;
+ WPARAM m_nActionID;
+ HWND m_hwndNotif;
+ UINT m_uNotifMsg;
+
+public:
+ CUIFBalloonWindow(HINSTANCE hInst, DWORD style);
+ ~CUIFBalloonWindow() override;
+
+ STDMETHOD_(void, Initialize)() override;
+ STDMETHOD_(LPCTSTR, GetClassName)() override;
+ STDMETHOD_(LPCTSTR, GetWndTitle)() override;
+ STDMETHOD_(void, OnCreate)(HWND hWnd) override;
+ STDMETHOD_(void, OnDestroy)(HWND hWnd) override;
+ STDMETHOD_(void, OnKeyDown)(HWND hWnd, WPARAM wParam, LPARAM lParam) override;
+ STDMETHOD_(LRESULT, OnObjectNotify)(CUIFObject *pObject, WPARAM wParam, LPARAM
lParam) override;
+ STDMETHOD_(void, OnPaint)(HDC hDC) override;
+
+ void AddButton(UINT nCommandId);
+ void AdjustPos();
+ HRGN CreateRegion(LPCRECT prc);
+ void DoneWindowRegion();
+ CUIFBalloonButton *FindButton(UINT nCommandID);
+ CUIFObject *FindUIObject(UINT nObjectID);
+
+ COLORREF GetBalloonBkColor();
+ COLORREF GetBalloonTextColor();
+ void GetButtonSize(LPSIZE pSize);
+ void GetMargin(LPRECT prcMargin);
+ void SetExcludeRect(LPCRECT prcExclude);
+ void SetTargetPos(POINT ptTarget);
+ void SetText(LPCWSTR pszText);
+
+ void InitWindowRegion();
+ void LayoutObject();
+ void PaintFrameProc(HDC hDC, LPCRECT prc);
+ void PaintMessageProc(HDC hDC, LPRECT prc, LPCWSTR pszText);
+ void SendNotification(WPARAM wParam);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
inline void cicInitUIFLib(void)
{
cicInitUIFSys();
@@ -1105,12 +1192,12 @@ CUIFTheme::SetActiveTheme(LPCWSTR pszClassList, INT iPartId, INT
iStateId)
/// @unimplemented
inline
-CUIFObject::CUIFObject(CUIFObject *pParent, DWORD dwUnknown3, LPCRECT prc, DWORD style)
+CUIFObject::CUIFObject(CUIFObject *pParent, DWORD nObjectID, LPCRECT prc, DWORD style)
{
m_pszClassList = NULL;
m_hTheme = NULL;
m_pParent = pParent;
- m_dwUnknown3 = dwUnknown3; //FIXME: name and type
+ m_nObjectID = nObjectID;
m_style = style;
if (prc)
@@ -2500,7 +2587,7 @@ inline LPCTSTR CUIFWindow::GetClassName()
return TEXT("CiceroUIWndFrame");
}
-inline LPCTSTR CUIFWindow::GetWndText()
+inline LPCTSTR CUIFWindow::GetWndTitle()
{
return TEXT("CiceroUIWndFrame");
}
@@ -2541,7 +2628,7 @@ CUIFWindow::GetWndStyleEx()
inline STDMETHODIMP_(HWND)
CUIFWindow::CreateWnd(HWND hwndParent)
{
- HWND hWnd = CreateWindowEx(GetWndStyleEx(), GetClassName(), GetWndText(),
GetWndStyle(),
+ HWND hWnd = CreateWindowEx(GetWndStyleEx(), GetClassName(), GetWndTitle(),
GetWndStyle(),
m_nLeft, m_nTop, m_nWidth, m_nHeight,
hwndParent, NULL, m_hInst, this);
if (m_pToolTip)
@@ -3238,7 +3325,7 @@ CUIFWindow::OnAnimationStart()
inline CUIFShadow::CUIFShadow(HINSTANCE hInst, DWORD style, CUIFWindow *pShadowOwner)
: CUIFWindow(hInst, (style | UIF_WINDOW_TOOLWINDOW))
{
- m_pShadowOrToolTipOwner = pShadowOwner;
+ m_pShadowOwner = pShadowOwner;
m_rgbShadowColor = RGB(0, 0, 0);
m_dwUnknown11[0] = 0;
m_dwUnknown11[1] = 0;
@@ -3248,8 +3335,8 @@ inline CUIFShadow::CUIFShadow(HINSTANCE hInst, DWORD style,
CUIFWindow *pShadowO
inline CUIFShadow::~CUIFShadow()
{
- if (m_pShadowOrToolTipOwner)
- m_pShadowOrToolTipOwner->m_pShadow = NULL;
+ if (m_pShadowOwner)
+ m_pShadowOwner->m_pShadow = NULL;
}
/// @unimplemented
@@ -3271,7 +3358,7 @@ inline void CUIFShadow::InitShadow()
inline void CUIFShadow::AdjustWindowPos()
{
- HWND hwndOwner = *m_pShadowOrToolTipOwner;
+ HWND hwndOwner = *m_pShadowOwner;
if (!::IsWindow(m_hWnd))
return;
@@ -3324,7 +3411,7 @@ inline STDMETHODIMP_(LRESULT)
CUIFShadow::OnWindowPosChanging(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
WINDOWPOS *wp = (WINDOWPOS *)lParam;
- wp->hwndInsertAfter = *m_pShadowOrToolTipOwner;
+ wp->hwndInsertAfter = *m_pShadowOwner;
return ::DefWindowProc(hWnd, Msg, wParam, lParam);
}
@@ -3369,7 +3456,7 @@ inline
CUIFToolTip::CUIFToolTip(HINSTANCE hInst, DWORD style, CUIFWindow *pToolTipOwner)
: CUIFWindow(hInst, style)
{
- m_pShadowOrToolTipOwner = pToolTipOwner;
+ m_pToolTipOwner = pToolTipOwner;
m_rcToolTipMargin.left = 2;
m_rcToolTipMargin.top = 2;
m_rcToolTipMargin.right = 2;
@@ -3390,8 +3477,8 @@ CUIFToolTip::CUIFToolTip(HINSTANCE hInst, DWORD style, CUIFWindow
*pToolTipOwner
inline
CUIFToolTip::~CUIFToolTip()
{
- if (m_pShadowOrToolTipOwner)
- m_pShadowOrToolTipOwner->m_pToolTip = NULL;
+ if (m_pToolTipOwner)
+ m_pToolTipOwner->m_pToolTip = NULL;
if (m_pszToolTipText)
delete[] m_pszToolTipText;
}
@@ -3455,8 +3542,8 @@ CUIFToolTip::GetTipTextColor()
inline CUIFObject*
CUIFToolTip::FindObject(HWND hWnd, POINT pt)
{
- if (hWnd == *m_pShadowOrToolTipOwner)
- return m_pShadowOrToolTipOwner->ObjectFromPoint(pt);
+ if (hWnd == *m_pToolTipOwner)
+ return m_pToolTipOwner->ObjectFromPoint(pt);
return NULL;
}
@@ -3733,9 +3820,9 @@ inline STDMETHODIMP_(void) CUIFToolTip::OnTimer(WPARAM wParam)
inline
CUIFButton::CUIFButton(
CUIFObject *pParent,
- DWORD dwUnknown3,
+ DWORD nObjectID,
LPCRECT prc,
- DWORD style) : CUIFObject(pParent, dwUnknown3, prc, style)
+ DWORD style) : CUIFObject(pParent, nObjectID, prc, style)
{
m_ButtonIcon.m_hIcon = NULL;
m_ButtonIcon.m_hImageList = NULL;
@@ -4128,9 +4215,9 @@ inline void CUIFButton::SetText(LPCWSTR pszText)
inline CUIFButton2::CUIFButton2(
CUIFObject *pParent,
- DWORD dwUnknown3,
+ DWORD nObjectID,
LPCRECT prc,
- DWORD style) : CUIFButton(pParent, dwUnknown3, prc, style)
+ DWORD style) : CUIFButton(pParent, nObjectID, prc, style)
{
m_iStateId = 0;
m_iPartId = BP_PUSHBUTTON;
@@ -4422,9 +4509,9 @@ CUIFGripper::SetStyle(DWORD style)
inline
CUIFToolbarMenuButton::CUIFToolbarMenuButton(
CUIFToolbarButton *pParent,
- DWORD dwUnknown3,
+ DWORD nObjectID,
LPCRECT prc,
- DWORD style) : CUIFButton2(pParent, dwUnknown3, prc, style)
+ DWORD style) : CUIFButton2(pParent, nObjectID, prc, style)
{
m_pToolbarButton = pParent;
@@ -4432,7 +4519,7 @@ CUIFToolbarMenuButton::CUIFToolbarMenuButton(
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH | FF_DONTCARE, TEXT("Marlett"));
SetFont(hFont);
- SetText(L"u");
+ SetText(L"u"); // downward triangle
}
inline
@@ -4461,9 +4548,9 @@ CUIFToolbarMenuButton::OnSetCursor(UINT uMsg, LONG x, LONG y)
inline
CUIFToolbarButtonElement::CUIFToolbarButtonElement(
CUIFToolbarButton *pParent,
- DWORD dwUnknown3,
+ DWORD nObjectID,
LPCRECT prc,
- DWORD style) : CUIFButton2(pParent, dwUnknown3, prc, style)
+ DWORD style) : CUIFButton2(pParent, nObjectID, prc, style)
{
m_pToolbarButton = pParent;
}
@@ -4497,11 +4584,11 @@ CUIFToolbarButtonElement::OnRButtonUp(LONG x, LONG y)
inline CUIFToolbarButton::CUIFToolbarButton(
CUIFObject *pParent,
- DWORD dwUnknown3,
+ DWORD nObjectID,
LPCRECT prc,
DWORD style,
DWORD dwToolbarButtonFlags,
- LPCWSTR pszUnknownText) : CUIFObject(pParent, dwUnknown3, prc, style)
+ LPCWSTR pszUnknownText) : CUIFObject(pParent, nObjectID, prc, style)
{
m_dwToolbarButtonFlags = dwToolbarButtonFlags;
m_pszUnknownText = pszUnknownText;
@@ -4523,7 +4610,7 @@ inline BOOL CUIFToolbarButton::Init()
style |= 0x10;
if (m_dwToolbarButtonFlags & 0x80000)
style |= UIF_BUTTON_VERTICAL;
- m_pToolbarButtonElement = new(cicNoThrow) CUIFToolbarButtonElement(this,
m_dwUnknown3, &rc1, style);
+ m_pToolbarButtonElement = new(cicNoThrow) CUIFToolbarButtonElement(this, m_nObjectID,
&rc1, style);
if (!m_pToolbarButtonElement)
return FALSE;
@@ -4837,3 +4924,536 @@ CUIFWndFrame::OnSetCursor(UINT uMsg, LONG x, LONG y)
::SetCursor(hCursor);
return TRUE;
}
+
+/////////////////////////////////////////////////////////////////////////////
+
+inline
+CUIFBalloonButton::CUIFBalloonButton(
+ CUIFObject *pParent,
+ DWORD nObjectID,
+ LPCRECT prc,
+ DWORD style) : CUIFButton(pParent, nObjectID, prc, style)
+{
+ m_nCommandID = 0;
+}
+
+inline STDMETHODIMP_(void)
+CUIFBalloonButton::OnPaint(HDC hDC)
+{
+ RECT rc = m_rc;
+ ::OffsetRect(&rc, -rc.left, -rc.top);
+
+ HDC hMemDC = ::CreateCompatibleDC(hDC);
+ HBITMAP hbmMem = ::CreateCompatibleBitmap(hDC, rc.right, rc.bottom);
+ HGDIOBJ hbmOld = ::SelectObject(hMemDC, hbmMem);
+
+ BOOL bPressed;
+ COLORREF rgbShadow, rgbBorder;
+ if (m_uButtonStatus == 1)
+ {
+ bPressed = TRUE;
+ rgbShadow = ::GetSysColor(COLOR_BTNSHADOW);
+ rgbBorder = ::GetSysColor(COLOR_BTNHIGHLIGHT);
+ }
+ else
+ {
+ bPressed = FALSE;
+ if (m_uButtonStatus < 4)
+ {
+ rgbShadow = ::GetSysColor(COLOR_BTNHIGHLIGHT);
+ rgbBorder = ::GetSysColor(COLOR_BTNSHADOW);
+ }
+ else
+ {
+ rgbShadow = ::GetSysColor(COLOR_INFOBK);
+ rgbBorder = ::GetSysColor(COLOR_INFOBK);
+ }
+ }
+
+ COLORREF rgbInfoBk = ::GetSysColor(COLOR_INFOBK);
+ HBRUSH hbrBack = ::CreateSolidBrush(rgbInfoBk);
+ ::FillRect(hMemDC, &rc, hbrBack);
+ ::DeleteObject(hbrBack);
+
+ DrawTextProc(hMemDC, &rc, bPressed);
+
+ HBRUSH hNullBrush = (HBRUSH)::GetStockObject(NULL_BRUSH);
+ HGDIOBJ hbrOld = ::SelectObject(hMemDC, hNullBrush);
+
+ HPEN hPen = ::CreatePen(PS_SOLID, 0, rgbShadow);
+ HGDIOBJ hPenOld = ::SelectObject(hMemDC, hPen);
+ ::RoundRect(hMemDC, rc.left, rc.top, rc.right - 1, rc.bottom - 1, 6, 6);
+ ::SelectObject(hMemDC, hPenOld);
+ ::DeleteObject(hPen);
+
+ hPen = ::CreatePen(PS_SOLID, 0, rgbBorder);
+ hPenOld = ::SelectObject(hMemDC, hPen);
+ ::RoundRect(hMemDC, rc.left + 1, rc.top + 1, rc.right, rc.bottom, 6, 6);
+ ::SelectObject(hMemDC, hPenOld);
+ ::DeleteObject(hPen);
+
+ hPen = ::CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_BTNFACE));
+ hPenOld = ::SelectObject(hMemDC, hPen);
+ ::RoundRect(hMemDC, rc.left + 1, rc.top + 1, rc.right - 1, rc.bottom - 1, 6, 6);
+ ::SelectObject(hMemDC, hPenOld);
+ ::DeleteObject(hPen);
+
+ ::SelectObject(hMemDC, hbrOld);
+ ::BitBlt(hDC, m_rc.left, m_rc.top, m_rc.right - m_rc.left, m_rc.bottom - m_rc.top,
+ hMemDC, rc.left, rc.top, SRCCOPY);
+ ::SelectObject(hMemDC, hbmOld);
+ ::DeleteObject(hbmMem);
+ ::DeleteDC(hMemDC);
+}
+
+inline void
+CUIFBalloonButton::DrawTextProc(HDC hDC, LPCRECT prc, BOOL bPressed)
+{
+ if (!m_pszButtonText)
+ return;
+
+ UINT uFlags = DT_SINGLELINE;
+
+ if ((m_style & UIF_BUTTON_H_ALIGN_MASK) == UIF_BUTTON_H_ALIGN_CENTER)
+ uFlags |= DT_CENTER;
+ else if ((m_style & UIF_BUTTON_H_ALIGN_MASK) == UIF_BUTTON_H_ALIGN_RIGHT)
+ uFlags |= DT_RIGHT;
+
+ if ((m_style & UIF_BUTTON_V_ALIGN_MASK) == UIF_BUTTON_V_ALIGN_MIDDLE)
+ uFlags |= DT_VCENTER;
+ else if ((m_style & UIF_BUTTON_V_ALIGN_MASK) == UIF_BUTTON_V_ALIGN_BOTTOM)
+ uFlags |= DT_BOTTOM;
+
+ COLORREF rgbOldColor = ::SetTextColor(hDC, ::GetSysColor(COLOR_BTNTEXT));
+ INT nOldBkMode = ::SetBkMode(hDC, TRANSPARENT);
+
+ RECT rc = *prc;
+ if (bPressed)
+ ::OffsetRect(&rc, 1, 1);
+
+ HGDIOBJ hFontOld = ::SelectObject(hDC, m_hFont);
+ ::DrawTextW(hDC, m_pszButtonText, -1, &rc, uFlags);
+ ::SelectObject(hDC, hFontOld);
+
+ ::SetBkMode(hDC, nOldBkMode);
+ ::SetTextColor(hDC, rgbOldColor);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+inline
+CUIFBalloonWindow::CUIFBalloonWindow(HINSTANCE hInst, DWORD style) : CUIFWindow(hInst,
style)
+{
+ m_dwUnknown6 = -1;
+ m_nActionID = -1;
+ m_hRgn = NULL;
+ m_pszBalloonText = NULL;
+ m_bHasBkColor = FALSE;
+ m_bHasTextColor = FALSE;
+ m_rgbBkColor = 0;
+ m_rgbTextColor = 0;
+ m_ptTarget.x = 0;
+ m_ptTarget.y = 0;
+ m_rcExclude.left = 0;
+ m_rcExclude.right = 0;
+ m_rcExclude.top = 0;
+ m_rcExclude.bottom = 0;
+ m_dwUnknown7 = 0;
+ m_nBalloonType = 0;
+ m_dwUnknown8[0] = 0;
+ m_dwUnknown8[1] = 0;
+ m_ptBalloon.x = 0;
+ m_ptBalloon.y = 0;
+ m_cButtons = 0;
+ m_hwndNotif = NULL;
+ m_uNotifMsg = 0;
+ m_rcMargin.left = 8;
+ m_rcMargin.top = 8;
+ m_rcMargin.right = 8;
+ m_rcMargin.bottom = 8;
+}
+
+inline
+CUIFBalloonWindow::~CUIFBalloonWindow()
+{
+ if (m_pszBalloonText)
+ {
+ delete[] m_pszBalloonText;
+ m_pszBalloonText = NULL;
+ }
+}
+
+inline STDMETHODIMP_(void)
+CUIFBalloonWindow::Initialize()
+{
+ CUIFWindow::Initialize();
+
+ if ((m_style & UIF_BALLOON_WINDOW_TYPE_MASK) == UIF_BALLOON_WINDOW_OK)
+ {
+ AddButton(IDOK);
+ }
+ else if ((m_style & UIF_BALLOON_WINDOW_TYPE_MASK) == UIF_BALLOON_WINDOW_YESNO)
+ {
+ AddButton(IDYES);
+ AddButton(IDNO);
+ }
+}
+
+inline STDMETHODIMP_(LPCTSTR)
+CUIFBalloonWindow::GetClassName()
+{
+ return TEXT("MSIME_PopupMessage");
+}
+
+inline STDMETHODIMP_(LPCTSTR)
+CUIFBalloonWindow::GetWndTitle()
+{
+ return TEXT("MSIME_PopupMessage");
+}
+
+inline STDMETHODIMP_(void)
+CUIFBalloonWindow::OnCreate(HWND hWnd)
+{
+ m_nActionID = -1;
+ AdjustPos();
+}
+
+inline STDMETHODIMP_(void)
+CUIFBalloonWindow::OnDestroy(HWND hWnd)
+{
+ SendNotification(m_nActionID);
+ DoneWindowRegion();
+}
+
+inline STDMETHODIMP_(void)
+CUIFBalloonWindow::OnKeyDown(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+ CUIFBalloonButton *pButton = NULL;
+
+ switch (wParam)
+ {
+ case VK_RETURN:
+ pButton = (CUIFBalloonButton *)FindUIObject(0);
+ break;
+ case VK_ESCAPE:
+ m_nActionID = -1;
+ ::DestroyWindow(m_hWnd);
+ return;
+ case TEXT('Y'):
+ pButton = FindButton(IDYES);
+ break;
+ case TEXT('N'):
+ pButton = FindButton(IDNO);
+ break;
+ }
+
+ if (!pButton)
+ return;
+
+ m_nActionID = pButton->m_nCommandID;
+ ::DestroyWindow(m_hWnd);
+}
+
+inline STDMETHODIMP_(LRESULT)
+CUIFBalloonWindow::OnObjectNotify(CUIFObject *pObject, WPARAM wParam, LPARAM lParam)
+{
+ CUIFBalloonButton *pButton = (CUIFBalloonButton *)pObject;
+ m_nActionID = pButton->m_nCommandID;
+ ::DestroyWindow(m_hWnd);
+ return 0;
+}
+
+inline STDMETHODIMP_(void)
+CUIFBalloonWindow::OnPaint(HDC hDC)
+{
+ RECT rc;
+ GetRect(&rc);
+ PaintFrameProc(hDC, &rc);
+
+ switch (m_nBalloonType)
+ {
+ case 1:
+ rc.top += 16;
+ break;
+ case 2:
+ rc.right -= 16;
+ break;
+ case 3:
+ rc.left += 16;
+ break;
+ default:
+ rc.bottom -= 16;
+ break;
+ }
+
+ RECT rcMargin;
+ GetMargin(&rcMargin);
+
+ rc.left += rcMargin.left;
+ rc.top += rcMargin.top;
+ rc.right -= rcMargin.right;
+ rc.bottom -= rcMargin.bottom;
+
+ PaintMessageProc(hDC, &rc, m_pszBalloonText);
+}
+
+inline void
+CUIFBalloonWindow::AddButton(UINT nCommandId)
+{
+ RECT rc = { 0, 0, 0, 0 };
+ if (!((IDOK <= nCommandId) && (nCommandId <= IDNO)))
+ return;
+
+ CUIFBalloonButton *pButton = new(cicNoThrow) CUIFBalloonButton(this, m_cButtons,
&rc, 5);
+ if (!pButton)
+ return;
+
+ pButton->Initialize();
+ pButton->m_nCommandID = nCommandId;
+
+ LPCWSTR pszText; // FIXME: Use resource strings
+ switch (nCommandId)
+ {
+ case IDOK:
+ pszText = L"OK";
+ break;
+ case IDCANCEL:
+ pszText = L"Cancel";
+ break;
+ case IDABORT:
+ pszText = L"&Abort";
+ break;
+ case IDRETRY:
+ pszText = L"&Retry";
+ break;
+ case IDIGNORE:
+ pszText = L"&Ignore";
+ break;
+ case IDYES:
+ pszText = L"&Yes";
+ break;
+ default:
+ pszText = L"&No";
+ break;
+ }
+
+ pButton->SetText(pszText);
+
+ AddUIObj(pButton);
+ ++m_cButtons;
+}
+
+/// @unimplemented
+inline void
+CUIFBalloonWindow::AdjustPos()
+{
+ //FIXME
+}
+
+/// @unimplemented
+inline HRGN
+CUIFBalloonWindow::CreateRegion(LPCRECT prc)
+{
+ //FIXME
+ return NULL;
+}
+
+inline void
+CUIFBalloonWindow::DoneWindowRegion()
+{
+ if (m_hRgn)
+ {
+ ::SetWindowRgn(m_hWnd, NULL, TRUE);
+ ::DeleteObject(m_hRgn);
+ m_hRgn = NULL;
+ }
+}
+
+inline CUIFBalloonButton *
+CUIFBalloonWindow::FindButton(UINT nCommandID)
+{
+ for (UINT iButton = 0; iButton < m_cButtons; ++iButton)
+ {
+ CUIFBalloonButton *pButton = (CUIFBalloonButton *)FindUIObject(iButton);
+ if (pButton && (pButton->m_nCommandID == nCommandID))
+ return pButton;
+ }
+ return NULL;
+}
+
+inline CUIFObject *
+CUIFBalloonWindow::FindUIObject(UINT nObjectID)
+{
+ for (size_t iItem = 0; iItem < m_ObjectArray.size(); ++iItem)
+ {
+ CUIFObject *pObject = m_ObjectArray[iItem];
+ if (pObject->m_nObjectID == nObjectID)
+ return pObject;
+ }
+ return NULL;
+}
+
+inline COLORREF
+CUIFBalloonWindow::GetBalloonBkColor()
+{
+ if (m_bHasBkColor )
+ return m_rgbBkColor;
+ else
+ return ::GetSysColor(COLOR_INFOBK);
+}
+
+inline COLORREF
+CUIFBalloonWindow::GetBalloonTextColor()
+{
+ if (m_bHasTextColor)
+ return m_rgbTextColor;
+ else
+ return ::GetSysColor(COLOR_INFOTEXT);
+}
+
+inline void
+CUIFBalloonWindow::GetButtonSize(LPSIZE pSize)
+{
+ HDC hDisplayDC = ::CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
+
+ TEXTMETRIC tm;
+ HGDIOBJ hFontOld = ::SelectObject(hDisplayDC, m_hFont);
+ ::GetTextMetrics(hDisplayDC, &tm);
+ ::SelectObject(hDisplayDC, hFontOld);
+ ::DeleteDC(hDisplayDC);
+
+ pSize->cx = 16 * tm.tmAveCharWidth;
+ pSize->cy = tm.tmHeight + 10;
+}
+
+inline void
+CUIFBalloonWindow::GetMargin(LPRECT prcMargin)
+{
+ if (prcMargin)
+ *prcMargin = m_rcMargin;
+}
+
+inline void
+CUIFBalloonWindow::SetExcludeRect(LPCRECT prcExclude)
+{
+ m_rcExclude = *prcExclude;
+ AdjustPos();
+}
+
+inline void
+CUIFBalloonWindow::SetTargetPos(POINT ptTarget)
+{
+ m_ptTarget = ptTarget;
+ AdjustPos();
+}
+
+inline void
+CUIFBalloonWindow::SetText(LPCWSTR pszText)
+{
+ if (m_pszBalloonText)
+ {
+ delete[] m_pszBalloonText;
+ m_pszBalloonText = NULL;
+ }
+
+ if (pszText == NULL)
+ pszText = L"";
+
+ size_t cch = wcslen(pszText);
+ m_pszBalloonText = new(cicNoThrow) WCHAR[cch + 1];
+ if (m_pszBalloonText)
+ lstrcpynW(m_pszBalloonText, pszText, cch + 1);
+
+ AdjustPos();
+}
+
+inline void
+CUIFBalloonWindow::InitWindowRegion()
+{
+ RECT rc;
+ GetRect(&rc);
+ m_hRgn = CreateRegion(&rc);
+ if (m_hRgn)
+ ::SetWindowRgn(m_hWnd, m_hRgn, TRUE);
+}
+
+inline void
+CUIFBalloonWindow::LayoutObject()
+{
+ SIZE size;
+ GetButtonSize(&size);
+
+ RECT rc;
+ GetRect(&rc);
+
+ switch (m_nBalloonType)
+ {
+ case 1:
+ rc.top += 16;
+ break;
+ case 2:
+ rc.right -= 16;
+ break;
+ case 3:
+ rc.left += 16;
+ break;
+ default:
+ rc.bottom -= 16;
+ break;
+ }
+
+ RECT rcMargin;
+ GetMargin(&rcMargin);
+ rc.left += rcMargin.left;
+ rc.top += rcMargin.top;
+ rc.right -= rcMargin.right;
+ rc.bottom -= rcMargin.bottom;
+
+ LONG xLeft = (rc.left + rc.right - size.cx * (((m_cButtons - 1) / 2) - m_cButtons)) /
2;
+ for (UINT iButton = 0; iButton < m_cButtons; ++iButton)
+ {
+ CUIFObject *UIObject = FindUIObject(iButton);
+ if (!UIObject)
+ continue;
+
+ rcMargin.left = xLeft + iButton * (size.cx * 3 / 2);
+ rcMargin.top = rc.bottom - size.cy;
+ rcMargin.right = rcMargin.left + size.cx;
+ rcMargin.bottom = rc.bottom;
+
+ UIObject->SetRect(&rcMargin);
+ UIObject->Show(TRUE);
+ }
+}
+
+inline void
+CUIFBalloonWindow::PaintFrameProc(HDC hDC, LPCRECT prc)
+{
+ HRGN hRgn = CreateRegion(prc);
+ HBRUSH hbrBack = ::CreateSolidBrush(GetBalloonBkColor());
+ HBRUSH hbrFrame = ::CreateSolidBrush(::GetSysColor(COLOR_WINDOWFRAME));
+ ::FillRgn(hDC, hRgn, hbrBack);
+ ::FrameRgn(hDC, hRgn, hbrFrame, 1, 1);
+ ::DeleteObject(hbrBack);
+ ::DeleteObject(hbrFrame);
+ ::DeleteObject(hRgn);
+}
+
+inline void
+CUIFBalloonWindow::PaintMessageProc(HDC hDC, LPRECT prc, LPCWSTR pszText)
+{
+ HGDIOBJ hFontOld = ::SelectObject(hDC, m_hFont);
+ COLORREF rgbOldColor = ::SetTextColor(hDC, GetBalloonTextColor());
+ INT nOldBkMode = ::SetBkMode(hDC, TRANSPARENT);
+ ::DrawTextW(hDC, pszText, -1, prc, DT_WORDBREAK);
+ ::SelectObject(hDC, hFontOld);
+ ::SetTextColor(hDC, rgbOldColor);
+ ::SetBkMode(hDC, nOldBkMode);
+}
+
+inline void
+CUIFBalloonWindow::SendNotification(WPARAM wParam)
+{
+ if (m_hwndNotif)
+ ::PostMessage(m_hwndNotif, m_uNotifMsg, wParam, 0);
+}