UiNewsMessage.cpp
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:17k
源码类别:

模拟服务器

开发平台:

C/C++

  1. /*********************************************************************************
  2. *文件    :UiNewsMessage
  3. *创建人  :Fyt(Fan Zhanpeng)
  4. *创建时间:08-01-2003
  5. *功能描述:游戏中的新消息通知窗口
  6. **********************************************************************************/
  7. #include "KWin32.h"
  8. #include "../../../Represent/iRepresent/iRepresentShell.h"
  9. #include "UiNewsMessage.h"
  10. #include "../Elem/Wnds.h"
  11. #include "../Elem/UiImage.h"
  12. #include "../UiBase.h"
  13. #include "../../../Engine/Src/Text.h"
  14. #include "UiNewsMessage.h"
  15. #include <time.h>
  16. #define NEWS_MESSAGE_INI "新闻消息来了.ini"
  17. #define DEFAULT_MESSAGE  "\Ui\DefaultMessage.ini"
  18. //最长无消息空闲时间,空闲时间持续超过此值时,就从ini中取消息来显示(单位:毫秒)
  19. #define MAX_IDLE_TIME 600000 //10分钟
  20. //同一消息两次显示之间的间隔(单位:毫秒)
  21. #define SHOW_INTERVAL 30000
  22. //两次字符滚动之间的时间(单位:毫秒)
  23. #define SCROLL_INTERVAL 250
  24. //一般消息最多滚动出现的次数
  25. #define MAX_NORMAL_SHOW_TIMES 3
  26. #define NOT_NEED_INSERT -1
  27. extern iRepresentShell *g_pRepresentShell;
  28. KUiNewsMessage* KUiNewsMessage::m_pSelf = NULL;
  29. BOOL KUiNewsMessage::ms_bEnableIdleMsg = FALSE;
  30. /*********************************************************************************
  31. *功能:构造
  32. **********************************************************************************/
  33. KUiNewsMessage::KUiNewsMessage()
  34. {
  35. m_pHead    = NULL;
  36.     m_pHandling= NULL;
  37. m_nCharasVisibleLimitNum = 0;
  38. m_nVisionWidth = 0;
  39. m_nFontSize = 8;
  40. m_nFontHalfWidth[0] = m_nFontHalfWidth[1] = 4;
  41. srand(IR_GetCurrentTime());
  42. }
  43. void KUiNewsMessage::EnableIdleMsg(BOOL bEnable)
  44. {
  45. if (!bEnable != !ms_bEnableIdleMsg)
  46. {
  47. ms_bEnableIdleMsg = bEnable;
  48. if (m_pSelf)
  49. {
  50. if (ms_bEnableIdleMsg)
  51. {
  52. m_pSelf->m_uLastShowTime = IR_GetCurrentTime();
  53. m_pSelf->m_IniFile.Load(DEFAULT_MESSAGE);
  54. }
  55. else
  56. {
  57. m_pSelf->m_IniFile.Clear();
  58. }
  59. }
  60. }
  61. }
  62. /*********************************************************************************
  63. *功能:增加一条消息在队列中
  64. **********************************************************************************/
  65. bool KUiNewsMessage::AddMessage(KNewsMessage* pMsg, unsigned int uTime, unsigned int uTimeParam)
  66. {
  67. KNewsMessageNode *pNew = NULL;
  68. if (pMsg)
  69. {
  70. pNew = (KNewsMessageNode*)malloc(sizeof(KNewsMessageNode));
  71. if (pNew)
  72. {
  73. *(KNewsMessage*)pNew = *pMsg;
  74. pNew->uTime = uTime;
  75. pNew->uStartTime = uTimeParam;
  76. pNew->pNext = m_pHead;
  77. m_pHead = pNew;
  78. }
  79. }
  80. return (pNew != NULL);
  81. }
  82. /*********************************************************************************
  83. *功能:把m_pHandling指针所指的消息从链表中分离出来
  84. **********************************************************************************/
  85. KNewsMessageNode* KUiNewsMessage::SeparateMsg()
  86. {
  87. KNewsMessageNode *pNode = m_pHandling;
  88. if(m_pHandling)
  89. {
  90. if (m_pHandling == m_pHead)
  91. {
  92. m_pHead = m_pHead->pNext;
  93. }
  94. else
  95. {
  96. pNode = m_pHead;
  97. while(pNode->pNext != m_pHandling)
  98. {
  99. pNode = pNode->pNext;
  100. //_ASSERT(pNode);
  101. };
  102. pNode->pNext = m_pHandling->pNext;
  103. pNode = m_pHandling;
  104. }
  105. m_pHandling = NULL;
  106. pNode->pNext = NULL;
  107. }
  108. return pNode;
  109. }
  110. // 把pNode所指的消息加到链表末端!
  111. void KUiNewsMessage::AddToTail(KNewsMessageNode* pNode)
  112. {
  113. if (pNode)
  114. {
  115. if (m_pHead)
  116. {
  117. KNewsMessageNode *pPrev = m_pHead;
  118. while(pPrev->pNext)
  119. pPrev = pPrev->pNext;
  120. pPrev->pNext = pNode;
  121. }
  122. else
  123. {
  124. m_pHead = pNode;
  125. }
  126. }
  127. }
  128. // 清除所有的消息
  129. void KUiNewsMessage::Clear()
  130. {
  131. m_IniFile.Clear();
  132. while (m_pHandling = m_pHead)
  133. {
  134. m_pHead = m_pHead->pNext;
  135. free (m_pHandling);
  136. };
  137. }
  138. /*********************************************************************************
  139. *功能:打开窗口
  140. **********************************************************************************/
  141. KUiNewsMessage* KUiNewsMessage::OpenWindow()
  142. {
  143. if (m_pSelf == NULL)
  144. {
  145. m_pSelf = new KUiNewsMessage;
  146. if (m_pSelf)
  147. {
  148. m_pSelf->Initialize();
  149. }
  150. }
  151. if (m_pSelf)
  152. {
  153. m_pSelf->m_uLastShowTime = IR_GetCurrentTime();
  154. m_pSelf->Show();
  155. m_pSelf->BringToTop();
  156. }
  157. return m_pSelf;
  158. }
  159. /*********************************************************************************
  160. *功能:如果窗口正被显示,则返回实例指针
  161. **********************************************************************************/
  162. KUiNewsMessage* KUiNewsMessage::GetIfVisible()
  163. {
  164. if (m_pSelf && m_pSelf->IsVisible())
  165. return m_pSelf;
  166. return NULL;
  167. }
  168. /*********************************************************************************
  169. *功能:关闭窗口
  170. **********************************************************************************/
  171. void KUiNewsMessage::CloseWindow(BOOL bDestory)
  172. {
  173. if (m_pSelf)
  174. {
  175. if(bDestory == TRUE)
  176. {
  177. m_pSelf->Clear();
  178. m_pSelf->Destroy();
  179.     m_pSelf = NULL;
  180. }
  181. else
  182. {
  183. m_pSelf->Hide();
  184. }
  185. }
  186. }
  187. /*********************************************************************************
  188. *功能:初始化
  189. **********************************************************************************/
  190. void KUiNewsMessage::Initialize()
  191. {
  192. if (ms_bEnableIdleMsg)
  193. m_IniFile.Load(DEFAULT_MESSAGE);
  194. char Scheme[128];
  195. g_UiBase.GetCurSchemePath(Scheme, 256);
  196. LoadScheme(Scheme);
  197. Wnd_AddWindow(this, WL_TOPMOST);
  198. }
  199. /*********************************************************************************
  200. *功能:载入界面方案
  201. **********************************************************************************/
  202. void KUiNewsMessage::LoadScheme(const char* pszScheme)
  203. {
  204. if (m_pSelf && pszScheme && pszScheme[0])
  205. {
  206. char    szBuf[128];
  207. sprintf(szBuf, "%s\%s", pszScheme, NEWS_MESSAGE_INI);
  208. KIniFile Ini;
  209. if (Ini.Load(szBuf))
  210. {
  211. m_pSelf->Init(&Ini, "Main");
  212. Ini.GetInteger("Main", "IndentH", 0, &m_pSelf->m_nIndentH);
  213. Ini.GetInteger("Main", "IndentV",   0, &m_pSelf->m_nIndentV);
  214. Ini.GetInteger("Main", "Font",      0, &m_pSelf->m_nFontSize);
  215. if(m_pSelf->m_nFontSize < 8)
  216.      m_pSelf->m_nFontSize = 8;
  217. m_pSelf->m_nFontHalfWidth[0] = (m_pSelf->m_nFontSize + 1) / 2;
  218. m_pSelf->m_nFontHalfWidth[1] = m_pSelf->m_nFontSize / 2;;
  219. m_pSelf->m_nVisionWidth = m_pSelf->m_Width - m_pSelf->m_nIndentH * 2;
  220. m_pSelf->m_nCharasVisibleLimitNum =
  221. (m_pSelf->m_nVisionWidth * 2) / m_pSelf->m_nFontSize;
  222. Ini.GetString ("Main", "TextColor", "0,0,0", szBuf, sizeof(szBuf));
  223.     m_pSelf->m_uTextColor = GetColor(szBuf);
  224. Ini.GetString ("Main", "TextBorderColor", "0,0,0", szBuf, sizeof(szBuf));
  225. m_pSelf->m_uTextBorderColor = GetColor(szBuf);
  226. Ini.GetInteger("Main", "MaxIdleTime",    MAX_IDLE_TIME,   (int*)&m_pSelf->m_uMaxIdleTime);
  227. Ini.GetInteger("Main", "ShowInterval" ,  SHOW_INTERVAL,   (int*)&m_pSelf->m_uShowInterval);
  228. Ini.GetInteger("Main", "ScrollInterval", SCROLL_INTERVAL, (int*)&m_pSelf->m_uScrollInterval);
  229. }
  230. }
  231. }
  232. /*********************************************************************************
  233. *功能:两个字 - 穿透!!!
  234. **********************************************************************************/
  235. int KUiNewsMessage::PtInWindow(int x, int y)
  236. {
  237. return 0;
  238. }
  239. //新闻消息真的来了
  240. void KUiNewsMessage::MessageArrival(KNewsMessage* pMsg, SYSTEMTIME* pTime)
  241. {
  242. unsigned int uTime;
  243. if (m_pSelf && pMsg &&
  244. pMsg->nMsgLen > 0 && pMsg->nMsgLen <= sizeof(pMsg->sMsg))
  245. {
  246. switch(pMsg->nType)
  247. {
  248. case NEWSMESSAGE_NORMAL://一般消息
  249. m_pSelf->AddMessage(pMsg, 0, 0);
  250. break;
  251. case NEWSMESSAGE_COUNTING://倒计(秒)数消息
  252. if (pTime && pTime->wSecond)
  253. uTime = pTime->wSecond * 1000;
  254. else
  255. uTime = 3000;
  256. m_pSelf->AddMessage(pMsg, uTime, IR_GetCurrentTime());
  257. break;
  258. case NEWSMESSAGE_TIMEEND: //定时消息
  259. if (pTime)
  260. {
  261. SYSTEMTIME Local;
  262. SystemTimeToTzSpecificLocalTime(NULL, pTime, &Local);
  263. tm TimeBuf;
  264. TimeBuf.tm_isdst= 0;
  265. TimeBuf.tm_year = Local.wYear - 1900;
  266. TimeBuf.tm_mon  = Local.wMonth - 1;
  267. TimeBuf.tm_mday = Local.wDay;
  268. TimeBuf.tm_hour = Local.wHour;
  269. TimeBuf.tm_min  = Local.wMinute;
  270. TimeBuf.tm_sec  = Local.wSecond;
  271. TimeBuf.tm_wday = Local.wDayOfWeek;
  272. TimeBuf.tm_yday = 0;
  273. uTime = mktime(&TimeBuf);
  274. if(uTime == (unsigned int)(time_t)-1)
  275. uTime = 0;
  276. }
  277. else
  278. uTime = 0;
  279. if (uTime)
  280. m_pSelf->AddMessage(pMsg, uTime, 0);
  281. else
  282. {
  283. pMsg->nType = NEWSMESSAGE_NORMAL;
  284. m_pSelf->AddMessage(pMsg, 0, 0);
  285. pMsg->nType = NEWSMESSAGE_TIMEEND;
  286. }
  287. break;
  288. }
  289. }
  290. }
  291. /*********************************************************************************
  292. *功能:显示消息,并在显示完成后对消息进行进一步处理
  293. **********************************************************************************/
  294. void KUiNewsMessage::PaintWindow()
  295. {
  296.     if(m_pHandling && g_pRepresentShell)
  297. {
  298. KWndShadow::PaintWindow();
  299. //画字串了  -___________-|||b
  300. KOutputTextParam Param;
  301. Param.Color       = m_uTextColor;
  302. Param.BorderColor = m_uTextBorderColor;
  303. Param.nSkipLine   = 0;
  304. Param.nNumLine    = 1;
  305. Param.nX   = m_nTextPosX;
  306. Param.nY          = m_nAbsoluteTop + m_nIndentV;
  307. Param.nZ          = TEXT_IN_SINGLE_PLANE_COORD;
  308. Param.nVertAlign  = 0;
  309. Param.bPicPackInSingleLine = true;
  310. if (m_bJustIncoming)
  311. { //消息正在进入,(头)还未开始离开显示区域
  312. g_pRepresentShell->OutputRichText(m_nFontSize, &Param,
  313. m_CurrentMsg.sMsg, m_nCharIndex, 0);
  314. }
  315. else
  316. { //消息头已经离开显示区域
  317. KTP_CTRL Ctrl0, Ctrl1;
  318. TGetEncodedTextEffectCtrls(m_CurrentMsg.sMsg, m_nCharIndex, Ctrl0, Ctrl1);
  319. char sBuffer[sizeof(m_CurrentMsg.sMsg)];
  320. int nRemainEffectCtrlsSize = 0;
  321. if (Ctrl0.cCtrl != KTC_INVALID)
  322. {
  323. *(int*)(sBuffer) = *(int*)(&Ctrl0);
  324. nRemainEffectCtrlsSize += 4;
  325. }
  326. if (Ctrl1.cCtrl != KTC_INVALID)
  327. {
  328. *(int*)(&sBuffer[nRemainEffectCtrlsSize]) = *(int*)(&Ctrl1);
  329. nRemainEffectCtrlsSize += 4;
  330. }
  331. if (nRemainEffectCtrlsSize == 0)
  332. {
  333. g_pRepresentShell->OutputRichText(m_nFontSize, &Param,
  334. &m_CurrentMsg.sMsg[m_nCharIndex], m_CurrentMsg.nMsgLen - m_nCharIndex,
  335. m_nVisionWidth);
  336. }
  337. else
  338. {
  339. memcpy(sBuffer + nRemainEffectCtrlsSize, m_CurrentMsg.sMsg + m_nCharIndex,
  340. m_CurrentMsg.nMsgLen - m_nCharIndex);
  341. g_pRepresentShell->OutputRichText(m_nFontSize, &Param,
  342. sBuffer, m_CurrentMsg.nMsgLen - m_nCharIndex + nRemainEffectCtrlsSize,
  343. m_nVisionWidth);
  344. }
  345. }
  346. }
  347. }
  348. /*********************************************************************************
  349. *功能:在队列中,寻找是否有符合显示条件的消息,使指针m_pHandling指向找到的消息
  350. **********************************************************************************/
  351. bool KUiNewsMessage::PickAMessage()
  352. {
  353. m_pHandling = NULL;
  354. unsigned int uCurrentTime = IR_GetCurrentTime();
  355. if (m_pHead == NULL)
  356. {
  357. if (ms_bEnableIdleMsg && uCurrentTime > m_uLastShowTime + m_uMaxIdleTime)
  358. { //如果过了时间了,还没有新消息到,就随机在ini中选一条消息,插入队列中
  359. PickFromIni();
  360. if (m_pHandling = m_pHead)
  361. m_pHandling->uShowTimes++;
  362. //ASSERT(m_pHandling->nType == NEWSMESSAGE_NORMAL);
  363. m_uLastShowTime = uCurrentTime; //对付从ini中也不能取到消息的情况
  364. }
  365. }
  366. else
  367. {
  368. KNewsMessageNode* pNode = m_pHead;
  369. while(pNode)
  370. {
  371. bool bTobeFree = false;
  372. if (pNode->nType == NEWSMESSAGE_NORMAL)
  373. {
  374. m_pHandling = pNode;
  375. if ((++pNode->uShowTimes) > MAX_NORMAL_SHOW_TIMES)
  376. bTobeFree = true;
  377. }
  378. else if (pNode->nType == NEWSMESSAGE_COUNTING)
  379. {
  380. m_pHandling = pNode;
  381. if (uCurrentTime - pNode->uStartTime >= pNode->uTime)
  382. bTobeFree = true;
  383. }
  384. else if (uCurrentTime > pNode->uLastShowTime + m_uShowInterval)
  385. {
  386. m_pHandling = pNode;
  387. if ((unsigned int)time(NULL) >= pNode->uTime)
  388. bTobeFree =  true; //限时消息到时了,消灭它
  389. else
  390. pNode->uLastShowTime = uCurrentTime;
  391. }
  392. else
  393. {
  394. pNode = pNode->pNext;
  395. continue;
  396. }
  397. if (bTobeFree == false)
  398. break;
  399. pNode = pNode->pNext;
  400. free(SeparateMsg());
  401. };
  402. }
  403. return (m_pHandling != NULL);
  404. }
  405. /*********************************************************************************
  406. *功能:在Ini文件中随机抽取一条消息插入队列
  407. **********************************************************************************/
  408. void KUiNewsMessage::PickFromIni()
  409. {
  410. int         i, nValue;
  411. char        szNum[16];
  412. KNewsMessage Msg;
  413. m_IniFile.GetInteger("Main", "Count", 0, &nValue);
  414. if(nValue > 0)
  415. {
  416.      i = rand() % nValue;
  417. m_IniFile.GetString("Main", itoa(i, szNum, 10), "", Msg.sMsg, sizeof(Msg.sMsg));
  418. Msg.nMsgLen = TEncodeText(Msg.sMsg, strlen(Msg.sMsg));
  419. if (Msg.nMsgLen > 0)
  420. {
  421. Msg.nType = NEWSMESSAGE_NORMAL;
  422. MessageArrival(&Msg, NULL);
  423. }
  424. }
  425. }
  426. /*********************************************************************************
  427. *功能:保持活动,更新消息信息
  428. **********************************************************************************/
  429. void KUiNewsMessage::Breathe()
  430. {
  431. if(m_pHandling)
  432. { //有消息正在显示
  433. if (IR_IsTimePassed(m_uScrollInterval, m_uLastScrollTime))
  434. {
  435. if (ScrollMsg())
  436. AddToTail(SeparateMsg()); // 当前消息显示完毕,移到末尾去
  437. }
  438. }
  439. if (m_pHandling == NULL)
  440. {
  441. if (PickAMessage())
  442. Reset();
  443. }
  444. }
  445. void KUiNewsMessage::ConvertMsg()
  446. {
  447. //_ASSERT(m_pHandling);
  448. //填充当前显示消息的内容
  449. m_CurrentMsg.nMsgLen = 0;
  450. m_nInsertPlace = NOT_NEED_INSERT;
  451.     if(m_pHandling->nType == NEWSMESSAGE_COUNTING)
  452. {
  453. m_nInsertPlace = TFindSpecialCtrlInEncodedText(m_pHandling->sMsg,
  454. m_pHandling->nMsgLen, 0, '%');
  455. if (m_nInsertPlace < 0 &&
  456. m_nInsertPlace > m_pHandling->nMsgLen - 2)
  457. {
  458. m_nInsertPlace = NOT_NEED_INSERT;
  459. }
  460. else if (m_pHandling->sMsg[m_nInsertPlace + 1] != 'd')
  461. {
  462. m_nInsertPlace = NOT_NEED_INSERT;
  463. }
  464. }
  465. if (m_nInsertPlace == NOT_NEED_INSERT)
  466. {
  467. memcpy(m_CurrentMsg.sMsg, m_pHandling->sMsg, m_pHandling->nMsgLen);
  468. m_CurrentMsg.nMsgLen = m_pHandling->nMsgLen;
  469. }
  470. }
  471. bool KUiNewsMessage::MakeCountingMsg()
  472. {
  473. //_ASSERT(m_pHandling &&
  474. // m_pHandling->nType == NEWSMESSAGE_COUNTING &&
  475. // m_nInsertPlace != NOT_NEED_INSERT);
  476. unsigned int uCurrent = IR_GetCurrentTime();
  477. if (uCurrent - m_pHandling->uStartTime >= m_pHandling->uTime)
  478. return false;
  479. char sBuffer[sizeof(m_pHandling->sMsg) + 8];
  480. memcpy(sBuffer, m_pHandling->sMsg, m_nInsertPlace);
  481. m_CurrentMsg.nMsgLen = m_nInsertPlace;
  482. int nNumLen = sprintf(sBuffer + m_nInsertPlace, "%d",
  483. (m_pHandling->uTime - uCurrent + m_pHandling->uStartTime + 999) / 1000);
  484. m_CurrentMsg.nMsgLen += nNumLen;
  485. m_nInsertPlace += 2;
  486. if (m_pHandling->nMsgLen > m_nInsertPlace)
  487. {
  488. memcpy(sBuffer + m_CurrentMsg.nMsgLen,
  489. m_pHandling->sMsg + m_nInsertPlace ,
  490. m_pHandling->nMsgLen - m_nInsertPlace);
  491. m_CurrentMsg.nMsgLen += m_pHandling->nMsgLen - m_nInsertPlace;
  492. }
  493. m_nInsertPlace -= 2;
  494. //此段特殊的额外处理是为了...
  495. {
  496. //_ASSERT(nNumLen > 5);
  497. nNumLen = 5 - nNumLen;
  498. if (nNumLen > 0)
  499. {
  500. memset(sBuffer + m_CurrentMsg.nMsgLen, 0, nNumLen);
  501. m_CurrentMsg.nMsgLen += nNumLen;
  502. }
  503. }
  504. if (m_CurrentMsg.nMsgLen > sizeof(m_CurrentMsg.sMsg))
  505. {
  506. m_CurrentMsg.nMsgLen = TSplitEncodedString(sBuffer, m_CurrentMsg.nMsgLen,
  507. sizeof(m_CurrentMsg.sMsg), true);
  508. }
  509. memcpy(m_CurrentMsg.sMsg, sBuffer, m_CurrentMsg.nMsgLen);
  510. return true;
  511. }
  512. /*********************************************************************************
  513. *功能:重置当前所显示消息的显示状态,重置计时器
  514. **********************************************************************************/
  515. void KUiNewsMessage::Reset()
  516. {
  517. if(m_pHandling == NULL)
  518. return;
  519. m_uLastShowTime = m_uLastScrollTime = IR_GetCurrentTime();
  520. ConvertMsg();
  521. m_bJustIncoming = true;
  522. m_nCharIndex = 0;
  523. m_nHalfIndex = 0;
  524. m_nTextPosX = m_nAbsoluteLeft + m_nIndentH + m_nVisionWidth;
  525. }
  526. bool KUiNewsMessage::ScrollMsg()
  527. {
  528. static int snSkipTimes = 0;
  529. if (snSkipTimes > 0)
  530. {
  531. m_nTextPosX -= m_nFontHalfWidth[m_nHalfIndex];
  532. m_nHalfIndex ^= 1;
  533. snSkipTimes--;
  534. if (snSkipTimes == 0 && m_bJustIncoming == false)
  535. {
  536. m_nTextPosX = m_nAbsoluteLeft + m_nIndentH;
  537. }
  538. return false;
  539. }
  540. //_ASSERT(m_pHandling);
  541. if (m_nInsertPlace != NOT_NEED_INSERT)
  542. {
  543. if (MakeCountingMsg() == false)
  544. return true;
  545. }
  546. int nPos, nLen;
  547. if (m_bJustIncoming)
  548. {
  549. nLen = 1;
  550. if (m_nCharIndex < m_CurrentMsg.nMsgLen)
  551. {
  552. nPos = TGetEncodedTextOutputLenPos(m_CurrentMsg.sMsg + m_nCharIndex,
  553. m_CurrentMsg.nMsgLen - m_nCharIndex, nLen, false, m_nFontSize);
  554. m_nCharIndex += nPos;
  555. }
  556. if (nLen)
  557. {
  558. m_nTextPosX -= m_nFontHalfWidth[m_nHalfIndex];
  559. m_nHalfIndex ^= 1;
  560. snSkipTimes = nLen - 1;
  561. }
  562. if (m_nTextPosX < m_nAbsoluteLeft + m_nIndentH)
  563. {
  564. m_nTextPosX = m_nAbsoluteLeft + m_nIndentH;
  565. m_bJustIncoming = false;
  566. nLen = 1;
  567. m_nCharIndex = TGetEncodedTextOutputLenPos(m_CurrentMsg.sMsg,
  568. m_CurrentMsg.nMsgLen, nLen, false, m_nFontSize);
  569. if (m_nCharIndex >= m_CurrentMsg.nMsgLen)
  570. {
  571. snSkipTimes = 0;
  572. return true;
  573. }
  574. }
  575. }
  576. else
  577. {
  578. nLen = 1;
  579. nPos = TGetEncodedTextOutputLenPos(m_CurrentMsg.sMsg + m_nCharIndex,
  580. m_CurrentMsg.nMsgLen - m_nCharIndex, nLen, false, m_nFontSize);
  581. m_nCharIndex += nPos;
  582. if (nLen > 1)
  583. {
  584. m_nTextPosX += nLen / 2 * m_nFontSize;
  585. if ((nLen % 2) == 0)
  586. {
  587. m_nTextPosX -= m_nFontHalfWidth[m_nHalfIndex];
  588. m_nHalfIndex ^= 1;
  589. }
  590. snSkipTimes = nLen - 1;
  591. }
  592. if (m_nCharIndex >= m_CurrentMsg.nMsgLen)
  593. {
  594. snSkipTimes = 0;
  595. return true;
  596. }
  597. }
  598. return false;
  599. }