152 lines
4.4 KiB
C++
152 lines
4.4 KiB
C++
// 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<CComControlBase*>(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();
|
|
}
|