📄 cwsh.cpp
字号:
{
if(m_TypeInfo == NULL)
{
m_TypeInfo = new CInterfaceObjectTypeInfo(this);
m_TypeInfo->AddRef();
}
(*ppTInfo) = m_TypeInfo;
(*ppTInfo)->AddRef();
return S_OK;
}
HRESULT STDMETHODCALLTYPE CInterfaceObject::GetTypeInfoCount(
/* [out] */ UINT __RPC_FAR *pctinfo)
{
*pctinfo = 1;
return S_OK;
}
#ifdef __BORLANDC__
#pragma argsused
#endif
HRESULT STDMETHODCALLTYPE CInterfaceObject::GetIDsOfNames(
REFIID riid,
OLECHAR FAR* FAR* rgszNames,
UINT cNames,
LCID lcid,
DISPID FAR* rgdispid)
{
for(unsigned I = 0; I < cNames; ++I)
{
#ifdef TEST
wcout << L"GetIDsOfNames:" << rgszNames[I] << endl;
#endif
for(unsigned J = 0; J < m_Methods.size(); ++J)
{
// Nov. 10, 2003 FILE Win9Xでは、[lstrcmpiW]が無効のため、[_wcsicmp]に修正
if(_wcsicmp(rgszNames[I], m_Methods[J].Name) == 0)
{
rgdispid[I] = J;
goto Found;
}
}
return DISP_E_UNKNOWNNAME;
Found:
;
}
return S_OK;
}
void CInterfaceObject::AddMethod(wchar_t *Name, int ID, VARTYPE *ArgumentTypes, int ArgumentCount, VARTYPE ResultType,
CInterfaceObjectMethod Method)
{
m_Methods.push_back(CMethodInfo());
CMethodInfo *Info = &m_Methods[m_Methods.size() - 1];
ZeroMemory(Info, sizeof(CMethodInfo));
Info->Desc.invkind = INVOKE_FUNC;
Info->Desc.cParams = ArgumentCount + 1; //戻り値の分
Info->Desc.lprgelemdescParam = Info->Arguments;
// Nov. 10, 2003 FILE Win9Xでは、[lstrcpyW]が無効のため、[wcscpy]に修正
wcscpy(Info->Name, Name);
Info->Method = Method;
Info->ID = ID;
for(int I = 0; I < ArgumentCount; ++I)
{
Info->Arguments[I].tdesc.vt = ArgumentTypes[ArgumentCount - I - 1];
Info->Arguments[I].paramdesc.wParamFlags = PARAMFLAG_FIN;
}
Info->Arguments[ArgumentCount].tdesc.vt = ResultType;
Info->Arguments[ArgumentCount].paramdesc.wParamFlags = PARAMFLAG_FRETVAL;
}
CWSHClient::CWSHClient(wchar_t const *AEngine, ScriptErrorHandler AErrorHandler, void *AData):
m_Engine(NULL), m_Data(AData), m_OnError(AErrorHandler), m_Valid(false)
{
m_InterfaceObject = new CInterfaceObject(this);
m_InterfaceObject->AddRef();
CLSID ClassID;
if(CLSIDFromProgID(AEngine, &ClassID) != S_OK)
Error(L"指名のスクリプトエンジンが見つかりません");
else
{
if(CoCreateInstance(ClassID, 0, CLSCTX_INPROC_SERVER, IID_IActiveScript, reinterpret_cast<void **>(&m_Engine)) != S_OK)
Error(L"指名のスクリプトエンジンが作成できません");
else
{
IActiveScriptSite *Site = new CWSHSite(this);
if(m_Engine->SetScriptSite(Site) != S_OK)
{
delete Site;
Error(L"サイトを登録できません");
}
else
{
m_Valid = true;
}
}
}
}
CWSHClient::~CWSHClient()
{
if(m_InterfaceObject != NULL)
m_InterfaceObject->Release();
if(m_Engine != NULL)
m_Engine->Release();
}
void CWSHClient::Execute(wchar_t const *AScript)
{
IActiveScriptParse *Parser;
if(m_Engine->QueryInterface(IID_IActiveScriptParse, reinterpret_cast<void **>(&Parser)) != S_OK)
Error(L"パーサを取得できません");
else
{
if(Parser->InitNew() != S_OK)
Error(L"初期化できません");
else
{
if(m_Engine->AddNamedItem(L"Editor", SCRIPTITEM_GLOBALMEMBERS | SCRIPTITEM_ISVISIBLE) != S_OK)
Error(L"オブジェクトを渡せなかった");
else
{
if(m_Engine->SetScriptState(SCRIPTSTATE_STARTED) != S_OK)
Error(L"状態変更エラー");
else
{
if(Parser->ParseScriptText(AScript, 0, 0, 0, 0, 0, SCRIPTTEXT_ISVISIBLE, 0, 0) != S_OK)
Error(L"実行に失敗しました");
}
}
}
Parser->Release();
}
m_Engine->Close();
}
void CWSHClient::Error(BSTR Description, BSTR Source)
{
if(m_OnError != NULL)
m_OnError(Description, Source, m_Data);
}
void CWSHClient::Error(wchar_t* Description)
{
BSTR S = SysAllocString(L"WSH");
BSTR D = SysAllocString(Description);
Error(D, S);
SysFreeString(S);
SysFreeString(D);
}
/////////////////////////////////////////////
static HRESULT MacroCommand(int ID, DISPPARAMS *Arguments, VARIANT* Result, void *Data)
{
if(Result != NULL)
VariantInit(Result);
CEditView *View = reinterpret_cast<CEditView*>(Data);
if(ID >= F_FUNCTION_FIRST)
{
if(Result == NULL) return E_FAIL;
return CMacro::HandleFunction(View, ID, Arguments->rgvarg, Arguments->cArgs, *Result) ? S_OK : E_FAIL;
}
else
{
int ArgCount = Arguments->cArgs;
if(ArgCount > 4) ArgCount = 4;
char *StrArgs[4];
for(int I = 0; I < ArgCount; ++I)
{
char *S;
switch(Arguments->rgvarg[I].vt)
{
case VT_INT:
{
S = new char[40]; //これだけあれば大丈夫かと
wsprintf(S, "%d", Arguments->rgvarg[I].intVal);
break;
}
case VT_UINT:
{
S = new char[40]; //これだけあれば大丈夫かと
wsprintf(S, "%u", Arguments->rgvarg[I].uintVal);
break;
}
case VT_I4:
{
S = new char[40]; //これだけあれば大丈夫かと
wsprintf(S, "%d", Arguments->rgvarg[I].lVal);
break;
}
case VT_BSTR:
{
int Len;
Wrap(&Arguments->rgvarg[I].bstrVal)->Get(&S, &Len);
break;
}
default:
S = new char[1];
S[0] = 0;
}
StrArgs[ArgCount - I - 1] = S;
}
CMacro::HandleCommand(View, ID, const_cast<char const **>(StrArgs), ArgCount);
for(int J = 0; J < ArgCount; ++J)
delete StrArgs[J];
return S_OK;
}
}
static void MacroError(BSTR Description, BSTR Source, void *Data)
{
CEditView *View = reinterpret_cast<CEditView*>(Data);
char MessageA[1024], SourceA[1024];
MessageA[WideCharToMultiByte(CP_ACP, 0, Description, SysStringLen(Description), MessageA, 1023, NULL, NULL)] = 0;
SourceA[WideCharToMultiByte(CP_ACP, 0, Source, SysStringLen(Source), SourceA, 1023, NULL, NULL)] = 0;
MessageBox(View->m_hWnd, MessageA, SourceA, MB_ICONERROR);
}
// ReadRegistryはetc_uty.cppに移動しました.
//
CWSHMacroManager::CWSHMacroManager(std::wstring const AEngineName) : m_EngineName(AEngineName)
{
}
CWSHMacroManager::~CWSHMacroManager()
{
}
void CWSHMacroManager::ReadyCommands(CInterfaceObject *Object, MacroFuncInfo *Info)
{
while(Info->m_nFuncID != -1) // Aug. 29, 2002 genta 番人の値が変更されたのでここも変更
{
wchar_t FuncName[256];
MultiByteToWideChar(CP_ACP, 0, Info->m_pszFuncName, -1, FuncName, 255);
int ArgCount = 0;
for(int I = 0; I < 4; ++I)
if(Info->m_varArguments[I] != VT_EMPTY)
++ArgCount;
Object->AddMethod(FuncName, Info->m_nFuncID, Info->m_varArguments, ArgCount, Info->m_varResult, MacroCommand);
++Info;
}
}
/*!
WSHマクロの実行
@param EditView [in] 操作対象EditView
*/
void CWSHMacroManager::ExecKeyMacro(CEditView *EditView) const
{
CWSHClient* Engine;
Engine = new CWSHClient(m_EngineName.c_str(), MacroError, EditView);
if(Engine->m_Valid)
{
/* // CSMacroMgr.hで配列のサイズが明確に宣言されて無いのでsizeofが使えない
Engine->m_InterfaceObject->ReserveMethods(
sizeof (CSMacroMgr::m_MacroFuncInfoArr) / sizeof (CSMacroMgr::m_MacroFuncInfoArr[0]) +
sizeof (CSMacroMgr::m_MacroFuncInfoNotCommandArr) / sizeof (CSMacroMgr::m_MacroFuncInfoNotCommandArr[0]));
*/
ReadyCommands(Engine->m_InterfaceObject, CSMacroMgr::m_MacroFuncInfoArr);
ReadyCommands(Engine->m_InterfaceObject, CSMacroMgr::m_MacroFuncInfoNotCommandArr);
Engine->Execute(m_Source.c_str());
//EditView->Redraw();
EditView->ShowEditCaret();
}
delete Engine;
}
/*!
WSHマクロの読み込み
@param Instance [in] インスタンスハンドル(未使用)
@param Path [in] ファイルのパス
*/
BOOL CWSHMacroManager::LoadKeyMacro(HINSTANCE Instance, char const* Path)
{
BOOL Result = FALSE;
HANDLE File = CreateFile(Path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if(File != INVALID_HANDLE_VALUE)
{
unsigned long Size = GetFileSize(File, NULL); //ギガ単位のマクロはさすがに無いでしょう…
char *Buffer = new char[Size];
wchar_t *WideBuffer = new wchar_t[Size + 1]; //Unicode化して長くはならない
if(ReadFile(File, Buffer, Size, &Size, NULL) != 0)
{
WideBuffer[MultiByteToWideChar(CP_ACP, 0, Buffer, Size, WideBuffer, Size)] = 0;
m_Source = WideBuffer;
Result = TRUE;
}
// Nov. 10, 2003 FILE 配列の破棄なので、[括弧]を追加
delete [] Buffer;
delete [] WideBuffer;
CloseHandle(File);
}
return Result;
}
CMacroManagerBase* CWSHMacroManager::Creator(char const *FileExt)
{
char FileExtWithDot[1024], FileType[1024], EngineName[1024]; //1024を超えたら後は知りません
wchar_t EngineNameW[1024];
strcpy( FileExtWithDot, "." );
strcat( FileExtWithDot, FileExt );
if(ReadRegistry(HKEY_CLASSES_ROOT, FileExtWithDot, NULL, FileType, 1024))
{
lstrcat(FileType, "\\ScriptEngine");
if(ReadRegistry(HKEY_CLASSES_ROOT, FileType, NULL, EngineName, 1024))
{
MultiByteToWideChar(CP_ACP, 0, EngineName, -1, EngineNameW, sizeof(EngineNameW) / sizeof(wchar_t));
return new CWSHMacroManager(EngineNameW);
}
}
return NULL;
}
void CWSHMacroManager::declare()
{
//暫定
CMacroFactory::Instance()->RegisterCreator(Creator);
}
#if 0
Feb. 08, 2003 使ってないのでとりあえずコメントアウト
void CWSHMacroManager::EnumEngines(EngineCallback Proc)
{
char FileExtWithDot[1024], FileType[1024], EngineName[1024]; //1024を超えたら後は知りません
LONG lret;
DWORD index;
DWORD dwSize;
FILETIME szFileTime;
for( index = 0; ; index++ )
{
/* 列挙する */
dwSize = sizeof( FileExtWithDot );
memset( FileExtWithDot, 0, sizeof( FileExtWithDot ) );
lret = RegEnumKeyEx( HKEY_CLASSES_ROOT, index, FileExtWithDot, &dwSize, NULL, NULL, NULL, &szFileTime );
//if( lret == ERROR_NO_MORE_ITEMS ) break; /* 列挙終了 */
if( lret != ERROR_SUCCESS ) break; /* 列挙終了 */
if( FileExtWithDot[0] == '.' ) /* 拡張子か? */
{
/* スクリプトエンジンか確認する */
if(ReadRegistry(HKEY_CLASSES_ROOT, FileExtWithDot, NULL, FileType, 1024))
{
lstrcat(FileType, "\\ScriptEngine");
if(ReadRegistry(HKEY_CLASSES_ROOT, FileType, NULL, EngineName, 1024))
{
Proc(FileExtWithDot + 1, EngineName);
}
}
}
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -