CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 26
  1. #1
    Join Date
    Apr 2013
    Location
    Prague / Cracow
    Posts
    47

    COleVariant in WinAPI (afxdisp.h)

    Hey ho...

    guess i need some help of experts again.. wanna export listview to MS excel. i found a really nice article on this:
    http://www.codeproject.com/Articles/...mation-Using-C

    however the only one thing that does not seem to work with my OLE is COleVariant class.
    It's simply not declared. I tried adding afxdisp.h but it's not a standard lib in my Microsoft Visual Visual Studio Express 2012 and it seems to be very specific to MFC.

    I tried to add it manually from internet but it's then referring (calling) to other *.h

    is there any way to either replace COleVariant with VARIANT (or something) or add afxdisp.h (and all connected libs) to my program?
    i wanna achieve this :

    Code:
    IDispatch* pRange;
    	{
    		COleVariant oleRange(szCell);
    		VARIANT result;
    		VariantInit(&result);
    		m_hr=OLEMethod(DISPATCH_PROPERTYGET, &result, pSheet, L"Range", 1, oleRange.Detach());
    		pRange = result.pdispVal;
    	}
    will be grateful for any hint!
    thanks
    .

  2. #2
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: COleVariant in WinAPI (afxdisp.h)

    COleVariant is a c++ wrapper class around VARIANT
    so yes, you can use VARIANT but you'll have to do all the conversions to/from yourself.

  3. #3
    Join Date
    Apr 2013
    Location
    Prague / Cracow
    Posts
    47

    Re: COleVariant in WinAPI (afxdisp.h)

    it doesnt really help coz i simply donno how to do this.
    i would like to use ATL and MFC libs in my VC Express 2012 version. i tried few links with using SDK but all refer to old version of SDK and VC Express 2008 which is completely different to mine.
    There must be some way to put those lib into my program.

  4. #4
    Join Date
    Apr 2013
    Location
    Prague / Cracow
    Posts
    47

    Re: COleVariant in WinAPI (afxdisp.h)

    Ok.. I tried to run it with ATL and MFC libs, i installed 30days version of VC Prof 2012, and although COleVariant worked, there is a lot of dependencies when i started adding ATL libs. i cannot even compile my program with windows.h anymore coz ATL does not go along with win32 app, i got hundred of warnings and errors, i permanently gave up with this approach.
    I guess my last chance now is to find some way to convert COleVariant to something else.

    original code:
    Code:
    IDispatch* pRange;
    {
    LPCTSTR szRange = "a1";
    COleVariant oleRange(szRange);
    VARIANT result;
    VariantInit(&result);
    m_hr=OLEMethod(DISPATCH_PROPERTYGET, &result, pSheet, L"Range", 1, oleRange.Detach());
    pRange = result.pdispVal;
    }
    i would like to change it to something like this:

    Code:
    IDispatch* pRange;
    {
    VARIANT xx;
    xx.vt=VT_I1;
    xx.pcVal="a1";
    VARIANT result;
    VariantInit(&result);
    m_hr=OLEMethod(DISPATCH_PROPERTYGET, &result, pSheet, L"Range", 1, functionDetach(xx));
    pRange = result.pdispVal;
    }
    does anyone have any idea how that functionDetach(xx) should look like to give me the same result as COleVariantClass.Detach()?

  5. #5
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,395

    Re: COleVariant in WinAPI (afxdisp.h)

    MSDN does know it for sure!
    COleVariant:etach
    So just pass in your xx instead of "functionDetach(xx)"!
    Victor Nijegorodov

  6. #6
    Join Date
    Apr 2013
    Location
    Prague / Cracow
    Posts
    47

    Re: COleVariant in WinAPI (afxdisp.h)

    Hi Victor,
    tried that but then the OLEMethod function breaks at Invoking:
    hr = pDisp->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, nType, &dp, pvResult, NULL, NULL);


    The code of OLEMethod:
    Code:
    HRESULT OLEMethod(int nType, VARIANT *pvResult, IDispatch *pDisp,LPOLESTR ptName, int cArgs...)
    {
    	if(!pDisp) return E_FAIL;
    
    	va_list marker;
    	va_start(marker, cArgs);
    
    	DISPPARAMS dp = { NULL, NULL, 0, 0 };
    	DISPID dispidNamed = DISPID_PROPERTYPUT;
    	DISPID dispID;
    	char szName[200];
    
    
    	// Convert down to ANSI
    	WideCharToMultiByte(CP_ACP, 0, ptName, -1, szName, 256, NULL, NULL);
    
    	// Get DISPID for name passed...
    	HRESULT hr= pDisp->GetIDsOfNames(IID_NULL, &ptName, 1, LOCALE_USER_DEFAULT, &dispID);
    	if(FAILED(hr)) {
    		return hr;
    	}
    	// Allocate memory for arguments...
    	VARIANT *pArgs = new VARIANT[cArgs+1];
    	// Extract arguments...
    	for(int i=0; i<cArgs; i++) {
    		pArgs[i] = va_arg(marker, VARIANT);
    	}
    
    	// Build DISPPARAMS
    	dp.cArgs = cArgs;
    	dp.rgvarg = pArgs;
    
    	// Handle special-case for property-puts!
    	if(nType & DISPATCH_PROPERTYPUT) {
    		dp.cNamedArgs = 1;
    		dp.rgdispidNamedArgs = &dispidNamed;
    	}
    
    	// Make the call!
    	hr = pDisp->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, nType, &dp, pvResult, NULL, NULL);
    	if(FAILED(hr)) {
    		return hr;
    	}
    	// End variable-argument section...
    	va_end(marker);
    
    	delete [] pArgs;
    	return hr;
    }

    The error says:
    Unhandled exception at 0x750E80EE (oleaut32.dll) in Kredens (OLE aut).exe: 0xC0000005: Access violation writing location 0x010B8074



    I will only add that the OLEMethod works correctly coz it does NOT break at e.g:
    Code:
    IDispatch *pSheet;
    	{
    		VARIANT result;
    		VariantInit(&result);
    		VARIANT itemn;
    		itemn.vt = VT_I4;
    		itemn.lVal = 1;
    		m_hr=OLEMethod(DISPATCH_PROPERTYGET, &result, pSheets, L"Item", 1, itemn);
    		pSheet = result.pdispVal;
    	}

  7. #7
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,395

    Re: COleVariant in WinAPI (afxdisp.h)

    Quote Originally Posted by berkov View Post
    i would like to change it to something like this:

    Code:
    IDispatch* pRange;
    {
    VARIANT xx;
    xx.vt=VT_I1;
    xx.pcVal="a1";
    VARIANT result;
    VariantInit(&result);
    m_hr=OLEMethod(DISPATCH_PROPERTYGET, &result, pSheet, L"Range", 1, functionDetach(xx));
    pRange = result.pdispVal;
    }
    Sorry! I missed this erroneos assignments.
    VT_I1 means theat the value is of type char (one and only one char symbol!) while you are trying to pass in the char* (a ponther to char array)
    Try to change your code to be:
    Code:
    VARIANT xx;
    xx.vt=VT_BSTR;
    xx.pcVal= L"a1";
    Victor Nijegorodov

  8. #8
    Join Date
    Apr 2013
    Location
    Prague / Cracow
    Posts
    47

    Re: COleVariant in WinAPI (afxdisp.h)

    Ah, you are right, didn't see it.

    i tried it and now it seems the BSTR does not take the UNICODE:
    IntelliSense: a value of type "const wchar_t *" cannot be assigned to an entity of type "CHAR *"

    i had to remove that "L" and put it like this:
    xx.pcVal = "a1";

    and unfortunately i got the same error on runtime as at the beginning.
    any other ideas?

  9. #9
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,395

    Re: COleVariant in WinAPI (afxdisp.h)

    Is your build an ANSI or UNICODE?
    Anyway, you should always use _T() macro for text/symbol constants.
    Victor Nijegorodov

  10. #10
    Join Date
    Apr 2013
    Location
    Prague / Cracow
    Posts
    47

    Re: COleVariant in WinAPI (afxdisp.h)

    The project is "Use Multi-Byte Character Set".
    i tried it with _T("a1") and still the same error.

  11. #11
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,395

    Re: COleVariant in WinAPI (afxdisp.h)

    Ok, then let's begin from the very begin! What error exactly do you have? Where? Please, show your actual code.
    Victor Nijegorodov

  12. #12
    Join Date
    Apr 2013
    Location
    Prague / Cracow
    Posts
    47

    Re: COleVariant in WinAPI (afxdisp.h)

    hmm.. the code is very long, it has a lot of pages as i've been writing it for 4 months now.
    but i will try to copy the most important parts:

    xls.cpp:
    Code:
    #include <windows.h>
    #include "xls.h"
    #include "classes.h"
    #include "resources.h"
    #include "Tchar.h"
    
    
    HRESULT hr2;
    HRESULT OLEMethod(int nType, VARIANT *pvResult, IDispatch *pDisp,LPOLESTR ptName, int cArgs...)
    {
    	if(!pDisp) return E_FAIL;
    
    	va_list marker;
    	va_start(marker, cArgs);
    
    	DISPPARAMS dp = { NULL, NULL, 0, 0 };
    	DISPID dispidNamed = DISPID_PROPERTYPUT;
    	DISPID dispID;
    	char szName[200];
    
    
    	// Convert down to ANSI
    	WideCharToMultiByte(CP_ACP, 0, ptName, -1, szName, 256, NULL, NULL);
    
    	// Get DISPID for name passed...
    	HRESULT hr= pDisp->GetIDsOfNames(IID_NULL, &ptName, 1, LOCALE_USER_DEFAULT, &dispID);
    	if(FAILED(hr)) {
    		return hr;
    	}
    	// Allocate memory for arguments...
    	VARIANT *pArgs = new VARIANT[cArgs+1];
    	// Extract arguments...
    	for(int i=0; i<cArgs; i++) {
    		pArgs[i] = va_arg(marker, VARIANT);
    	}
    
    	// Build DISPPARAMS
    	dp.cArgs = cArgs;
    	dp.rgvarg = pArgs;
    
    	// Handle special-case for property-puts!
    	if(nType & DISPATCH_PROPERTYPUT) {
    		dp.cNamedArgs = 1;
    		dp.rgdispidNamedArgs = &dispidNamed;
    	}
    
    	// Make the call!
    	hr = pDisp->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, nType, &dp, pvResult, NULL, NULL);
    	if(FAILED(hr)) {
    		return hr;
    	}
    	// End variable-argument section...
    	va_end(marker);
    
    	delete [] pArgs;
    	return hr;
    }
    CMSExcel::CMSExcel(void)
    {
    	m_hr=S_OK;
    	m_pEApp=NULL;
    	m_pBooks=NULL;
    	m_pActiveBook=NULL;
    }
    HRESULT CMSExcel::Initialize(bool bVisible)
    {
    	CoInitialize(NULL);
    	CLSID clsid;
    	m_hr = CLSIDFromProgID(L"Excel.Application", &clsid);
    	if(SUCCEEDED(m_hr))
    	{
    		m_hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void **)&m_pEApp);
    		if(FAILED(m_hr)) m_pEApp=NULL;
    	}
    	{
    		m_hr=SetVisible(bVisible);
    	}
    	return m_hr;
    }
    HRESULT CMSExcel::SetVisible(bool bVisible)
    {
    
    	if(!m_pEApp) return E_FAIL;
    	VARIANT x;
    	x.vt = VT_I4;
    	x.lVal = bVisible;
    	m_hr=OLEMethod(DISPATCH_PROPERTYPUT, NULL, m_pEApp, L"Visible", 1, x);
    
    	return m_hr;
    }
    
    HRESULT CMSExcel::NewExcelBook(bool bVisible)
    {
    	if(m_pEApp==NULL) 
    	{
    		if(FAILED(m_hr=Initialize(bVisible)))
    			return m_hr;
    	}
    
    	{
    		VARIANT result;
    		VariantInit(&result);
    		m_hr=OLEMethod(DISPATCH_PROPERTYGET, &result, m_pEApp, L"Workbooks", 0);
    		m_pBooks = result.pdispVal;
    	}	
    
    	{
    		VARIANT result;
    		VariantInit(&result);
    		m_hr=OLEMethod(DISPATCH_METHOD, &result, m_pBooks, L"Add", 0);
    		m_pActiveBook = result.pdispVal;
    	}
    	return m_hr;
    }
    
    HRESULT CMSExcel::SetExcelValue(LPCTSTR szRange,LPCTSTR szValue,bool bAutoFit, int nAlignment)
    {
    	if(!m_pEApp) return E_FAIL;
    	if(!m_pActiveBook) return E_FAIL;
    	IDispatch *pSheets;
    	{
    		VARIANT result;
    		VariantInit(&result);
    
    		m_hr=OLEMethod(DISPATCH_PROPERTYGET, &result, m_pActiveBook, L"Sheets", 0);
    		pSheets = result.pdispVal;
    	}
    	IDispatch *pSheet;
    	{
    		VARIANT result;
    		VariantInit(&result);
    		VARIANT itemn;
    		itemn.vt = VT_I4;
    		itemn.lVal = 1;
    		m_hr=OLEMethod(DISPATCH_PROPERTYGET, &result, pSheets, L"Item", 1, itemn);
    		pSheet = result.pdispVal;
    	}
    	
    	IDispatch* pRange;
    	{
    		//COleVariant oleRange(szRange);
    		VARIANT xx;
    		xx.vt=VT_BSTR;
    		xx.pcVal = _T("a1");
    	
    		VARIANT result;
    		VariantInit(&result);
    		m_hr=OLEMethod(DISPATCH_PROPERTYGET, &result, pSheet, L"Range", 1, xx);
    		pRange = result.pdispVal;
    	}
    
    	{
    		//COleVariant oleValue(szValue);
    		m_hr=OLEMethod(DISPATCH_PROPERTYPUT, NULL, pRange, L"Value", 1, "aa");
    	}
    
    
    	if(bAutoFit)
    	{
    		IDispatch* pEntireColumn;
    		{
    			VARIANT result;
    			VariantInit(&result);
    			m_hr=OLEMethod(DISPATCH_PROPERTYGET, &result, pRange, L"EntireColumn",0);
    			pEntireColumn= result.pdispVal;
    		}
    
    		{
    			m_hr=OLEMethod(DISPATCH_METHOD, NULL, pEntireColumn, L"AutoFit", 0);
    		}	
    		pEntireColumn->Release();
    	}
    
    	{
    		VARIANT x;
    		x.vt = VT_I4;
    		x.lVal = nAlignment;
    		m_hr=OLEMethod(DISPATCH_PROPERTYPUT, NULL, pRange, L"HorizontalAlignment", 1, x);
    	}
    
    	pRange->Release();
    	pSheet->Release();
    	pSheets->Release();
    	return m_hr;
    }
    
    HRESULT CMSExcel::Quit()
    {
    	if(m_pEApp==NULL) return E_FAIL;
    	DISPID dispID;
    	LPOLESTR ptName=(LPOLESTR)"Quit";// LPOLESTR ptName=_T("Quit");
    	m_hr = m_pEApp->GetIDsOfNames(IID_NULL, &ptName, 1, LOCALE_USER_DEFAULT, &dispID);
    	
    	if(SUCCEEDED(m_hr))
    	{
    		DISPPARAMS dp = { NULL, NULL, 0, 0 };
    		m_hr = m_pEApp->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, 
    									&dp, NULL, NULL, NULL);
    	}
    	m_pEApp->Release();
    	m_pEApp=NULL;
    	return m_hr;
    }
    
    
    CMSExcel::~CMSExcel(void)
    {
    	Quit();
    	CoUninitialize();
    }

    xls.h:
    Code:
    #include "classes.h"
    #ifndef xls_h
    #define xls_h
    
    class CMSExcel
    {
    protected:
    	HRESULT m_hr;
    	IDispatch*	m_pEApp;
    	IDispatch*  m_pBooks;
    	IDispatch*	m_pActiveBook;
    private:
    	HRESULT Initialize(bool bVisible=true);
    public:
    	CMSExcel(void);
    	~CMSExcel(void);
    	HRESULT SetVisible(bool bVisible=true);
    	HRESULT NewExcelBook(bool bVisible=true);
    	HRESULT SetExcelValue(LPCTSTR szRange,LPCTSTR szValue,bool bAutoFit, int nAlignment);
    	HRESULT Quit();
    };
    
    HRESULT OLEMethod(int nType, VARIANT *pvResult, IDispatch *pDisp,LPOLESTR ptName, int cArgs...);
    
    
    
    
    #endif


    and let's say that i call this somewhere from main.cpp:
    Code:
    CMSExcel xx;
    xx.NewExcelBook(true);
    xx.SetExcelValue("a2","1",true,1);




    The error is:
    Unhandled exception at 0x00B996C3 in Kredens (OLE aut).exe: 0xC0000005: Access violation reading location 0xCCCCCCCC.

    and it's caused in OLEMEthos function at the line:
    WideCharToMultiByte(CP_ACP, 0, ptName, -1, szName, 256, NULL, NULL);


    where this OLEMethod is called by (/from):
    m_hr=OLEMethod(DISPATCH_PROPERTYGET, &result, pSheet, L"Range", 1, xx);

    I guess i did some stupid mistake when i was copying the code from some example, not fully understanding it.
    I believe you are right saying that it must have somethign to do with that conversion thing which i dont quite understand yet.

  13. #13
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,395

    Re: COleVariant in WinAPI (afxdisp.h)

    Quote Originally Posted by berkov View Post
    Code:
    ...
    	IDispatch* pRange;
    	{
    		//COleVariant oleRange(szRange);
    		VARIANT xx;
    		xx.vt=VT_BSTR;
    		xx.pcVal = _T("a1");
    	
    		VARIANT result;
    		VariantInit(&result);
    		m_hr=OLEMethod(DISPATCH_PROPERTYGET, &result, pSheet, L"Range", 1, xx);
    		pRange = result.pdispVal;
    	}
    ...
    Well, Did you read the documentation about VARIANT in MSDN?
    It states that for pcVal you have to use VT_BYREF | VT_I1. And if you set the type as VT_BSTR you have to set the bstrVal, not a B]pcVal[/B].

    And again: why do you use such a mixture of L"...", T("...") and "..."?
    Victor Nijegorodov

  14. #14
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: COleVariant in WinAPI (afxdisp.h)

    In xls.cpp

    Code:
    char szName[200];
    
    	// Convert down to ANSI
    	WideCharToMultiByte(CP_ACP, 0, ptName, -1, szName, 256, NULL, NULL);
    szName is defined as size 200, but WideCharToMultiByte is told that is is 256!

    Also, you are not testing the return value from WideCharToMultiByte to determine if the function succeeded or failed.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  15. #15
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,395

    Re: COleVariant in WinAPI (afxdisp.h)

    Quote Originally Posted by 2kaud View Post
    szName is defined as size 200, but WideCharToMultiByte is told that is is 256!
    Good catch!
    Victor Nijegorodov

Page 1 of 2 12 LastLast

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured