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

    Re: COleVariant in WinAPI (afxdisp.h)

    Ok. Let me come back home and check it out.

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

    Re: COleVariant in WinAPI (afxdisp.h)

    ok .. so i tried this:
    Code:
    VARIANT xx;
    xx.vt=VT_BYREF | VT_I1;
    xx.pcVal = "a1";
    and no luck.


    i tried then:
    Code:
    VARIANT xx;
    xx.vt=VT_BSTR;
    xx.bstrVal = "a1";
    but it says "a value of type const char * cannot be assigned to an entity of type BSTR"

    i also changed char szName[200]; to 256.
    with no luck.

    and i think also i misled you a bit by saying that the error appears while executing:
    WideCharToMultiByte(CP_ACP, 0, ptName, -1, szName, 256, NULL, NULL);

    i checked it again and it fails a bit farther, at:
    hr = pDisp->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, nType, &dp, pvResult, NULL, NULL);

    i think the problem is that when i look into &dp during the execution it says:
    dp = {rgvarg=0x004b6768 byref of I1 = 0x00d28074 "a" rgdispidNamedArgs=0x00000000 {???} cArgs=1 ...}
    .. it is "a" but it should be "a1" right?
    so i guess i am still not passing the full string... if i understand it correctly of course.

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

    Re: COleVariant in WinAPI (afxdisp.h)

    Quote Originally Posted by VictorN View Post
    Try to change your code to be:
    Code:
    VARIANT xx;
    xx.vt=VT_BSTR;
    xx.pcVal= L"a1";
    this doesn't create a proper VARIANT to a BSTR, even if you fixed it to set it to bstrVal instead of pcVal.
    it creates a variant of type VT_BSTR with the BSTR part pointing to a static wide character string. Wide char string != BSTR.

    Depending on how the receiving function works. This can either work without any form of issue, or it can have all kinds of failures.

    BSTR's are BSTR's, they are NOT simply pointers to any type of wide character strings.



    The above would be correct if you used a VT_LPWSTR type, but not everything accepting a VARIANT will handle that type properly (a lot don't).
    If you pass a VT_BSTR, make sure you have an actual BSTR, meaning, it should be allocated via SysAllocString() or it should be NULL indicating an empty string (not a NULL string). There are C++ wrapper classes such as CComBSTR (ATL/MFC) and _bstr_t (compiler COM support) to help you manage BSTR's.
    Last edited by OReubens; May 27th, 2013 at 07:44 AM.

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

    Re: COleVariant in WinAPI (afxdisp.h)

    Quote Originally Posted by OReubens View Post
    this doesn't create a proper VARIANT to a BSTR, even if you fixed it to set it to bstrVal instead of pcVal.
    it creates a variant of type VT_BSTR with the BSTR part pointing to a static wide character string. Wide char string != BSTR.
    ...
    If you pass a VT_BSTR, make sure you have an actual BSTR, meaning, it should be allocated via SysAllocString() ...
    Right!
    And sorry for my incorrect suggestion.

    Frankly, I never use row VARIANT and BSTR data types. Only their wrapper: usually _variant_t and _bstr_t and rarely COleVarinat and CComBSTR, so I never have to use SysAllocString/SysFreeString. I has just forgotten these function exist and are used by the wrapper classes!
    Victor Nijegorodov

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

    Re: COleVariant in WinAPI (afxdisp.h)

    Hi Victor.
    Me too, i've only used _variant_t and _bstr_t with ADO, never the raw ones. guess i will have to come back to the documentation and read it once again with understanding this time :-)

    anyways, in the meantime i decided to use XML format for saving files for xls, easier, quicker and more reliable.
    but i will still try to play with the VARIANT and OLE Auto. if i figure it out, you'll be the first one to know...


    thanks
    b
    .

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

    Re: COleVariant in WinAPI (afxdisp.h)

    Quote Originally Posted by berkov View Post
    Hi Victor.
    Me too, i've only used _variant_t and _bstr_t with ADO, never the raw ones. guess i will have to come back to the documentation and read it once again with understanding this time :-)
    Did you try to use _variant_t and _bstr_t in your current project?
    Victor Nijegorodov

  7. #22
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: COleVariant in WinAPI (afxdisp.h)

    Code:
    . . .
    #include <comdef.h>
    . . .
    
    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_t result;
    		m_hr=OLEMethod(DISPATCH_PROPERTYGET, &result, m_pActiveBook, L"Sheets", 0);
    		pSheets = result;
    	}
    	IDispatch *pSheet;
    	{
    		_variant_t result;
    		_variant_t itemn(1);
    		m_hr=OLEMethod(DISPATCH_PROPERTYGET, &result, pSheets, L"Item", 1, itemn);
    		pSheet = result;
    	}
    	
    	IDispatch* pRange;
    	{
    		//COleVariant oleRange(szRange);
    		_variant_t vRange(szRange);
    		_variant_t result;
    		m_hr=OLEMethod(DISPATCH_PROPERTYGET, &result, pSheet, L"Range", 1, vRange);
    		pRange = result;
    	}
    
    	{
    		//COleVariant oleValue(szValue);
    		_variant_t vValue(szValue);
    		m_hr=OLEMethod(DISPATCH_PROPERTYPUT, NULL, pRange, L"Value", 1, vValue);
    	}
    . . .
    Best regards,
    Igor

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

    Re: COleVariant in WinAPI (afxdisp.h)

    Quote Originally Posted by VictorN View Post
    Right!
    And sorry for my incorrect suggestion.

    Frankly, I never use row VARIANT and BSTR data types. Only their wrapper: usually _variant_t and _bstr_t and rarely COleVarinat and CComBSTR, so I never have to use SysAllocString/SysFreeString. I has just forgotten these function exist and are used by the wrapper classes!
    Well... the wrappers are there for a reason ofc

    And yes, you can get into a habbit of using the wrappers and forgetting that there's actually a bunch of code happening behind all the neat operators and constructors


    Not using the wrappers is definately tedious and annoying.

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

    Re: COleVariant in WinAPI (afxdisp.h)

    @Victor, thanks a lot for your suggestion. it works!!!
    @Igor, why didn't you come here earlier! :-)

    Code:
    IDispatch* pRange;
    	{
    		_variant_t xx;
    		xx = "a1";
    		VARIANT result;
    		VariantInit(&result);
    		m_hr=OLEMethod(DISPATCH_PROPERTYGET, &result, pSheet, L"Range", 1, xx);
    		pRange = result.pdispVal;
    	}
    Thanks a lot to all. I would probably never come out with _variant_t myself.

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

    Re: COleVariant in WinAPI (afxdisp.h)

    ok.. so everything works.
    the Excel gets open and the cells get filled in .. and all by using OLE Auto.
    btw you won't believe how slow this is!!!! and it seems OLE Auto does not have formatting option. you can only create a "raw" excel.


    here is the final function (without a need of use libs form MFC or ATL) which sets the cell value for the given row and column (int).

    Code:
    HRESULT CMSExcel::SetExcelValueByCoordins(LPCTSTR text, int rzad, int kolumna, bool bAutoFit, int nAlignment)
    {
    	if(!m_pEApp) return E_FAIL;
    	if(!m_pActiveBook) return E_FAIL;
    	
    	IDispatch *pXLApp;
    	{  
    		VARIANT result;
    		VariantInit(&result);
    		OLEMethod(DISPATCH_PROPERTYGET, &result, m_pActiveBook, L"Application", 0);
    		pXLApp= result.pdispVal;
    	}
    
    	IDispatch* pCells;
    	{
    		VARIANT result;
    		VariantInit(&result);
    		VARIANT row, col;
    		row.vt =VT_I4;
    		row.lVal =rzad;
    		col.vt =VT_I4;
    		col.lVal =kolumna;
    
    		m_hr=OLEMethod(DISPATCH_PROPERTYGET, &result, pXLApp, L"Cells", 2,col,row);
    		pCells = result.pdispVal;
    	}
    
    	{
    		_variant_t value(text);
    		VARIANT result;
    		m_hr=OLEMethod(DISPATCH_PROPERTYPUT, NULL, pCells, L"Value", 1, value);
    	}
    
    
    	if(bAutoFit)
    	{
    		IDispatch* pEntireColumn;
    		{
    			VARIANT result;
    			VariantInit(&result);
    			m_hr=OLEMethod(DISPATCH_PROPERTYGET, &result, pCells, 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, pCells, L"HorizontalAlignment", 1, x);
    	}
    
    	pCells->Release();
    	pXLApp->Release();
    	return m_hr;
    }
    int rzad - row
    int kolumna - column

  11. #26
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: COleVariant in WinAPI (afxdisp.h)

    I would recommend to stick with some particular approach/style, and never mix ones. You either go with bare VARIANT or use _variant_t the way I showed it in my snippet.
    Best regards,
    Igor

Page 2 of 2 FirstFirst 12

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