Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

COleVariant w WinAPI (afxdisp.h)

Ostatnio zmodyfikowano 2013-05-25 21:11
Autor Wiadomość
berkov
Temat założony przez niniejszego użytkownika
COleVariant w WinAPI (afxdisp.h)
» 2013-05-24 08:59:56
Hey ho...

Chyba znowu potrzebuje pomocy eksperta, program prawie skonczony, teraz potrzebuje dac uzytkownikowi mozliwosc raportowania, z listview do excela... .. Znalazlem fajny artyul o OLE Automation:
http://www.codeproject.com/Articles/34998/MS-Office-OLE-Automation-Using-C

Jedyna rzecz jednak, ktora nie chce dzialac z moim OLE to klasa COleVariant.
kompilator mi ja podkresla poniewaz nie jest zdeklarowana. Probowalem dodac afxdisp.h ale niestety jak doczytalem ta biblioteka nie jest w standardzie mojego Microsoft Visual Visual Studio Express 2012, pozatym najwyrazniej to specyficzna biblioteka glownie w MFC a ja pisze WINAPI.

No nic, i tak probowalem dodac biblioteke recznie (sciagnieta z netu) ale odnosi sie do wielu *.h a te z koleji do kolejnych i tak moglbym bez konca dodawac :-)

Czy istnieje jakis sposob zastapienia COleVariant z np VARIANT albo (preferowana opcja) w jakis sposob dodania biblioteki afxdisp.h (oraz wszystkich z nia polaczonych) do mojego prgramu?
Chcialbym osiagnac to:

C/C++
IDispatch * pRange;
{
    COleVariant oleRange( szCell );
    VARIANT result;
    VariantInit( & result );
    m_hr = OLEMethod( DISPATCH_PROPERTYGET, & result, pSheet, L"Range", 1, oleRange.Detach() );
    pRange = result.pdispVal;
}
 
OLEMethod to:
HRESULT OLEMethod( int nType, VARIANT * pvResult, IDispatch * pDisp, LPOLESTR ptName, int cArgs...)
 
Bede wdzieczny za pomoc!
berkov
.
P-83764
DejaVu
» 2013-05-24 17:35:45
Ponoć istnieje jakaś archaiczna wersja MFC jak również wersja ATL-a, którą da radę dograć do Visuala w wersji Express. Niestety sam się często odbijam od dwóch barier:
1) brak MFC oraz brak ATL
2) cena Visual C++ Professional :P
Koniec końców fajne pomysły idą w zapomnienie, bo klepanie tego samego w WinAPI co jest zapakowane we wspomnianych dwóch bibliotekach jest masakryczne.
P-83789
berkov
Temat założony przez niniejszego użytkownika
» 2013-05-25 00:43:35
@DejaVu - dzieki za odpowiedz, pol dnia spedzilem na szukaniu w necie rozwiazania i nic.
Znalazlem ze mozna dodac te biblioteki z instalacji SDK. Ale po instalacji okazalo sie ze wszystko to co mam to nowsze wersje (i SDK i VC Express) niz opisywane na forach wiec instrukcje juz nie pasowaly i suma sumaru nic z tego nie wyszlo, udalo mi sie dodac kilka bibliotek i nawet COleVariant  mi sie podswietlilo jako zdeklarowane ale co z tego jak kompilator krzyczy ze dolaczone sa biblioteki ktore sie odwoluja znowu do innych, ktorych oczywiscie ja nie mam.
Moze jakis hint co w googlu wpisac zeby doinstalowac ta "archaiczna wersje" ATL i MFC?
P-83821
DejaVu
» 2013-05-25 00:47:12
Też miałem problem ze znalezieniem tej starej wersji MFC-a i ATL-a. Koniec końców zaniechałem poszukiwania...
P-83822
maly
» 2013-05-25 07:47:06
Źródła MFC są w Borlandzie 6 Enterprise i chyba w Profesional.
P-83823
berkov
Temat założony przez niniejszego użytkownika
» 2013-05-25 09:05:51
@maly, no niby ok ale to kolejne platne wersje jak widze, za ktore trzeba zaplacic a i tak pewnosci nie masz czy pojda biblioteki, to juz chyba wole sobie M VC 2012 prof kupic.
P-83824
berkov
Temat założony przez niniejszego użytkownika
» 2013-05-25 09:41:58
No dobra, a dalo by sie to jakos ugryz z innej strony? czyli przerobic COleVariant na np VARIANT?

Tutaj mam opis funkcji OLEMethod:
C/C++
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;
}

Swoja droga przyznaje sie ze troche nie rouzmiem tej funkcji (sciagnalem ja z przykladu z netu - link wyzej), glownie nie rozumiem czemu przyjmuje 6 argumentow a nie 5 jak w opisie, podejrzewam ze ma to cos wspolnego z tymi trzema kropkami (...) na koncu argumentow. czytalem ten tutorial ale troche go nie ogarnalem, gdybym zrozumial do konca to pewnie nie mial bym problemu z tym COleVariant i z jego ewymiana na cos innego.

ok w main.cpp:
C/C++
CMSExcel xx;
xx.NewExcelBook( true );
xx.SetExcelValue( "a2", "1", true, 1 );

nowe okno excela sie otwiera i wszystko jest w porzadku (xx.NewExcelBook(true);), wiec wywoluje xx.SetExcelValue("a2","1",true,1);

SetExcelValue wyglada nastepujaco:
C/C++
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 result;
        VariantInit( & result );
        m_hr = OLEMethod( DISPATCH_PROPERTYGET, & result, pSheet, L"Range", 1, oleRange.Detach() );
        pRange = result.pdispVal;
    }
   
    {
        COleVariant oleValue( szValue );
        m_hr = OLEMethod( DISPATCH_PROPERTYPUT, NULL, pRange, L"Value", 1, oleValue.Detach() );
    }
   
    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;
}

wiem ze do momentu IDispatch* pRange - kod sie wykonuje prawidlowo i OLEMethod(..) wypelnia mi &result- wiem to stad ze probowalem zakomentowac COleVariant i do funkcji poprostu wrzucic "a1" zamiast oleRange.Detach() - niestety  OLEMethod(..) zwraca wtedy do result pusty wskaznik no i od tego momentu kod sie sypie.

Moze ktos ma jakis pomysl co mam wrzucic do OLEMethod(DISPATCH_PROPERTYGET, &result, pSheet, L"Range", 1, oleRange.Detach()); zamiast oleRange.Detach() zeby OLEMethod wypelnilo mi &result? Moze wtedy nie bede musial dolaczac zadnych bibliotek ATL ani MFC?


------------
update:
wiem ze wartosci range w excel powinny byc w takim a nie innym formacie poniewaz w przykladzie z netu funkcje (metode) wywolywalo sie tak:
m_msExcel.SetExcelValue(_T("a1"),_T("Title1"),true,1);
wiec "a1" jako range powinno bez problemu dzialac.
P-83826
DejaVu
» 2013-05-25 12:39:34
Wszystko da się napisać bez MFC-a i ATL-a, ale sprowadzi się to do pisania własnej implementacji wspomnianych bibliotek, czyli... do masy bugów, czytania dokumentacji i wielu eksperymentów.
P-83832
« 1 » 2
  Strona 1 z 2 Następna strona