In eine RichEditBox ohne MFC ein Icon ?



  • Das teste ich gleich morgen mal!

    Danke so weit!

    HBITMAP wird doch im normalfall aus einer Datei geladen,
    gibts da auch nen weg es aus der Ressourcedatei zu laden?

    Evtl. per LoadIcon ?



  • '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);
    }
    

Anmelden zum Antworten