MyBands.h
////////////////////////////////////////////////////////////////
// Microsoft Systems Journal -- November 1999
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual C++ 6.0, runs on Windows 98 and probably Windows NT too.
#include "Resource.h"
#include "BandObj.h"
#include "EditSearch.h"
//////////////////
// Application class: derive from CBandObjApp
class CMyBandsDll : public CBandObjDll {
public:
CMyBandsDll();
virtual ~CMyBandsDll();
virtual BOOL InitInstance();
protected:
DECLARE_MESSAGE_MAP()
};
DECLARE_SMARTPTR(IWebBrowser2);
//////////////////
// common base class for info and comm bands
class CMyIEBand : public CBandObj {
public:
CMyIEBand(REFIID clsid);
~CMyIEBand();
protected:
SPIWebBrowser2 m_spWebBrowser2; // browser interface
CString m_message; // window text
COLORREF m_bgColor; // background color
CString m_url; // where to go when clicked
HRESULT OnSetSite(IUnknown*); // override to get web browser
DECLARE_MESSAGE_MAP();
afx_msg void OnPaint();
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnCommand(UINT nID);
DECLARE_DYNAMIC(CMyIEBand)
};
//////////////////
// Info band lives in IE left pane
class CMyInfoBand : public CMyIEBand {
public:
CMyInfoBand();
DECLARE_DYNCREATE(CMyInfoBand)
};
//////////////////
// Comm band lives in IE bottom pane
class CMyCommBand : public CMyIEBand {
public:
CMyCommBand();
DECLARE_DYNCREATE(CMyCommBand)
};
//////////////////
// Desk band lives in task bar
class CMyDeskBand : public CBandObj {
public:
CMyDeskBand();
~CMyDeskBand();
protected:
CEditSearch m_wndEdit;
// override
virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra,
AFX_CMDHANDLERINFO* pHandlerInfo);
afx_msg void OnPaint();
afx_msg void OnSetFocus(CWnd* pOldWnd);
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnSize(UINT nType, int cx, int cy);
DECLARE_MESSAGE_MAP();
DECLARE_DYNCREATE(CMyDeskBand)
};
MyBands.cpp
////////////////////////////////////////////////////////////////
// Microsoft Systems Journal -- November 1999
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual C++ 6.0, runs on Windows 98 and probably Windows NT too.
//
#include "StdAfx.h"
#include "MyBands.h"
#include "Debug.h"
#include "TraceWin.h"
#include "resource.h"
#include "ComToys.h"
#include "IniFile.h"
#include <initguid.h> // so my GUIDs are created
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
BEGIN_MESSAGE_MAP(CMyBandsDll, CBandObjDll)
END_MESSAGE_MAP()
CMyBandsDll theApp;
// {4647E381-520B-11d2-A0D0-004033D0645D}
DEFINE_GUID(CLSID_MYINFOBAND,
0x4647e381, 0x520b, 0x11d2, 0xa0, 0xd0, 0x0, 0x40, 0x33, 0xd0, 0x64, 0x5d);
// {4647E382-520B-11d2-A0D0-004033D0645D}
DEFINE_GUID(CLSID_MYCOMMBAND,
0x4647e382, 0x520b, 0x11d2, 0xa0, 0xd0, 0x0, 0x40, 0x33, 0xd0, 0x64, 0x5d);
// {4647E383-520B-11d2-A0D0-004033D0645D}
DEFINE_GUID(CLSID_MYDESKBAND,
0x4647e383, 0x520b, 0x11d2, 0xa0, 0xd0, 0x0, 0x40, 0x33, 0xd0, 0x64, 0x5d);
CMyBandsDll::CMyBandsDll()
{
CBandObj::bTRACE=TRUE; // TRACEing on for bandobj
}
CMyBandsDll::~CMyBandsDll()
{
}
//////////////////
// initialize: add each band class
BOOL CMyBandsDll::InitInstance()
{
TRACEFN(_T("CMyBandsDll::InitInstance\n"));
// SetRegistryKey(_T("MSJ"));
CIniFile::Use(this, CIniFile::LocalDir);
VERIFY(AddBandClass(CLSID_MYINFOBAND,
RUNTIME_CLASS(CMyInfoBand),
CATID_InfoBand,
IDR_INFOBAND));
VERIFY(AddBandClass(CLSID_MYCOMMBAND,
RUNTIME_CLASS(CMyCommBand),
CATID_CommBand,
IDR_COMMBAND));
VERIFY(AddBandClass(CLSID_MYDESKBAND,
RUNTIME_CLASS(CMyDeskBand),
CATID_DeskBand,
IDR_DESKBAND));
return CBandObjDll::InitInstance();
}
//////////////// CMyIEBand ////////////////
IMPLEMENT_DYNAMIC(CMyIEBand, CBandObj)
BEGIN_MESSAGE_MAP(CMyIEBand, CBandObj)
ON_WM_PAINT()
ON_WM_LBUTTONDOWN()
ON_WM_ERASEBKGND()
ON_COMMAND_RANGE(ID_COMMAND1, ID_COMMAND2, OnCommand)
END_MESSAGE_MAP()
CMyIEBand::CMyIEBand(REFIID clsid) : CBandObj(clsid)
{
}
CMyIEBand::~CMyIEBand()
{
}
BOOL CMyIEBand::OnEraseBkgnd(CDC* pDC)
{
CClientDC dc(this);
CRect rc;
GetClientRect(&rc);
dc.FillSolidRect(&rc, m_bgColor);
return TRUE;
}
void CMyIEBand::OnPaint()
{
CPaintDC dc(this);
CRect rc;
GetClientRect(&rc);
dc.SetTextColor(RGB(0,0,0));
dc.SetBkMode(TRANSPARENT);
dc.DrawText(m_message, -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
}
void CMyIEBand::OnCommand(UINT nID)
{
CString s;
s.Format(_T("Command %d received!"), nID-ID_COMMAND1+1);
GetParent()->MessageBox(s, GetTitle(), MB_OK | MB_ICONINFORMATION);
SetFocus();
}
//////////////////
// SetSite override gets web browser when Explorer sets itself as my site
HRESULT CMyIEBand::OnSetSite(IUnknown* pSite)
{
HRESULT hr = CBandObj::OnSetSite(pSite);
if (SUCCEEDED(hr)) {
CComQIPtr<IServiceProvider> sp = pSite;
if (sp)
sp->QueryService(IID_IWebBrowserApp,
IID_IWebBrowser2, (void**)&m_spWebBrowser2);
else
m_spWebBrowser2 = (LPUNKNOWN)NULL;
}
return hr;
}
//////////////////
// Mouse click: navigate to page
void CMyIEBand::OnLButtonDown(UINT nFlags, CPoint point)
{
if (m_spWebBrowser2) {
m_spWebBrowser2->Navigate(_bstr_t(m_url), NULL, NULL, NULL, NULL);
}
}
//////////////// CMyCommBand ////////////////
IMPLEMENT_DYNCREATE(CMyCommBand, CMyIEBand)
CMyCommBand::CMyCommBand() : CMyIEBand(CLSID_MYCOMMBAND)
{
m_strTitle.Empty();
m_dbiDefault.ptMinSize = CPointL(-1,30);
m_dbiDefault.ptMaxSize = CPointL(-1,30);
m_dbiDefault.ptActual = CPointL(100,30);
m_url = _T("http://www.microsoft.com/mind");
m_message = _T("Buy MInD");
m_bgColor = RGB(255,0,128);
}
IMPLEMENT_DYNCREATE(CMyInfoBand, CMyIEBand)
CMyInfoBand::CMyInfoBand() : CMyIEBand(CLSID_MYINFOBAND)
{
m_dbiDefault.dwModeFlags = DBIMF_VARIABLEHEIGHT;
m_dbiDefault.ptActual = CPointL(10,-1);
m_url = _T("http://www.microsoft.com/msj");
m_message = _T("MSJ");
m_bgColor = RGB(255,255,255);
}
//////////////// CMyDeskBand ////////////////
IMPLEMENT_DYNCREATE(CMyDeskBand, CBandObj)
BEGIN_MESSAGE_MAP(CMyDeskBand, CBandObj)
ON_WM_CREATE()
ON_WM_SIZE()
ON_WM_SETFOCUS()
END_MESSAGE_MAP()
CMyDeskBand::CMyDeskBand() : CBandObj(CLSID_MYDESKBAND),
m_wndEdit(_T("SearchStrings"))
{
const CXDESIRED = 100; // desired width = 100
m_dbiDefault.ptActual = CPointL(CXDESIRED,0);
m_dbiDefault.dwModeFlags = DBIMF_VARIABLEHEIGHT;
}
CMyDeskBand::~CMyDeskBand()
{
}
//////////////////
// I'm being created: create edit control and set band obj
// context menu from edit search control
int CMyDeskBand::OnCreate(LPCREATESTRUCT lpcs)
{
TRACE(_T("CMyDeskBand::OnCreate\n"));
if (CBandObj::OnCreate(lpcs)==-1)
return -1;
m_wndEdit.Create(WS_VISIBLE|WS_CHILD, CRect(0,0,0,0), this, 1);
m_wndEdit.CreateSearchMenu(m_contextMenu);
return 0;
}
//////////////////
// Window was resized: adjust edit control
void CMyDeskBand::OnSize(UINT nType, int cx, int cy)
{
TRACE(_T("CMyDeskBand::OnSize(%d,%d)\n"),cx,cy);
CBandObj::OnSize(nType, cx, cy);
CRect rc(CPoint(0,0),CSize(cx,cy));
rc.DeflateRect(2,2);
m_wndEdit.SetWindowPos(NULL, rc.left, rc.top, rc.Width(), rc.Height(), 0);
}
//////////////////
// I got focus: pass to edit control
void CMyDeskBand::OnSetFocus(CWnd* pOldWnd)
{
CBandObj::OnSetFocus(pOldWnd);
m_wndEdit.SetFocus();
}
//////////////////
// route commands through edit control
BOOL CMyDeskBand::OnCmdMsg(UINT a, int b, void* c, AFX_CMDHANDLERINFO* d)
{
return m_wndEdit.OnCmdMsg(a, b, c, d) ? TRUE :
CBandObj::OnCmdMsg(a, b, c, d);
}
Figure 7 IRegistrar Methods
//////////////////
// IRegistrar -- The eaisest way to deal with registration
//
IRegistrar : public IUnknown {
public:
HRESULT STDMETHODCALLTYPE AddReplacement(
/* [in] */ LPCOLESTR key,
/* [in] */ LPCOLESTR item) = 0;
HRESULT STDMETHODCALLTYPE ClearReplacements( void) = 0;
HRESULT STDMETHODCALLTYPE ResourceRegisterSz(
/* [in] */ LPCOLESTR resFileName,
/* [in] */ LPCOLESTR szID,
/* [in] */ LPCOLESTR szType) = 0;
HRESULT STDMETHODCALLTYPE ResourceUnregisterSz(
/* [in] */ LPCOLESTR resFileName,
/* [in] */ LPCOLESTR szID,
/* [in] */ LPCOLESTR szType) = 0;
HRESULT STDMETHODCALLTYPE FileRegister(
/* [in] */ LPCOLESTR fileName) = 0;
HRESULT STDMETHODCALLTYPE FileUnregister(
/* [in] */ LPCOLESTR fileName) = 0;
HRESULT STDMETHODCALLTYPE StringRegister(
/* [in] */ LPCOLESTR data) = 0;
HRESULT STDMETHODCALLTYPE StringUnregister(
/* [in] */ LPCOLESTR data) = 0;
HRESULT STDMETHODCALLTYPE ResourceRegister(
/* [in] */ LPCOLESTR resFileName,
/* [in] */ UINT nID,
/* [in] */ LPCOLESTR szType) = 0;
HRESULT STDMETHODCALLTYPE ResourceUnregister(
/* [in] */ LPCOLESTR resFileName,
/* [in] */ UINT nID,
/* [in] */ LPCOLESTR szType) = 0;
};
Figure 8 BandObj.rgs
HKCR
{
NoRemove CLSID
{
ForceRemove %CLSID% = s '%ClassName%'
{
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
}
}
NoRemove 'Component Categories'
{
NoRemove {00021492-0000-0000-C000-000000000046}
{
Delete Enum
}
}
}
Figure 9 RGSRUN.cpp
////////////////////////////////////////////////////////////////
// Microsoft Systems Journal November 1999
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual C++ 6.0, runs on Windows 98 and probably Windows NT too.
//
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
#include <afxwin.h>
#include <afxcoll.h>
#include <atlbase.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
void usage()
{
printf("\n");
printf("Purpose: Load RGS registrar scripts into the registry\n");
printf("Usage: rgsrun [-u -q] files\n");
printf(" -u = unregister\n");
printf(" -q = quiet\n");
printf(" Written 7-99 by Paul Dilascia for MSJ.\n");
exit(-1);
}
/////////////////
// Instantiate IRegistrar
//
class CTRegistrar : public CComQIPtr<IRegistrar> {
public:
CTRegistrar() {
CoCreateInstance(CLSID_Registrar, NULL, CLSCTX_INPROC);
ASSERT(p);
}
};
//////////////////
// Console app entry point
//
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)) {
fprintf(stderr, "Fatal Error: MFC initialization failed");
return -1;
}
if (FAILED(CoInitialize(0))) {
printf("Error initializing COM\n");
(-1);
} else {
CTRegistrar spReg;
BOOL unregister=0;
BOOL quiet=0;
BOOL any=0;
for (int i=1; i<argc; i++) {
if (argv[i][0]=='/' || argv[i][0]=='-') {
switch (tolower(argv[i][1])) {
case 'u':
unregister=1;
break;
case 'q':
quiet=1;
break;
default:
usage();
break;
}
} else {
USES_CONVERSION;
LPOLESTR lpo = T2OLE(argv[i]);
HRESULT hr = unregister ?
spReg->FileUnregister(lpo) :
spReg->FileRegister(lpo);
if (!quiet) {
printf(FAILED(hr) ?
"Error processing %s - ignored\n" : "%s loaded\n",
argv[i]);
}
any = 1;
}
}
if (!any)
usage();
}
CoUninitialize();
return 0;
}
Figure 11 TRACEFN Output for MyBands
// Select "Web Search Band" from Toolbars menu
//
DllGetClassObject({4647E383-520B-11D2-A0D0-004033D0645D}, IClassFactory)
CTComDll::OnGetClassObject
DllGetClassObject returns S_OK
CBandObj(011152F0)::CBandObj
CBandObj(011152F0)::QueryInterface(IPersistStreamInit), returns E_NOINTERFACE,
*ppv=00000000, count=1
CBandObj(011152F0)::QueryInterface(IDeskBand), returns S_OK, *ppv=01115330,
count=2
CBandObj(011152F0)::QueryInterface({EA5F2D61-E008-11CF-99CB-00C04FD64497}),
returns E_NOINTERFACE, *ppv=00000000, count=2
CBandObj(011152F0)::QueryInterface(IObjectWithSite), returns S_OK, *ppv=01115334,
count=3
CBandObj(011152F0)::IObjectWithSite::SetSite 00431008
CMyDeskBand::OnCreate
CBandObj(011152F0)::OnCreate
CMyDeskBand::OnSize(1131,20)
CBandObj(011152F0)::Release, returns count=2
CBandObj(011152F0)::IOleWindow::GetWindow
CBandObj(011152F0)::IDeskBand::GetBandInfo id=6 mode=0
CBandObj(011152F0)::AddRef, returns count=3
CBandObj(011152F0)::QueryInterface(IUnknown), returns S_OK, *ppv=01115330,
count=4
CBandObj(011152F0)::Release, returns count=3
CMyDeskBand::OnSize(0,20)
CBandObj(011152F0)::AddRef, returns count=4
CBandObj(011152F0)::QueryInterface(IUnknown), returns S_OK, *ppv=01115330,
count=5
CBandObj(011152F0)::Release, returns count=4
CBandObj(011152F0)::IDockingWindow::ShowDW(1)
CBandObj(011152F0)::AddRef, returns count=5
CBandObj(011152F0)::QueryInterface(IUnknown), returns S_OK, *ppv=01115330,
count=6
CBandObj(011152F0)::Release, returns count=5
CMyDeskBand::OnSize(98,20)
CBandObj(011152F0)::Release, returns count=4
// ...running... //
// Right-click for context menu, select "Hotbot"
//
CBandObj(011152F0)::IDeskBand::GetBandInfo id=6 mode=0
CBandObj(011152F0)::QueryInterface(IContextMenu), returns S_OK, *ppv=01115340, count=5
CBandObj(011152F0)::IContextMenu::QueryContextMenu
CTContextMenu::QueryContextMenu(0x65c,i=0,first=4,last=32767,flags=0x0)
CBandObj(011152F0)::AddRef, returns count=6
CBandObj(011152F0)::QueryInterface(IUnknown), returns S_OK, *ppv=01115330, count=7
CBandObj(011152F0)::Release, returns count=6
CBandObj(011152F0)::QueryInterface(IPersist), returns S_OK, *ppv=0111533C, count=7
CBandObj(011152F0)::IPersist::GetClassID
CTPersist::GetClassID
CBandObj(011152F0)::QueryInterface(IOleCommandTarget), returns E_NOINTERFACE,
*ppv=00000000, count=7
CBandObj(011152F0)::Release, returns count=6
CBandObj(011152F0)::Release, returns count=5
CBandObj(011152F0)::AddRef, returns count=6
CBandObj(011152F0)::QueryInterface(IUnknown), returns S_OK, *ppv=01115330, count=7
CBandObj(011152F0)::Release, returns count=6
CBandObj(011152F0)::Release, returns count=5
CBandObj(011152F0)::IContextMenu::InvokeCommand(102)
CTContextMenu::InvokeCommand
CBandObj(011152F0)::Release, returns count=4
// Now close
//
CBandObj(011152F0)::IDeskBand::GetBandInfo id=6 mode=0
CBandObj(011152F0)::QueryInterface(IContextMenu), returns S_OK, *ppv=01115340,
count=5
CBandObj(011152F0)::IContextMenu::QueryContextMenu
CTContextMenu::QueryContextMenu(0x698,i=0,first=4,last=32767,flags=0x0)
CBandObj(011152F0)::AddRef, returns count=6
CBandObj(011152F0)::QueryInterface(IUnknown), returns S_OK, *ppv=01115330, count=7
CBandObj(011152F0)::Release, returns count=6
CBandObj(011152F0)::QueryInterface(IPersist), returns S_OK, *ppv=0111533C, count=7
CBandObj(011152F0)::IPersist::GetClassID
CTPersist::GetClassID
CBandObj(011152F0)::QueryInterface(IOleCommandTarget), returns E_NOINTERFACE,
*ppv=00000000, count=7
CBandObj(011152F0)::Release, returns count=6
CBandObj(011152F0)::Release, returns count=5
CBandObj(011152F0)::AddRef, returns count=6
CBandObj(011152F0)::QueryInterface(IUnknown), returns S_OK, *ppv=01115330, count=7
CBandObj(011152F0)::Release, returns count=6
CBandObj(011152F0)::Release, returns count=5
CBandObj(011152F0)::IDockingWindow::CloseDW
CEditSearch::PostNcDestroy
CBandObj(011152F0)::QueryInterface(IObjectWithSite), returns S_OK, *ppv=01115334,
count=6
CBandObj(011152F0)::IObjectWithSite::SetSite 00000000
CBandObj(011152F0)::Release, returns count=5
CBandObj(011152F0)::Release, returns count=4
CBandObj(011152F0)::Release, returns count=3
Figure 14 MyBands.ini
[SearchStrings]
&Altavista=http://www.altavista.com/cgi-bin/query?pg=q&kl=XX&stype=stext&q=MYSEARCH
E&xcite=http://search.excite.com/search.gw?search=MYSEARCH
&Hotbot=http://www.hotbot.com/?MT=MYSEARCH&SM=MC&DV=0&LG=any&DC=10&DE=2&_v=2&OPs=MDRTP
&Infoseek=http://infoseek.go.com/Titles?qt=MYSEARCH&col=WW&sv=IS&lk=noframes
&Lycos=http://www.lycos.com/cgi-bin/pursuit?matchmode=and&cat=lycos&query=MYSEARCH
&Yahoo=http://search.yahoo.com/search?p=MYSEARCH&n=25
AllKeys=&Altavista;E&xcite;&Hotbot;&Infoseek;&Lycos;&Yahoo;
Current=0