1 LPLOCKBYTES lpLockBytes = NULL;
2 SCODE sc;
3 HRESULT hr;
4 //print to RichEdit' s IClientSite
5 LPOLECLIENTSITE m_lpClientSite;
6 //A smart point to IAnimator
7 IGifAnimatorPtr m_lpAnimator;
8 //ptr 2 storage
9 LPSTORAGE m_lpStorage;
10 //the object 2 b insert 2
11 LPOLEOBJECT m_lpObject;
12
13 //Create lockbytes
14 sc = ::CreateILockBytesOnHGlobal(NULL, TRUE, &lpLockBytes);
15 if (sc != S_OK)
16 AfxThrowOleException(sc);
17 ASSERT(lpLockBytes != NULL);
18
19 //use lockbytes to create storage
20 sc = ::StgCreateDocfileOnILockBytes(lpLockBytes,
21 STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE, 0, &m_lpStorage);
22 if (sc != S_OK)
23 {
24 VERIFY(lpLockBytes->Release() == 0);
25 lpLockBytes = NULL;
26 AfxThrowOleException(sc);
27 }
28 ASSERT(m_lpStorage != NULL);
29
30 //get the ClientSite of the very RichEditCtrl
31 GetIRichEditOle()->GetClientSite(&m_lpClientSite);
32 ASSERT(m_lpClientSite != NULL);
33
34 try
35 {
36 //Initlize COM interface
37 hr = ::CoInitializeEx( NULL, COINIT_APARTMENTTHREADED );
38 if( FAILED(hr) )
39 _com_issue_error(hr);
40
41 //Get GifAnimator object
42 //here, I used a smart point, so I do not need to free it
43 hr = m_lpAnimator.CreateInstance(CLSID_GifAnimator);
44 if( FAILED(hr) )
45 _com_issue_error(hr);
46 //COM operation need BSTR, so get a BSTR
47 BSTR path = strPicPath.AllocSysString();
48
49 //Load the gif
50 hr = m_lpAnimator->LoadFromFile(path);
51 if( FAILED(hr) )
52 _com_issue_error(hr);
53
54 TRACE0( m_lpAnimator->GetFilePath() );
55
56 //get the IOleObject
57 hr = m_lpAnimator.QueryInterface(IID_IOleObject, (void**)&m_lpObject);
58 if( FAILED(hr) )
59 _com_issue_error(hr);
60
61 //Set it 2 b inserted
62 OleSetContainedObject(m_lpObject, TRUE);
63
64 //2 insert in 2 richedit, you need a struct of REOBJECT
65 REOBJECT reobject;
66 ZeroMemory(&reobject, sizeof(REOBJECT));
67
68 reobject.cbStruct = sizeof(REOBJECT);
69 CLSID clsid;
70 sc = m_lpObject->GetUserClassID(&clsid);
71 if (sc != S_OK)
72 AfxThrowOleException(sc);
73 //set clsid
74 reobject.clsid = clsid;
75 //can be selected
76 reobject.cp = REO_CP_SELECTION;
77 //content, but not static
78 reobject.dvaspect = DVASPECT_CONTENT;
79 //goes in the same line of text line
80 reobject.dwFlags = REO_BELOWBASELINE; //REO_RESIZABLE |
81 reobject.dwUser = 0;
82 //the very object
83 reobject.poleobj = m_lpObject;
84 //client site contain the object
85 reobject.polesite = m_lpClientSite;
86 //the storage
87 reobject.pstg = m_lpStorage;
88
89 SIZEL sizel;
90 sizel.cx = sizel.cy = 0;
91 reobject.sizel = sizel;
92 HWND hWndRT = this->m_hWnd;
93 //Sel all text
94// ::SendMessage(hWndRT, EM_SETSEL, 0, -1);
95// DWORD dwStart, dwEnd;
96// ::SendMessage(hWndRT, EM_GETSEL, (WPARAM)&dwStart, (LPARAM)&dwEnd);
97// ::SendMessage(hWndRT, EM_SETSEL, dwEnd+1, dwEnd+1);
98 //Insert after the line of text
99 GetIRichEditOle()->InsertObject(&reobject);
100 ::SendMessage(hWndRT, EM_SCROLLCARET, (WPARAM)0, (LPARAM)0);
101 VARIANT_BOOL ret;
102 //do frame changing
103 ret = m_lpAnimator->TriggerFrameChange();
104 //show it
105 m_lpObject->DoVerb(OLEIVERB_UIACTIVATE, NULL, m_lpClientSite, 0, m_hWnd, NULL);
106 m_lpObject->DoVerb(OLEIVERB_SHOW, NULL, m_lpClientSite, 0, m_hWnd, NULL);
107
108 //redraw the window to show animation
109 RedrawWindow();
110
111 if (m_lpClientSite)
112 {
113 m_lpClientSite->Release();
114 m_lpClientSite = NULL;
115 }
116 if (m_lpObject)
117 {
118 m_lpObject->Release();
119 m_lpObject = NULL;
120 }
121 if (m_lpStorage)
122 {
123 m_lpStorage->Release();
124 m_lpStorage = NULL;
125 }
126
127 SysFreeString(path);
128 }
129 catch( _com_error e )
130 {
131 AfxMessageBox(e.ErrorMessage());
132 ::CoUninitialize();
133 }
呵呵,核心代码,就这么点,我还弄了好长时间。惭愧!
本文地址:http://com.8s8s.com/it/it25292.htm