Commit 5a67b266 authored by Gabriel Ivăncescu's avatar Gabriel Ivăncescu Committed by Alexandre Julliard

msscript.ocx: Implement IScriptControl::Run.

parent e076f84c
...@@ -20,12 +20,14 @@ ...@@ -20,12 +20,14 @@
#include "windows.h" #include "windows.h"
#include "initguid.h" #include "initguid.h"
#include "dispex.h"
#include "ole2.h" #include "ole2.h"
#include "olectl.h" #include "olectl.h"
#include "objsafe.h" #include "objsafe.h"
#include "activscp.h" #include "activscp.h"
#include "rpcproxy.h" #include "rpcproxy.h"
#include "msscript.h" #include "msscript.h"
DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
#include "wine/debug.h" #include "wine/debug.h"
#include "wine/heap.h" #include "wine/heap.h"
...@@ -71,6 +73,7 @@ typedef struct ScriptHost { ...@@ -71,6 +73,7 @@ typedef struct ScriptHost {
IActiveScript *script; IActiveScript *script;
IActiveScriptParse *parse; IActiveScriptParse *parse;
IDispatch *script_dispatch;
SCRIPTSTATE script_state; SCRIPTSTATE script_state;
CLSID clsid; CLSID clsid;
...@@ -200,6 +203,17 @@ static struct named_item *host_get_named_item(ScriptHost *host, const WCHAR *nam ...@@ -200,6 +203,17 @@ static struct named_item *host_get_named_item(ScriptHost *host, const WCHAR *nam
return NULL; return NULL;
} }
static HRESULT get_script_dispatch(struct ScriptControl *control, IDispatch **disp)
{
if (!control->host->script_dispatch)
{
HRESULT hr = IActiveScript_GetScriptDispatch(control->host->script, NULL, &control->host->script_dispatch);
if (FAILED(hr)) return hr;
}
*disp = control->host->script_dispatch;
return S_OK;
}
static HRESULT set_script_state(ScriptHost *host, SCRIPTSTATE state) static HRESULT set_script_state(ScriptHost *host, SCRIPTSTATE state)
{ {
HRESULT hr; HRESULT hr;
...@@ -210,6 +224,19 @@ static HRESULT set_script_state(ScriptHost *host, SCRIPTSTATE state) ...@@ -210,6 +224,19 @@ static HRESULT set_script_state(ScriptHost *host, SCRIPTSTATE state)
return hr; return hr;
} }
static HRESULT start_script(struct ScriptControl *control)
{
HRESULT hr = S_OK;
if (!control->host || control->state != Initialized)
return E_FAIL;
if (control->host->script_state != SCRIPTSTATE_STARTED)
hr = set_script_state(control->host, SCRIPTSTATE_STARTED);
return hr;
}
static inline ScriptControl *impl_from_IScriptControl(IScriptControl *iface) static inline ScriptControl *impl_from_IScriptControl(IScriptControl *iface)
{ {
return CONTAINING_RECORD(iface, ScriptControl, IScriptControl_iface); return CONTAINING_RECORD(iface, ScriptControl, IScriptControl_iface);
...@@ -316,7 +343,10 @@ static void release_script_engine(ScriptHost *host) ...@@ -316,7 +343,10 @@ static void release_script_engine(ScriptHost *host)
if (host->parse) if (host->parse)
IActiveScriptParse_Release(host->parse); IActiveScriptParse_Release(host->parse);
if (host->script_dispatch)
IDispatch_Release(host->script_dispatch);
host->script_dispatch = NULL;
host->parse = NULL; host->parse = NULL;
host->script = NULL; host->script = NULL;
...@@ -539,6 +569,7 @@ static HRESULT init_script_host(const CLSID *clsid, ScriptHost **ret) ...@@ -539,6 +569,7 @@ static HRESULT init_script_host(const CLSID *clsid, ScriptHost **ret)
host->ref = 1; host->ref = 1;
host->script = NULL; host->script = NULL;
host->parse = NULL; host->parse = NULL;
host->script_dispatch = NULL;
host->clsid = *clsid; host->clsid = *clsid;
list_init(&host->named_items); list_init(&host->named_items);
...@@ -982,15 +1013,8 @@ static HRESULT parse_script_text(ScriptControl *control, BSTR script_text, DWORD ...@@ -982,15 +1013,8 @@ static HRESULT parse_script_text(ScriptControl *control, BSTR script_text, DWORD
EXCEPINFO excepinfo; EXCEPINFO excepinfo;
HRESULT hr; HRESULT hr;
if (!control->host || control->state != Initialized) hr = start_script(control);
return E_FAIL; if (FAILED(hr)) return hr;
if (control->host->script_state != SCRIPTSTATE_STARTED)
{
hr = set_script_state(control->host, SCRIPTSTATE_STARTED);
if (FAILED(hr))
return hr;
}
hr = IActiveScriptParse_ParseScriptText(control->host->parse, script_text, NULL, hr = IActiveScriptParse_ParseScriptText(control->host->parse, script_text, NULL,
NULL, NULL, 0, 1, flag, res, &excepinfo); NULL, NULL, 0, 1, flag, res, &excepinfo);
...@@ -1032,8 +1056,62 @@ static HRESULT WINAPI ScriptControl_ExecuteStatement(IScriptControl *iface, BSTR ...@@ -1032,8 +1056,62 @@ static HRESULT WINAPI ScriptControl_ExecuteStatement(IScriptControl *iface, BSTR
static HRESULT WINAPI ScriptControl_Run(IScriptControl *iface, BSTR procedure_name, SAFEARRAY **parameters, VARIANT *res) static HRESULT WINAPI ScriptControl_Run(IScriptControl *iface, BSTR procedure_name, SAFEARRAY **parameters, VARIANT *res)
{ {
ScriptControl *This = impl_from_IScriptControl(iface); ScriptControl *This = impl_from_IScriptControl(iface);
FIXME("(%p)->(%s %p %p)\n", This, debugstr_w(procedure_name), parameters, res); IDispatchEx *dispex;
return E_NOTIMPL; IDispatch *disp;
SAFEARRAY *sa;
DISPPARAMS dp;
DISPID dispid;
HRESULT hr;
UINT i;
TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(procedure_name), parameters, res);
if (!parameters || !res) return E_POINTER;
if (!(sa = *parameters)) return E_POINTER;
V_VT(res) = VT_EMPTY;
if (sa->cDims == 0) return DISP_E_BADINDEX;
if (!(sa->fFeatures & FADF_VARIANT)) return DISP_E_BADVARTYPE;
hr = start_script(This);
if (FAILED(hr)) return hr;
hr = get_script_dispatch(This, &disp);
if (FAILED(hr)) return hr;
hr = IDispatch_GetIDsOfNames(disp, &IID_NULL, &procedure_name, 1, LOCALE_USER_DEFAULT, &dispid);
if (FAILED(hr)) return hr;
dp.cArgs = sa->rgsabound[0].cElements;
dp.rgdispidNamedArgs = NULL;
dp.cNamedArgs = 0;
dp.rgvarg = heap_alloc(dp.cArgs * sizeof(*dp.rgvarg));
if (!dp.rgvarg) return E_OUTOFMEMORY;
hr = SafeArrayLock(sa);
if (SUCCEEDED(hr))
{
/* The DISPPARAMS are stored in reverse order */
for (i = 0; i < dp.cArgs; i++)
dp.rgvarg[i] = *(VARIANT*)((char*)(sa->pvData) + (dp.cArgs - i - 1) * sa->cbElements);
SafeArrayUnlock(sa);
hr = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
if (FAILED(hr))
{
hr = IDispatch_Invoke(disp, dispid, &IID_NULL, LOCALE_USER_DEFAULT,
DISPATCH_METHOD, &dp, res, NULL, NULL);
}
else
{
hr = IDispatchEx_InvokeEx(dispex, dispid, LOCALE_USER_DEFAULT,
DISPATCH_METHOD, &dp, res, NULL, NULL);
IDispatchEx_Release(dispex);
}
}
heap_free(dp.rgvarg);
return hr;
} }
static const IScriptControlVtbl ScriptControlVtbl = { static const IScriptControlVtbl ScriptControlVtbl = {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment