WEB开发网
开发学院软件开发VC Windows区对象(Bands)的创建与定制 阅读

Windows区对象(Bands)的创建与定制

 2009-11-11 20:32:13 来源:WEB开发网   
核心提示:必须实现的接口垂直浏览栏例子实现了四个必须的接口:IUnknown, IObjectWithSite, IPersistStream, 和IDeskBand,它们都在CExplorerBar类中实现,Windows区对象(Bands)的创建与定制(5),IUnknown构造函数,析构函数和IUnknown实现比较简单,

必须实现的接口

垂直浏览栏例子实现了四个必须的接口:IUnknown, IObjectWithSite, IPersistStream, 和IDeskBand,它们都在CExplorerBar类中实现。

IUnknown

构造函数,析构函数和IUnknown实现比较简单,本文在此不讨论。细节请参见源代码。

IObjectWithSite接口

当用户选择某个浏览栏时,容器调用相应band对象的IObjectWithSite::SetSite方法。参数将被设置成这个现场(Site)的IUnknown指针。

通常,SetSite实现应该完成下列步骤:

释放当前所把持的任何现场指针。

如果传递到SetSite的指针被置为NULL,此则区对象被删除。SetSite可以返回S_OK。

如果传递到SetSite的指针被置为非NULL,则建立新的现场。SetSite应该做以下的事情:

调用现场QueryInterface方法请求IOleWindow接口。

调用IOleWindow::GetWindow获取父窗口句柄,并存储它,以便以后使用。如果不再使用的话,就释放IOleWindow接口。

创建此band对象的窗口为一个子窗口,其父窗口就是上一步获得的那个窗口。注意在此不能将它创建成可见窗口。

如果此band对象实现IInputObject,调用现场QueryInterface方法请求IInputObjectSite接口,存储这个接口的指针以备后用。

如果所有步骤都成功,则返回S_OK,否则返回OLE定义的错误代码以指示错误类型。

以下是浏览栏实现SetSite的方法。m_pSite是私有成员变量,用它来保存IInputObjectSite指针,而m_hwndParent保存父窗口句柄。

STDMETHODIMP CExplorerBar::SetSite(IUnknown* punkSite)
{
//如果某个现场被把持,则释放它
if(m_pSite)
{
m_pSite->Release();
m_pSite = NULL;
}
//如果punkSite 不为NULL, 建立一个新的现场
if(punkSite)
{
//获取父窗口
IOleWindow *pOleWindow;
m_hwndParent = NULL;

if(SUCCEEDED(punkSite->QueryInterface(IID_IOleWindow, (LPVOID*)&pOleWindow)))
{
pOleWindow->GetWindow(&m_hwndParent);
pOleWindow->Release();
}
if(!m_hwndParent)
return E_FAIL;
if(!RegisterAndCreateWindow())
return E_FAIL;
//获取柄保存IInputObjectSite指针
if(SUCCEEDED(punkSite->QueryInterface(IID_IInputObjectSite, (LPVOID*)&m_pSite)))
{
return S_OK;
} 
return E_FAIL;
}
return S_OK;
}
这个例子的GetSite只简单地用SetSite保存的现场指针实现了对现场QueryInterface方法的调用。

STDMETHODIMP CExplorerBar::GetSite(REFIID riid, LPVOID *ppvReturn)
{
*ppvReturn = NULL;
if(m_pSite)
return m_pSite->QueryInterface(riid, ppvReturn);
return E_FAIL;
}
窗口创建由私有方法RegisterAndCreateWindow负责。如果这个窗口不存在,此方法将浏览栏窗口创建成一个大小适当的子窗口,它的父窗口就是由SetSite获得的那个窗口。子窗口的句柄存储在m_hwnd变量中。

BOOL CExplorerBar::RegisterAndCreateWindow(void)
{
//如果这个窗口不存在,则创建它
if(!m_hWnd)
{
//子窗口不能没有父窗口
if(!m_hwndParent)
{
return FALSE;
}
//如果窗口类没有注册,则必须注册
WNDCLASS wc;
if(!GetClassInfo(g_hInst, EB_CLASS_NAME, &wc))
{
ZeroMemory(&wc, sizeof(wc));
wc.style     = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
wc.lpfnWndProc  = (WNDPROC)WndProc;
wc.cbClsExtra   = 0;
wc.cbWndExtra   = 0;
wc.hInstance   = g_hInst;
wc.hIcon     = NULL;
wc.hCursor    = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(0, 0, 192));
wc.lpszMenuName  = NULL;
wc.lpszClassName = EB_CLASS_NAME;

if(!RegisterClass(&wc))
{
//如果注册失败,下面的CreateWindow函数将失败
}
}
RECT rc;
GetClientRect(m_hwndParent, &rc);
//创建这个窗口。WndProc 将建立m_hWnd变量
CreateWindowEx(  0,
EB_CLASS_NAME,
NULL,
WS_CHILD | WS_CLIPSIBLINGS | WS_BORDER,
rc.left,
rc.top,
rc.right - rc.left,
rc.bottom - rc.top,
m_hwndParent,
NULL,
g_hInst,
(LPVOID)this);

}
return (NULL != m_hWnd);
}
IPersistStream接口

IE将调用浏览栏的IPersistStream接口,以便允许这个浏览栏加载或存储持久性数据。如果没有持久性数据,这个方法仍然必须返回一个成功代码。IPersistStream接口从IPersist继承而来,所以要实现五个方法:

GetClassID, IsDirty, Load, Save, GetSizeMax。

本文的这个浏览栏例子不使用持久性数据,并且只有IPersistStream的最小实现。GetClassID返回对象的CLSID(CLSID_SampleExplorerBar),其余的方法返回S_OK, 或者S_FALSE, 或者 E_NOTIMPL。有关细节请参见IPersistStream的实现。

上一页  1 2 3 4 5 6 7  下一页

Tags:Windows 对象 Bands

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接