📄 hostshell.h
字号:
/////////////////////////////////////////////////////////////
//
// hostshell.h - Don Box, 1996-1997
//
// An implementation of a shell object that exports the IShell
// interface and imports the IShellNotify interface as an event
// interface.
//
#ifndef _HOSTSHELL_H
#define _HOSTSHELL_H
#include "host.h"
HRESULT LoadTypeInfoFromThisModule(REFIID riid, ITypeInfo **ppti);
class CHostShell : public IShell,
public IConnectionPointContainer {
LONG m_cRef;
ITypeInfo *m_pTypeInfo;
// define the connection point for IShellNotify
class XShellCP : public IConnectionPoint {
IShellNotify *m_pdnSink;
inline CHostShell *This(void)
{ return (CHostShell*)(LPBYTE(this) - offsetof(CHostShell, m_cp)); }
public:
XShellCP(void) : m_pdnSink(0) {}
virtual ~XShellCP(void) {
if (m_pdnSink)
m_pdnSink->Release();
}
STDMETHODIMP QueryInterface(REFIID riid, void **ppv) {
if (riid == IID_IConnectionPoint)
*ppv = (IConnectionPoint*)this;
else if (riid == IID_IUnknown)
*ppv = (IConnectionPoint*)this;
else {
*ppv = 0;
return E_NOINTERFACE;
}
((IUnknown*)*ppv)->AddRef();
return S_OK;
}
STDMETHODIMP_(ULONG) AddRef(void) { return This()->AddRef(); }
STDMETHODIMP_(ULONG) Release(void) { return This()->Release(); }
STDMETHODIMP Advise(IUnknown *pUnkSink, DWORD *pdwCookie) {
if (m_pdnSink)
return CONNECT_E_ADVISELIMIT;
HRESULT hr = pUnkSink->QueryInterface(DIID_IShellNotify,
(void**)&m_pdnSink);
*pdwCookie = DWORD(m_pdnSink);
return hr;
}
STDMETHODIMP Unadvise(DWORD dwCookie) {
if (dwCookie == DWORD(m_pdnSink)) {
m_pdnSink->Release();
m_pdnSink = 0;
return S_OK;
}
return CONNECT_E_NOCONNECTION;
}
STDMETHODIMP GetConnectionInterface(IID *piid)
{ *piid = DIID_IShellNotify; return S_OK; }
STDMETHODIMP GetConnectionPointContainer(IConnectionPointContainer **ppcpc)
{ (*ppcpc = This())->AddRef(); return S_OK; }
STDMETHODIMP EnumConnections(IEnumConnections **pp)
{ *pp = 0; return E_NOTIMPL; }
// helper function to send OnPlayGame notification
void SendOnPlayGame(const OLECHAR *pwsz) {
if (m_pdnSink)
{
VARIANTARG arg; ZeroMemory(&arg, sizeof(arg));
arg.vt = VT_BSTR;
arg.bstrVal = SysAllocString(pwsz);
DISPPARAMS params = { &arg, 0, 1, 0 };
m_pdnSink->Invoke(10, IID_NULL, 9, DISPATCH_METHOD,
¶ms, 0, 0, 0);
VariantClear(&arg);
}
}
// helper function to send OnEndOfLine notification
void SendOnEndOfLine(void)
{
if (m_pdnSink)
{
DISPPARAMS params = { 0, 0, 0, 0 };
m_pdnSink->Invoke(11, IID_NULL, 9, DISPATCH_METHOD,
¶ms, 0, 0, 0);
}
}
};
friend class XShellCP;
XShellCP m_cp;
public:
// CHostShell methods
CHostShell(void) : m_cRef(0), m_pTypeInfo(0)
{
HRESULT hr = LoadTypeInfoFromThisModule(IID_IShell, &m_pTypeInfo);
}
~CHostShell(void)
{
if (m_pTypeInfo)
m_pTypeInfo->Release();
}
// IUnknown methods
STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
{
if (riid == IID_IShell)
*ppv = m_pTypeInfo ? (IShell*)this : 0;
else if (riid == IID_IDispatch)
*ppv = m_pTypeInfo ? (IShell*)this : 0;
else if (riid == IID_IUnknown)
*ppv = (IShell*)this;
else if (riid == IID_IConnectionPointContainer)
*ppv = (IConnectionPointContainer*)this;
else
{
*ppv = 0;
return E_NOINTERFACE;
}
((IUnknown*)*ppv)->AddRef();
return S_OK;
}
STDMETHODIMP_(ULONG) AddRef(void)
{
return InterlockedIncrement(&m_cRef);
}
STDMETHODIMP_(ULONG) Release(void)
{
if (InterlockedDecrement(&m_cRef))
return m_cRef;
delete this;
return 0;
}
// IConnectionPointContainer methods
STDMETHODIMP EnumConnectionPoints(IEnumConnectionPoints **ppecp)
{ return E_NOTIMPL; }
STDMETHODIMP FindConnectionPoint(REFIID riid, IConnectionPoint **ppcp) {
if (riid == DIID_IShellNotify)
*ppcp = &m_cp;
else
{
*ppcp = 0;
return E_FAIL;
}
(*ppcp)->AddRef();
return S_OK;
}
// IDispatch methods
STDMETHODIMP GetTypeInfoCount(UINT *pctinfo)
{ *pctinfo = 1; return S_OK; }
STDMETHODIMP GetTypeInfo(UINT ctinfo, LCID lcid, ITypeInfo **ppti)
{ (*ppti = m_pTypeInfo)->AddRef(); return S_OK; }
STDMETHODIMP GetIDsOfNames(REFIID riid, OLECHAR **rgszNames,
UINT cNames, LCID lcid, DISPID *rgdispid)
{ return m_pTypeInfo->GetIDsOfNames(rgszNames, cNames, rgdispid); }
STDMETHODIMP Invoke(DISPID id, REFIID riid, LCID lcid, WORD wFlg,
DISPPARAMS *pdp, VARIANT *pvr, EXCEPINFO *pei, UINT *pu)
{
return m_pTypeInfo->Invoke((IShell*)this, id, wFlg, pdp, pvr, pei, pu);
}
// IShell methods
STDMETHODIMP alert(BSTR bstr) {
if (bstr)
MessageBoxW(0, bstr, L"Active Scripting", MB_SETFOREGROUND);
return S_OK;
}
STDMETHODIMP write(BSTR bstr) {
if (bstr)
printf("%S", bstr);
return S_OK;
}
STDMETHODIMP writeLn(BSTR bstr) {
if (bstr)
printf("%S\n", bstr);
else
printf("\n");
m_cp.SendOnEndOfLine();
return S_OK;
}
STDMETHODIMP exec(BSTR bstr) {
if (bstr)
{
if (_wcsicmp(OLESTR("freecell.exe"), bstr) == 0
|| _wcsicmp(OLESTR("winmine.exe"), bstr) == 0)
m_cp.SendOnPlayGame(bstr);
char szCmdParam[MAX_PATH];
wcstombs(szCmdParam, bstr, MAX_PATH);
ShellExecuteA(GetDesktopWindow(), "open",
szCmdParam, "", ".", SW_SHOWDEFAULT);
}
return S_OK;
}
STDMETHODIMP beep(void) {
MessageBeep(0xFFFFFFFF);
return S_OK;
}
};
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -