M
Mika Hakkarainen
Hi all,
I have a strange(?) problem and I hope someone could help me or explain
the reason.
I have multithreaded COM dll written with C++ (Visual Studio .NET 2003).
From this DLL I try to invoke Excel's Run method with parameters. So I try
to call my own procedure written in excel VBA when timer or network even
occurs.
Everything works just fine until I try to update any cell on worksheet in
this Sub. I can take the passed values, I even can change the sheet name,
but updating any cell stops the system. Task managers prosessor usage is
100%. It might work once, but when I call the Invoke second time, this
time it totally stops.
Why I can't update any cell in worksheet in this procedure?
Below you can find excel macros and dll (c++) functions.
I am using Windows 2000, Visual Studio .NET 2003 and Excel 97 (tested also
in Excel in XP)
Please help!
Regards,
Mika Hakkarainen
The excel sub :
(1)This works:
Public Sub IncomingCommand(id As String, guidlist As String, buffer As
String)
End Sub
(2)This works also:
Public Sub IncomingCommand(id As String, guidlist As String, buffer As
String)
MsgBox buffer
End Sub
(3)Also this works
Dim b As String
Public Sub IncomingCommand(id As String, guidlist As String, buffer As
String)
b = buffer
End Sub
(4)This stops the system
Dim b As String
Public Sub IncomingCommand(id As String, guidlist As String, buffer As
String)
Range("A1").Value = buffer
End Sub
(5)This stops the system also
Dim b As String
Public Sub IncomingCommand(id As String, guidlist As String, buffer As
String)
Range("A1").Value = "Test string"
End Sub
In DLL I have tried two different aproach. Both of them works equally.
int MyClass::NetworkEvent1(int id, const char* values, const char* data){
CComVariant varArgs_param1(L"IncomingCommand");
CComVariant varArgs_param2(id);
CComVariant varArgs_param3(guidList);
CComVariant varArgs_param4(data);
CComVariant varArgs[4] ={varArgs_param4,
varArgs_param3,varArgs_param2,varArgs_param1};
EXCEPINFO pExcepInfo;
DISPPARAMS dispparams = { &varArgs[0], NULL, 4, 0 };
HRESULT hr;
char cErr[64];
unsigned int puArgErr = 0;
// I have previously took m_pOfficeDispatch and RunDispid values
// And those are ok, because I am able to call Run?
hr = m_pOfficeDispatch->Invoke(m_RunDispid,IID_NULL,LOCALE_SYSTEM_DEFAULT,
DISPATCH_METHOD, &dispparams, NULL, &pExcepInfo, &puArgErr);
if(FAILED(hr))
{
sprintf(cErr, "Error, hr = 0x%08lx", hr);
MessageBox(NULL, cErr, "InvokeGuids",
MB_OK | MB_SETFOREGROUND);
return hr;
}
return 0;
}
int MyClass::NetworkEvent2(int id, const char* values, const char* data){
wchar_t cmd[50];
wchar_t guid[20];
wchar_t buffer[20];
int i = id;
if (0 == MultiByteToWideChar(CP_ACP, 0, "IncomingCommand", -1, cmd, 50) )
{
return 0;
}
SysAllocString(cmd);
VARIANT c1;
c1.vt = VT_BSTR;
c1.bstrVal = SysAllocString(cmd);
VARIANT c2;
c2.vt = VT_I2;
c2.iVal = i;
if (0 == MultiByteToWideChar(CP_ACP, 0, values, -1, guid, 20) ) {
return 0;
}
VARIANT c3;
c3.vt = VT_BSTR;
c3.bstrVal = SysAllocString(guid);
if (0 == MultiByteToWideChar(CP_ACP, 0, data, -1, buffer, 20) ) {
return 0;
}
VARIANT c4;
c4.vt = VT_BSTR;
c4.bstrVal = SysAllocString(buffer);
VARIANT full[4] = {c4,c3,c2,c1};
EXCEPINFO pExcepInfo;
DISPPARAMS dispparams = { full, NULL, 4, 0 };
HRESULT hr;
char cErr[64];
unsigned int puArgErr = 0;
// I have previously took m_pOfficeDispatch and RunDispid values
// And those are ok, because I am able to call Run?
hr = m_pOfficeDispatch->Invoke(m_RunDispid,IID_NULL,LOCALE_SYSTEM_DEFAULT,
DISPATCH_METHOD, &dispparams, NULL, &pExcepInfo, &puArgErr);
if(FAILED(hr))
{
sprintf(cErr, "Error, hr = 0x%08lx", hr);
MessageBox(NULL, cErr, "InvokeGuids",
MB_OK | MB_SETFOREGROUND);
SysFreeString(cmd);
SysFreeString(guid);
SysFreeString(buffer);
return hr;
}
SysFreeString(cmd);
SysFreeString(guid);
SysFreeString(buffer);
return 0;
}
I have a strange(?) problem and I hope someone could help me or explain
the reason.
I have multithreaded COM dll written with C++ (Visual Studio .NET 2003).
From this DLL I try to invoke Excel's Run method with parameters. So I try
to call my own procedure written in excel VBA when timer or network even
occurs.
Everything works just fine until I try to update any cell on worksheet in
this Sub. I can take the passed values, I even can change the sheet name,
but updating any cell stops the system. Task managers prosessor usage is
100%. It might work once, but when I call the Invoke second time, this
time it totally stops.
Why I can't update any cell in worksheet in this procedure?
Below you can find excel macros and dll (c++) functions.
I am using Windows 2000, Visual Studio .NET 2003 and Excel 97 (tested also
in Excel in XP)
Please help!
Regards,
Mika Hakkarainen
The excel sub :
(1)This works:
Public Sub IncomingCommand(id As String, guidlist As String, buffer As
String)
End Sub
(2)This works also:
Public Sub IncomingCommand(id As String, guidlist As String, buffer As
String)
MsgBox buffer
End Sub
(3)Also this works
Dim b As String
Public Sub IncomingCommand(id As String, guidlist As String, buffer As
String)
b = buffer
End Sub
(4)This stops the system
Dim b As String
Public Sub IncomingCommand(id As String, guidlist As String, buffer As
String)
Range("A1").Value = buffer
End Sub
(5)This stops the system also
Dim b As String
Public Sub IncomingCommand(id As String, guidlist As String, buffer As
String)
Range("A1").Value = "Test string"
End Sub
In DLL I have tried two different aproach. Both of them works equally.
int MyClass::NetworkEvent1(int id, const char* values, const char* data){
CComVariant varArgs_param1(L"IncomingCommand");
CComVariant varArgs_param2(id);
CComVariant varArgs_param3(guidList);
CComVariant varArgs_param4(data);
CComVariant varArgs[4] ={varArgs_param4,
varArgs_param3,varArgs_param2,varArgs_param1};
EXCEPINFO pExcepInfo;
DISPPARAMS dispparams = { &varArgs[0], NULL, 4, 0 };
HRESULT hr;
char cErr[64];
unsigned int puArgErr = 0;
// I have previously took m_pOfficeDispatch and RunDispid values
// And those are ok, because I am able to call Run?
hr = m_pOfficeDispatch->Invoke(m_RunDispid,IID_NULL,LOCALE_SYSTEM_DEFAULT,
DISPATCH_METHOD, &dispparams, NULL, &pExcepInfo, &puArgErr);
if(FAILED(hr))
{
sprintf(cErr, "Error, hr = 0x%08lx", hr);
MessageBox(NULL, cErr, "InvokeGuids",
MB_OK | MB_SETFOREGROUND);
return hr;
}
return 0;
}
int MyClass::NetworkEvent2(int id, const char* values, const char* data){
wchar_t cmd[50];
wchar_t guid[20];
wchar_t buffer[20];
int i = id;
if (0 == MultiByteToWideChar(CP_ACP, 0, "IncomingCommand", -1, cmd, 50) )
{
return 0;
}
SysAllocString(cmd);
VARIANT c1;
c1.vt = VT_BSTR;
c1.bstrVal = SysAllocString(cmd);
VARIANT c2;
c2.vt = VT_I2;
c2.iVal = i;
if (0 == MultiByteToWideChar(CP_ACP, 0, values, -1, guid, 20) ) {
return 0;
}
VARIANT c3;
c3.vt = VT_BSTR;
c3.bstrVal = SysAllocString(guid);
if (0 == MultiByteToWideChar(CP_ACP, 0, data, -1, buffer, 20) ) {
return 0;
}
VARIANT c4;
c4.vt = VT_BSTR;
c4.bstrVal = SysAllocString(buffer);
VARIANT full[4] = {c4,c3,c2,c1};
EXCEPINFO pExcepInfo;
DISPPARAMS dispparams = { full, NULL, 4, 0 };
HRESULT hr;
char cErr[64];
unsigned int puArgErr = 0;
// I have previously took m_pOfficeDispatch and RunDispid values
// And those are ok, because I am able to call Run?
hr = m_pOfficeDispatch->Invoke(m_RunDispid,IID_NULL,LOCALE_SYSTEM_DEFAULT,
DISPATCH_METHOD, &dispparams, NULL, &pExcepInfo, &puArgErr);
if(FAILED(hr))
{
sprintf(cErr, "Error, hr = 0x%08lx", hr);
MessageBox(NULL, cErr, "InvokeGuids",
MB_OK | MB_SETFOREGROUND);
SysFreeString(cmd);
SysFreeString(guid);
SysFreeString(buffer);
return hr;
}
SysFreeString(cmd);
SysFreeString(guid);
SysFreeString(buffer);
return 0;
}