|
|
// DeviceIcon.cpp : Implementation of CDeviceIcon
#include "stdafx.h"
#include "DevCon2.h"
#include "DeviceIcon.h"
#include "Device.h"
#include "SetupClass.h"
/////////////////////////////////////////////////////////////////////////////
// CDeviceIcon
//
// SetupDiLoadClassIcon(guid,&hIcon,&miniicon)
// SetupDiDrawMiniIcon(....)
//
void CDeviceIcon::ResetIcon() { if(m_hIcon) { DestroyIcon(m_hIcon); m_hIcon = NULL; } if(m_hSmallImage) { DeleteObject(m_hSmallImage); m_hSmallImage = NULL; } if(m_hSmallMask) { DeleteObject(m_hSmallMask); m_hSmallMask = NULL; } }
HRESULT CDeviceIcon::OnDraw(ATL_DRAWINFO& di) { if(!m_hIcon) { return S_OK; } RECT rect = *(RECT*)di.prcBounds; int asp_x; int asp_y; int asp; asp_x = rect.right-rect.left; asp_y = rect.bottom-rect.top; asp = min(asp_x,asp_y); if(asp>=32) { asp = 32; } else { asp = 16; } rect.left += (asp_x-asp)/2; rect.top += (asp_y-asp)/2; rect.right = rect.left+asp; rect.bottom = rect.top+asp;
if(asp == 16) { //
// draw mini-icon
// this is complex because of the way SetupDiDrawMiniIcon works
// and we want this to be like a real icon when placed on a web page
//
DrawMiniIcon(di.hdcDraw,rect,m_MiniIcon); } else { //
// draw regular icon
//
DrawIcon(di.hdcDraw,rect.left,rect.top,m_hIcon); }
return S_OK; }
BOOL CDeviceIcon::DrawMiniIcon(HDC hDC, RECT &rect,INT icon) { HBITMAP hbmOld; HDC hdcMem;
hdcMem = CreateCompatibleDC(hDC); if(!hdcMem) { return FALSE; } if(!(m_hSmallImage && m_hSmallMask)) { //
// create bitmaps (once)
//
if(!m_hSmallImage) { m_hSmallImage = CreateCompatibleBitmap(hDC,rect.right-rect.left,rect.bottom-rect.top); if(!m_hSmallImage) { DeleteDC(hdcMem); return FALSE; } } if(!m_hSmallMask) { m_hSmallMask = CreateBitmap(rect.right-rect.left,rect.bottom-rect.top,1,1,NULL); if(!m_hSmallMask) { DeleteDC(hdcMem); return FALSE; } } //
// obtain the bitmap data (once)
//
RECT memRect; memRect.left = memRect.top = 0; memRect.right = rect.right-rect.left; memRect.bottom = rect.bottom-rect.top; //
// mask first
//
hbmOld = (HBITMAP)SelectObject(hdcMem,m_hSmallMask); SetupDiDrawMiniIcon(hdcMem,memRect,icon,DMI_USERECT|DMI_MASK); //
// now source
//
SelectObject(hdcMem,m_hSmallImage); SetupDiDrawMiniIcon(hdcMem,memRect,icon,DMI_USERECT); } else { //
// select source
//
hbmOld = (HBITMAP)SelectObject(hdcMem,m_hSmallImage); }
//
// now blt image via mask
//
if(GetDeviceCaps(hDC,RASTERCAPS)&RC_BITBLT) { //
// draw icon using mask
//
MaskBlt(hDC, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, hdcMem, 0, 0, m_hSmallMask, 0, 0, MAKEROP4(0xAA0029,SRCCOPY) // 0xAA0029 (from MSDN) = transparent
); } SelectObject(hdcMem,hbmOld); DeleteDC(hdcMem);
return TRUE; }
STDMETHODIMP CDeviceIcon::ObtainIcon(LPDISPATCH pSource) { HRESULT hr; CComQIPtr<IDeviceInternal> pDevice; CComQIPtr<ISetupClassInternal> pSetupClass; BSTR pMachine = NULL; GUID cls; HICON hIcon; INT miniIcon;
if(!pSource) { ResetIcon(); return S_OK; } pSetupClass = pSource; pDevice = pSource; if(pSetupClass) { //
// obtain icon for specified device/class
// based on devices class
//
hr = pSetupClass->get__Machine(&pMachine); if(FAILED(hr)) { pMachine = NULL; } else { hr = pSetupClass->get__ClassGuid(&cls); } if(FAILED(hr)) { cls = GUID_DEVCLASS_UNKNOWN; }
//
// obtain icon
//
if(!SetupDiLoadClassIcon(&cls,&hIcon,&miniIcon)) { cls = GUID_DEVCLASS_UNKNOWN; if(!SetupDiLoadClassIcon(&cls,&hIcon,&miniIcon)) { DWORD err = GetLastError(); SysFreeString(pMachine); return HRESULT_FROM_SETUPAPI(err); } } ResetIcon(); m_hIcon = hIcon; m_MiniIcon = miniIcon; FireViewChange(); if(pMachine) { SysFreeString(pMachine); } return S_OK;
} else { return E_INVALIDARG; } }
|