Windows区对象(Bands)的创建与定制
2009-11-11 20:32:13 来源:WEB开发网IInputObject接口
如果某个band对象要接受用户输入。那就必须实现IInputObject接口。IE实现IInputObjectSite并用IInputObject维护用户的输入焦点。浏览栏需要实现三个方法:UIActivateIO, HasFocusIO, 和 TranslateAcceleratorIO。
IE调用UIActivateIO通知浏览栏它以被激活或者被置灰。当被激活时,浏览栏例子调用SetFocus来设置窗口输入焦点。
当要确定哪个窗口有输入焦点时,IE调用HasFocusIO。如果浏览栏的窗口或它的子窗口之一有输入焦点,HasFocusIO返回S_OK。否则,它返回S_FALSE。
TranslateAcceleratorIO允许对象处理键盘加速键。本文浏览栏例子没有实现这个方法,所以它返回S_FALSE。
浏览栏例子实现IInputObjectSite的细节如下:
STDMETHODIMP CExplorerBar::UIActivateIO(BOOL fActivate, LPMSG pMsg)
窗口过程
{
if(fActivate)
SetFocus(m_hWnd);
return S_OK;
}
STDMETHODIMP CExplorerBar::HasFocusIO(void)
{
if(m_bFocus)
return S_OK;
return S_FALSE;
}
STDMETHODIMP CExplorerBar::TranslateAcceleratorIO(LPMSG pMsg)
{
return S_FALSE;
}
因为区对象的显示用的是子窗口,所以它必须实现窗口过程来处理Windows消息。浏览栏例子实现了一个最简单的版本,它的窗口过程只处理了五个消息:WM_NCCREATE, WM_PAINT, WM_COMMAND, WM_SETFOCUS, 和 WM_KILLFOCUS。如果要实现更多的功能,很容易扩充使它处理其它的消息。
LRESULT CALLBACK CExplorerBar::WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
这里WM_COMMAND消息处理器简单地返回零。WM_PAINT消息处理器创建文本并显示在资源管理器或IE的区对象中。
{
CExplorerBar *pThis = (CExplorerBar*)GetWindowLong(hWnd, GWL_USERDATA);
switch (uMessage)
{
case WM_NCCREATE:
{
LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam;
pThis = (CExplorerBar*)(lpcs->lpCreateParams);
SetWindowLong(hWnd, GWL_USERDATA, (LONG)pThis);
//设置窗口句柄
pThis->m_hWnd = hWnd;
}
break;
case WM_PAINT:
return pThis->OnPaint();
case WM_COMMAND:
return pThis->OnCommand(wParam, lParam);
case WM_SETFOCUS:
return pThis->OnSetFocus();
case WM_KILLFOCUS:
return pThis->OnKillFocus();
}
return DefWindowProc(hWnd, uMessage, wParam, lParam);
}
LRESULT CExplorerBar::OnPaint(void)
WM_SETFOCUS 和 WM_KILLFOCUS消息处理器通过调用本现场的IInputObjectSite::OnFocusChangeIS方法通知输入焦点现场改变:
{
PAINTSTRUCT ps;
RECT rc;
BeginPaint(m_hWnd, &ps);
GetClientRect(m_hWnd, &rc);
SetTextColor(ps.hdc, RGB(255, 255, 255));
SetBkMode(ps.hdc, TRANSPARENT);
DrawText(ps.hdc, TEXT("浏览栏例子"), -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint(m_hWnd, &ps);
return 0;
}
LRESULT CExplorerBar::OnSetFocus(void)
四、总结
{
FocusChange(TRUE);
return 0;
}
LRESULT CExplorerBar::OnKillFocus(void)
{
FocusChange(FALSE);
return 0;
}
void CExplorerBar::FocusChange(BOOL bFocus)
{
m_bFocus = bFocus;
//通知焦点已改变的输入对象现场
if(m_pSite)
{
m_pSite->OnFocusChangeIS((IDockingWindow*)this, bFocus);
}
}
区对象提供了灵活和强大的扩展方式,通过定制浏览栏使得IE的功能大为增强。桌面区的实现扩展了普通窗口的能力。尽管需要一些对COM的编程,但终究以子窗口的形式提供了一种用户界面。从而使今后的许多这种编程实现都能用类似的Windows编程技术。虽然本文所讨论的例子只提供了有限的功能,但它示范了区对象全部的特性,并且可以在此基础上进行扩充来创建独特和功能强大的的用户界面。
更多精彩
赞助商链接