Вот. Написал я плагин, вот код класса ExplorerBar:
extern DWORD server_ref_count;
extern HINSTANCE g_hInst;
ExplorerBar::ExplorerBar()
{
m_pSite = NULL;
m_hWnd = NULL;
m_hwndParent = NULL;
m_bFocus = FALSE;
m_dwViewMode = 0;
m_dwBandID = 0;
obj_ref_count = 1;
server_ref_count++;
}
ExplorerBar::~ExplorerBar()
{
if(m_pSite)
{
m_pSite->Release();
m_pSite = NULL;
}
server_ref_count--;
}
//Методы IUnknown
STDMETHODIMP ExplorerBar::QueryInterface(REFIID riid, LPVOID *ppReturn)
{
*ppReturn = NULL;
if(IsEqualIID(riid, IID_IUnknown))
{
*ppReturn = this;
}
else
if(IsEqualIID(riid, IID_IOleWindow))
{
*ppReturn = (IOleWindow*)this;
}
else
if(IsEqualIID(riid, IID_IDockingWindow))
{
*ppReturn = (IDockingWindow*)this;
}
else
if(IsEqualIID(riid, IID_IInputObject))
{
*ppReturn = (IInputObject*)this;
}
else
if(IsEqualIID(riid, IID_IObjectWithSite))
{
*ppReturn = (IObjectWithSite*)this;
}
else
if(IsEqualIID(riid, IID_IDeskBand))
{
*ppReturn = (IDeskBand*)this;
}
else
if(IsEqualIID(riid, IID_IPersist))
{
*ppReturn = (IPersist*)this;
}
else
if(IsEqualIID(riid, IID_IPersistStream))
{
*ppReturn = (IPersistStream*)this;
}
if(*ppReturn)
{
(*(LPUNKNOWN*)ppReturn)->AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
STDMETHODIMP_(DWORD) ExplorerBar::AddRef()
{
return ++obj_ref_count;
}
STDMETHODIMP_(DWORD) ExplorerBar::Release()
{
if(--obj_ref_count == 0)
{
delete this;
return 0;
}
return obj_ref_count;
}
//Методы IOleWindow
STDMETHODIMP ExplorerBar::GetWindow(HWND *phWnd)
{
*phWnd = m_hWnd;
return S_OK;
}
STDMETHODIMP ExplorerBar::ContextSensitiveHelp(BOOL fEnterMode)
{
return E_NOTIMPL;
}
//Методы IDockingWindow
STDMETHODIMP ExplorerBar::ShowDW(BOOL fShow)
{
if(m_hWnd)
{
if(fShow)
{
ShowWindow(m_hWnd, SW_SHOW);
}
else
{
ShowWindow(m_hWnd, SW_HIDE);
}
}
return S_OK;
}
STDMETHODIMP ExplorerBar::CloseDW(DWORD dwReserved)
{
ShowDW(FALSE);
if(IsWindow(m_hWnd))
DestroyWindow(m_hWnd);
m_hWnd = NULL;
return S_OK;
}
STDMETHODIMP ExplorerBar::ResizeBorderDW(LPCRECT prcBorder,
IUnknown* punkSite,
BOOL fReserved)
{
return E_NOTIMPL;
}
//Методы IInputObject
STDMETHODIMP ExplorerBar::UIActivateIO(BOOL fActivate, LPMSG pMsg)
{
if(fActivate)
SetFocus(m_hWnd);
return S_OK;
}
STDMETHODIMP ExplorerBar::HasFocusIO(void)
{
if(m_bFocus)
return S_OK;
return S_FALSE;
}
STDMETHODIMP ExplorerBar::TranslateAcceleratorIO(LPMSG pMsg)
{
return S_FALSE;
}
//Методы IObjectWithSite
STDMETHODIMP ExplorerBar::SetSite(IUnknown* punkSite)
{
if(m_pSite)
{
m_pSite->Release();
m_pSite = 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;
if(SUCCEEDED(punkSite->QueryInterface(IID_IInputObjectSite,
(LPVOID*)&m_pSite)))
{
return S_OK;
}
return E_FAIL;
}
return S_OK;
}
STDMETHODIMP ExplorerBar::GetSite(REFIID riid, LPVOID *ppvReturn)
{
*ppvReturn = NULL;
if(m_pSite)
return m_pSite->QueryInterface(riid, ppvReturn);
return E_FAIL;
}
//Методы IDeskBand
STDMETHODIMP ExplorerBar::GetBandInfo(DWORD dwBandID,
DWORD dwViewMode,
DESKBANDINFO* pdbi)
{
if(pdbi)
{
m_dwBandID = dwBandID;
m_dwViewMode = dwViewMode;
if(pdbi->dwMask & DBIM_MINSIZE)
{
pdbi->ptMinSize.x = MIN_SIZE_X;
pdbi->ptMinSize.y = MIN_SIZE_Y;
}
if(pdbi->dwMask & DBIM_MAXSIZE)
{
pdbi->ptMaxSize.x = MAX_SIZE_X;
pdbi->ptMaxSize.y = MAX_SIZE_Y;
}
if(pdbi->dwMask & DBIM_INTEGRAL)
{
pdbi->ptIntegral.x = 1;
pdbi->ptIntegral.y = 1;
}
if(pdbi->dwMask & DBIM_ACTUAL)
{
pdbi->ptActual.x = 0;
pdbi->ptActual.y = 0;
}
if(pdbi->dwMask & DBIM_TITLE)
{
StringCchCopyW(pdbi->wszTitle, 256, L"BelWebs Explorer Bar");
}
if(pdbi->dwMask & DBIM_MODEFLAGS)
{
pdbi->dwModeFlags = DBIMF_VARIABLEHEIGHT;
}
if(pdbi->dwMask & DBIM_BKCOLOR)
{
pdbi->dwMask &= ~DBIM_BKCOLOR;
}
return S_OK;
}
return E_INVALIDARG;
}
//Методы IPersistStream
STDMETHODIMP ExplorerBar::GetClassID(LPCLSID pClassID)
{
*pClassID = CLSID_BelWebsDeskBand;
return S_OK;
}
STDMETHODIMP ExplorerBar::IsDirty(void)
{
return S_FALSE;
}
STDMETHODIMP ExplorerBar::Load(LPSTREAM pStream)
{
return S_OK;
}
STDMETHODIMP ExplorerBar::Save(LPSTREAM pStream, BOOL fClearDirty)
{
return S_OK;
}
STDMETHODIMP ExplorerBar::GetSizeMax(ULARGE_INTEGER *pul)
{
return E_NOTIMPL;
}
//Приватные методы
LRESULT CALLBACK ExplorerBar::WndProc(HWND hWnd,
UINT uMessage,
WPARAM wParam,
LPARAM lParam)
{
ExplorerBar *pThis = (ExplorerBar*)GetWindowLong(hWnd, GWL_USERDATA);
switch (uMessage)
{
case WM_NCCREATE:
{
LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam;
pThis = (ExplorerBar*)(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 ExplorerBar::OnPaint(void)
{
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("BelWebs Explorer Bar"),
-1,
&rc,
DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint(m_hWnd, &ps);
return 0;
}
LRESULT ExplorerBar::OnCommand(WPARAM wParam, LPARAM lParam)
{
return 0;
}
void ExplorerBar::FocusChange(BOOL bFocus)
{
m_bFocus = bFocus;
if(m_pSite)
{
m_pSite->OnFocusChangeIS((IDockingWindow*)this, bFocus);
}
}
LRESULT ExplorerBar::OnSetFocus(void)
{
FocusChange(TRUE);
return 0;
}
LRESULT ExplorerBar::OnKillFocus(void)
{
FocusChange(FALSE);
return 0;
}
BOOL ExplorerBar::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))
{
//If RegisterClass fails, CreateWindow below will fail.
}
}
RECT rc;
GetClientRect(m_hwndParent, &rc);
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 (m_hWnd != NULL);
}
А вот код регистрации/дерегистрации:
STDAPI DllRegisterServer()
{
LPCTSTR servName=_T("BelWebs ToolBar");
TCHAR fileName[_MAX_PATH] = "D:\\Program Files\\Internet Explorer\\Plugins\\BelWebsToolBar.dll";
DWORD len = strlen(fileName);
HKEY hClassKey, hServKey;
if(RegCreateKeyEx(HKEY_CLASSES_ROOT,
_T("CLSID\\{32997D65-AB17-470e-B29E-27384E8A2A60}"), 0, NULL,
0, KEY_WRITE, NULL, &hClassKey, NULL) != ERROR_SUCCESS)
return SELFREG_E_CLASS;
if(RegSetValueEx(hClassKey, NULL, 0, REG_SZ, (BYTE*)servName, _tcslen(servName)+1)
!=ERROR_SUCCESS)
return SELFREG_E_CLASS;
if (RegCreateKeyEx(hClassKey, _T("InprocServer32"), 0, NULL, 0, KEY_WRITE,
NULL, &hServKey, NULL) != ERROR_SUCCESS)
return SELFREG_E_CLASS;
if (RegOpenKeyEx(hClassKey, _T("InprocServer32"), 0, KEY_WRITE, &hServKey)
!= ERROR_SUCCESS)
return SELFREG_E_CLASS;
RegCloseKey(hClassKey);
if(RegSetValue(hServKey, NULL, REG_SZ, fileName, len) != ERROR_SUCCESS)
return SELFREG_E_CLASS;
RegCloseKey(hServKey);
HKEY hPluginKey;
if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\Microsoft\\Internet Explorer\\")
_T("Explorer Bars\\{32997D65-AB17-470e-B29E-27384E8A2A60}"),
0, NULL, 0, KEY_WRITE, NULL, &hPluginKey, NULL)
!= ERROR_SUCCESS)
return SELFREG_E_CLASS;
RegCloseKey(hPluginKey);
return S_OK;
}
STDAPI DllUnregisterServer()
{
HKEY hCurrKey;
if (RegOpenKeyEx(HKEY_CLASSES_ROOT, _T("CLSID"), 0, KEY_WRITE, &hCurrKey)
!= ERROR_SUCCESS)
return SELFREG_E_CLASS;
if (SHDeleteKey(hCurrKey, _T("{32997D65-AB17-470e-B29E-27384E8A2A60}"))
!= ERROR_SUCCESS)
return SELFREG_E_CLASS;
RegCloseKey(hCurrKey);
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\Microsoft\\Internet Explorer\\")
_T("Explorer Bars"), 0, KEY_WRITE, &hCurrKey) != ERROR_SUCCESS)
return SELFREG_E_CLASS;
if (SHDeleteKey(hCurrKey, _T("{32997D65-AB17-470e-B29E-27384E8A2A60}"))
!= ERROR_SUCCESS)
return SELFREG_E_CLASS;
RegCloseKey(hCurrKey);
return S_OK;
}
Работать-то оно работает, но... Мне нужет ToolBar, а оно делает Horzontal ExplorerBar, в самом низу браузера. А нужно что-то типа ЯндексБар-а. Я почитал MSDN, и так и не понял, это я регистрирую неправильно, или надо как-то перепаять ExplorerBar? Заранее всем спасибо.