Insert dynamic GIF in the RicheDit control

xiaoxiao2021-03-06  46

This is an old FAQ on the 9CBS VC Forum. I am writing a self-defined icon in Richedit (http://www.blogcn.com/User3/jiangsheng/blogcn.com/user3/jiangsheng/blogcn.com/User3/jiangsheng/blogcn.com/User3/jiangsheng/blogcn.com/User3/jiangsheng/blogc/1319738.html) When this article wants to use this technology to do animation GIF, but how It is said that the problem in Richedit is GIF has not been resolved. Good in QQ, one control supports animation GIF, can insert this object to solve the problem.

First, a timer needs to be updated to update the GIF.

Public: System :: void Onload (System :: Object ^ Sender, System :: Eventargs ^ e) {this-> typingrichtextbox-> richtextshortcutsenabled = false; this-> Timer1-> start ();}

Private: System :: Void ONFORMCLOSING (System :: Object ^ Sender, System :: Windows :: Forms :: formClosingeventargs ^ e) {this-> Timer1-> stop (); this-> frameclosing = True;

Then notify the GIF control update display in the processing function of the timer.

private: System :: Void OnTimer1Elapsed (System :: Object ^ sender, System :: Timers :: ElapsedEventArgs ^ e) {if (this-> frameClosing == false) UnmanagedGifTriggerFrameChange (this-> contentRichTextBox-> Handle.ToInt32 ()) }

The final job is inserting GIF.

Private: System :: Void SmileToolstripMenuItem_Click (System :: Object ^ Sender, System :: Eventargs ^ e) {INSERTEMOTION (Sender, E, "C: // qq // face // 20.gif ");

private: System :: Void insertemotion (System :: Object ^ sender, System :: EventArgs ^ e, String ^ gifPath) {System :: Windows :: Forms :: RichTextBox ^ ptypingRichTextBox = this-> typingRichTextBox; stdcli :: language: : PIN_PTR wch = ptrtostringchars (gifpath); unmanagedInsertgif (ptypingrichtextbox-> handle.toint32 (), wch);}

In order to lazy, the key code is still written in Native C , so these function names start at unmanaged.

//unmanagedwin32.h// Hybrid hosted and unmanaged programming, you can't use / CLR: SAFE and / CLR: Pure Switch when compiled, # pragma overce # pragma unmanaged // Switch to switch managed and unmanaged code EXTERN void UnmanagedScrollToButton (int hwndRichEdit); extern void UnmanagedInsertGif (int hwndRichEdit, wchar_t * pFilePath); extern void UnmanagedGifTriggerFrameChange (int hwndRichEdit); # pragma managed // unmanagedwin32.cc

// Use the Windows platform SDK // must use CLR: Oldsyntax to avoid conflicts of SDK header files and C / CLI syntax // and add / D1PrivateNativeTypes switches to avoid mixing LNK2022 errors in Visual C 2005 Express. #define unicode # define _unicode # define _win32_dcom # include "windows.h" #include "richedit.h" #include "richole.h" #pragma Comment (lib, "user32.lib") #include "unmanagedwin32.h" / / Pure C: The automated operation will be dead. Fortunately, you can automatically import #import "c: // imageole.dll" named_guids // move the cursor to the end and call System :: Windows: : Forms :: RichTextBox ScrollTocaret method, you need to drag the scroll bar to see the text before the last line. Old approach, API is serving. void UnmanagedScrollToButton hwndRichEdit (int hwndRichEdit) {HWND h = (HWND); int line = SendMessage (h, EM_GETFIRSTVISIBLELINE, 0, 0); int linecount = SendMessage (h, EM_GETLINECOUNT, 0, 0); SendMessage (h, EM_LINESCROLL, 0 (Linecount - Line - 2));

The following function UnmanagedInsertGif (int hwndRichEdit, wchar_t * pFilePath) is inserted into a ImageOle :: GifAnimator objects, UnmanagedGifTriggerFrameChange (int hwndRichEdit) is an enumeration richedit already inserted object, if it is ImageOle :: GifAnimator object, then call its TriggerFrameChange method.

Void unmanagedInsertgif (int hwndrichedit, wchar_t * pfilepath)

{

HWND H = (hwnd) hwndrichedit;

LpricheDitole LprichEditole = NULL;

LPOLEOBJECT LPOBJECT = NULL;

LPSTORAGE LPSTORAGE = NULL;

LPOLECLIENTSITE LPCLIENTSIENTSIENTSIENTSIENTSIENTSIENTSIENTSIENTSIENTSIENTSIENTSIENTSIENTSIENT = NULL;

LPLOCKBYTES LPLOCKBYTES = NULL;

Reobject reobject;

ZeromeMory (& Reobject); Reobject.cbstruct = SizeOf (Reobject);

HRESULT HR = S_OK;

CLSID CLSID = CLSID_NULL;

Do {

:: SendMessage (h, em_getoleinterface, 0, (lparam) & lprichditole;

IF (lprichditole == null) Break;

HR = :: CreateilockBytesonhglobal (Null, True, & lplockbytes);

IF (hr! = s_ok || lplockbytes == null) Break;

HR = :: StegcreatedocfileonIlockBytes (LPLOCKBYTES,

STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 0, & LPSTORAGE

IF (hr! = s_ok || lpStorage == null) Break;

HR = LprichEditole-> getClientSite (& lpclients);

IF (hr! = s_ok || lpclientsite == NULL) BREAK;

Try

{

ImageoLELIB :: Igifanimatorptr LPANIMATOR;

HR = lpanimator.createInstance (imageoLIB :: CLSID_GIFANIMATOR);

IF (Failed (HR)) _COM_ISSUE_ERROR (HR);

_BSTR_T BSTRPATH (PFILEPATH);

HR = lpanimator-> loadingfromfile (BSTRPATH);

IF (Failed (HR)) _COM_ISSUE_ERROR (HR);

HR = lpanimator.queryinterface (IID_IOLOBJECT, (Void **) & lpobject);

IF (Failed (HR) || LPObject == NULL) _COM_ISSUE_ERROR (HR);

HR = OleSetContainedObject (LPObject, true);

IF (Failed (HR)) _COM_ISSUE_ERROR (HR);

HR = LPOBJECT-> GetUserClassID (& CLSID);

IF (Failed (HR)) _COM_ISSUE_ERROR (HR);

Reobject.clsid = CLSID;

Reobject.cp = reo_cp_selection;

Reobject.dvaspect = dvaspect_content;

Reobject.dwflags = reo_belowbaseline;

REOBJECT.DWUSER = 0;

Reobject.poleobj = lpobject;

Reobject.polsite = lpclients;

Reobject.pstg = lpStorage;

Sizel Sizel = {0,0};

Reobject.sizel = sizel;

HR = lpricheditole-> INSERTOBJECT (& REOBJECT);

}

Catch (_COM_ERROR E)

{

LPCTSTR LPSZERRMESSAGE = E.ERRORMESSAGE ();

}

WHILE (FALSE);

IF (lplockbytes) lpobject-> release ();

LPLOCKBYTES)

LPLOCKBYTES-> Release ();

LPClientSite

LPClientSite-> Release ();

IF (LprichEditole)

LprichEditole-> Release ();

}

Void unmanagedgiftriggerframechange (int hwndrichedit)

{

HWND H = (hwnd) hwndrichedit;

LpricheDitole LprichEditole = NULL;

LPOLECLIENTSITE LPCLIENTSIENTSIENTSIENTSIENTSIENTSIENTSIENTSIENTSIENTSIENTSIENTSIENTSIENTSIENT = NULL;

LPOLECONTAINER LPCONTAINER = NULL;

LPENUMUNKNOWN LPENUNUNUNKNOWN = NULL;

HRESULT HR = S_OK;

Do {

:: SendMessage (h, em_getoleinterface, 0, (lparam) & lprichditole;

IF (lprichditole == null) Break;

HR = LprichEditole-> getClientSite (& lpclients);

IF (hr! = s_ok || lpclientsite == NULL) BREAK;

HR = lpclientsite-> getContainer (& lpContainer);

IF (hr! = s_ok || lpclientsite == NULL) BREAK;

HR = lpContainer-> EnumObjects (OLECONTF_EMBEDDINGS, & LPENUNKNOWN);

IF (hr! = s_ok || lpenumunknown == null) Break;

Iunknown * punk = null;

Ulong ufetched = 0;

For (uint i = 0; s_ok == lpenumunknoven-> next (1, & punk, & ufetched); i )

{

ImageoLIB :: igifanimator * panimator = null;

Do {

HR = punk-> queryinterface (__ uuidof (imageolelib :: igifanimator), (lpvoid *) & panimator);

IF (hr! = s_ok) Break;

Try {

ImageoLELIB :: Igifanimatorptr LPANIMATOR;

Lpanimator.attach (Panimator, true);

LPANIMATOR-> TriggerFramechange ();

}

Catch (_COM_ERROR E)

{

LPCTSTR LPSZERRMESSAGE = E.ERRORMESSAGE ();

}

}

WHILE (FALSE);

punk-> release ();

IF (PANIMATOR)

PANIMATOR-> Release ();

}

WHILE (FALSE);

LpenumunkNown

LPENUMUNKNOWN-> Release ();

IF (lpcontainer)

LpContainer-> Release ();

IF (LprichEditole)

LprichEditole-> Release ();

LPClientSite

LPClientSite-> Release ();

}

The methods in these two functions can also be used to insert other types of controls, and communicate with the inserted object. Using Windows 2000, QQ2004SP1, Visual C 2005 Express, Platform SDK (Windows 2003) compiled.

转载请注明原文地址:https://www.9cbs.com/read-80479.html

New Post(0)