-
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
.
-
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.
-
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.
-
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()?
-
Re: COleVariant in WinAPI (afxdisp.h)
MSDN does know it for sure!
COleVariant::Detach
So just pass in your xx instead of "functionDetach(xx)"!
-
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;
}
-
Re: COleVariant in WinAPI (afxdisp.h)
Quote:
Originally Posted by
berkov
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";
-
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?
-
Re: COleVariant in WinAPI (afxdisp.h)
Is your build an ANSI or UNICODE?
Anyway, you should always use _T() macro for text/symbol constants.
-
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.
-
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.
-
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.
-
Re: COleVariant in WinAPI (afxdisp.h)
Quote:
Originally Posted by
berkov
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? :confused:
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 "..."? :confused:
-
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.
-
Re: COleVariant in WinAPI (afxdisp.h)
Quote:
Originally Posted by
2kaud
szName is defined as size 200, but WideCharToMultiByte is told that is is 256!
Good catch! :thumb:
-
Re: COleVariant in WinAPI (afxdisp.h)
Ok. Let me come back home and check it out.
-
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.
-
Re: COleVariant in WinAPI (afxdisp.h)
Quote:
Originally Posted by
VictorN
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.
-
Re: COleVariant in WinAPI (afxdisp.h)
Quote:
Originally Posted by
OReubens
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!
-
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
.
-
Re: COleVariant in WinAPI (afxdisp.h)
Quote:
Originally Posted by
berkov
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?
-
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);
}
. . .
-
Re: COleVariant in WinAPI (afxdisp.h)
Quote:
Originally Posted by
VictorN
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.
-
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.
-
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
-
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.