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

模拟服务器

开发平台:

C/C++

  1. /*****************************************************************************************
  2. // 界面窗口体系结构--列表窗口
  3. // Copyright : Kingsoft 2002
  4. // Author :   Wooy(Wu yue)
  5. // CreateTime: 2002-8-8
  6. *****************************************************************************************/
  7. #include "KWin32.h"
  8. #include "KIniFile.h"
  9. #include "../Elem/WndMessage.h"
  10. #include "../Elem/WndScrollBar.h"
  11. #include "WndList.h"
  12. #include "UiImage.h"
  13. #include "../../../Represent/iRepresent/iRepresentShell.h"
  14. #include "../../../Engine/Src/Text.h"
  15. extern iRepresentShell* g_pRepresentShell;
  16. #define NO_BG_COLOR 0xffffffff
  17. #define IS_MULTI_SEL (m_Style & WNDLIST_ES_MULTI_SEL)
  18. //--------------------------------------------------------------------------
  19. // 功能:构造函数
  20. //--------------------------------------------------------------------------
  21. KWndList::KWndList()
  22. {
  23. m_pContent = NULL;
  24. m_nNumItem = 0;
  25. m_nItemSize = 0;
  26. m_nStringOffset = 0;
  27. m_nColorOffset  = NO_CUSTOM_COLOR;
  28. m_nTopItemIndex = 0;
  29. m_nFontSize = 12;
  30. m_nSelItemIndex   = -1;
  31. m_nHighLightItemIndex = -1;
  32. m_nNumColumn = 1;
  33. m_uIsItemSelStatus = 0;
  34. m_puItemSelStatusList = NULL;
  35. m_uNumSelStatusList = 0;
  36. m_pScrollbar = NULL;
  37. m_ItemBorderColor = m_SelItemBorderColor = m_HighLightBorderColor = 0;
  38. }
  39. void KWndList::Clone(KWndList* pCopy)
  40. {
  41. if (pCopy)
  42. {
  43. KWndWindow::Clone(pCopy);
  44. pCopy->m_nFontSize = m_nFontSize;
  45. pCopy->m_nNumColumn = m_nNumColumn;
  46. pCopy->m_ItemColor = m_ItemColor;
  47. pCopy->m_SelItemColor = m_SelItemColor;
  48. pCopy->m_uSelItemBgColor = m_uSelItemBgColor;
  49. pCopy->m_HighLightColor  = m_HighLightColor;
  50. pCopy->m_ItemBorderColor = m_ItemBorderColor;
  51. pCopy->m_SelItemBorderColor = m_SelItemBorderColor;
  52. pCopy->m_HighLightBorderColor = m_HighLightBorderColor;
  53. pCopy->EnableMultiSel(IS_MULTI_SEL);
  54. pCopy->UpdateData();
  55. }
  56. }
  57. KWndList::~KWndList()
  58. {
  59. EnableMultiSel(0);
  60. }
  61. void KWndList::SetScrollbar(KWndScrollBar* pScroll)
  62. {
  63. if (m_pScrollbar = pScroll)
  64. {
  65. m_pScrollbar->SetStyle(m_pScrollbar->GetStyle() | WND_S_MOVEALBE);
  66. if (m_nNumItem > GetVisibleItemCount())
  67. {
  68. m_pScrollbar->Enable(true);
  69. m_pScrollbar->SetValueRange(0, m_nNumItem - GetVisibleItemCount());
  70. }
  71. else
  72. m_pScrollbar->Enable(false);
  73. }
  74. }
  75. //--------------------------------------------------------------------------
  76. // 功能:初始化
  77. //--------------------------------------------------------------------------
  78. int KWndList::Init(KIniFile* pIniFile, const char* pSection)
  79. {
  80. if (KWndWindow::Init(pIniFile, pSection))
  81. {
  82. pIniFile->GetInteger(pSection, "NumColumn", 1, &m_nNumColumn);
  83. if (m_nNumColumn < 1)
  84. m_nNumColumn = 1;
  85. pIniFile->GetInteger(pSection, "Font", 16, &m_nFontSize);
  86. if (m_nFontSize < 8)
  87. m_nFontSize = 8;
  88. //====读取文字对齐方式====
  89. m_Style &= ~WNDLIST_ES_HALIGN_FILTER;
  90. int nValue;
  91. pIniFile->GetInteger(pSection, "HAlign", 0, &nValue);
  92. if (nValue == 1)
  93. m_Style |= WNDLIST_ES_HALIGN_CENTRE;
  94. else if (nValue == 2)
  95. m_Style |= WNDLIST_ES_HALIGN_RIGHT;
  96. char Buff[16];
  97. pIniFile->GetString(pSection, "Color", "", Buff, 16);
  98. m_ItemColor = GetColor(Buff);
  99. pIniFile->GetString(pSection, "BorderColor", "", Buff, 16);
  100. m_ItemBorderColor = GetColor(Buff);
  101. pIniFile->GetString(pSection, "SelColor", "", Buff, 16);
  102. m_SelItemColor = GetColor(Buff);
  103. pIniFile->GetString(pSection, "SelBorderColor", "", Buff, 16);
  104. m_SelItemBorderColor = GetColor(Buff);
  105. if (pIniFile->GetString(pSection, "SelItemBgColor", "", Buff, 16) && Buff[0])
  106. m_uSelItemBgColor = (GetColor(Buff) & 0xffffff);
  107. else
  108. m_uSelItemBgColor = NO_BG_COLOR;
  109. pIniFile->GetInteger(pSection, "HighLight", 0, &nValue);
  110. if (nValue)
  111. {
  112. m_Style |= WNDLIST_ES_HIGHLIGHT_ENABLE;
  113. pIniFile->GetString(pSection, "HighLightColor", "", Buff, 16);
  114. m_HighLightColor = GetColor(Buff);
  115. pIniFile->GetString(pSection, "HighLightBorderColor", "", Buff, 16);
  116. m_HighLightBorderColor = GetColor(Buff);
  117. }
  118. else
  119. {
  120. m_nHighLightItemIndex = -1;
  121. m_Style &= ~WNDLIST_ES_HIGHLIGHT_ENABLE;
  122. }
  123. pIniFile->GetInteger(pSection, "MultiSel", 0, &nValue);
  124. EnableMultiSel(nValue);
  125. UpdateData();
  126. return true;
  127. }
  128. return false;
  129. }
  130. //启用/禁用多选
  131. void KWndList::EnableMultiSel(int bEnable)
  132. {
  133. if (bEnable && IS_MULTI_SEL == 0)
  134. {
  135. m_Style |= WNDLIST_ES_MULTI_SEL;
  136. m_uIsItemSelStatus = 0;
  137. m_nSelItemIndex = -1;
  138. if (m_nNumItem > 32)
  139. {
  140. m_uNumSelStatusList = (m_nNumItem - 1) / 32;
  141. m_puItemSelStatusList = (unsigned int*)malloc(sizeof(unsigned int) * m_uNumSelStatusList);
  142. if (m_puItemSelStatusList)
  143. memset(m_puItemSelStatusList, 0, sizeof(unsigned int) * m_uNumSelStatusList);
  144. else
  145. {
  146. m_uNumSelStatusList = 0;
  147. m_Style &= ~WNDLIST_ES_MULTI_SEL;
  148. }
  149. }
  150. }
  151. else if (bEnable == false && IS_MULTI_SEL)
  152. {
  153. m_Style &= ~WNDLIST_ES_MULTI_SEL;
  154. m_uIsItemSelStatus = 0;
  155. if (m_puItemSelStatusList)
  156. {
  157. free(m_puItemSelStatusList);
  158. m_puItemSelStatusList = NULL;
  159. }
  160. m_uNumSelStatusList = 0;
  161. }
  162. }
  163. void KWndList::SetCustomColorOffset(int nOffset)
  164. {
  165. if (nOffset >= 0)
  166. m_nColorOffset = nOffset;
  167. else
  168. m_nColorOffset = NO_CUSTOM_COLOR;
  169. }
  170. //--------------------------------------------------------------------------
  171. // 功能:窗口函数
  172. //--------------------------------------------------------------------------
  173. int KWndList::WndProc(unsigned int uMsg, unsigned int uParam, int nParam)
  174. {
  175. switch(uMsg)
  176. {
  177. case WM_MOUSEMOVE://to be check
  178. if (m_Style & WNDLIST_ES_HIGHLIGHT_ENABLE)
  179. OnMouseMove(LOWORD(nParam), HIWORD(nParam));
  180. break;
  181. case WM_LBUTTONDOWN:
  182. OnLButtonDown(LOWORD(nParam), HIWORD(nParam));
  183. break;
  184. case WM_MOUSEWHEEL:
  185. {
  186. if (m_pScrollbar && !m_pScrollbar->IsDisable())
  187. {
  188. int zDelta = short(HIWORD(uParam));
  189. int nPos = m_pScrollbar->GetScrollPos();
  190. nPos += (-zDelta / WHEEL_DELTA);
  191. m_pScrollbar->SetScrollPos(nPos);
  192. }
  193. }
  194. break;
  195. case WM_RBUTTONDOWN:
  196. OnRButtonDown(LOWORD(nParam), HIWORD(nParam));
  197. break;
  198. case WM_LBUTTONDBLCLK:
  199. OnLButtonDClick(LOWORD(nParam), HIWORD(nParam));
  200. break;
  201. default:
  202. return KWndWindow::WndProc(uMsg, uParam, nParam);
  203. }
  204. return 0;
  205. }
  206. //获得的指定位置的选项的索引
  207. int KWndList::GetIemIndexAtPoint(int x, int y)
  208. {
  209. int nSel = m_nTopItemIndex + (y - m_nAbsoluteTop) / (m_nFontSize + 1) * m_nNumColumn;
  210. if (m_nNumColumn > 1)
  211. {
  212. int nColumnWidth = m_Width / m_nNumColumn;
  213. if (nColumnWidth > 0)
  214. nSel += (x - m_nAbsoluteLeft) / nColumnWidth;
  215. }
  216. if (nSel >= m_nNumItem)
  217. nSel =  -1;
  218. return nSel;
  219. }
  220. //--------------------------------------------------------------------------
  221. // 功能:响应鼠标左键在此按下
  222. //--------------------------------------------------------------------------
  223. void KWndList::OnLButtonDown(int x, int y)
  224. {
  225. int nSel = GetIemIndexAtPoint(x, y);
  226. if (nSel != m_nSelItemIndex)
  227. {
  228. if (IS_MULTI_SEL == 0)
  229. {
  230. m_nSelItemIndex = nSel;
  231. if (m_pParentWnd)
  232. {
  233. m_pParentWnd->WndProc(WND_N_LIST_ITEM_SEL,
  234. (unsigned int)(KWndWindow*)this, m_nSelItemIndex);
  235. }
  236. }
  237. else if (nSel >= 0)
  238. {
  239. unsigned int uFlag = (1 << (nSel % 32));
  240. if (nSel < 32)
  241. m_uIsItemSelStatus ^= uFlag;
  242. else
  243. m_puItemSelStatusList[nSel / 32] ^= uFlag;
  244. if (m_pParentWnd)
  245. {
  246. m_pParentWnd->WndProc(WND_N_LIST_ITEM_SEL,
  247. (unsigned int)(KWndWindow*)this, nSel);
  248. }
  249. }
  250. }
  251. }
  252. //判断某项是否被选中
  253. int KWndList::IsItemSel(int nIndex)
  254. {
  255. if (IS_MULTI_SEL == 0)
  256. return (m_nSelItemIndex == nIndex);
  257. unsigned int uFlag = (1 << (nIndex % 32));
  258. if (nIndex < 32)
  259. return (m_uIsItemSelStatus & uFlag);
  260. return (m_puItemSelStatusList[nIndex / 32] & uFlag);
  261. }
  262. //--------------------------------------------------------------------------
  263. // 功能:响应鼠标右键在此按下
  264. //--------------------------------------------------------------------------
  265. void KWndList::OnRButtonDown(int x, int y)
  266. {
  267. int nSel = GetIemIndexAtPoint(x, y);
  268. if (nSel >= 0 && m_pParentWnd)
  269. {
  270. m_pParentWnd->WndProc(WND_N_LIST_ITEM_R_CLICK,
  271. (unsigned int)(KWndWindow*)this, nSel);
  272. }
  273. }
  274. //响应鼠标左键double click
  275. void KWndList::OnLButtonDClick(int x, int y)
  276. {
  277. int nSel = GetIemIndexAtPoint(x, y);
  278. if (nSel >= 0 && m_pParentWnd)
  279. {
  280. m_pParentWnd->WndProc(WND_N_LIST_ITEM_D_CLICK,
  281. (unsigned int)(KWndWindow*)this, nSel);
  282. }
  283. }
  284. int KWndList::SetCurSel(int nSel)
  285. {
  286. if (nSel < 0 || nSel >= m_nNumItem)
  287. {
  288. nSel = -1;
  289. if (IS_MULTI_SEL)
  290. return nSel;
  291. }
  292. if (IS_MULTI_SEL)
  293. {
  294. unsigned int uFlag = (1 << (nSel % 32));
  295. if (nSel < 32)
  296. m_uIsItemSelStatus |= uFlag;
  297. else
  298. m_puItemSelStatusList[nSel / 32] |= uFlag;
  299. }
  300. else if (nSel != m_nSelItemIndex)
  301. {
  302. m_nSelItemIndex = nSel;
  303. UpdateData();
  304. if (m_pParentWnd)
  305. m_pParentWnd->WndProc(WND_N_LIST_ITEM_SEL, (unsigned int)(KWndWindow*)this, m_nSelItemIndex);
  306. }
  307. return nSel;
  308. }
  309. void KWndList::UpdateData()
  310. {
  311. int nVisibleItem = GetVisibleItemCount();
  312. if (m_nTopItemIndex > m_nSelItemIndex)
  313. m_nTopItemIndex = m_nSelItemIndex / m_nNumColumn * m_nNumColumn;
  314. else if(m_nTopItemIndex + nVisibleItem <= m_nSelItemIndex)
  315. m_nTopItemIndex = m_nNumColumn * ( m_nSelItemIndex / m_nNumColumn  + 1) - nVisibleItem;
  316. if (m_nTopItemIndex < 0)
  317. m_nTopItemIndex = 0;
  318. }
  319. //--------------------------------------------------------------------------
  320. // 功能:响应鼠标移动
  321. //--------------------------------------------------------------------------
  322. void KWndList::OnMouseMove(int x, int y)
  323. {
  324. int nIndex = GetIemIndexAtPoint(x, y);
  325. if (nIndex != m_nHighLightItemIndex)
  326. {
  327. m_nHighLightItemIndex = nIndex;
  328. if (m_pParentWnd)
  329. {
  330. m_pParentWnd->WndProc(WND_N_LIST_ITEM_HIGHLIGHT, (unsigned int)(KWndWindow*)this, m_nHighLightItemIndex);
  331. }
  332. }
  333. }
  334. //--------------------------------------------------------------------------
  335. // 功能:绘制窗口
  336. //--------------------------------------------------------------------------
  337. void KWndList::PaintWindow()
  338. {
  339. KWndWindow::PaintWindow();
  340. if (g_pRepresentShell)
  341. {
  342. int nVisibleItem = GetVisibleItemCount();
  343. int EndIndex = m_nTopItemIndex + nVisibleItem;
  344. if (EndIndex > m_nNumItem)
  345. EndIndex = m_nNumItem;
  346. char szBuffer[128];
  347. unsigned int uColor;
  348. unsigned int uBorderColor;
  349. BYTE* pItem = m_pContent + m_nTopItemIndex * m_nItemSize;
  350. int i, nColumn, x, y, nColumnWidth;
  351. x = m_nAbsoluteLeft;
  352. y = m_nAbsoluteTop;
  353. nColumnWidth = m_Width / m_nNumColumn;
  354. int nMaxLen = (nColumnWidth * 2) / m_nFontSize + 1;
  355. if (nMaxLen > sizeof(szBuffer))
  356. nMaxLen = sizeof(szBuffer);
  357. for (i = m_nTopItemIndex, nColumn = 0; i < EndIndex; i++, nColumn++)
  358. {
  359. if (nColumn == m_nNumColumn)
  360. {
  361. nColumn = 0;
  362. x = m_nAbsoluteLeft;
  363. y += m_nFontSize + 1;
  364. }
  365. if (IsItemSel(i))
  366. {
  367. uColor = m_SelItemColor;
  368. uBorderColor = m_SelItemBorderColor;
  369. if (m_uSelItemBgColor != NO_BG_COLOR)
  370. {
  371. KRUShadow Shadow;
  372. Shadow.Color.Color_dw = m_uSelItemBgColor;
  373. Shadow.oPosition.nX = x;
  374. Shadow.oPosition.nY = y;
  375. Shadow.oPosition.nZ = 0;
  376. Shadow.oEndPos.nX = x + nColumnWidth;
  377. Shadow.oEndPos.nY = y + m_nFontSize + 1;
  378. g_pRepresentShell->DrawPrimitives(1, &Shadow, RU_T_SHADOW, true);
  379. }
  380. }
  381. else if ((m_nColorOffset != NO_CUSTOM_COLOR) &&
  382. (*(int*)(&pItem[m_nColorOffset])))
  383. {
  384. uColor = *(int*)(&pItem[m_nColorOffset]);
  385. uBorderColor = m_ItemBorderColor;
  386. }
  387. else if (i == m_nHighLightItemIndex)
  388. {
  389. uColor = m_HighLightColor;
  390. uBorderColor = m_HighLightBorderColor;
  391. }
  392. else
  393. {
  394. uColor = m_ItemColor;
  395. uBorderColor = m_ItemBorderColor;
  396. }
  397. const char* pShowString = TGetLimitLenString((const char*)(&pItem[m_nStringOffset]), -1, szBuffer, nMaxLen);
  398. int nLen = strlen(pShowString);
  399. int nPaintX;
  400. if (m_Style & WNDLIST_ES_HALIGN_CENTRE)
  401. nPaintX = x + (nColumnWidth - nLen * m_nFontSize / 2) / 2;
  402. else if (m_Style & WNDLIST_ES_HALIGN_RIGHT)
  403. nPaintX = x + nColumnWidth - nLen * m_nFontSize / 2;
  404. else
  405. nPaintX = x;
  406. g_pRepresentShell->OutputText(m_nFontSize, pShowString, nLen, nPaintX, y,
  407. uColor, 0, TEXT_IN_SINGLE_PLANE_COORD, uBorderColor);
  408. pItem += m_nItemSize;
  409. x += nColumnWidth;
  410. }
  411. }
  412. }
  413. //--------------------------------------------------------------------------
  414. // 功能:设置列表内容
  415. //--------------------------------------------------------------------------
  416. void KWndList::SetContent(BYTE* pContent, int nNumItem, int nItemSize, int nStringOffset)
  417. {
  418. bool bRestoreMultiSel = false;
  419. if (IS_MULTI_SEL)
  420. {
  421. bRestoreMultiSel = true;
  422. EnableMultiSel(false);
  423. }
  424. m_pContent = pContent;
  425. m_nSelItemIndex       = -1;
  426. m_nHighLightItemIndex = -1;
  427. m_nTopItemIndex = 0;
  428. if (m_pContent)
  429. {
  430. m_nNumItem = nNumItem;
  431. m_nItemSize = nItemSize;
  432. m_nStringOffset = nStringOffset;
  433. }
  434. else
  435. {
  436. m_nNumItem = 0;
  437. m_nItemSize = 0;
  438. m_nStringOffset = 0;
  439. }
  440. if (m_pParentWnd)
  441. {
  442. if (m_Style & WNDLIST_ES_HIGHLIGHT_ENABLE)
  443. m_pParentWnd->WndProc(WND_N_LIST_ITEM_HIGHLIGHT, (unsigned int)(KWndWindow*)this, m_nHighLightItemIndex);
  444. m_pParentWnd->WndProc(WND_N_LIST_ITEM_SEL, (unsigned int)(KWndWindow*)this, m_nSelItemIndex);
  445. }
  446. if (bRestoreMultiSel)
  447. EnableMultiSel(true);
  448. if (m_pScrollbar)
  449. {
  450. if (m_nNumItem > GetVisibleItemCount())
  451. {
  452. m_pScrollbar->Enable(true);
  453. m_pScrollbar->SetValueRange(0, m_nNumItem - GetVisibleItemCount());
  454. }
  455. else
  456. m_pScrollbar->Enable(false);
  457. }
  458. }
  459. //--------------------------------------------------------------------------
  460. // 功能:查找列表(显示)字串
  461. //--------------------------------------------------------------------------
  462. int KWndList::FindString(int nPrecedingStart, const char* pString)
  463. {
  464. if (pString)
  465. {
  466. BYTE* pItem = m_pContent;
  467. for (int i = nPrecedingStart + 1; i < m_nNumItem; i++, pItem += m_nItemSize)
  468. {
  469. if (strcmp((const char*)&pItem[m_nStringOffset], pString) == 0)
  470. return i;
  471. }
  472. }
  473. return -1;
  474. }
  475. //--------------------------------------------------------------------------
  476. // 功能:获得列表项数据中的一个整数
  477. //--------------------------------------------------------------------------
  478. int KWndList::GetItemDataInt(int nItemIndex, int nDataOffset)
  479. {
  480. if (nItemIndex >= 0 && nItemIndex < m_nNumItem &&
  481. nDataOffset >= 0 && ((int)(nDataOffset + sizeof(int)) <= m_nItemSize))
  482. {
  483. return (*(int*)&m_pContent[m_nItemSize * nItemIndex + nDataOffset]);
  484. }
  485. return 0;
  486. }
  487. //--------------------------------------------------------------------------
  488. // 功能:获得列表项的(显示)字串
  489. //--------------------------------------------------------------------------
  490. void KWndList::GetString(int nItemIndex, char* pBuffer)
  491. {
  492. if (pBuffer)
  493. {
  494. if (nItemIndex >= 0 && nItemIndex < m_nNumItem)
  495. {
  496. strcpy(pBuffer, (char*)&m_pContent[m_nItemSize * nItemIndex + m_nStringOffset]);
  497. }
  498. else
  499. pBuffer[0] = 0;
  500. }
  501. }
  502. //--------------------------------------------------------------------------
  503. // 功能:获得列表项的(显示)字串的长度
  504. //--------------------------------------------------------------------------
  505. int KWndList::GetStrignLen(int nItemIndex)
  506. {
  507. if (nItemIndex >= 0 && nItemIndex < m_nNumItem)
  508. {
  509. return strlen((char*)&m_pContent[m_nItemSize * nItemIndex + m_nStringOffset]);
  510. }
  511. return 0;
  512. }
  513. //--------------------------------------------------------------------------
  514. // 功能:设置被显示的最顶列表项的索引值
  515. //--------------------------------------------------------------------------
  516. void KWndList::SetTopItemIndex(int nTopItemIndex)
  517. {
  518. if (nTopItemIndex >= 0 && nTopItemIndex < m_nNumItem)
  519. m_nTopItemIndex = nTopItemIndex;
  520. }
  521. //--------------------------------------------------------------------------
  522. // 功能:获得列表框可以同时显示的项的数目
  523. //--------------------------------------------------------------------------
  524. int KWndList::GetVisibleItemCount() const
  525. {
  526. return (m_Height / (m_nFontSize + 1)) * m_nNumColumn;
  527. }