• Welcome to Powerbasic Museum 2020-B.
 

64 Bit COM C++ Code Works With Out Of Process 32 Bit Servers ...

Started by Frederick J. Harris, February 12, 2015, 08:42:08 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Frederick J. Harris

...such as MS Excel.  Hadn't really thought of that scenario!  Of course, we all know of the dll situation where 32 bit code needs 32 bit dlls and 64 bit code needs 64 bits dlls, but the out of process server thing appears to be something of a wrinkle.  Here is some C++ code that opens an Excel file for me created with 32 bit Excel and 32 bit Excel is what is running on my 64 Bit Windows.  The file is C:\Tallies\Documents\01200206.xls and it successfully reads 10 rows of data and prints it to the console window.  Some of these wrappers some might find useful.  Oh!  I'm using my String Class instead of the C++ one so you would have to change that.  Shouldn't be a biggie.  Was using 64 bit Mingw GNU C++ ...


#ifndef   UNICODE
#define   UNICODE
#endif
#ifndef   _UNICODE
#define   _UNICODE
#endif
#include <windows.h>
#include <cstdio>
#include "Strings.h"
const CLSID CLSID_XLApplication = {0x00024500,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
const IID   IID_Application     = {0x000208D5,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};


String GetXLCell(IDispatch* pXLWorksheet, LCID& lcid, String& strRange)
{
DISPPARAMS      NoArgs         = {NULL,NULL,0,0};
IDispatch*      pXLRange       = NULL;
VARIANT         vArgArray[1];
VARIANT         vResult;
DISPPARAMS      DispParams;
HRESULT         hr;
String          strCell;

VariantInit(&vResult);
vArgArray[0].vt                = VT_BSTR,
vArgArray[0].bstrVal           = SysAllocString(strRange.lpStr());
DispParams.rgvarg              = vArgArray;
DispParams.rgdispidNamedArgs   = 0;
DispParams.cArgs               = 1;  // Try to get Range
DispParams.cNamedArgs          = 0;  // Invoke _Worksheet::Range("A1")  << returns IDispatch** to dispinterface Range
hr=pXLWorksheet->Invoke(197,IID_NULL,lcid,DISPATCH_PROPERTYGET,&DispParams,&vResult,NULL,NULL);
if(FAILED(hr))
    return strCell;
pXLRange=vResult.pdispVal;

//Member Get Value <6> () As Variant
VariantClear(&vArgArray[0]);
hr=pXLRange->Invoke(6,IID_NULL,lcid,DISPATCH_PROPERTYGET,&NoArgs,&vResult,NULL,NULL);
if(SUCCEEDED(hr))
{
    strCell=vResult.bstrVal;
    VariantClear(&vResult);
}

return strCell;
}


IDispatch* ptrSetWorkSheet(IDispatch* pXLWorksheets, LCID& lcid, String& strSheet, BOOL& blnSuccess)
{
VARIANT         vResult;
HRESULT         hr;
VARIANT         vArgArray[1];
DISPPARAMS      DispParams;
DISPID          dispidNamed;
IDispatch*      pXLWorksheet   = NULL;

// Member Get Item <170> (In Index As Variant<0>) As IDispatch  >> Gets pXLWorksheet
// [id(0x000000aa), propget, helpcontext(0x000100aa)] IDispatch* Item([in] VARIANT Index);
VariantInit(&vResult);
vArgArray[0].vt                = VT_BSTR;
vArgArray[0].bstrVal           = SysAllocString(strSheet.lpStr());
DispParams.rgvarg              = vArgArray;
DispParams.rgdispidNamedArgs   = &dispidNamed;
DispParams.cArgs               = 1;
DispParams.cNamedArgs          = 0;
hr=pXLWorksheets->Invoke(0xAA,IID_NULL,lcid,DISPATCH_PROPERTYGET,&DispParams,&vResult,NULL,NULL);
if(FAILED(hr))
    return NULL;
pXLWorksheet=vResult.pdispVal;
SysFreeString(vArgArray[0].bstrVal);

// Worksheet::Select()
VariantInit(&vResult);
VARIANT varReplace;
varReplace.vt                  = VT_BOOL;
varReplace.boolVal             = VARIANT_TRUE;
dispidNamed                    = 0;
DispParams.rgvarg              = &varReplace;
DispParams.rgdispidNamedArgs   = &dispidNamed;
DispParams.cArgs               = 1;
DispParams.cNamedArgs          = 1;
hr=pXLWorksheet->Invoke(0xEB,IID_NULL,lcid,DISPATCH_METHOD,&DispParams,&vResult,NULL,NULL);
if(SUCCEEDED(hr))
    blnSuccess=TRUE;
else
    blnSuccess=FALSE;

return pXLWorksheet;
}


IDispatch* ptrXLWorkBook(IDispatch* pXLWorkbooks, LCID& lcid, String& strWorkBookPath, BOOL& blnSuccess)
{
IDispatch*      pXLWorkbook   = NULL;
VARIANT         vResult;
VARIANT         vArgArray[1];
DISPPARAMS      DispParams;
DISPID          dispidNamed;
HRESULT         hr;

VariantInit(&vResult);         // Call Workbooks::Open() - 682  >> Gets pXLWorkbook
vArgArray[0].vt                = VT_BSTR;
vArgArray[0].bstrVal           = SysAllocString(strWorkBookPath.lpStr());
DispParams.rgvarg              = vArgArray;
DispParams.rgdispidNamedArgs   = &dispidNamed;
DispParams.cArgs               = 1;
DispParams.cNamedArgs          = 0;
hr=pXLWorkbooks->Invoke(682,IID_NULL,lcid,DISPATCH_METHOD,&DispParams,&vResult,NULL,NULL);
if(FAILED(hr))
{
    blnSuccess=FALSE;
    return NULL;
}
SysFreeString(vArgArray[0].bstrVal);
pXLWorkbook=vResult.pdispVal;
blnSuccess=TRUE;

return pXLWorkbook;
}


int main()
{
DISPPARAMS NoArgs         = {NULL,NULL,0,0};
IDispatch* pXLApp         = NULL;
IDispatch* pXLWorkbooks   = NULL;
IDispatch* pXLWorkbook    = NULL;
IDispatch* pXLWorksheets  = NULL;
IDispatch* pXLWorksheet   = NULL;
IDispatch* pXLRange       = NULL;
String strParam,strNum;
VARIANT vResult;
BOOL blnSuccess;
HRESULT hr;
LCID lcid;

CoInitialize(NULL);
hr=CoCreateInstance(CLSID_XLApplication, NULL, CLSCTX_LOCAL_SERVER, IID_Application, (void**)&pXLApp);
if(FAILED(hr))
    goto Sad_Ending;
printf("CoCreateInstance() Succeeded!  pXLApp = %u\n",(unsigned)pXLApp);
lcid=GetUserDefaultLCID();
VariantInit(&vResult);  //572 Get _Application::Workbooks  >> Gets pXLWorkbooks
hr=pXLApp->Invoke(572,IID_NULL,lcid,DISPATCH_PROPERTYGET,&NoArgs,&vResult,NULL,NULL);
if(FAILED(hr))
    goto Sad_Ending;
pXLWorkbooks=vResult.pdispVal;
strParam=L"C:\\Tallies\\Documents\\01200206.xls";
pXLWorkbook=ptrXLWorkBook(pXLWorkbooks, lcid, strParam, blnSuccess);
if(!pXLWorkbook)
    goto Sad_Ending;
if(!blnSuccess)
    goto Sad_Ending;
VariantInit(&vResult);
hr=pXLWorkbook->Invoke(494,IID_NULL,lcid,DISPATCH_PROPERTYGET,&NoArgs,&vResult,NULL,NULL);
if(FAILED(hr))
    goto Sad_Ending;
pXLWorksheets=vResult.pdispVal;
blnSuccess=FALSE, strParam=L"FMT-19";
pXLWorksheet=ptrSetWorkSheet(pXLWorksheets, lcid, strParam, blnSuccess);
if(!pXLWorksheet)
    goto Sad_Ending;
if(!blnSuccess)
    goto Sad_Ending;
for(int i=16; i<=25; i++)
{
     strParam=L"K", strNum=i;
     strParam=strParam+strNum;
     //strCell=GetXLCell(pXLWorksheet, lcid, strParam);
     wprintf(L"%s\n",GetXLCell(pXLWorksheet, lcid, strParam).lpStr());
}
pXLApp->Invoke(0x0000012e,IID_NULL,LOCALE_USER_DEFAULT,DISPATCH_METHOD,&NoArgs,NULL,NULL,NULL); // pXLApp->Quit() 0x12E

Sad_Ending: // Workbooks::Close() 277
if(pXLRange)
    pXLRange->Release();
if(pXLWorksheet)
    pXLWorksheet->Release();
if(pXLWorksheets)
    pXLWorksheets->Release();
if(pXLWorkbook)
    pXLWorkbook->Release();
if(pXLWorkbooks)
    pXLWorkbooks->Release();
if(pXLApp)
    pXLApp->Release();
CoUninitialize();
getchar();

return 0;
}

// Call Workbook::Worksheets()  //Member Get Worksheets  <494> () As XLSheets  >> Gets pXLWorksheets
// Call Workbook::Sheets()      //Member Get Sheets      <485> () As XLSheets
//[id(0x000001e5), propget, helpcontext(0x000101e5)] HRESULT Sheets([out, retval] Sheets** RHS);
//[id(0x000001ee), propget, helpcontext(0x000101ee)] HRESULT Worksheets([out, retval] Sheets** RHS);