In eine RichEditBox ohne MFC ein Icon ?
-
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 = 0x00168e60Ich 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 !!!!!!
-
Nu hab ich schon das nächste mir unerklärliche Problem...
Und zwar habe ich zum verdeutlichen einfach mal das Funktionierende Beispiel
von Trolli genommen und abgeändert.Ich habe nichts weiter gemacht als folgendes Global Declariert:
IRichEditOle* pRichEditOle; HBITMAP hBitmap; HANDLE hThread; DWORD hThreadID; HWND hRichEdit;Somit müste ich ja alle Funktionen in jeder Funktion benutzen können.
Dann habe ich das Adden des Smilies in einen Tread verpackt und Sekündlich
einen Smilie adden lassen...Doch da hört es auf... Sobald er den Smilie adden will, kommt der selbe fehler wie bei mir in meinem Programm ( Der Speicher Fehler )
Kann mir das jemand erklären ?
So sieht der gesamte Code aus:
#include <windows.h> #include <Richedit.h> #include <richole.h> IRichEditOle* pRichEditOle; HBITMAP hBitmap; HANDLE hThread; DWORD hThreadID; HWND hRichEdit; 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; } 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); }Zum testen ob der Tread funktioniert, einfach mal das InsertBitmap
auskommentieren und die MessageBox wieder beifügen !Vielen Dank soweit !
-
Konnte den Thread nochmal wiederherstellen - trotzdem geht es jetzt hier weiter.
Der Fehler entsteht afaik durch ein Bug im Syntax-Coloring-Mod - also bei Fehlern einfach stattdessen [code] anstelle von [cpp] verwenden.