In eine RichEditBox ohne MFC ein Icon ?



  • 's gibt doch eh LoadBitmap() 🙂



  • Hi,

    ich hab das jetz mal ausprobiert...
    Aber irgent wie funktioniert es bei mir nicht...
    Mit einfach dem Assert usw rausnehmen ist es nicht getahn...
    So bekomm ich jedes mal Speicherzugrifsfehler 😞

    Hat jemand ein kleines simples Code Sniplet für mich?

    Vielen Dank soweit an alle!



  • Debugger - und dann zeig doch mal die betreffende Codestelle mit der Zugriffsverletzung 🙂



  • Also ich hab jetz nochmal
    die Classe eingefügt, die Header declariert und die entsprechenden Zeilen auskommentiert...

    Dann habe ich mein Projekt mit debug gestartet und raus kahm:

    Unbehandelte Ausnahme in Chat Client.exe:0xC0000005: Access Violation

    Zum einfügen eines Icons hab ich dies gemacht:

    void AddIcon( void )
    {
    	::SendMessage( Edit_ChatText, EM_GETOLEINTERFACE, 0, (LPARAM)&m_pRichEditOle);
    
    	HBITMAP hBitmap = LoadBitmap( hInst, MAKEINTRESOURCE( IDB_BITMAP1 ) );
    
    	if (hBitmap)
    	{
    		CImageDataObject::InsertBitmap(m_pRichEditOle, hBitmap);
    	}
    }
    

    Wobei pRichEditOle so declariert ist:
    IRichEditOle *m_pRichEditOle;

    Das Edit_ChatText ist folgendermassen declariert:

    HWND Edit_ChatText;

    und wird in der Init des Proggys folgendermassen gefüllt:

    Edit_ChatText = CreateWindowEx(WS_EX_CLIENTEDGE,RICHEDIT_CLASS,"", WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL | ES_READONLY, 0, 0, 645, 529, hWnd, (HMENU)Edit_ChatTextID, hInst, NULL);
    			SendMessage(Edit_ChatText, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), 0);
    

    Dazu muss ich sagen, dass das Create der Rich Edit Box auf jeden fall vor dem Insert geschieht !

    Ich hoffe ihr könnt mir helfen !



  • In welcher Zeile genau kommt denn die Zugriffsverletzung - Breakpoint setzen oder Schritt für Schritt ausführen lassen 😉



  • Es scheint
    CImageDataObject::InsertBitmap(m_pRichEditOle, hBitmap);
    zu sein...

    Wenn ich die Zeile auskommentiere funzt es alles ordentlich!



  • Ist m_pRichEditOle dort gültig?



  • Ja ist es!

    pRichEditOle declariere ich global!

    So ist der gesamte code der add routine:

    void AddIcon( void ) 
    { 
        ::SendMessage( Edit_ChatText, EM_GETOLEINTERFACE, 0, (LPARAM)&m_pRichEditOle); 
    
        HBITMAP hBitmap = LoadBitmap( hInst, MAKEINTRESOURCE( IDB_BITMAP1 ) ); 
    
        if (hBitmap) 
        { 
            CImageDataObject::InsertBitmap(m_pRichEditOle, hBitmap); 
        } 
    }
    


  • Was liefert der SendMessage-Aufruf zurück?



  • Hallo,

    ich habs jetz mal so getestet:

    if ( SendMessage( Edit_ChatText, EM_GETOLEINTERFACE, 0, (LPARAM)&m_pRichEditOle) == 0 )
    {
    	MessageBox( NULL, "RichEdit Ole = 0", "", MB_OK );	
    }
    

    Die MessageBox kommt nicht hoch also geh ich mal davon aus, dass das Succeded ist... 😞



  • Hast du mal geschaut, wo innerhalb von CImageDataObject::InsertBitmap der Fehler auftritt?



  • Erstmal Danke das du mir hilfst!

    Der Fehler tritt hier auf:

    sc = pOleObject->GetUserClassID(&clsid);
    

    Im InsertBitmap.



  • Und OleCreateStaticFromData in CImageDataObject::GetOleObject liefert S_OK zurück? Irgendwie ist das alles etwas merkwürdig 🙄



  • Ich hab das gerade noch mal weiter ausgetestet....

    Ich denke das Problem liegt hier:

    IOleObject *pOleObject; 
    pOleObject = pods->GetOleObject(pOleClientSite, pStorage);
    
    OleSetContainedObject(pOleObject, TRUE);
    

    Danach ist pOleObject = 0x00000000

    Was ja auf einen Fehler schliessen lässt...

    pOleClientSite ist = 0x00159750
    und pStorage = 0x00168e60

    Ich hoffe du kanst mir helfen !



  • Gleichzeitig drauf gekommen *G* Nu fehlt nur die Lösung 🙂



  • Kann dir da leider auch nicht weiterhelfen - du musst eben mal die CImageDataObject::GetOleObject Memberfunktion untersuchen 🙄



  • Also der Fehler liegt definitief hier:

    IOleObject *CImageDataObject::GetOleObject(IOleClientSite *pOleClientSite, IStorage *pStorage)
    {
    	SCODE sc;
    	IOleObject *pOleObject;
    	sc = ::OleCreateStaticFromData(this, IID_IOleObject, OLERENDER_FORMAT, &m_fromat, pOleClientSite, pStorage, (void **)&pOleObject);
    
    	return pOleObject;
    }
    

    Kommentier ich den aufruf und:

    sc = pOleObject->GetUserClassID(&clsid);
    

    aus, dann bekomme ich ein Blankes Transparentes Feld in der RicheditBox...

    Kann es sein, dass es daran liegt, dass ich beim InsertBitmap evtl ein falsches oder fehlerhaftes bild übergebe ?

    if ( SendMessage( Edit_ChatText, EM_GETOLEINTERFACE, 0, (LPARAM)&m_pRichEditOle) == 0 )
    	{
    		MessageBox( NULL, "RichEdit Ole = 0", "", MB_OK );	
    	}
    
    	HBITMAP hBitmap = LoadBitmap( hInst, MAKEINTRESOURCE( IDB_BITMAP1 ) );
    
    	if (hBitmap)
    	{
    		CImageDataObject::InsertBitmap(m_pRichEditOle, hBitmap);
    	}
    

    ist ein bild welches ich in der Ressource Datei habe!

    Danke soweit !



  • Kann mir den wirklich keiner helfen ?



  • Ich kann dir auch nicht helfen, aber ich habe mir gerade einfach mal den Code zusammenkopiert und bei mir läuft es. Das Bitmap wird aus C:\test.bmp geladen.

    /*-----------------------------------------------------------------------
    Muster Window.cpp 
    
    www.winapi.net
    -----------------------------------------------------------------------*/
    
    #include <windows.h>
    #include <Richedit.h>
    #include <richole.h>
    
    class CImageDataObject : IDataObject
    {
    public: 
    	// This static function accepts a pointer to IRochEditOle 
    	//   and the bitmap handle.
    	// After that the function insert the image in the current 
    	//   position of the RichEdit
    	//
    	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);
    
    		sc = ::StgCreateDocfileOnILockBytes(lpLockBytes,
    			STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE, 0, &pStorage);
    		if (sc != S_OK)
    		{
    			lpLockBytes = 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();
    	}
    private:
    	ULONG m_ulRefCnt;
    	BOOL  m_bRelease;
    
    	// The data being bassed to the richedit
    	//
    	STGMEDIUM m_stgmed;
    	FORMATETC m_fromat;
    
    public:
    	CImageDataObject() : m_ulRefCnt(0) {
    		m_bRelease = FALSE;
    	}
    
    	~CImageDataObject() {
    		if (m_bRelease)
    			::ReleaseStgMedium(&m_stgmed);
    	}
    
    	// Methods of the IUnknown interface
    	// 
    	STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject)
    	{
    		if (iid == IID_IUnknown || iid == IID_IDataObject)
    		{
    			*ppvObject = this;
    			AddRef();
    			return S_OK;
    		}
    		else
    			return E_NOINTERFACE;
    	}
    	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;
    }
    
    // Die Hauptnachrichtenschleife
    LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    
    	switch (message)
    	{
    	case WM_CREATE:
    		{
    			LoadLibrary("riched20.dll");
    			HWND hRichEdit = CreateWindowEx(0, RICHEDIT_CLASS, NULL, WS_CHILD | WS_VISIBLE | WS_BORDER, 0, 0, 200, 200, hwnd, (HMENU) 0, GetModuleHandle(NULL), NULL);
    			IRichEditOle* pRichEditOle = NULL;
    			::SendMessage(hRichEdit, EM_GETOLEINTERFACE, 0, (LPARAM)&pRichEditOle);
    			HBITMAP hBitmap = (HBITMAP) LoadImage(NULL, TEXT("C:\\test.bmp"), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); 
    			CImageDataObject::InsertBitmap(pRichEditOle, hBitmap);
    		}
    		return (0);
    
    	case WM_DESTROY:
    		PostQuitMessage (0);
    		return (0);
    	}
    
    	return DefWindowProc (hwnd, message, wParam, lParam);
    }
    


  • Sehr komisch...

    Ich hab mir jetz dein kompletten Source rauskopiert
    und es hat funktioniert !

    Der fehler ist jetz auch gefunden:

    Die RichEditBox darf auf keinen Fall ES_READONLY sein !

    Sonst gibt es nen Speicher fehler !

    Danke dir !!!!!!


Anmelden zum Antworten