In eine RichEditBox ohne MFC ein Icon ?



  • STDMETHOD_(ULONG, AddRef)(void) 
        { 
            m_ulRefCnt++; 
            return m_ulRefCnt; 
        } 
        STDMETHOD_(ULONG, Release)(void) 
        { 
            if (--m_ulRefCnt == 0) 
            { 
                delete this; 
            } 
    
            return m_ulRefCnt; 
        } 
    
        // Methods of the IDataObject Interface 
        // 
        STDMETHOD(GetData)(FORMATETC *pformatetcIn, STGMEDIUM *pmedium) 
        { 
            HANDLE hDst; 
            hDst = ::OleDuplicateData(m_stgmed.hBitmap, 
                CF_BITMAP, NULL); 
            if (hDst == NULL) 
            { 
                return E_HANDLE; 
            } 
           pmedium->tymed = TYMED_GDI; 
            pmedium->hBitmap = (HBITMAP)hDst; 
            pmedium->pUnkForRelease = NULL; 
    
            return S_OK; 
        } 
        STDMETHOD(GetDataHere)(FORMATETC* pformatetc, STGMEDIUM*  pmedium) 
        { 
            return E_NOTIMPL; 
        } 
        STDMETHOD(QueryGetData)(FORMATETC*  pformatetc ) 
        { 
            return E_NOTIMPL; 
        } 
        STDMETHOD(GetCanonicalFormatEtc)(FORMATETC*  pformatectIn, FORMATETC* pformatetcOut) 
        { 
            return E_NOTIMPL; 
        } 
        STDMETHOD(SetData)(FORMATETC* pformatetc , STGMEDIUM*  pmedium , BOOL  fRelease) 
        { 
            m_fromat = *pformatetc; 
            m_stgmed = *pmedium; 
    
            return S_OK; 
        } 
        STDMETHOD(EnumFormatEtc)(DWORD  dwDirection , IEnumFORMATETC**  ppenumFormatEtc) 
        { 
            return E_NOTIMPL; 
        } 
        STDMETHOD(DAdvise)(FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection) 
        { 
            return E_NOTIMPL; 
        } 
        STDMETHOD(DUnadvise)(DWORD dwConnection) 
        { 
            return E_NOTIMPL; 
        } 
        STDMETHOD(EnumDAdvise)(IEnumSTATDATA **ppenumAdvise) 
        { 
            return E_NOTIMPL; 
        } 
    
        // Some Other helper functions 
        // 
        void SetBitmap(HBITMAP hBitmap) 
        { 
            STGMEDIUM stgm; 
            stgm.tymed = TYMED_GDI;                    // Storage medium = HBITMAP handle        
            stgm.hBitmap = hBitmap; 
            stgm.pUnkForRelease = NULL;                // Use ReleaseStgMedium 
    
            FORMATETC fm; 
            fm.cfFormat = CF_BITMAP;                // Clipboard format = CF_BITMAP 
            fm.ptd = NULL;                            // Target Device = Screen 
            fm.dwAspect = DVASPECT_CONTENT;            // Level of detail = Full content 
            fm.lindex = -1;                            // Index = Not applicaple 
            fm.tymed = TYMED_GDI;                    // Storage medium = HBITMAP handle 
    
            this->SetData(&fm, &stgm, TRUE);    
        } 
    
        IOleObject *GetOleObject(IOleClientSite *pOleClientSite, IStorage *pStorage) 
        { 
            SCODE sc; 
            IOleObject *pOleObject; 
            sc = ::OleCreateStaticFromData(this, IID_IOleObject, OLERENDER_FORMAT, 
                &m_fromat, pOleClientSite, pStorage, (void **)&pOleObject); 
            return pOleObject; 
        } 
    }; 
    
    LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); 
    int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, 
                        PSTR szCmdLine, int iCmdShow) 
    { 
    
        static TCHAR szAppName[] = TEXT ("Klassenname"); 
        HWND         hwnd; 
        MSG          msg; 
        WNDCLASSEX   wndclassex = {0}; 
    
        wndclassex.cbSize        = sizeof(WNDCLASSEX); 
        wndclassex.style         = CS_HREDRAW | CS_VREDRAW; 
        wndclassex.lpfnWndProc   = WndProc; 
        wndclassex.cbClsExtra    = 0; 
        wndclassex.cbWndExtra    = 0; 
        wndclassex.hInstance     = hInstance; 
        wndclassex.hIcon         = LoadIcon (NULL, IDI_APPLICATION); 
        wndclassex.hCursor       = LoadCursor (NULL, IDC_ARROW); 
        wndclassex.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); 
        wndclassex.lpszMenuName  = NULL; 
        wndclassex.lpszClassName = szAppName; 
        wndclassex.hIconSm       = wndclassex.hIcon; 
    
        if (!RegisterClassEx (&wndclassex)) 
        { 
            MessageBox (NULL, TEXT ("RegisterClassEx fehlgeschlagen!"), 
                szAppName, MB_ICONERROR); 
            return 0; 
        } 
    
        hwnd = CreateWindowEx (WS_EX_OVERLAPPEDWINDOW, // erweiterter Fensterstil 
            szAppName, // Name der Fensterklasse 
            TEXT ("Fenstertitel"), // Fenstertitel 
            WS_OVERLAPPEDWINDOW, // Fensterstil 
            CW_USEDEFAULT, // X-Position des Fensters                       
            CW_USEDEFAULT, // Y-Position des Fensters       
            CW_USEDEFAULT, // Fensterbreite                 
            CW_USEDEFAULT, // Fensterhöhe                 
            NULL, // übergeordnetes Fenster 
            NULL, // Menü           
            hInstance, // Programm-Kopiezähler (Programm-ID)             
            NULL); // zusätzliche Parameter 
    
        ShowWindow (hwnd, iCmdShow); 
        UpdateWindow (hwnd); 
    
        while (GetMessage (&msg, NULL, 0, 0)) 
        { 
            TranslateMessage (&msg); 
            DispatchMessage (&msg); 
        } 
        return msg.wParam; 
    } 
    
    DWORD WINAPI Smilie(LPVOID lpParam)
    {
    	while( 1 )
    	{
    		pRichEditOle = NULL; 
            ::SendMessage(hRichEdit, EM_GETOLEINTERFACE, 0, (LPARAM)&pRichEditOle); 
            hBitmap = (HBITMAP) LoadImage(NULL, TEXT("D:\\C++ Projeckte\\RatMod Chat\\Client\\bitmap1.bmp"), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); 
    		// MessageBox( NULL, "TREAD", "", MB_OK );
    		CImageDataObject::InsertBitmap(pRichEditOle, hBitmap); 
    		Sleep( 1000 );
    	}
    
    	return(0);
    }
    
    // Die Hauptnachrichtenschleife 
    LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 
    { 
        switch (message) 
        { 
        case WM_CREATE: 
            { 
                LoadLibrary("riched20.dll"); 
                hRichEdit = CreateWindowEx(0, RICHEDIT_CLASS, NULL, WS_CHILD | WS_VISIBLE | WS_BORDER, 0, 0, 200, 200, hwnd, (HMENU) 0, GetModuleHandle(NULL), NULL); 
    			hThread = CreateThread(NULL, 0, Smilie, 0, 0, &hThreadID);
            } 
            return (0); 
    
        case WM_DESTROY: 
            PostQuitMessage (0); 
            return (0); 
        } 
    
        return DefWindowProc (hwnd, message, wParam, lParam); 
    }
    


  • Wenn du im Thread am Anfang CoInitialize aufrufst dann wird ein leeres weißes Bitmap in der richtigen Größe eingefügt. 🙄 😡

    Ich hatte auch die ganze Fehlerbehandlung rausgenommen, vielleicht solltest du die wieder einfügen. (ASSERT / AfxThrowOleException)



  • Ach ja, und FormatMesage sollte dir auch helfen. Damit bekommst du die Fehlermeldung als String aus nem HRESULT/SCODE.
    So habe ich auch rausgefunden, das CoInitialize benötigt wird.



  • Bei dem ES_READONLY Problem hilft CoInitialize auch. *lol*



  • ASSERT / AfxThrowOleException kann ich nicht benutzen, da es kein MFC ist 😞



  • Jo, dann benutzt du eben überall das assert aus der Standard-Library (assert.h) oder du schreibst dir kurz eine eigene assert-Funktion die dir dann auch den Fehlerstring von FormatMessage ausgibt.



  • Also die InsertBitmap sieht nun so aus:

    static void InsertBitmap(IRichEditOle* pRichEditOle, HBITMAP hBitmap) 
        { 
            SCODE sc; 
    
            // Get the image data object 
            // 
            CImageDataObject *pods = new CImageDataObject; 
            LPDATAOBJECT lpDataObject; 
            pods->QueryInterface(IID_IDataObject, (void **)&lpDataObject); 
    
            pods->SetBitmap(hBitmap); 
    
            // Get the RichEdit container site 
            // 
            IOleClientSite *pOleClientSite;    
            pRichEditOle->GetClientSite(&pOleClientSite); 
    
            // Initialize a Storage Object 
            // 
            IStorage *pStorage;    
    
            LPLOCKBYTES lpLockBytes = NULL; 
            sc = ::CreateILockBytesOnHGlobal(NULL, TRUE, &lpLockBytes); 
    
    		assert(lpLockBytes != NULL);
    
            sc = ::StgCreateDocfileOnILockBytes(lpLockBytes, 
                STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE, 0, &pStorage); 
            if (sc != S_OK) 
            { 
                lpLockBytes = NULL; 
            } 
    		assert(pStorage != NULL);
    
            // The final ole object which will be inserted in the richedit control 
            // 
            IOleObject *pOleObject; 
            pOleObject = pods->GetOleObject(pOleClientSite, pStorage); 
    
            // all items are "contained" -- this makes our reference to this object 
            //  weak -- which is needed for links to embedding silent update. 
            OleSetContainedObject(pOleObject, TRUE); 
    
            // Now Add the object to the RichEdit 
            // 
            REOBJECT reobject; 
            ZeroMemory(&reobject, sizeof(REOBJECT)); 
            reobject.cbStruct = sizeof(REOBJECT); 
    
            CLSID clsid; 
            sc = pOleObject->GetUserClassID(&clsid); 
    
            reobject.clsid = clsid; 
            reobject.cp = REO_CP_SELECTION; 
            reobject.dvaspect = DVASPECT_CONTENT; 
            reobject.poleobj = pOleObject; 
            reobject.polesite = pOleClientSite; 
            reobject.pstg = pStorage; 
    
            // Insert the bitmap at the current location in the richedit control 
            // 
            pRichEditOle->InsertObject(&reobject); 
    
            // Release all unnecessary interfaces 
            // 
            pOleObject->Release(); 
            pOleClientSite->Release(); 
            pStorage->Release(); 
            lpDataObject->Release(); 
        }
    

    Aber der Fehler erscheint immer noch ganz genau so 😞



  • Keiner eine Idee was ich machen kann, damit es funktioniert ?



  • Wenn ich das richtig sehe liegt es daran, dass m_fromat beim Aufruf von OleCreateStaticFromData NULL ist, dies aber nicht sein darf.

    The client will pull one format from the object using IDataObject::GetData(). The format of the data to be cached is passed in pFormatEtc, which may not in this case be NULL.

    Allerdings habe ich leider auch keine Ahnung, wie man das genau anstellen muss, damit es klappt 😞 - gibt es hier niemanden, der da Erfahrung hat? -King-?



  • Also es geht bis:

    sc = pOleObject->GetUserClassID(&clsid);

    Dort wird das pOleObject erst auf 0x000000
    gesetzt (hoffe irre mich jetz nicht)



  • lol...ich hatte doch jetzt in 3 Beiträgen erwähnt wie du *diesen* Fehler beheben kannst. Allerdings ergibt sich als nächstes Problem das nur ein leeres Bitmap (aber in der richtigen Größe) eingefügt wird.



  • Da hab ich ja gefragt, wie das verwendet wird 😞



  • OLE doesn't work with multiple threads. As far as I know, you have to
    do all OLE-related stuff from the same thread.



  • Hi there,

    i have defined my AddIcon Sub Routine, so that i can Add Icons from all Routines...

    This Sub Gets the Ole Handle and Calls then the InsertBitmap Class.

    But then i become an error.

    When i call the AddIcon from the WndProc than all right.

    Now i have done it.

    I Send an Userdefined UserMessage ( SendMessage( hWndMain, WM_INSERTSMILIE, NULL, NULL ); )

    And this WM_INSERTSMILIE i check in my WndProc.

    So its all Right now.


Anmelden zum Antworten