Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

151 lines
4.2 KiB

// 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();
}