사용자 도구

사이트 도구


kb:comvariant

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

kb:comvariant [2014/11/06 19:59] (현재)
줄 1: 줄 1:
 +====== COM Variant ======
 +[[COM]]과 관련된 여러 오브젝트들이 VARIANT라는 것을 함수 인자로 받아들인다. 아래의 코드들은 이 VARIANT와 C 타입 간의 상호 변환을 다룬다.
 +
 +====== 화폐 단위 변환 ======
 +<code cpp>
 +void CVarUseDlg::​OnCurrency() ​
 +{
 +    VARIANT myVar;
 +    myVar.vt = VT_CY;
 +
 +    // put 15.15 into the currency variant.
 +    CURRENCY myValue;
 +    myValue.Hi = 0;
 +    myValue.Lo = (LONG)(15*10000 + 1537); // set the value to $15.15;
 +    myVar.cyVal = myValue;
 +    //or
 +    myValue.int64 = (151234);
 +    myVar.cyVal = myValue;
 +    ​
 +    //Now get the value from a float and put it into the currency.
 +    float myMoney = (float)5.37;​
 +    myVar.vt = VT_R4;
 +    myVar.fltVal = myMoney;
 +    //no loss of precission.
 +    VariantChangeType(&​myVar,​ &myVar, 0, VT_CY);
 +
 +    //Now get the value from a String
 +    USES_CONVERSION;​
 +    myVar.bstrVal = SysAllocString(L"​$23.4345"​);​
 +    myVar.vt = VT_BSTR;
 +    VariantChangeType(&​myVar,​ &myVar, 0, VT_CY);
 +
 +    //Finally output a currency to a string.
 +    myVar.cyVal.int64 += myVar.cyVal.int64;​ // + myVar.cyVal;​
 +    VariantChangeType(&​myVar,​ &myVar, 0, VT_BSTR);
 +}
 +</​code>​
 +
 +====== 문자열 변환 ======
 +<code cpp>
 +void CVarUseDlg::​OnStrings() ​
 +{
 +    //Create a BSTR and assign it to a Variant
 +    BSTR x = SysAllocString(L"​Hello"​);​
 +    VARIANT myVariant;
 +    myVariant.vt = VT_BSTR;
 +    myVariant.bstrVal = x;
 +    SysFreeString(x);​
 +
 +    //Create a CString and change it to a variant;
 +    CString myCString(_T("​My String"​));​
 +    CString mySecondString;​
 +    ​
 +    //This is required to use the T2COLE macro.
 +    USES_CONVERSION;​
 +    ​
 +    BSTR y = SysAllocString(T2COLE(myCString));​
 +    myVariant.bstrVal = y;
 +    mySecondString = y;
 +    SysFreeString(y);​
 +    ​
 +    //Create two BSTRs and add them.
 +    BSTR a = SysAllocString(L"​One two ");
 +    BSTR b = SysAllocString(L"​three four."​);​
 +    _bstr_t my_bstr_t(a,​ TRUE);
 +    my_bstr_t += b;
 +    myVariant.bstrVal = my_bstr_t;
 +    // or
 +    myVariant.bstrVal = _bstr_t(a, FALSE) + b;
 +
 +    //Change a bstr to a CString.
 +    CString ANewString(b);​
 +    //or if CString already exists.
 +    myCString = b;
 +
 +    //Use of CComBSTR
 +    CComBSTR myCComBSTR(L"​Hello"​);​
 +    myCComBSTR.Append(L",​ how are you?"​);​
 +    VARIANT varFromCCom;​
 +    varFromCCom.vt = VT_BSTR;
 +    varFromCCom.bstrVal = myCComBSTR;
 +}
 +</​code>​
 +
 +====== 기본형 변환 ======
 +<code cpp>
 +void CVarUseDlg::​OnBasic() ​
 +{
 +    //create a variant of the character '​c'​
 +    VARIANT varC;
 +    varC.vt=VT_UI1;​
 +    varC.cVal = '​c';​
 +
 +    //create a variant of the short 12
 +    VARIANT varS;
 +    varS.vt = VT_I2;
 +    varS.iVal = 12;
 +
 +    //create a variant of the long 1234567;
 +    VARIANT varL;
 +    varL.vt = VT_I4;
 +    varL.lVal = 1234567; ​   ​
 +}
 +</​code>​
 +
 +====== SAFEARRAY 변환 ======
 +<code cpp>
 +void CVarUseDlg::​OnSafeArray() ​
 +{
 +    //Create a standard array;
 +    int* pMyOriginalArray = new int[100];
 +    for(int count = 0; count < 100; count++) pMyOriginalArray[count] = count;
 +    ​
 +    //Now get ready to put it into a safe array
 +    HRESULT hr;
 +    //create an array bound
 +    SAFEARRAYBOUND rgsabound[1];​
 +    rgsabound[0].lLbound = 0;       //The first (and only) collumn of our array starts at 0.
 +    rgsabound[0].cElements = 100;   //and has 100 elements.
 +    ​
 +    //create the array
 +    SAFEARRAY FAR* pMySafeArray;​
 +    pMySafeArray = SafeArrayCreate(VT_I4,​ 1, rgsabound); //create the array of 4byte integers, one dimension
 +    ​
 +    //now access the safe array'​s data.
 +    int* pData;
 +    hr = SafeArrayAccessData( ​ pMySafeArray,​ (void**)&​pData);​ //Get a pointer to the data.
 +    ​
 +    //copy the 400 bytes of data from our old array to the new one.
 +    memcpy(pData,​ pMyOriginalArray,​ 400);
 +    ​
 +    //here we verify to you that the data is correct.
 +    for(count = 0; count < 100; count++) ASSERT(pData[count] == pMyOriginalArray[count]);​
 +    SafeArrayUnaccessData(pMySafeArray);​
 +    ​
 +    //To put the SafeArray in a Variant
 +    VARIANT myVariant; ​
 +    myVariant.parray = pMySafeArray;​
 +    myVariant.vt = VT_ARRAY|VT_I4;​ // state it's an array and what type it holds.
 +    ​
 +    //pass the Variant to a function call.  ​
 +    FunctionCallWithVariant(myVariant);​
 +    //see that the original array was modified.
 +    hr = SafeArrayAccessData(myVariant.parray,​ (void**)&​pData);​ //Get a pointer to the data.
 +    ASSERT(pData[0] == 1234);
 +    SafeArrayUnaccessData(pMySafeArray);​
 +    ​
 +    //Copy the variant.
 +    VARIANT NewVariant;
 +    NewVariant.vt = VT_EMPTY; // must set variant type for copy to work.
 +    hr = VariantCopy(&​NewVariant,​ &​myVariant);​
 +
 +    //check array in copy of variant
 +    int* pNewData;
 +    hr = SafeArrayAccessData(NewVariant.parray,​ (void**) &​pNewData);​
 +    for(count = 0; count < 100; count++) ASSERT(pData[count] == pNewData[count]);​
 +    ASSERT(pData != pNewData); //copying the varriant created a new copy of the 
 +                               //​array it contained too.  There is now 2 copies of the data.
 +    SafeArrayUnaccessData(NewVariant.parray);​
 +
 +    //Or you could use CreateVector to create the 1 dimensional array.
 +    SAFEARRAY* pMyVector = SafeArrayCreateVector(VT_I4,​ -50, 100);  //Vecoor of VT_I4, starting at 0
 +                                                                //with 100 elements.
 +    int* pVectorData;​
 +    hr = SafeArrayAccessData(pMyVector,​ (void**)&​pVectorData);​
 +    memcpy(pVectorData,​ pMyOriginalArray,​ 400); //copy the 400 bytes of data from our old array into the new one.
 +    int element;
 +    long location[1] = {-50};
 +    hr = SafeArrayGetElement(pMyVector,​ location, (void*)&​element);​
 +    ASSERT(element == 0); //element -50 is the first element from the original array
 +    location[0] = 0;
 +    hr = SafeArrayGetElement(pMyVector,​ location, (void*)&​element);​
 +    ASSERT(element == 50); // element 0 is the 50th element from the original array
 +    delete[] pMyOriginalArray;​
 +    hr = SafeArrayDestroy(pMySafeArray);​
 +    hr = SafeArrayDestroy(pMyVector);​
 +    hr = SafeArrayDestroy(NewVariant.parray);​
 +}
 +</​code>​
 +
 +====== OLEARRAY 변환 ======
 +<code cpp>
 +void CVarUseDlg::​OnOleArray() ​
 +{
 +    //Create and fill an array.
 +    int* pMyOriginalArray = new int[100];
 +    int* pData;
 +    for(int count = 0; count < 100; count++) pMyOriginalArray[count]=count;​
 +    ​
 +    //Put it into a safe array.
 +    COleSafeArray myOleSafeArray;​
 +    myOleSafeArray.CreateOneDim(VT_I4,​ 100, pMyOriginalArray);​ // create one dimension array of 4-byte values
 +                                                               // 100 entries w/data from pMyOriginalArray.
 +    // Access that safe array.
 +    //Get a pointer to the Data.
 +    myOleSafeArray.AccessData((void**)&​pData); ​
 +    //verify all of the data.
 +    for(count = 0; count < 100; count++) ASSERT(pData[count] == pMyOriginalArray[count]);​
 +    myOleSafeArray.UnaccessData();​
 +    ​
 +    //clean up.
 +    delete[] pMyOriginalArray;  ​
 +}
 +</​code>​
 +
 +====== 다차원배열 변환 ======
 +<code cpp>
 +void CVarUseDlg::​OnMultiDimensionArray() ​
 +{
 +    short pMyOriginalData[2][3][4][5];​
 +    HRESULT hr;
 +    //​initialize data
 +    for(short a = 0; a < 2; a++)
 +        for(short b = 0; b < 3; b++)
 +            for(short c = 0; c < 4; c++)
 +                for(short d = 0; d < 5; d++)
 +                    pMyOriginalData[a][b][c][d] = a*b*c*d;
 +
 +    SAFEARRAY* pMyArray;
 +    SAFEARRAYBOUND rgsabound[4];​
 +    for(int count = 2; count < 6; count++)
 +    {
 +        rgsabound[count - 2].lLbound = 0;
 +        rgsabound[count - 2].cElements = count;
 +    }
 +    pMyArray = SafeArrayCreate(VT_I2,​ 4, rgsabound);
 +    short* pData;
 +    hr = SafeArrayAccessData(pMyArray,​ (void**)&​pData);​
 +    memcpy(pData,​ pMyOriginalData,​ 2*3*4*5*2);
 +    short element;
 +    long location[4] = {1,2,3,4};
 +    hr = SafeArrayGetElement(pMyArray,​ location, (void*)&​element);​
 +    ASSERT(element == 1*2*3*4);
 +    ​
 +    hr = SafeArrayDestroy(pMyArray);​
 +    ASSERT(hr != S_OK);
 +    hr = SafeArrayUnaccessData(pMyArray);​
 +    hr = SafeArrayDestroy(pMyArray);​
 +    ASSERT(hr == S_OK);
 +}
 +</​code>​
 +
 +====== 날짜변환 ======
 +<code cpp>
 +void CVarUseDlg::​OnDate() ​
 +{
 +    VARIANT timeSelection;​
 +    COleDateTime timeNow;
 +    DATE curDate;
 +    HRESULT hr;
 +    //Get current Time.
 +    timeNow = COleDateTime::​GetCurrentTime();​
 +    ​
 +    //Put time into variant.
 +    timeSelection.vt = VT_DATE;
 +    timeSelection.date = timeNow.m_dt;​
 +    ​
 +    //Convert Variant into string using Variant Change Type.
 +    hr = VariantChangeType(&​timeSelection,​ &​timeSelection,​ 0, VT_BSTR);
 +    CString sCurTime(timeSelection.bstrVal);​
 +    ​
 +    //Get Time as System Time.
 +    SYSTEMTIME mySysTime;
 +    timeNow.GetAsSystemTime(mySysTime);​
 +    ​
 +    //Use COleDateTime functionality to get change SYSTEMTIME into DATE.
 +    COleDateTime pastTime(mySysTime);​
 +    curDate = pastTime.m_dt;​
 +
 +
 +    //Use COldeDateTime Format command to get date as CString.
 +    LPCTSTR format = _T("%X %z"​); ​ //Current time and time zone.
 +    //Note see "​strftime"​ help for valid formating strings. ​
 +    CString sTime = pastTime.Format(format);​
 +}
 +</​code>​
 +
 +====== VARIANT를 인자로 함수 호출 ======
 +<code cpp>
 +void CVarUseDlg::​FunctionCallWithVariant(VARIANT myVariant)
 +{
 +    HRESULT hr;
 +    int* pData;
 +    int count;
 +    hr = SafeArrayAccessData(myVariant.parray,​ (void**)&​pData);​ //access the array stored in the varriant.
 +    for(count = 0; count < 100; count++) ASSERT(pData[count] == count); //check data;
 +    pData[0] = 1234; //modify data
 +    SafeArrayUnaccessData(myVariant.parray);​
 +}
 +</​code>​
 +
 +====== 참고 ======
 +  * [[http://​www.codeproject.com/​cpp/​cvariant.asp | A simple class to encapsulate VARIANTs]]
 +
 +----
 +  * see also [[COM]]
  
kb/comvariant.txt · 마지막으로 수정됨: 2014/11/06 19:59 (바깥 편집)