// IconCtrl.cpp : Implementation of CIconControl #include "stdafx.h" #include "ndmgr.h" #include "IconControl.h" #include "findview.h" #include "util.h" ///////////////////////////////////////////////////////////////////////////// // CIconControl const CLSID CLSID_IconControl = {0xB0395DA5, 0x06A15, 0x4E44, {0x9F, 0x36, 0x9A, 0x9D, 0xC7, 0xA2, 0xF3, 0x41}}; //+------------------------------------------------------------------- // // Member: CIconControl::ScConnectToAMCViewForImageInfo // // Synopsis: Find the CAMCView that hosts this control and ask // for the icon information. // // Arguments: // // Returns: SC // //-------------------------------------------------------------------- SC CIconControl::ScConnectToAMCViewForImageInfo () { DECLARE_SC(sc, _T("CIconControl::ScGetAMCView")); HWND hWnd = FindMMCView((*dynamic_cast(this))); if (!hWnd) return (sc = E_FAIL); // check if we need the notch on the right side m_fLayoutRTL = (::GetWindowLong(hWnd, GWL_EXSTYLE) & WS_EX_LAYOUTRTL); m_fAskedForImageInfo = true; sc = SendMessage(hWnd, MMC_MSG_GET_ICON_INFO, (WPARAM)&m_hIcon, 0); if (!m_hIcon) return (sc = E_FAIL); m_fImageInfoValid = true; return (sc); } //+------------------------------------------------------------------- // // Member: CIconControl::OnDraw // // Synopsis: Called by the host to draw. // // Arguments: // // Returns: HRESULT // //-------------------------------------------------------------------- HRESULT CIconControl::OnDraw(ATL_DRAWINFO& di) { DECLARE_SC(sc, _T("CIconControl::OnDraw")); RECT& rc = *(RECT*)di.prcBounds; // If never got the icon, ask CAMCView. if (!m_fAskedForImageInfo) { sc = ScConnectToAMCViewForImageInfo(); if (sc) return sc.ToHr(); } // Our attempt to get icon failed, so just return. if (!m_fImageInfoValid) { sc.TraceAndClear(); return sc.ToHr(); } // Draw the outline. Looks like: // xxxxxxxxxxxxxxxxxxxxxx // x x // x x // x xx // x x // xxxxxxxxxxxxxxxxxxxx <------- "Notch" // color the complete area COLORREF bgColor = GetSysColor(COLOR_ACTIVECAPTION); WTL::CBrush brush; brush.CreateSolidBrush(bgColor); // background brush WTL::CDC dc(di.hdcDraw); // clear the DC dc.FillRect(&rc, brush); if(m_bDisplayNotch) //Draw the notch if needed { WTL::CRgn rgn; int roundHeight = 10; // hack // clear out a quarter circle int left = (m_fLayoutRTL==false ? rc.right : rc.left) - roundHeight; int right = (m_fLayoutRTL==false ? rc.right : rc.left) + roundHeight; int bottom= rc.bottom + roundHeight; int top = rc.bottom - roundHeight; rgn.CreateRoundRectRgn(left, top, right, bottom, roundHeight*2, roundHeight*2); { COLORREF bgColor = GetSysColor(COLOR_WINDOW); WTL::CBrush brush; brush.CreateSolidBrush(bgColor); // background brush dc.FillRgn(rgn, brush); } } dc.Detach(); // release the DC before exiting!! const int LEFT_MARGIN = 10; const int TOP_MARGIN = 5; POINT ptIconPos = { (m_fLayoutRTL==false ? rc.left + LEFT_MARGIN : rc.right - LEFT_MARGIN -1 ), rc.top + TOP_MARGIN }; // if we are on rtl mode - need to make dc behave that way as well // For a time we draw an icon ( to appear in place and be flipped correctly ) // (IE does not have RTL dc by default) DWORD dwLayout=0L; if ( m_fLayoutRTL && !( (dwLayout=GetLayout(di.hdcDraw)) & LAYOUT_RTL) ) { LPtoDP( di.hdcDraw, &ptIconPos, 1/*nPoint*/); SetLayout(di.hdcDraw, dwLayout|LAYOUT_RTL); DPtoLP( di.hdcDraw, &ptIconPos, 1/*nPoint*/); } if (! DrawIconEx(di.hdcDraw, ptIconPos.x, ptIconPos.y, m_hIcon, 0, 0, 0, NULL, DI_NORMAL)) { sc.FromLastError(); sc.TraceAndClear(); return sc.ToHr(); } // Restore the DC to its previous layout state. if ( m_fLayoutRTL && !( dwLayout & LAYOUT_RTL ) ) { SetLayout(di.hdcDraw, dwLayout); } return sc.ToHr(); }