Excel hangs up (Invoke Run method from dll)

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;
}
 
K

Kim Greenlee

First, I have no idea why your code would fail. However, what you might want
to do is add some code to watch for errors. For example:

Public Sub IncomingCommand(id As String, guidlist As String, buffer As
String)

On Error GoTo SomethingIsFunky
Range("A1").Value = "Test string"
GoTo NoErrorOccurred

SomethingIsFunky:

' Open a file
' Write out the error
' Close the file


NoErrorOccurred:

End Sub

Good luck,

Kim
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top