⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cwsh.cpp

📁 日本的开源编辑器源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
{
	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 + -