#include #include #include "DeskBand.h" #define RECTWIDTH(x) ((x).right - (x).left) #define RECTHEIGHT(x) ((x).bottom - (x).top) extern long g_cDllRef; extern HINSTANCE g_hInst; extern CLSID CLSID_DeskBandSample; static const WCHAR g_szDeskBandSampleClass[] = L"DeskBandSampleClass"; CDeskBand::CDeskBand() : m_cRef(1), m_pSite(NULL), m_pInputObjectSite(NULL), m_fHasFocus(FALSE), m_fIsDirty(FALSE), m_dwBandID(0), m_hwnd(NULL), m_hwndParent(NULL) { InterlockedIncrement(&g_cDllRef); } CDeskBand::~CDeskBand() { if (m_pSite) { m_pSite->Release(); } if (m_pInputObjectSite) { m_pInputObjectSite->Release(); } InterlockedDecrement(&g_cDllRef); } // // IUnknown // STDMETHODIMP CDeskBand::QueryInterface(REFIID riid, void **ppv) { HRESULT hr = S_OK; if (IsEqualIID(IID_IUnknown, riid) || IsEqualIID(IID_IOleWindow, riid) || IsEqualIID(IID_IDockingWindow, riid) || IsEqualIID(IID_IDeskBand, riid) || IsEqualIID(IID_IDeskBand2, riid)) { *ppv = static_cast(this); } else if (IsEqualIID(IID_IPersist, riid) || IsEqualIID(IID_IPersistStream, riid)) { *ppv = static_cast(this); } else if (IsEqualIID(IID_IObjectWithSite, riid)) { *ppv = static_cast(this); } else if (IsEqualIID(IID_IInputObject, riid)) { *ppv = static_cast(this); } else { hr = E_NOINTERFACE; *ppv = NULL; } if (*ppv) { AddRef(); } return hr; } STDMETHODIMP_(ULONG) CDeskBand::AddRef() { return InterlockedIncrement(&m_cRef); } STDMETHODIMP_(ULONG) CDeskBand::Release() { ULONG cRef = InterlockedDecrement(&m_cRef); if (0 == cRef) { delete this; } return cRef; } // // IOleWindow // STDMETHODIMP CDeskBand::GetWindow(HWND *phwnd) { *phwnd = m_hwnd; return S_OK; } STDMETHODIMP CDeskBand::ContextSensitiveHelp(BOOL) { return E_NOTIMPL; } // // IDockingWindow // STDMETHODIMP CDeskBand::ShowDW(BOOL fShow) { if (m_hwnd) { ShowWindow(m_hwnd, fShow ? SW_SHOW : SW_HIDE); } return S_OK; } STDMETHODIMP CDeskBand::CloseDW(DWORD) { if (m_hwnd) { ShowWindow(m_hwnd, SW_HIDE); DestroyWindow(m_hwnd); m_hwnd = NULL; } return S_OK; } STDMETHODIMP CDeskBand::ResizeBorderDW(const RECT *, IUnknown *, BOOL) { return E_NOTIMPL; } // // IDeskBand // STDMETHODIMP CDeskBand::GetBandInfo(DWORD dwBandID, DWORD, DESKBANDINFO *pdbi) { HRESULT hr = E_INVALIDARG; if (pdbi) { m_dwBandID = dwBandID; if (pdbi->dwMask & DBIM_MINSIZE) { pdbi->ptMinSize.x = 200; pdbi->ptMinSize.y = 30; } if (pdbi->dwMask & DBIM_MAXSIZE) { pdbi->ptMaxSize.y = -1; } if (pdbi->dwMask & DBIM_INTEGRAL) { pdbi->ptIntegral.y = 1; } if (pdbi->dwMask & DBIM_ACTUAL) { pdbi->ptActual.x = 200; pdbi->ptActual.y = 30; } if (pdbi->dwMask & DBIM_TITLE) { // Don't show title by removing this flag. pdbi->dwMask &= ~DBIM_TITLE; } if (pdbi->dwMask & DBIM_MODEFLAGS) { pdbi->dwModeFlags = DBIMF_NORMAL | DBIMF_VARIABLEHEIGHT; } if (pdbi->dwMask & DBIM_BKCOLOR) { // Use the default background color by removing this flag. pdbi->dwMask &= ~DBIM_BKCOLOR; } hr = S_OK; } return hr; } // // IDeskBand2 // STDMETHODIMP CDeskBand::CanRenderComposited(BOOL *pfCanRenderComposited) { *pfCanRenderComposited = TRUE; return S_OK; } STDMETHODIMP CDeskBand::SetCompositionState(BOOL fCompositionEnabled) { m_fCompositionEnabled = fCompositionEnabled; InvalidateRect(m_hwnd, NULL, TRUE); UpdateWindow(m_hwnd); return S_OK; } STDMETHODIMP CDeskBand::GetCompositionState(BOOL *pfCompositionEnabled) { *pfCompositionEnabled = m_fCompositionEnabled; return S_OK; } // // IPersist // STDMETHODIMP CDeskBand::GetClassID(CLSID *pclsid) { *pclsid = CLSID_DeskBandSample; return S_OK; } // // IPersistStream // STDMETHODIMP CDeskBand::IsDirty() { return m_fIsDirty ? S_OK : S_FALSE; } STDMETHODIMP CDeskBand::Load(IStream * /*pStm*/) { return S_OK; } STDMETHODIMP CDeskBand::Save(IStream * /*pStm*/, BOOL fClearDirty) { if (fClearDirty) { m_fIsDirty = FALSE; } return S_OK; } STDMETHODIMP CDeskBand::GetSizeMax(ULARGE_INTEGER * /*pcbSize*/) { return E_NOTIMPL; } // // IObjectWithSite // STDMETHODIMP CDeskBand::SetSite(IUnknown *pUnkSite) { HRESULT hr = S_OK; m_hwndParent = NULL; if (m_pSite) { m_pSite->Release(); m_pSite = NULL; } if (m_pInputObjectSite) { m_pInputObjectSite->Release(); m_pInputObjectSite = NULL; } if (pUnkSite) { m_pSite = pUnkSite; m_pSite->AddRef(); IOleWindow *pow; hr = pUnkSite->QueryInterface(IID_IOleWindow, reinterpret_cast(&pow)); if (SUCCEEDED(hr)) { hr = pow->GetWindow(&m_hwndParent); if (SUCCEEDED(hr)) { WNDCLASSW wc = { 0 }; wc.style = CS_HREDRAW | CS_VREDRAW; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hInstance = g_hInst; wc.lpfnWndProc = WndProc; wc.lpszClassName = g_szDeskBandSampleClass; wc.hbrBackground = CreateSolidBrush(RGB(255, 255, 0)); RegisterClassW(&wc); CreateWindowExW(0, g_szDeskBandSampleClass, NULL, WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0, 0, 0, 0, m_hwndParent, NULL, g_hInst, this); if (!m_hwnd) { hr = E_FAIL; } } pow->Release(); } if (SUCCEEDED(hr)) { pUnkSite->QueryInterface(IID_PPV_ARGS(&m_pInputObjectSite)); } } return hr; } STDMETHODIMP CDeskBand::GetSite(REFIID riid, void **ppv) { HRESULT hr = E_FAIL; if (m_pSite) { hr = m_pSite->QueryInterface(riid, ppv); } else { *ppv = NULL; } return hr; } // // IInputObject // STDMETHODIMP CDeskBand::UIActivateIO(BOOL fActivate, MSG *) { if (fActivate) { SetFocus(m_hwnd); } return S_OK; } STDMETHODIMP CDeskBand::HasFocusIO() { return m_fHasFocus ? S_OK : S_FALSE; } STDMETHODIMP CDeskBand::TranslateAcceleratorIO(MSG *) { return S_FALSE; }; void CDeskBand::OnFocus(const BOOL fFocus) { m_fHasFocus = fFocus; if (m_pInputObjectSite) { m_pInputObjectSite->OnFocusChangeIS(static_cast(this), m_fHasFocus); } } void CDeskBand::OnPaint(const HDC hdcIn) { HDC hdc = hdcIn; PAINTSTRUCT ps; static WCHAR szContent[] = L"DeskBand Sample"; static WCHAR szContentGlass[] = L"DeskBand Sample (Glass)"; if (!hdc) { hdc = BeginPaint(m_hwnd, &ps); } if (hdc) { RECT rc; GetClientRect(m_hwnd, &rc); SIZE size; if (m_fCompositionEnabled) { HTHEME hTheme = OpenThemeData(NULL, L"BUTTON"); if (hTheme) { HDC hdcPaint = NULL; HPAINTBUFFER hBufferedPaint = BeginBufferedPaint(hdc, &rc, BPBF_TOPDOWNDIB, NULL, &hdcPaint); DrawThemeParentBackground(m_hwnd, hdcPaint, &rc); GetTextExtentPointW(hdc, szContentGlass, ARRAYSIZE(szContentGlass), &size); RECT rcText; rcText.left = (RECTWIDTH(rc) - size.cx) / 2; rcText.top = (RECTHEIGHT(rc) - size.cy) / 2; rcText.right = rcText.left + size.cx; rcText.bottom = rcText.top + size.cy; DTTOPTS dttOpts = {sizeof(dttOpts)}; dttOpts.dwFlags = DTT_COMPOSITED | DTT_TEXTCOLOR | DTT_GLOWSIZE; dttOpts.crText = RGB(255, 255, 0); dttOpts.iGlowSize = 10; DrawThemeTextEx(hTheme, hdcPaint, 0, 0, szContentGlass, -1, 0, &rcText, &dttOpts); EndBufferedPaint(hBufferedPaint, TRUE); CloseThemeData(hTheme); } } else { SetBkColor(hdc, RGB(255, 255, 0)); GetTextExtentPointW(hdc, szContent, ARRAYSIZE(szContent), &size); TextOutW(hdc, (RECTWIDTH(rc) - size.cx) / 2, (RECTHEIGHT(rc) - size.cy) / 2, szContent, ARRAYSIZE(szContent)); } } if (!hdcIn) { EndPaint(m_hwnd, &ps); } } LRESULT CALLBACK CDeskBand::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { LRESULT lResult = 0; CDeskBand *pDeskBand = reinterpret_cast(GetWindowLongPtr(hwnd, GWLP_USERDATA)); switch (uMsg) { case WM_CREATE: pDeskBand = reinterpret_cast(reinterpret_cast(lParam)->lpCreateParams); pDeskBand->m_hwnd = hwnd; SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast(pDeskBand)); break; case WM_SETFOCUS: pDeskBand->OnFocus(TRUE); break; case WM_KILLFOCUS: pDeskBand->OnFocus(FALSE); break; case WM_PAINT: pDeskBand->OnPaint(NULL); break; case WM_PRINTCLIENT: pDeskBand->OnPaint(reinterpret_cast(wParam)); break; case WM_ERASEBKGND: if (pDeskBand->m_fCompositionEnabled) { lResult = 1; } break; } if (uMsg != WM_ERASEBKGND) { lResult = DefWindowProc(hwnd, uMsg, wParam, lParam); } return lResult; }