本文列出Desk Band的具体实现细节与代码。
我这个Desk Band都是用SDK直接实现,没有用ATL来实现,用ATL也是可以的。用SDK可能麻烦一点。
SdkDeskBandObject.h文件
说明:SdkDeskBandObject这个类定义了Band对象的接口。
#ifdef __cplusplus
#ifndef _SDKDESKBANDDEF_H_
#define _SDKDESKBANDDEF_H_
#include "SdkCommonHelper.h"
#include "IDeskBandWindow.h"
class SdkDeskBandObject : public IDeskBand2,
public IPersistStream,
public IInputObject,
public IObjectWithSite
{
public:
SdkDeskBandObject(void);
// IUnknown
STDMETHODIMP QueryInterface(REFIID riid, void** ppv);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();
// IOleWindow
STDMETHODIMP GetWindow(HWND *phwnd);
STDMETHODIMP ContextSensitiveHelp(BOOL fEnterMode);
// IDockingWindow
STDMETHODIMP ShowDW(BOOL fShow);
STDMETHODIMP CloseDW(DWORD dwReserved);
STDMETHODIMP ResizeBorderDW(LPCRECT prcBorder, IUnknown *punkToolbarSite, BOOL fReserved);
// IDeskBand (needed for all desk bands)
STDMETHODIMP GetBandInfo(DWORD dwBandID, DWORD dwViewMode, DESKBANDINFO *pdbi);
// IDeskBand2 (needed for glass desk band)
STDMETHODIMP CanRenderComposited(BOOL *pfCanRenderComposited);
STDMETHODIMP SetCompositionState(BOOL fCompositionEnabled);
STDMETHODIMP GetCompositionState(BOOL *pfCompositionEnabled);
// IPersist
STDMETHODIMP GetClassID(CLSID *pclsid);
// IPersistStream
STDMETHODIMP IsDirty();
STDMETHODIMP Load(IStream *pStm);
STDMETHODIMP Save(IStream *pStm, BOOL fClearDirty);
STDMETHODIMP GetSizeMax(ULARGE_INTEGER *pcbSize);
// IObjectWithSite
STDMETHODIMP SetSite(IUnknown *pUnkSite);
STDMETHODIMP GetSite(REFIID riid, void **ppv);
// IInputObject
STDMETHODIMP UIActivateIO(BOOL fActivate, MSG *pMsg);
STDMETHODIMP HasFocusIO();
STDMETHODIMP TranslateAcceleratorIO(MSG *pMsg);
BOOL OnSetFocus(BOOL fSetFocus);
BOOL IsVerticalViewMode();
protected:
~SdkDeskBandObject(void);
private:
BOOL m_fHasFocus; // Whether desk band has focus
BOOL m_fIsDirty; // Whether desk band setting has changed
BOOL m_fCompositionEnabled; // Whether glass is currently enabled in desk band
DWORD m_dwViewMode; // The view mode of the band object
DWORD m_dwBandID; // The ID of desk band
volatile LONG m_lRefCount; // The reference count of CDeskBandObject
IDeskBandWindow *m_pDeskBandWin; // The desk band window object
IInputObjectSite *m_pInputObjSite; // Parent site that contains desk band
};
#endif // _SDKDESKBANDDEF_H_
#endif // __cplusplus
注意:CDeskBandOjbect依赖于IDeskBandWindow(定义请参见下面)这个接口去管理窗体,包括创建,显示或隐藏,关闭等操作。这个接口的实现从哪里来呢?可以再实现一个类似于类工厂的类,创建一个IDeskBandWindow接口类型的指针,所有的初始化操作都放在类工厂中去做。这样做的好处是CDeskBandOjbect不依赖于具体类。
SdkClassFactory.h文件
说明:这个类实现了IClassFactory接口,CreateInstance会创建出SdkDeskBandObject对象。
#ifdef __cplusplus
#ifndef _CLASSFACTORY_H_
#define _CLASSFACTORY_H_
#include "SdkCommonHelper.h"
class SdkClassFactory : public IClassFactory
{
public:
SdkClassFactory(void);
来源:(http://blog.sina.com.cn/s/blog_5f8817250100hqw2.html) - DeskBand 实现2(实现声明)_LeeHong_新浪博客
STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();
// IClassFactory
STDMETHODIMP CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppv);
STDMETHODIMP LockServer(BOOL fLock);
protected:
~SdkClassFactory(void);
private:
volatile LONG m_lRefCount; // The reference count of current class.
};
#endif // _CLASSFACTORY_H_
#endif //__cplusplus
IDeskBandWIndow.h文件
说明:这是一个接口,定义了一系列实现一个窗体的接口,这样,BAND对象依赖于这个接口,而不依赖于具体实现类。
#ifdef __cplusplus
#ifndef _IDESKBANDWINDOW_H_
#define _IDESKBANDWINDOW_H_
#include "SdkCommon.h"
class IDeskBandWindow
{
public:
virtual BOOL CreateDeskBand(HWND hParentWnd, HINSTANCE hInstance, LPVOID pData) = 0;
virtual BOOL ShowDeskBand(BOOL fShowOrHide = TRUE) = 0;
virtual void CloseDeskBand() = 0;
virtual HWND GetDeskBandHandle() = 0;
virtual SIZE GetDeskBandMinSize(BOOL fNormalViewMode = TRUE) = 0;
virtual void RefreshDeskBand() = 0;
};
#endif // _IDESKBANDWINDOW_H_
#endif // __cplusplus
SdkDeskBandDef.h文件
说明:这个文件定义了DeskBand共通的常量
#ifdef __cplusplus
#ifndef _SDKDESKBANDDEF_H_
#define _SDKDESKBANDDEF_H_
#include <Windows.h>
//
//
// The global variables
//
#ifdef _DEFINE_GLOBAL_VARIABLES
HINSTANCE g_hDllInst = NULL; // A handle to the DLL module. The value is the base address of the Dll.
LONG g_lDllRefCount = 1; // The reference count of the Dll.
#else
extern HINSTANCE g_hDllInst; // A handle to the DLL module. The value is the base address of the Dll.
extern LONG g_lDllRefCount; // The reference count of the Dll.
#endif // _DEFINE_GLOBAL_VARIABLES
//
//
// The constant variable
//
// {DAF82547-D986-4f30-AF80-24CC3577D6EB}
const CLSID CLSID_SdkDeskBand = { 0xdaf82547, 0xd986, 0x4f30, { 0xaf, 0x80, 0x24, 0xcc, 0x35, 0x77, 0xd6, 0xeb } };
#endif // _SDKDESKBANDDEF_H_
#endif // __cplusplus
未完待续,下一篇我将给出一些具体实现细节和代码。