您的位置:首页 > 其它

ATL复合控件更换背景图

2016-04-20 00:10 239 查看

前言

在做ATL COMDLL中的复合控件练习, 空荡荡的背景好尴尬.

试了一下,加了背景后,在复合控件UI上再放其它标准控件,不影响效果.

那就给复合控件加一张背景位图^_^

加背景位图的操作是纯SDK编码, 用到的实例句柄和窗口句柄是ATL复合控件的.

ATL编程,除了ATL框架代码外,其它都可以用SDK编程.

效果图

用控件容器插入后,能看到复合控件的背景位图.



在复合控件上添加按钮, 用MFCDialog包含。从运行效果上看,确实背景图不影响复合控件上的标准控件的显示效果.



demo

我们的ATL复合控件接管了WM_PAINT消息处理.

/// @todo 可能还需要根据位图大小重新设置一下控件大小.

// MyUserLogin.h : Declaration of the CMyUserLogin

#ifndef __MYUSERLOGIN_H_
#define __MYUSERLOGIN_H_

#define MAX_LOADSTRING 0x100

#include "resource.h"       // main symbols
#include <atlctl.h>
#include <Atlwin.h>

/////////////////////////////////////////////////////////////////////////////
// CMyUserLogin
class ATL_NO_VTABLE CMyUserLogin :
public CComObjectRootEx<CComSingleThreadModel>,
public IDispatchImpl<IMyUserLogin, &IID_IMyUserLogin, &LIBID_MYLOGINCONTROLLib>,
public CComCompositeControl<CMyUserLogin>,
public IPersistStreamInitImpl<CMyUserLogin>,
public IOleControlImpl<CMyUserLogin>,
public IOleObjectImpl<CMyUserLogin>,
public IOleInPlaceActiveObjectImpl<CMyUserLogin>,
public IViewObjectExImpl<CMyUserLogin>,
public IOleInPlaceObjectWindowlessImpl<CMyUserLogin>,
public IConnectionPointContainerImpl<CMyUserLogin>,
public IPersistStorageImpl<CMyUserLogin>,
public ISpecifyPropertyPagesImpl<CMyUserLogin>,
public IQuickActivateImpl<CMyUserLogin>,
public IDataObjectImpl<CMyUserLogin>,
public IProvideClassInfo2Impl<&CLSID_MyUserLogin, &DIID__IMyUserLoginEvents, &LIBID_MYLOGINCONTROLLib>,
public IPropertyNotifySinkCP<CMyUserLogin>,
public CComCoClass<CMyUserLogin, &CLSID_MyUserLogin>
{
public:
CMyUserLogin()
{
m_bWindowOnly = TRUE;
CalcExtent(m_sizeExtent);

m_BgBmp_lWidth = 435;
m_BgBmp_lHeight = 337;
}

DECLARE_REGISTRY_RESOURCEID(IDR_MYUSERLOGIN)

DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CMyUserLogin)
COM_INTERFACE_ENTRY(IMyUserLogin)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IViewObjectEx)
COM_INTERFACE_ENTRY(IViewObject2)
COM_INTERFACE_ENTRY(IViewObject)
COM_INTERFACE_ENTRY(IOleInPlaceObjectWindowless)
COM_INTERFACE_ENTRY(IOleInPlaceObject)
COM_INTERFACE_ENTRY2(IOleWindow, IOleInPlaceObjectWindowless)
COM_INTERFACE_ENTRY(IOleInPlaceActiveObject)
COM_INTERFACE_ENTRY(IOleControl)
COM_INTERFACE_ENTRY(IOleObject)
COM_INTERFACE_ENTRY(IPersistStreamInit)
COM_INTERFACE_ENTRY2(IPersist, IPersistStreamInit)
COM_INTERFACE_ENTRY(IConnectionPointContainer)
COM_INTERFACE_ENTRY(ISpecifyPropertyPages)
COM_INTERFACE_ENTRY(IQuickActivate)
COM_INTERFACE_ENTRY(IPersistStorage)
COM_INTERFACE_ENTRY(IDataObject)
COM_INTERFACE_ENTRY(IProvideClassInfo)
COM_INTERFACE_ENTRY(IProvideClassInfo2)
END_COM_MAP()

BEGIN_PROP_MAP(CMyUserLogin)
PROP_DATA_ENTRY("_cx", m_sizeExtent.cx, VT_UI4)
PROP_DATA_ENTRY("_cy", m_sizeExtent.cy, VT_UI4)
// Example entries
// PROP_ENTRY("Property Description", dispid, clsid)
// PROP_PAGE(CLSID_StockColorPage)
END_PROP_MAP()

BEGIN_CONNECTION_POINT_MAP(CMyUserLogin)
CONNECTION_POINT_ENTRY(IID_IPropertyNotifySink)
END_CONNECTION_POINT_MAP()

BEGIN_MSG_MAP(CMyUserLogin)
CHAIN_MSG_MAP(CComCompositeControl<CMyUserLogin>)
MESSAGE_HANDLER(WM_DRAWITEM, OnDrawItem)
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
MESSAGE_HANDLER(WM_PAINT, OnPaint)
MESSAGE_HANDLER(WM_SIZE, OnSize)
END_MSG_MAP()
// Handler prototypes:
//  LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
//  LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
//  LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);

BEGIN_SINK_MAP(CMyUserLogin)
//Make sure the Event Handlers have __stdcall calling convention
END_SINK_MAP()

STDMETHOD(OnAmbientPropertyChange)(DISPID dispid)
{
if (dispid == DISPID_AMBIENT_BACKCOLOR)
{
SetBackgroundColorFromAmbient();
FireViewChange();
}
return IOleControlImpl<CMyUserLogin>::OnAmbientPropertyChange(dispid);
}

// IViewObjectEx
DECLARE_VIEW_STATUS(0)

// IMyUserLogin
public:
STDMETHOD(GetBgBmpRect)(/*[out]*/long* lWidth, /*[out]*/long* lHeight);

enum { IDD = IDD_MYUSERLOGIN };
LRESULT OnDrawItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
// TODO : Add Code for message handler. Call DefWindowProc if necessary.
return 0;
}
LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
// TODO : Add Code for message handler. Call DefWindowProc if necessary.
return 0;
}
LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
// TODO : Add Code for message handler. Call DefWindowProc if necessary.
CWindow myWindow;
PAINTSTRUCT ps;
HDC hDC = NULL;
HDC hCompatibleDC = NULL;
HBITMAP hBitmap = NULL;
HGDIOBJ hOldGdi = NULL;
RECT rt;

myWindow.Attach(m_hWnd);
hDC = myWindow.BeginPaint(&ps);
//Use the hDC as much as you want

hCompatibleDC = ::CreateCompatibleDC(hDC);
hBitmap = ::LoadBitmap(_Module.m_hInst, MAKEINTRESOURCE(IDB_BITMAP_BG));
hOldGdi = ::SelectObject(hCompatibleDC, hBitmap);

GetClientRect(&rt);
::BitBlt(hDC, 0, 0, rt.right - rt.left, rt.bottom - rt.top, hCompatibleDC, 0, 0, SRCCOPY);

::SelectObject(hCompatibleDC, hOldGdi);
DeleteObject(hBitmap);
myWindow.EndPaint(&ps);

return 0;
}
LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
// TODO : Add Code for message handler. Call DefWindowProc if necessary.
return 0;
}

private:
/// 背景位图size
long m_BgBmp_lWidth;
long m_BgBmp_lHeight;
};

#endif //__MYUSERLOGIN_H_
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: