分享
 
 
 

MSN / QQ 中的CRichEditCtrl (一) —— 动画表情

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

首先对标题说明一下,在MSN中,聊天的窗口可能是一个自定义的类。大家用Spy ++可以看看。

对与自定义窗口,可以使用CreateWindow, SetWindowLong或者是SubclassWindow实现,不过这不

是我现在讨论的话题。

好, 先看看效果再说:

我实现的主要就是:(一)字体格式; (二)超链接;(三)背景图片;(四)动画表情

关于这个的实现。我们首先应该明了,我们必须实现一个OLE对象。而且这个对象能够播放GIF.

对于播放GIF,代码已经很多了。比较有名气的就是那个谁封装的Gif89a,还不错,我喜欢那个CPictureEx.

可以在vchelp找到。

有了这个就完了么?当然不是。你还有写一个OLE/COM对象。实现IOleObject等。

你是用ATL还是MFC呢?

呵呵,我什么也没有用。在这个目录下%program file%\tencent\qq\,你可以看到一个ImageOle.dll,她就是

你日夜思念的人!

好吧,让我们来看看他的真面目。怎么看?X Ray? 当然不是——OLE/COM Viewer.

Click on “All Objects”,

View TypeLib... 打开那个文件,你可以看到:

[

uuid(0C1CF2DF-05A3-4FEF-8CD4-F5CFC4355A16),

helpstring("IGifAnimator Interface"),

dual,

nonextensible

]

dispinterface IGifAnimator {

properties:

methods:

[id(0x00000001), helpstring("method LoadFromFile")]

void LoadFromFile([in] BSTR FileName);

[id(0x00000002), helpstring("method TriggerFrameChange")]

VARIANT_BOOL TriggerFrameChange();

[id(0x00000003), helpstring("method GetFilePath")]

BSTR GetFilePath();

[id(0x00000004), helpstring("method ShowText")]

void ShowText([in] BSTR Text);

};

这个接口就是我们要的。你可以用ActiveX Control Test Container测试一下。还挺管用的。

那么怎么在我们的程序中使用呢?我也没有那么多的时间,先给出代码吧,有时间再说啊,见谅。

1LPLOCKBYTES lpLockBytes = NULL;

2SCODE sc;

3HRESULT hr;

4//print to RichEdit' s IClientSite

5LPOLECLIENTSITE m_lpClientSite;

6//A smart point to IAnimator

7IGifAnimatorPtrm_lpAnimator;

8//ptr 2 storage

9LPSTORAGE m_lpStorage;

10//the object 2 b insert 2

11LPOLEOBJECTm_lpObject;

12

13//Create lockbytes

14sc = ::CreateILockBytesOnHGlobal(NULL, TRUE, &lpLockBytes);

15if (sc != S_OK)

16AfxThrowOleException(sc);

17ASSERT(lpLockBytes != NULL);

18

19//use lockbytes to create storage

20sc = ::StgCreateDocfileOnILockBytes(lpLockBytes,

21STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE, 0, &m_lpStorage);

22if (sc != S_OK)

23{

24VERIFY(lpLockBytes->Release() == 0);

25lpLockBytes = NULL;

26AfxThrowOleException(sc);

27}

28ASSERT(m_lpStorage != NULL);

29

30//get the ClientSite of the very RichEditCtrl

31GetIRichEditOle()->GetClientSite(&m_lpClientSite);

32ASSERT(m_lpClientSite != NULL);

33

34try

35{

36//Initlize COM interface

37hr = ::CoInitializeEx( NULL, COINIT_APARTMENTTHREADED );

38if( 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

43hr = m_lpAnimator.CreateInstance(CLSID_GifAnimator);

44if( FAILED(hr) )

45_com_issue_error(hr);

46//COM operation need BSTR, so get a BSTR

47BSTR path = strPicPath.AllocSysString();

48

49//Load the gif

50hr = m_lpAnimator->LoadFromFile(path);

51if( FAILED(hr) )

52_com_issue_error(hr);

53

54TRACE0( m_lpAnimator->GetFilePath() );

55

56//get the IOleObject

57hr = m_lpAnimator.QueryInterface(IID_IOleObject, (void**)&m_lpObject);

58if( FAILED(hr) )

59_com_issue_error(hr);

60

61//Set it 2 b inserted

62OleSetContainedObject(m_lpObject, TRUE);

63

64//2 insert in 2 richedit, you need a struct of REOBJECT

65REOBJECT reobject;

66ZeroMemory(&reobject, sizeof(REOBJECT));

67

68reobject.cbStruct = sizeof(REOBJECT);

69CLSID clsid;

70sc = m_lpObject->GetUserClassID(&clsid);

71if (sc != S_OK)

72AfxThrowOleException(sc);

73//set clsid

74reobject.clsid = clsid;

75//can be selected

76reobject.cp = REO_CP_SELECTION;

77//content, but not static

78reobject.dvaspect = DVASPECT_CONTENT;

79//goes in the same line of text line

80reobject.dwFlags = REO_BELOWBASELINE; //REO_RESIZABLE |

81reobject.dwUser = 0;

82//the very object

83reobject.poleobj = m_lpObject;

84//client site contain the object

85reobject.polesite = m_lpClientSite;

86//the storage

87reobject.pstg = m_lpStorage;

88

89SIZEL sizel;

90sizel.cx = sizel.cy = 0;

91reobject.sizel = sizel;

92HWND 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

99GetIRichEditOle()->InsertObject(&reobject);

100::SendMessage(hWndRT, EM_SCROLLCARET, (WPARAM)0, (LPARAM)0);

101VARIANT_BOOL ret;

102//do frame changing

103ret = m_lpAnimator->TriggerFrameChange();

104//show it

105m_lpObject->DoVerb(OLEIVERB_UIACTIVATE, NULL, m_lpClientSite, 0, m_hWnd, NULL);

106m_lpObject->DoVerb(OLEIVERB_SHOW, NULL, m_lpClientSite, 0, m_hWnd, NULL);

107

108//redraw the window to show animation

109RedrawWindow();

110

111if (m_lpClientSite)

112{

113m_lpClientSite->Release();

114m_lpClientSite = NULL;

115}

116if (m_lpObject)

117{

118m_lpObject->Release();

119m_lpObject = NULL;

120}

121if (m_lpStorage)

122{

123m_lpStorage->Release();

124m_lpStorage = NULL;

125}

126

127SysFreeString(path);

128}

129catch( _com_error e )

130{

131AfxMessageBox(e.ErrorMessage());

132::CoUninitialize();

133}

呵呵,核心代码,就这么点,我还弄了好长时间。惭愧!

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有