BuddyListBox.cpp 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085
  1. #include "StdAfx.h"
  2. #include "BuddyListBox.h"
  3. BEGIN_MESSAGE_MAP(CBuddyListBox, CWnd)
  4. ON_WM_CREATE()
  5. ON_WM_ERASEBKGND()
  6. ON_WM_PAINT()
  7. ON_WM_LBUTTONDBLCLK()
  8. ON_WM_LBUTTONDOWN()
  9. ON_WM_LBUTTONUP()
  10. ON_WM_MOUSEMOVE()
  11. ON_WM_MOUSELEAVE()
  12. ON_WM_TIMER()
  13. ON_WM_MOUSEWHEEL()
  14. ON_WM_KEYDOWN()
  15. ON_WM_SIZE()
  16. //ON_WM_GETDLGCODE()
  17. ON_WM_DESTROY()
  18. ON_WM_VSCROLL()
  19. ON_WM_GETDLGCODE()
  20. END_MESSAGE_MAP()
  21. CBuddyItem::CBuddyItem(void)
  22. {
  23. m_nID = 0;
  24. m_bOnline = FALSE;
  25. m_bOnlineAnim = FALSE;
  26. m_nOnlineAnimState = 0;
  27. m_bOfflineAnim = FALSE;
  28. m_bHeadFlashAnim = FALSE;
  29. m_nHeadFlashAnimState = 0;
  30. m_lpHeadImg = NULL;
  31. m_bGender = FALSE;
  32. }
  33. CBuddyItem::~CBuddyItem(void)
  34. {
  35. if (m_lpHeadImg != NULL)
  36. {
  37. delete m_lpHeadImg;
  38. m_lpHeadImg = NULL;
  39. }
  40. }
  41. //////////////////////////////////////////////////////////////////////////
  42. CBuddyRootItem::CBuddyRootItem(void)
  43. {
  44. m_nID = 0;
  45. m_nCurCnt = -1;
  46. m_nMaxCnt = 0;
  47. m_bExpand = FALSE;
  48. m_nHeadFlashAnim = 0;
  49. m_nHeadFlashAnimState = 0;
  50. }
  51. CBuddyRootItem::~CBuddyRootItem(void)
  52. {
  53. for (int i = 0; i < (int)m_arrBuddys.size(); i++)
  54. {
  55. CBuddyItem * lpItem = m_arrBuddys[i];
  56. if (lpItem != NULL)
  57. delete lpItem;
  58. }
  59. m_arrBuddys.clear();
  60. }
  61. //////////////////////////////////////////////////////////////////////////
  62. CBuddyListBox::CBuddyListBox(void)
  63. {
  64. m_colBack = RGB(255,255,255);
  65. m_nCurrentPos = 0;
  66. m_lpBgImg = NULL;
  67. m_lpBuddyTeamBgImgH = NULL;
  68. m_lpArrowImgN = NULL;
  69. m_lpArrowImgH = NULL;
  70. m_lpArrowImgS = NULL;
  71. m_lpExpArrowImgN = NULL;
  72. m_lpExpArrowImgH = NULL;
  73. m_lpExpArrowImgS = NULL;
  74. m_lpBuddyItemBgImgH = NULL;
  75. m_lpBuddyItemBgImgS = NULL;
  76. m_lpHeadFrameImg = NULL;
  77. m_lpStdGGHeadImg = NULL;
  78. m_lpStdMMHeadImg = NULL;
  79. m_nSelTeamIndex = m_nSelIndex = -1;
  80. m_nHoverTeamIndex = m_nHoverIndex = -1;
  81. m_nHoverSmallIconIndex = -1;
  82. m_nPressTeamIndex = m_nPressIndex = -1;
  83. m_nLeft = m_nTop = 0;
  84. m_bMouseTracking = FALSE;
  85. m_nStyle = BLC_BIG_ICON_STYLE;
  86. m_bShowBigIconInSel = TRUE;
  87. m_nBuddyTeamHeight = 0;
  88. m_nBuddyItemHeightInBig = 0;
  89. m_nBuddyItemHeightInSmall = 0;
  90. m_nBuddyItemHeightInStd = 0;
  91. m_nBuddyTeamPadding = 0;
  92. m_nBuddyItemPadding = 0;
  93. m_rcMargin = CRect(0,0,0,0);
  94. m_dwOnlineAnimTimerId = NULL;
  95. m_dwOfflineAnimTimerId = NULL;
  96. m_dwHeadFlashAnimTimerId = NULL;
  97. }
  98. CBuddyListBox::~CBuddyListBox(void)
  99. {
  100. }
  101. BOOL CBuddyListBox::SetBgPic(LPCTSTR lpszFileName)
  102. {
  103. RenderEngine->RemoveImage(m_lpBgImg);
  104. m_lpBgImg = RenderEngine->GetImage(lpszFileName);
  105. return (m_lpBgImg != NULL) ? TRUE : FALSE;
  106. }
  107. BOOL CBuddyListBox::SetBuddyTeamHotBgPic(LPCTSTR lpszFileName)
  108. {
  109. RenderEngine->RemoveImage(m_lpBuddyTeamBgImgH);
  110. m_lpBuddyTeamBgImgH = RenderEngine->GetImage(lpszFileName);
  111. return (m_lpBuddyTeamBgImgH != NULL) ? TRUE : FALSE;
  112. }
  113. BOOL CBuddyListBox::SetBuddyItemHotBgPic(LPCTSTR lpszFileName, RECT * lpNinePart/* = NULL*/)
  114. {
  115. RenderEngine->RemoveImage(m_lpBuddyItemBgImgH);
  116. m_lpBuddyItemBgImgH = RenderEngine->GetImage(lpszFileName);
  117. if (m_lpBuddyItemBgImgH != NULL)
  118. m_lpBuddyItemBgImgH->SetNinePart(lpNinePart);
  119. return (m_lpBuddyItemBgImgH != NULL) ? TRUE : FALSE;
  120. }
  121. BOOL CBuddyListBox::SetBuddyItemSelBgPic(LPCTSTR lpszFileName, RECT * lpNinePart/* = NULL*/)
  122. {
  123. RenderEngine->RemoveImage(m_lpBuddyItemBgImgS);
  124. m_lpBuddyItemBgImgS = RenderEngine->GetImage(lpszFileName);
  125. if (m_lpBuddyItemBgImgS != NULL)
  126. m_lpBuddyItemBgImgS->SetNinePart(lpNinePart);
  127. return (m_lpBuddyItemBgImgS != NULL) ? TRUE : FALSE;
  128. }
  129. BOOL CBuddyListBox::SetHeadFramePic(LPCTSTR lpszFileName, RECT * lpNinePart/* = NULL*/)
  130. {
  131. RenderEngine->RemoveImage(m_lpHeadFrameImg);
  132. m_lpHeadFrameImg = RenderEngine->GetImage(lpszFileName);
  133. if (m_lpHeadFrameImg != NULL)
  134. m_lpHeadFrameImg->SetNinePart(lpNinePart);
  135. return (m_lpHeadFrameImg != NULL) ? TRUE : FALSE;
  136. }
  137. BOOL CBuddyListBox::SetNormalArrowPic(LPCTSTR lpszFileName)
  138. {
  139. RenderEngine->RemoveImage(m_lpArrowImgN);
  140. m_lpArrowImgN = RenderEngine->GetImage(lpszFileName);
  141. return (m_lpArrowImgN != NULL) ? TRUE : FALSE;
  142. }
  143. BOOL CBuddyListBox::SetHotArrowPic(LPCTSTR lpszFileName)
  144. {
  145. RenderEngine->RemoveImage(m_lpArrowImgH);
  146. m_lpArrowImgH = RenderEngine->GetImage(lpszFileName);
  147. return (m_lpArrowImgH != NULL) ? TRUE : FALSE;
  148. }
  149. BOOL CBuddyListBox::SetSelArrowPic(LPCTSTR lpszFileName)
  150. {
  151. RenderEngine->RemoveImage(m_lpArrowImgS);
  152. m_lpArrowImgS = RenderEngine->GetImage(lpszFileName);
  153. return (m_lpArrowImgS != NULL) ? TRUE : FALSE;
  154. }
  155. BOOL CBuddyListBox::SetNormalExpArrowPic(LPCTSTR lpszFileName)
  156. {
  157. RenderEngine->RemoveImage(m_lpExpArrowImgN);
  158. m_lpExpArrowImgN = RenderEngine->GetImage(lpszFileName);
  159. return (m_lpExpArrowImgN != NULL) ? TRUE : FALSE;
  160. }
  161. BOOL CBuddyListBox::SetHotExpArrowPic(LPCTSTR lpszFileName)
  162. {
  163. RenderEngine->RemoveImage(m_lpExpArrowImgH);
  164. m_lpExpArrowImgH = RenderEngine->GetImage(lpszFileName);
  165. return (m_lpExpArrowImgH != NULL) ? TRUE : FALSE;
  166. }
  167. BOOL CBuddyListBox::SetSelExpArrowPic(LPCTSTR lpszFileName)
  168. {
  169. RenderEngine->RemoveImage(m_lpExpArrowImgS);
  170. m_lpExpArrowImgS = RenderEngine->GetImage(lpszFileName);
  171. return (m_lpExpArrowImgS != NULL) ? TRUE : FALSE;
  172. }
  173. BOOL CBuddyListBox::SetStdGGHeadPic(LPCTSTR lpszFileName)
  174. {
  175. RenderEngine->RemoveImage(m_lpStdGGHeadImg);
  176. m_lpStdGGHeadImg = RenderEngine->GetImage(lpszFileName);
  177. return (m_lpStdGGHeadImg != NULL) ? TRUE : FALSE;
  178. }
  179. BOOL CBuddyListBox::SetStdMMHeadPic(LPCTSTR lpszFileName)
  180. {
  181. RenderEngine->RemoveImage(m_lpStdMMHeadImg);
  182. m_lpStdMMHeadImg = RenderEngine->GetImage(lpszFileName);
  183. return (m_lpStdMMHeadImg != NULL) ? TRUE : FALSE;
  184. }
  185. void CBuddyListBox::SetStyle(BLCTRL_STYLE nStyle)
  186. {
  187. m_nStyle = nStyle;
  188. }
  189. void CBuddyListBox::SetShowBigIconInSel(BOOL bShowBigIconInSel)
  190. {
  191. m_bShowBigIconInSel = bShowBigIconInSel;
  192. }
  193. void CBuddyListBox::SetBuddyTeamHeight(int nHeight)
  194. {
  195. m_nBuddyTeamHeight = nHeight;
  196. }
  197. void CBuddyListBox::SetBuddyItemHeightInBigIcon(int nHeight)
  198. {
  199. m_nBuddyItemHeightInBig = nHeight;
  200. }
  201. void CBuddyListBox::SetBuddyItemHeightInSmallIcon(int nHeight)
  202. {
  203. m_nBuddyItemHeightInSmall = nHeight;
  204. }
  205. void CBuddyListBox::SetBuddyItemHeightInStandardIcon(int nHeight)
  206. {
  207. m_nBuddyItemHeightInStd = nHeight;
  208. }
  209. void CBuddyListBox::SetBuddyTeamPadding(int nPadding)
  210. {
  211. m_nBuddyTeamPadding = nPadding;
  212. }
  213. void CBuddyListBox::SetBuddyItemPadding(int nPadding)
  214. {
  215. m_nBuddyItemPadding = nPadding;
  216. }
  217. void CBuddyListBox::SetMargin(const RECT * lpMargin)
  218. {
  219. if (lpMargin != NULL)
  220. m_rcMargin = *lpMargin;
  221. }
  222. int CBuddyListBox::AddBuddyTeam(int nID)
  223. {
  224. CBuddyRootItem * lpItem = new CBuddyRootItem;
  225. if (NULL == lpItem)
  226. return -1;
  227. lpItem->m_nID = nID;
  228. m_arrBuddyTeamItems.push_back(lpItem);
  229. return m_arrBuddyTeamItems.size() - 1;
  230. }
  231. int CBuddyListBox::InsertBuddyTeam(int nTeamIndex, int nID)
  232. {
  233. return -1;
  234. }
  235. BOOL CBuddyListBox::DelBuddyTeam(int nTeamIndex)
  236. {
  237. if (nTeamIndex >= 0 && nTeamIndex < (int)m_arrBuddyTeamItems.size())
  238. {
  239. CBuddyRootItem * lpBuddyTeamItem = m_arrBuddyTeamItems[nTeamIndex];
  240. if (lpBuddyTeamItem != NULL)
  241. delete lpBuddyTeamItem;
  242. m_arrBuddyTeamItems.erase(m_arrBuddyTeamItems.begin()+nTeamIndex);
  243. return TRUE;
  244. }
  245. return FALSE;
  246. }
  247. int CBuddyListBox::AddBuddyItem(int nTeamIndex, int nID)
  248. {
  249. CBuddyRootItem * lpTeamItem = GetBuddyTeamByIndex(nTeamIndex);
  250. if (NULL == lpTeamItem)
  251. return -1;
  252. CBuddyItem * lpItem = new CBuddyItem;
  253. if (NULL == lpItem)
  254. return -1;
  255. lpItem->m_nID = nID;
  256. lpTeamItem->m_arrBuddys.push_back(lpItem);
  257. return lpTeamItem->m_arrBuddys.size() - 1;
  258. }
  259. int CBuddyListBox::InsertBuddyItem(int nTeamIndex, int nIndex, int nID)
  260. {
  261. return -1;
  262. }
  263. BOOL CBuddyListBox::DelBuddyItem(int nTeamIndex, int nIndex)
  264. {
  265. if (nTeamIndex >= 0 && nTeamIndex < (int)m_arrBuddyTeamItems.size())
  266. {
  267. CBuddyRootItem * lpTeamItem = m_arrBuddyTeamItems[nTeamIndex];
  268. if (lpTeamItem != NULL)
  269. {
  270. if (nIndex >= 0 && nIndex < (int)lpTeamItem->m_arrBuddys.size())
  271. {
  272. CBuddyItem * lpBuddyItem = lpTeamItem->m_arrBuddys[nIndex];
  273. if (lpBuddyItem != NULL)
  274. delete lpBuddyItem;
  275. lpTeamItem->m_arrBuddys.erase(lpTeamItem->m_arrBuddys.begin()+nIndex);
  276. return TRUE;
  277. }
  278. }
  279. }
  280. return FALSE;
  281. }
  282. void CBuddyListBox::DelAllItems()
  283. {
  284. for (int i = 0; i < (int)m_arrBuddyTeamItems.size(); i++)
  285. {
  286. CBuddyRootItem * lpTeamItem = m_arrBuddyTeamItems[i];
  287. if (lpTeamItem != NULL)
  288. delete lpTeamItem;
  289. }
  290. m_arrBuddyTeamItems.clear();
  291. }
  292. void CBuddyListBox::SetBuddyTeamID(int nTeamIndex, int nID)
  293. {
  294. CBuddyRootItem * lpItem = GetBuddyTeamByIndex(nTeamIndex);
  295. if (lpItem != NULL)
  296. lpItem->m_nID = nID;
  297. }
  298. void CBuddyListBox::SetBuddyTeamName(int nTeamIndex, LPCTSTR lpszText)
  299. {
  300. CBuddyRootItem * lpItem = GetBuddyTeamByIndex(nTeamIndex);
  301. if (lpItem != NULL)
  302. lpItem->m_strName = lpszText;
  303. }
  304. void CBuddyListBox::SetBuddyTeamMaxCnt(int nTeamIndex, int nMaxCnt)
  305. {
  306. CBuddyRootItem * lpItem = GetBuddyTeamByIndex(nTeamIndex);
  307. if (lpItem != NULL)
  308. lpItem->m_nMaxCnt = nMaxCnt;
  309. }
  310. void CBuddyListBox::SetBuddyTeamCurCnt(int nTeamIndex, int nCurCnt)
  311. {
  312. CBuddyRootItem * lpItem = GetBuddyTeamByIndex(nTeamIndex);
  313. if (lpItem != NULL)
  314. lpItem->m_nCurCnt = nCurCnt;
  315. }
  316. void CBuddyListBox::SetBuddyTeamExpand(int nTeamIndex, BOOL bExpand)
  317. {
  318. CBuddyRootItem * lpItem = GetBuddyTeamByIndex(nTeamIndex);
  319. if (lpItem != NULL)
  320. lpItem->m_bExpand = bExpand;
  321. }
  322. int CBuddyListBox::GetBuddyTeamID(int nTeamIndex)
  323. {
  324. CBuddyRootItem * lpItem = GetBuddyTeamByIndex(nTeamIndex);
  325. if (lpItem != NULL)
  326. return lpItem->m_nID;
  327. else
  328. return 0;
  329. }
  330. CString CBuddyListBox::GetBuddyTeamName(int nTeamIndex)
  331. {
  332. CBuddyRootItem * lpItem = GetBuddyTeamByIndex(nTeamIndex);
  333. if (lpItem != NULL)
  334. return lpItem->m_strName;
  335. else
  336. return _T("");
  337. }
  338. int CBuddyListBox::GetBuddyTeamMaxCnt(int nTeamIndex)
  339. {
  340. CBuddyRootItem * lpItem = GetBuddyTeamByIndex(nTeamIndex);
  341. if (lpItem != NULL)
  342. return lpItem->m_nMaxCnt;
  343. else
  344. return 0;
  345. }
  346. int CBuddyListBox::GetBuddyTeamCurCnt(int nTeamIndex)
  347. {
  348. CBuddyRootItem * lpItem = GetBuddyTeamByIndex(nTeamIndex);
  349. if (lpItem != NULL)
  350. return lpItem->m_nCurCnt;
  351. else
  352. return 0;
  353. }
  354. BOOL CBuddyListBox::IsBuddyTeamExpand(int nTeamIndex)
  355. {
  356. CBuddyRootItem * lpItem = GetBuddyTeamByIndex(nTeamIndex);
  357. if (lpItem != NULL)
  358. return lpItem->m_bExpand;
  359. else
  360. return FALSE;
  361. }
  362. void CBuddyListBox::SetBuddyItemID(int nTeamIndex, int nIndex, int nID)
  363. {
  364. CBuddyItem * lpItem = GetBuddyItemByIndex(nTeamIndex, nIndex);
  365. if (lpItem != NULL)
  366. lpItem->m_nID = nID;
  367. }
  368. void CBuddyListBox::SetBuddyItemQQNum(int nTeamIndex, int nIndex, LPCTSTR lpszText)
  369. {
  370. CBuddyItem * lpItem = GetBuddyItemByIndex(nTeamIndex, nIndex);
  371. if (lpItem != NULL)
  372. lpItem->m_strQQNum = lpszText;
  373. }
  374. void CBuddyListBox::SetBuddyItemNickName(int nTeamIndex, int nIndex, LPCTSTR lpszText)
  375. {
  376. CBuddyItem * lpItem = GetBuddyItemByIndex(nTeamIndex, nIndex);
  377. if (lpItem != NULL)
  378. lpItem->m_strNickName = lpszText;
  379. }
  380. void CBuddyListBox::SetBuddyItemMarkName(int nTeamIndex, int nIndex, LPCTSTR lpszText)
  381. {
  382. CBuddyItem * lpItem = GetBuddyItemByIndex(nTeamIndex, nIndex);
  383. if (lpItem != NULL)
  384. lpItem->m_strMarkName = lpszText;
  385. }
  386. void CBuddyListBox::SetBuddyItemSign(int nTeamIndex, int nIndex, LPCTSTR lpszText)
  387. {
  388. CBuddyItem * lpItem = GetBuddyItemByIndex(nTeamIndex, nIndex);
  389. if (lpItem != NULL)
  390. lpItem->m_strSign = lpszText;
  391. }
  392. void CBuddyListBox::SetBuddyItemGender(int nTeamIndex, int nIndex, BOOL bGender)
  393. {
  394. CBuddyItem * lpItem = GetBuddyItemByIndex(nTeamIndex, nIndex);
  395. if (lpItem != NULL)
  396. lpItem->m_bGender = bGender;
  397. }
  398. BOOL CBuddyListBox::SetBuddyItemHeadPic(int nTeamIndex, int nIndex, LPCTSTR lpszFileName, BOOL bGray)
  399. {
  400. CBuddyItem * lpItem = GetBuddyItemByIndex(nTeamIndex, nIndex);
  401. if (NULL == lpItem)
  402. return FALSE;
  403. if (lpItem->m_lpHeadImg != NULL)
  404. delete lpItem->m_lpHeadImg;
  405. lpItem->m_lpHeadImg = new CImageEx;
  406. if (NULL == lpItem->m_lpHeadImg)
  407. return FALSE;
  408. BOOL bRet = lpItem->m_lpHeadImg->LoadImage(lpszFileName);
  409. if (!bRet)
  410. {
  411. delete lpItem->m_lpHeadImg;
  412. lpItem->m_lpHeadImg = NULL;
  413. return FALSE;
  414. }
  415. if (bGray)
  416. lpItem->m_lpHeadImg->SetGray();
  417. if (IsWindowVisible())
  418. Invalidate(FALSE);
  419. return TRUE;
  420. }
  421. void CBuddyListBox::SetBuddyItemHeadFlashAnim(int nTeamIndex, int nIndex, BOOL bHeadFlashAnim)
  422. {
  423. CBuddyItem * lpBuddyItem = GetBuddyItemByIndex(nTeamIndex, nIndex);
  424. if (NULL == lpBuddyItem || bHeadFlashAnim == lpBuddyItem->m_bHeadFlashAnim)
  425. return;
  426. lpBuddyItem->m_bHeadFlashAnim = bHeadFlashAnim;
  427. lpBuddyItem->m_nHeadFlashAnimState = 0;
  428. if (bHeadFlashAnim)
  429. {
  430. CBuddyRootItem * lpBuddyTeam = GetBuddyTeamByIndex(nTeamIndex);
  431. if (lpBuddyTeam != NULL)
  432. {
  433. lpBuddyTeam->m_nHeadFlashAnim++;
  434. }
  435. if (NULL == m_dwHeadFlashAnimTimerId) // 启动头像闪动动画计时器
  436. m_dwHeadFlashAnimTimerId = SetTimer(2, 250, NULL);
  437. }
  438. else
  439. {
  440. CBuddyRootItem * lpBuddyTeam = GetBuddyTeamByIndex(nTeamIndex);
  441. if (lpBuddyTeam != NULL)
  442. {
  443. lpBuddyTeam->m_nHeadFlashAnim--;
  444. if (lpBuddyTeam->m_nHeadFlashAnim <= 0)
  445. lpBuddyTeam->m_nHeadFlashAnimState = 0;
  446. }
  447. BOOL bHasAnim = FALSE;
  448. int nTeamCnt = GetBuddyTeamCount();
  449. for (int i = 0; i < nTeamCnt; i++)
  450. {
  451. lpBuddyTeam = GetBuddyTeamByIndex(i);
  452. if (lpBuddyTeam != NULL && lpBuddyTeam->m_nHeadFlashAnim > 0)
  453. {
  454. bHasAnim = TRUE;
  455. break;
  456. }
  457. }
  458. if (!bHasAnim)
  459. {
  460. KillTimer(m_dwHeadFlashAnimTimerId);
  461. m_dwHeadFlashAnimTimerId = NULL;
  462. if (IsWindowVisible())
  463. Invalidate(FALSE);
  464. }
  465. }
  466. }
  467. void CBuddyListBox::SetBuddyItemOnline(int nTeamIndex, int nIndex, BOOL bOnline, BOOL bAnim)
  468. {
  469. CBuddyItem * lpBuddyItem = GetBuddyItemByIndex(nTeamIndex, nIndex);
  470. if (NULL == lpBuddyItem || bOnline == lpBuddyItem->m_bOnline)
  471. return;
  472. lpBuddyItem->m_bOnline = bOnline;
  473. if (bAnim) // 显示动画
  474. {
  475. if (bOnline) // 上线动画
  476. {
  477. lpBuddyItem->m_bOfflineAnim = FALSE;
  478. lpBuddyItem->m_bOnlineAnim = TRUE;
  479. lpBuddyItem->m_nOnlineAnimState = 0;
  480. if (NULL == m_dwOnlineAnimTimerId) // 启动上线动画计时器
  481. m_dwOnlineAnimTimerId = SetTimer(3, 250, NULL);
  482. }
  483. else // 下线动画
  484. {
  485. lpBuddyItem->m_bOnlineAnim = FALSE;
  486. lpBuddyItem->m_nOnlineAnimState = 0;
  487. lpBuddyItem->m_bOfflineAnim = TRUE;
  488. if (NULL == m_dwOfflineAnimTimerId) // 启动下线动画计时器
  489. m_dwOfflineAnimTimerId = SetTimer(4, 1000, NULL);
  490. }
  491. }
  492. }
  493. int CBuddyListBox::GetBuddyItemID(int nTeamIndex, int nIndex)
  494. {
  495. CBuddyItem * lpItem = GetBuddyItemByIndex(nTeamIndex, nIndex);
  496. if (lpItem != NULL)
  497. return lpItem->m_nID;
  498. else
  499. return 0;
  500. }
  501. CString CBuddyListBox::GetBuddyItemQQNum(int nTeamIndex, int nIndex)
  502. {
  503. CBuddyItem * lpItem = GetBuddyItemByIndex(nTeamIndex, nIndex);
  504. if (lpItem != NULL)
  505. return lpItem->m_strQQNum;
  506. else
  507. return _T("");
  508. }
  509. CString CBuddyListBox::GetBuddyItemNickName(int nTeamIndex, int nIndex)
  510. {
  511. CBuddyItem * lpItem = GetBuddyItemByIndex(nTeamIndex, nIndex);
  512. if (lpItem != NULL)
  513. return lpItem->m_strNickName;
  514. else
  515. return _T("");
  516. }
  517. CString CBuddyListBox::GetBuddyItemMarkName(int nTeamIndex, int nIndex)
  518. {
  519. CBuddyItem * lpItem = GetBuddyItemByIndex(nTeamIndex, nIndex);
  520. if (lpItem != NULL)
  521. return lpItem->m_strMarkName;
  522. else
  523. return _T("");
  524. }
  525. CString CBuddyListBox::GetBuddyItemSign(int nTeamIndex, int nIndex)
  526. {
  527. CBuddyItem * lpItem = GetBuddyItemByIndex(nTeamIndex, nIndex);
  528. if (lpItem != NULL)
  529. return lpItem->m_strSign;
  530. else
  531. return _T("");
  532. }
  533. BOOL CBuddyListBox::GetBuddyItemGender(int nTeamIndex, int nIndex)
  534. {
  535. CBuddyItem * lpItem = GetBuddyItemByIndex(nTeamIndex, nIndex);
  536. if (lpItem != NULL)
  537. return lpItem->m_bGender;
  538. else
  539. return FALSE;
  540. }
  541. BOOL CBuddyListBox::IsBuddyItemHasMsg(int nTeamIndex, int nIndex)
  542. {
  543. CBuddyItem * lpItem = GetBuddyItemByIndex(nTeamIndex, nIndex);
  544. if (lpItem != NULL)
  545. return lpItem->m_bHeadFlashAnim;
  546. else
  547. return FALSE;
  548. }
  549. int CBuddyListBox::GetBuddyTeamCount()
  550. {
  551. return m_arrBuddyTeamItems.size();
  552. }
  553. int CBuddyListBox::GetBuddyItemCount(int nTeamIndex)
  554. {
  555. CBuddyRootItem * lpTeamItem = GetBuddyTeamByIndex(nTeamIndex);
  556. if (lpTeamItem != NULL)
  557. return lpTeamItem->m_arrBuddys.size();
  558. else
  559. return 0;
  560. }
  561. BOOL CBuddyListBox::GetItemIndexByID(int nID, int& nTeamIndex, int& nIndex)
  562. {
  563. nTeamIndex = -1;
  564. nIndex = -1;
  565. for (int i = 0; i < (int)m_arrBuddyTeamItems.size(); i++)
  566. {
  567. CBuddyRootItem * lpTeamItem = m_arrBuddyTeamItems[i];
  568. if (lpTeamItem != NULL)
  569. {
  570. if (nID == lpTeamItem->m_nID)
  571. {
  572. nTeamIndex = i;
  573. return TRUE;
  574. }
  575. for (int j = 0; j < (int)lpTeamItem->m_arrBuddys.size(); j++)
  576. {
  577. CBuddyItem * lpItem = lpTeamItem->m_arrBuddys[j];
  578. if (lpItem != NULL && nID == lpItem->m_nID)
  579. {
  580. if (nID == lpItem->m_nID)
  581. {
  582. nTeamIndex = i;
  583. nIndex = j;
  584. return TRUE;
  585. }
  586. }
  587. }
  588. }
  589. }
  590. return FALSE;
  591. }
  592. BOOL CBuddyListBox::GetItemRectByIndex(int nTeamIndex, int nIndex, CRect& rect)
  593. {
  594. CBuddyRootItem * lpTeamItem;
  595. CBuddyItem * lpItem;
  596. int nLeft = m_rcMargin.left+m_nLeft, nTop = m_nTop;
  597. int nBuddyTeamWidth, nBuddyItemWidth, nBuddyItemHeight;
  598. CRect rcClient;
  599. GetClientRect(&rcClient);
  600. int nVScrollBarWidth = 0;
  601. if (m_VScrollBar.IsVisible())
  602. {
  603. CRect rcVScrollBar;
  604. m_VScrollBar.GetRect(&rcVScrollBar);
  605. nVScrollBarWidth = rcVScrollBar.Width();
  606. }
  607. nBuddyTeamWidth = rcClient.Width() - m_rcMargin.left - m_rcMargin.right - nVScrollBarWidth;
  608. nBuddyItemWidth = nBuddyTeamWidth;
  609. if (BLC_BIG_ICON_STYLE == m_nStyle)
  610. nBuddyItemHeight = m_nBuddyItemHeightInBig;
  611. else if (BLC_SMALL_ICON_STYLE == m_nStyle)
  612. nBuddyItemHeight = m_nBuddyItemHeightInSmall;
  613. else
  614. nBuddyItemHeight = m_nBuddyItemHeightInStd;
  615. for (int i = 0; i < (int)m_arrBuddyTeamItems.size(); i++)
  616. {
  617. lpTeamItem = m_arrBuddyTeamItems[i];
  618. if (lpTeamItem != NULL)
  619. {
  620. if (-1 == nIndex && i == nTeamIndex)
  621. {
  622. rect = CRect(nLeft, nTop, nLeft+nBuddyTeamWidth, nTop+m_nBuddyTeamHeight);
  623. return TRUE;
  624. }
  625. nTop += m_nBuddyTeamHeight;
  626. nTop += m_nBuddyTeamPadding;
  627. if (lpTeamItem->m_bExpand)
  628. {
  629. for (int j = 0; j < (int)lpTeamItem->m_arrBuddys.size(); j++)
  630. {
  631. lpItem = lpTeamItem->m_arrBuddys[j];
  632. if (lpItem != NULL)
  633. {
  634. if (BLC_SMALL_ICON_STYLE == m_nStyle && m_bShowBigIconInSel
  635. && (m_nSelTeamIndex == i && m_nSelIndex == j))
  636. nBuddyItemHeight = m_nBuddyItemHeightInBig;
  637. if (i == nTeamIndex && j == nIndex)
  638. {
  639. rect = CRect(nLeft, nTop, nLeft+nBuddyItemWidth, nTop+nBuddyItemHeight);
  640. return TRUE;
  641. }
  642. nTop += nBuddyItemHeight;
  643. nTop += m_nBuddyItemPadding;
  644. if (BLC_SMALL_ICON_STYLE == m_nStyle && m_bShowBigIconInSel
  645. && (m_nSelTeamIndex == i && m_nSelIndex == j))
  646. nBuddyItemHeight = m_nBuddyItemHeightInSmall;
  647. }
  648. }
  649. }
  650. }
  651. }
  652. return FALSE;
  653. }
  654. void CBuddyListBox::GetCurSelIndex(int& nTeamIndex, int& nIndex)
  655. {
  656. nTeamIndex = m_nSelTeamIndex;
  657. nIndex = m_nSelIndex;
  658. }
  659. BLCTRL_STYLE CBuddyListBox::GetStyle()
  660. {
  661. return m_nStyle;
  662. }
  663. BOOL CBuddyListBox::IsShowBigIconInSel()
  664. {
  665. return m_bShowBigIconInSel;
  666. }
  667. int CBuddyListBox::OnCreate(LPCREATESTRUCT lpCreateStruct)
  668. {
  669. CWnd::OnCreate(lpCreateStruct);
  670. CRect rcClient;
  671. GetClientRect(&rcClient);
  672. CRect rc = CRect(rcClient.Width()-8, 0, rcClient.Width(), rcClient.Height());
  673. m_VScrollBar.Create(m_hWnd, 1, &rc, 1, FALSE, FALSE);
  674. m_VScrollBar.SetBgNormalPic(_T("QQ\\ScrollBar\\scrollbar_bkg.png"));
  675. m_VScrollBar.SetBgHotPic(_T("QQ\\ScrollBar\\scrollbar_bkg.png"));
  676. m_VScrollBar.SetBgPushedPic(_T("QQ\\ScrollBar\\scrollbar_bkg.png"));
  677. m_VScrollBar.SetBgDisabledPic(_T("QQ\\ScrollBar\\scrollbar_bkg.png"));
  678. m_VScrollBar.SetShowLeftUpBtn(TRUE);
  679. m_VScrollBar.SetLeftUpBtnNormalPic(_T("QQ\\ScrollBar\\scrollbar_arrowup_normal.png"));
  680. m_VScrollBar.SetLeftUpBtnHotPic(_T("QQ\\ScrollBar\\scrollbar_arrowup_highlight.png"));
  681. m_VScrollBar.SetLeftUpBtnPushedPic(_T("QQ\\ScrollBar\\scrollbar_arrowup_down.png"));
  682. m_VScrollBar.SetLeftUpBtnDisabledPic(_T("QQ\\ScrollBar\\scrollbar_arrowup_normal.png"));
  683. m_VScrollBar.SetShowRightDownBtn(TRUE);
  684. m_VScrollBar.SetRightDownBtnNormalPic(_T("QQ\\ScrollBar\\scrollbar_arrowdown_normal.png"));
  685. m_VScrollBar.SetRightDownBtnHotPic(_T("QQ\\ScrollBar\\scrollbar_arrowdown_highlight.png"));
  686. m_VScrollBar.SetRightDownBtnPushedPic(_T("QQ\\ScrollBar\\scrollbar_arrowdown_down.png"));
  687. m_VScrollBar.SetRightDownBtnDisabledPic(_T("QQ\\ScrollBar\\scrollbar_arrowdown_normal.png"));
  688. m_VScrollBar.SetThumbNormalPic(_T("QQ\\ScrollBar\\scrollbar_bar_normal.png"), CRect(4,4,4,4));
  689. m_VScrollBar.SetThumbHotPic(_T("QQ\\ScrollBar\\scrollbar_bar_highlight.png"), CRect(4,4,4,4));
  690. m_VScrollBar.SetThumbPushedPic(_T("QQ\\ScrollBar\\scrollbar_bar_down.png"), CRect(4,4,4,4));
  691. m_VScrollBar.SetThumbDisabledPic(_T("QQ\\ScrollBar\\scrollbar_bar_normal.png"), CRect(4,4,4,4));
  692. return 0;
  693. }
  694. BOOL CBuddyListBox::OnEraseBkgnd(CDC*pDC)
  695. {
  696. return TRUE;
  697. }
  698. void CBuddyListBox::OnPaint()
  699. {
  700. CPaintDC dc(this);
  701. CRect rcClient;
  702. GetClientRect(&rcClient);
  703. CMemoryDC BufferDC(&dc, rcClient);
  704. CheckScrollBarStatus();
  705. BufferDC.FillSolidRect(rcClient,m_colBack);
  706. DrawParentWndBg(GetSafeHwnd(),BufferDC.m_hDC);
  707. if (m_lpBgImg != NULL && !m_lpBgImg->IsNull())
  708. m_lpBgImg->Draw(&BufferDC, rcClient);
  709. CBuddyRootItem * lpTeamItem;
  710. for (int i = 0; i < (int)m_arrBuddyTeamItems.size(); i++)
  711. {
  712. DrawBuddyTeam(&BufferDC, i);
  713. lpTeamItem = m_arrBuddyTeamItems[i];
  714. if (lpTeamItem != NULL && lpTeamItem->m_bExpand)
  715. {
  716. for (int j = 0; j < (int)lpTeamItem->m_arrBuddys.size(); j++)
  717. {
  718. DrawBuddyItem(&BufferDC, i, j);
  719. }
  720. }
  721. }
  722. m_VScrollBar.OnPaint(&BufferDC);
  723. }
  724. void CBuddyListBox::OnLButtonDblClk(UINT nFlags, CPoint point)
  725. {
  726. SetFocus();
  727. int nTeamIndex = -1, nIndex = -1;
  728. HitTest(point, nTeamIndex, nIndex);
  729. m_nSelTeamIndex = nTeamIndex;
  730. m_nSelIndex = nIndex;
  731. Invalidate(FALSE);
  732. NMHDR stNmhdr = {m_hWnd, GetDlgCtrlID(), NM_DBLCLK};
  733. ::SendMessage(::GetParent(m_hWnd), WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&stNmhdr);
  734. }
  735. void CBuddyListBox::OnLButtonDown(UINT nFlags, CPoint point)
  736. {
  737. SetFocus();
  738. int nTeamIndex = -1, nIndex = -1;
  739. HitTest(point, nTeamIndex, nIndex);
  740. m_nPressTeamIndex = nTeamIndex;
  741. m_nPressIndex = nIndex;
  742. m_VScrollBar.OnLButtonDown(nFlags, point);
  743. CWnd::OnLButtonDown(nFlags, point);
  744. }
  745. void CBuddyListBox::OnLButtonUp(UINT nFlags, CPoint point)
  746. {
  747. int nTeamIndex = -1, nIndex = -1;
  748. HitTest(point, nTeamIndex, nIndex);
  749. if (nTeamIndex != -1 && nTeamIndex == m_nPressTeamIndex
  750. && nIndex == m_nPressIndex)
  751. {
  752. m_nSelTeamIndex = nTeamIndex;
  753. m_nSelIndex = nIndex;
  754. if (-1 == nIndex) // 点击的是好友分组项
  755. {
  756. BOOL bExpand = IsBuddyTeamExpand(nTeamIndex);
  757. SetBuddyTeamExpand(nTeamIndex, !bExpand);
  758. }
  759. EnsureVisible(m_nSelTeamIndex, m_nSelIndex);
  760. Invalidate(FALSE);
  761. }
  762. m_nPressTeamIndex = -1;
  763. m_nPressIndex = -1;
  764. m_VScrollBar.OnLButtonUp(nFlags, point);
  765. CWnd::OnLButtonUp(nFlags, point);
  766. }
  767. void CBuddyListBox::OnMouseMove(UINT nFlags, CPoint point)
  768. {
  769. if (m_nPressTeamIndex != -1)
  770. return;
  771. if (!m_bMouseTracking)
  772. {
  773. TrackMouseLeave(GetSafeHwnd());
  774. m_bMouseTracking = TRUE;
  775. }
  776. int nTeamIndex = -1, nIndex = -1;
  777. HitTest(point, nTeamIndex, nIndex);
  778. if (nTeamIndex != m_nHoverTeamIndex || nIndex != m_nHoverIndex)
  779. {
  780. m_nHoverTeamIndex = nTeamIndex;
  781. m_nHoverIndex = nIndex;
  782. Invalidate(FALSE);
  783. }
  784. m_VScrollBar.OnMouseMove(nFlags, point);
  785. CWnd::OnMouseMove(nFlags, point);
  786. }
  787. void CBuddyListBox::OnMouseLeave()
  788. {
  789. m_bMouseTracking = FALSE;
  790. if (-1 != m_nHoverTeamIndex || -1 != m_nHoverIndex)
  791. {
  792. m_nHoverTeamIndex = -1;
  793. m_nHoverIndex = -1;
  794. Invalidate(FALSE);
  795. }
  796. m_VScrollBar.OnMouseLeave();
  797. CWnd::OnMouseLeave();
  798. }
  799. void CBuddyListBox::OnTimer(UINT_PTR nIDEvent)
  800. {
  801. m_VScrollBar.OnTimer(nIDEvent);
  802. if (nIDEvent == m_dwHeadFlashAnimTimerId) // 头像闪动动画
  803. {
  804. OnTimer_HeadFlashAnim(nIDEvent);
  805. }
  806. else if (nIDEvent == m_dwOnlineAnimTimerId) // 上线动画
  807. {
  808. OnTimer_OnlineAnim(nIDEvent);
  809. }
  810. else if (nIDEvent == m_dwOfflineAnimTimerId) // 下线动画
  811. {
  812. OnTimer_OfflineAnim(nIDEvent);
  813. }
  814. CWnd::OnTimer(nIDEvent);
  815. }
  816. BOOL CBuddyListBox::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
  817. {
  818. int nLineSize = 100;
  819. if (zDelta < 0) // SB_LINEDOWN
  820. Scroll(0, nLineSize);
  821. else // SB_LINEUP
  822. Scroll(0, -nLineSize);
  823. Invalidate(FALSE);
  824. return TRUE;
  825. }
  826. void CBuddyListBox::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
  827. {
  828. if (GetBuddyTeamCount() <= 0)
  829. return;
  830. switch (nChar)
  831. {
  832. case VK_UP: // 向上光标键
  833. {
  834. if (-1 == m_nSelIndex)
  835. {
  836. if (0 == m_nSelTeamIndex)
  837. return;
  838. m_nSelTeamIndex--;
  839. m_nSelIndex = -1;
  840. if (IsBuddyTeamExpand(m_nSelTeamIndex))
  841. {
  842. int nItemCnt = GetBuddyItemCount(m_nSelTeamIndex);
  843. if (nItemCnt > 0)
  844. m_nSelIndex = nItemCnt - 1;
  845. }
  846. }
  847. else
  848. {
  849. if (0 == m_nSelIndex)
  850. m_nSelIndex = -1;
  851. else
  852. m_nSelIndex--;
  853. }
  854. }
  855. break;
  856. case VK_DOWN: // 向下光标键
  857. {
  858. if (-1 == m_nSelIndex)
  859. {
  860. if (IsBuddyTeamExpand(m_nSelTeamIndex) &&
  861. GetBuddyItemCount(m_nSelTeamIndex) > 0)
  862. {
  863. m_nSelIndex = 0;
  864. }
  865. else
  866. {
  867. if ((GetBuddyTeamCount() - 1) == m_nSelTeamIndex)
  868. return;
  869. m_nSelTeamIndex++;
  870. m_nSelIndex = -1;
  871. }
  872. }
  873. else
  874. {
  875. if (GetBuddyItemCount(m_nSelTeamIndex) - 1 == m_nSelIndex)
  876. {
  877. if (GetBuddyTeamCount() - 1 == m_nSelTeamIndex)
  878. return;
  879. m_nSelTeamIndex++;
  880. m_nSelIndex = -1;
  881. }
  882. else
  883. m_nSelIndex += 1;
  884. }
  885. }
  886. break;
  887. case VK_LEFT: // 向左光标键
  888. {
  889. if (-1 == m_nSelIndex) //
  890. {
  891. if (IsBuddyTeamExpand(m_nSelTeamIndex))
  892. SetBuddyTeamExpand(m_nSelTeamIndex, FALSE);
  893. }
  894. else
  895. m_nSelIndex = -1;
  896. }
  897. break;
  898. case VK_RIGHT: // 向右光标键
  899. {
  900. if (-1 == m_nSelIndex)
  901. {
  902. if (!IsBuddyTeamExpand(m_nSelTeamIndex))
  903. SetBuddyTeamExpand(m_nSelTeamIndex, TRUE);
  904. else if (GetBuddyItemCount(m_nSelTeamIndex) > 0)
  905. m_nSelIndex = 0;
  906. }
  907. }
  908. break;
  909. case VK_PRIOR: // PgUp键
  910. {
  911. CRect rcClient;
  912. GetClientRect(&rcClient);
  913. Scroll(0, -rcClient.Height());
  914. Invalidate(FALSE);
  915. }
  916. return;
  917. case VK_NEXT: // PgDn键
  918. {
  919. CRect rcClient;
  920. GetClientRect(&rcClient);
  921. Scroll(0, rcClient.Height());
  922. Invalidate(FALSE);
  923. }
  924. return;
  925. case VK_HOME: // Home键
  926. {
  927. m_nSelTeamIndex = 0;
  928. m_nSelIndex = -1;
  929. }
  930. break;
  931. case VK_END: // End键
  932. {
  933. int TeamCnt = GetBuddyTeamCount();
  934. m_nSelTeamIndex = TeamCnt - 1;
  935. m_nSelIndex = -1;
  936. if (IsBuddyTeamExpand(TeamCnt - 1) &&
  937. GetBuddyItemCount(TeamCnt - 1) > 0)
  938. m_nSelIndex = GetBuddyItemCount(TeamCnt - 1) - 1;
  939. }
  940. break;
  941. case VK_RETURN: // 回车键
  942. {
  943. }
  944. return;
  945. default:
  946. return;
  947. }
  948. EnsureVisible(m_nSelTeamIndex, m_nSelIndex);
  949. Invalidate(FALSE);
  950. CWnd::OnKeyDown(nChar,nRepCnt,nFlags);
  951. }
  952. void CBuddyListBox::OnSize(UINT nType, int cx, int cy)
  953. {
  954. CWnd::OnSize(nType, cx, cy);
  955. CRect rcClient;
  956. GetClientRect(&rcClient);
  957. CRect rc = CRect(rcClient.Width()-8, 0, rcClient.Width(), rcClient.Height());
  958. m_VScrollBar.SetRect(&rc);
  959. Invalidate(FALSE);
  960. }
  961. void CBuddyListBox::OnDestroy()
  962. {
  963. CWnd::OnDestroy();
  964. if (m_dwHeadFlashAnimTimerId != NULL)
  965. {
  966. KillTimer(m_dwHeadFlashAnimTimerId);
  967. m_dwHeadFlashAnimTimerId = NULL;
  968. }
  969. if (m_ToolTipCtrl.GetSafeHwnd())
  970. m_ToolTipCtrl.DestroyWindow();
  971. m_ToolTipCtrl.m_hWnd = NULL;
  972. m_VScrollBar.Destroy();
  973. RenderEngine->RemoveImage(m_lpBgImg);
  974. RenderEngine->RemoveImage(m_lpBuddyTeamBgImgH);
  975. RenderEngine->RemoveImage(m_lpArrowImgN);
  976. RenderEngine->RemoveImage(m_lpArrowImgH);
  977. RenderEngine->RemoveImage(m_lpArrowImgS);
  978. RenderEngine->RemoveImage(m_lpExpArrowImgN);
  979. RenderEngine->RemoveImage(m_lpExpArrowImgH);
  980. RenderEngine->RemoveImage(m_lpExpArrowImgS);
  981. RenderEngine->RemoveImage(m_lpBuddyItemBgImgH);
  982. RenderEngine->RemoveImage(m_lpBuddyItemBgImgS);
  983. RenderEngine->RemoveImage(m_lpHeadFrameImg);
  984. RenderEngine->RemoveImage(m_lpStdGGHeadImg);
  985. RenderEngine->RemoveImage(m_lpStdMMHeadImg);
  986. RemoveScorll();
  987. m_nSelTeamIndex = m_nSelIndex = -1;
  988. m_nHoverTeamIndex = m_nHoverIndex = -1;
  989. m_nHoverSmallIconIndex = -1;
  990. m_nPressTeamIndex = m_nPressIndex = -1;
  991. m_nLeft = m_nTop = 0;
  992. m_bMouseTracking = FALSE;
  993. m_nStyle = BLC_BIG_ICON_STYLE;
  994. m_bShowBigIconInSel = TRUE;
  995. m_nBuddyTeamHeight = 0;
  996. m_nBuddyItemHeightInBig = 0;
  997. m_nBuddyItemHeightInSmall = 0;
  998. m_nBuddyItemHeightInStd = 0;
  999. m_nBuddyTeamPadding = 0;
  1000. m_nBuddyItemPadding = 0;
  1001. m_rcMargin = CRect(0,0,0,0);
  1002. for (int i = 0; i < (int)m_arrBuddyTeamItems.size(); i++)
  1003. {
  1004. CBuddyRootItem * lpTeamItem = m_arrBuddyTeamItems[i];
  1005. if (lpTeamItem != NULL)
  1006. delete lpTeamItem;
  1007. }
  1008. m_arrBuddyTeamItems.clear();
  1009. }
  1010. void CBuddyListBox::DrawBuddyTeam(CDC*pDC, int nIndex)
  1011. {
  1012. CBuddyRootItem * lpItem = GetBuddyTeamByIndex(nIndex);
  1013. if (NULL == lpItem)
  1014. return;
  1015. CRect rcItem;
  1016. GetItemRectByIndex(nIndex, -1, rcItem);
  1017. int nArrowWidth = 12, nArrowHeight = 12;
  1018. if (m_lpArrowImgN != NULL && !m_lpArrowImgN->IsNull())
  1019. {
  1020. nArrowWidth = m_lpArrowImgN->GetWidth();
  1021. nArrowHeight = m_lpArrowImgN->GetHeight();
  1022. }
  1023. CRect rcArrow;
  1024. CalcCenterRect(rcItem, nArrowWidth, nArrowHeight, rcArrow);
  1025. rcArrow.left = rcItem.left + 2;
  1026. rcArrow.right = rcArrow.left + nArrowWidth;
  1027. CRect rcText(rcItem);
  1028. rcText.left = rcArrow.right + 6;
  1029. if (m_nSelTeamIndex == nIndex && m_nSelIndex == -1)
  1030. {
  1031. if (!lpItem->m_bExpand)
  1032. {
  1033. if (m_lpArrowImgS != NULL && !m_lpArrowImgS->IsNull())
  1034. m_lpArrowImgS->Draw(pDC, rcArrow);
  1035. }
  1036. else
  1037. {
  1038. if (m_lpExpArrowImgS != NULL && !m_lpExpArrowImgS->IsNull())
  1039. m_lpExpArrowImgS->Draw(pDC, rcArrow);
  1040. }
  1041. }
  1042. else if (m_nHoverTeamIndex == nIndex && m_nHoverIndex == -1)
  1043. {
  1044. if (m_lpBuddyTeamBgImgH != NULL && !m_lpBuddyTeamBgImgH->IsNull())
  1045. m_lpBuddyTeamBgImgH->Draw(pDC, rcItem);
  1046. if (!lpItem->m_bExpand)
  1047. {
  1048. if (m_lpArrowImgH != NULL && !m_lpArrowImgH->IsNull())
  1049. m_lpArrowImgH->Draw(pDC, rcArrow);
  1050. }
  1051. else
  1052. {
  1053. if (m_lpExpArrowImgH != NULL && !m_lpExpArrowImgH->IsNull())
  1054. m_lpExpArrowImgH->Draw(pDC, rcArrow);
  1055. }
  1056. }
  1057. else
  1058. {
  1059. if (!lpItem->m_bExpand)
  1060. {
  1061. if (m_lpArrowImgN != NULL && !m_lpArrowImgN->IsNull())
  1062. m_lpArrowImgN->Draw(pDC, rcArrow);
  1063. }
  1064. else
  1065. {
  1066. if (m_lpExpArrowImgN != NULL && !m_lpExpArrowImgN->IsNull())
  1067. m_lpExpArrowImgN->Draw(pDC, rcArrow);
  1068. }
  1069. }
  1070. BOOL bShowText = TRUE;
  1071. if (!lpItem->m_bExpand && lpItem->m_nHeadFlashAnim > 0)
  1072. {
  1073. if (1 == lpItem->m_nHeadFlashAnimState)
  1074. bShowText = FALSE;
  1075. }
  1076. if (bShowText)
  1077. {
  1078. CString strText;
  1079. if (lpItem->m_nCurCnt != -1)
  1080. strText.Format(_T("%s [%d/%d]"), lpItem->m_strName, lpItem->m_nCurCnt, lpItem->m_nMaxCnt);
  1081. else
  1082. strText.Format(_T("%s [%d]"), lpItem->m_strName, lpItem->m_nMaxCnt);
  1083. UINT nFormat = DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS;
  1084. pDC->SetTextColor(RGB(0, 0, 0));
  1085. int nMode = pDC->SetBkMode(TRANSPARENT);
  1086. HFONT hFont = (HFONT)SendMessage(WM_GETFONT, 0, 0);
  1087. if (NULL == hFont)
  1088. hFont = (HFONT)::GetStockObject(DEFAULT_GUI_FONT);
  1089. HFONT hOldFont = (HFONT)pDC->SelectObject(hFont);
  1090. pDC->DrawText(strText, &rcText, nFormat);
  1091. pDC->SelectObject(hOldFont);
  1092. pDC->SetBkMode(nMode);
  1093. }
  1094. }
  1095. void CBuddyListBox::DrawBuddyItem(CDC*pDC, int nTeamIndex, int nIndex)
  1096. {
  1097. int nMode = pDC->SetStretchBltMode(HALFTONE);
  1098. if (BLC_BIG_ICON_STYLE == m_nStyle)
  1099. DrawBuddyItemInBigIcon(pDC, nTeamIndex, nIndex);
  1100. else if (BLC_SMALL_ICON_STYLE == m_nStyle)
  1101. DrawBuddyItemInSmallIcon(pDC, nTeamIndex, nIndex);
  1102. else if (BLC_STANDARD_ICON_STYLE == m_nStyle)
  1103. DrawBuddyItemInStdIcon(pDC, nTeamIndex, nIndex);
  1104. pDC->SetStretchBltMode(nMode);
  1105. }
  1106. void CBuddyListBox::DrawBuddyItemInBigIcon(CDC*pDC, int nTeamIndex, int nIndex)
  1107. {
  1108. CBuddyItem * lpItem = GetBuddyItemByIndex(nTeamIndex, nIndex);
  1109. if (NULL == lpItem)
  1110. return;
  1111. CRect rcItem;
  1112. GetItemRectByIndex(nTeamIndex, nIndex, rcItem);
  1113. int nHeadWidth = 40, nHeadHeight = 40;
  1114. CRect rcHead;
  1115. CalcCenterRect(rcItem, nHeadWidth, nHeadHeight, rcHead);
  1116. rcHead.left = rcItem.left + 6;
  1117. rcHead.right = rcHead.left + nHeadWidth;
  1118. int nHeadRight = rcHead.right;
  1119. CString strName1, strName2;
  1120. if (lpItem->m_strMarkName.GetLength() > 0)
  1121. {
  1122. strName1 = lpItem->m_strMarkName;
  1123. strName2.Format(_T("(%s)"), lpItem->m_strNickName);
  1124. }
  1125. else
  1126. {
  1127. strName1 = lpItem->m_strNickName;
  1128. strName2 = _T("");
  1129. }
  1130. if (m_nSelTeamIndex == nTeamIndex && m_nSelIndex == nIndex) // 选中状态
  1131. {
  1132. if (m_lpBuddyItemBgImgS != NULL && !m_lpBuddyItemBgImgS->IsNull())
  1133. m_lpBuddyItemBgImgS->Draw(pDC, rcItem);
  1134. }
  1135. else if (m_nHoverTeamIndex == nTeamIndex && m_nHoverIndex == nIndex) // 高亮状态
  1136. {
  1137. if (m_lpBuddyItemBgImgH != NULL && !m_lpBuddyItemBgImgH->IsNull())
  1138. m_lpBuddyItemBgImgH->Draw(pDC, rcItem);
  1139. }
  1140. else
  1141. {
  1142. }
  1143. if (lpItem->m_bHeadFlashAnim) // 头像闪动动画
  1144. {
  1145. POINT pt[] = {{-1,1},{0,0},{1,1},{0,0}};
  1146. if (lpItem->m_nHeadFlashAnimState >= 0 && lpItem->m_nHeadFlashAnimState < 4)
  1147. rcHead.OffsetRect(pt[lpItem->m_nHeadFlashAnimState]);
  1148. }
  1149. if (lpItem->m_lpHeadImg != NULL && !lpItem->m_lpHeadImg->IsNull()) // 绘制头像
  1150. lpItem->m_lpHeadImg->Draw(pDC, rcHead);
  1151. if (m_nSelTeamIndex == nTeamIndex && m_nSelIndex == nIndex)
  1152. {
  1153. CRect rcHeadFrame(rcHead);
  1154. rcHeadFrame.left -= 3;
  1155. rcHeadFrame.right += 3;
  1156. rcHeadFrame.top -= 3;
  1157. rcHeadFrame.bottom += 3;
  1158. if (m_lpHeadFrameImg != NULL && !m_lpHeadFrameImg->IsNull()) // 绘制头像焦点框
  1159. m_lpHeadFrameImg->Draw(pDC, rcHeadFrame);
  1160. }
  1161. UINT nFormat = DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS;
  1162. int nMode = pDC->SetBkMode(TRANSPARENT);
  1163. HFONT hFont = (HFONT)SendMessage(WM_GETFONT, 0, 0);
  1164. if (NULL == hFont)
  1165. hFont = (HFONT)::GetStockObject(DEFAULT_GUI_FONT);
  1166. HFONT hOldFont = (HFONT)pDC->SelectObject(hFont);
  1167. CRect rcName1, rcName2, rcSign;
  1168. if (strName1.GetLength() > 0)
  1169. {
  1170. CRect rcText(0,0,0,0); // 计算文字宽高
  1171. pDC->DrawText(strName1,&rcText, DT_SINGLELINE | DT_CALCRECT);
  1172. rcName1.left = nHeadRight + 6;
  1173. rcName1.right = rcName1.left + rcText.Width();
  1174. rcName1.top = rcItem.top + 9;
  1175. rcName1.bottom = rcName1.top + rcText.Height();
  1176. if (rcName1.right > rcItem.right - 10)
  1177. rcName1.right = rcItem.right - 10;
  1178. COLORREF clrText;
  1179. if (lpItem->m_bOnlineAnim)
  1180. {
  1181. COLORREF colors[] = {RGB(255,0,0), RGB(255,192,0), RGB(37,228,226), RGB(28,197,28), RGB(0,111,225)};
  1182. clrText = colors[lpItem->m_nOnlineAnimState % 5];
  1183. }
  1184. else
  1185. clrText = RGB(0, 0, 0);
  1186. pDC->SetTextColor(clrText);
  1187. pDC->DrawText(strName1, &rcName1, nFormat);
  1188. if (strName2.GetLength() > 0)
  1189. {
  1190. CRect rcText(0,0,0,0); // 计算文字宽高
  1191. pDC->DrawText(strName2, &rcText, DT_SINGLELINE | DT_CALCRECT);
  1192. rcName2.left = rcName1.right;
  1193. rcName2.right = rcName2.left + rcText.Width();
  1194. rcName2.top = rcItem.top + 9;
  1195. rcName2.bottom = rcName2.top + rcText.Height();
  1196. if (rcName2.right > rcItem.right - 10)
  1197. rcName2.right = rcItem.right - 10;
  1198. pDC->SetTextColor(RGB(128, 128, 128));
  1199. pDC->DrawText(strName2, &rcName2, nFormat);
  1200. }
  1201. }
  1202. if (lpItem->m_strSign.GetLength() > 0)
  1203. {
  1204. CRect rcText(0,0,0,0); // 计算文字宽高
  1205. pDC->DrawText(lpItem->m_strSign,&rcText, DT_SINGLELINE | DT_CALCRECT);
  1206. rcSign.left = nHeadRight + 6;
  1207. rcSign.right = rcSign.left + rcText.Width();
  1208. rcSign.top = rcName1.bottom + 10;
  1209. rcSign.bottom = rcSign.top + rcText.Height();
  1210. if (rcSign.right > rcItem.right - 10)
  1211. rcSign.right = rcItem.right - 10;
  1212. COLORREF clrText;
  1213. if (lpItem->m_bOnlineAnim)
  1214. {
  1215. COLORREF colors[] = {RGB(255,0,0), RGB(255,192,0), RGB(37,228,226), RGB(28,197,28), RGB(0,111,225)};
  1216. clrText = colors[lpItem->m_nOnlineAnimState % 5];
  1217. }
  1218. else
  1219. clrText = RGB(128,128,128);
  1220. pDC->SetTextColor(clrText);
  1221. pDC->DrawText(lpItem->m_strSign, &rcSign, nFormat);
  1222. }
  1223. pDC->SelectObject(hOldFont);
  1224. pDC->SetBkMode(nMode);
  1225. }
  1226. void CBuddyListBox::DrawBuddyItemInSmallIcon(CDC*pDC, int nTeamIndex, int nIndex)
  1227. {
  1228. if (m_bShowBigIconInSel && m_nSelTeamIndex == nTeamIndex && m_nSelIndex == nIndex)
  1229. {
  1230. DrawBuddyItemInBigIcon(pDC, nTeamIndex, nIndex);
  1231. return;
  1232. }
  1233. CBuddyItem * lpItem = GetBuddyItemByIndex(nTeamIndex, nIndex);
  1234. if (NULL == lpItem)
  1235. return;
  1236. CRect rcItem;
  1237. GetItemRectByIndex(nTeamIndex, nIndex, rcItem);
  1238. int nHeadWidth = 20, nHeadHeight = 20;
  1239. CRect rcHead;
  1240. CalcCenterRect(rcItem, nHeadWidth, nHeadHeight, rcHead);
  1241. rcHead.left = rcItem.left + 6;
  1242. rcHead.right = rcHead.left + nHeadWidth;
  1243. int nHeadRight = rcHead.right;
  1244. CString strName;
  1245. if (lpItem->m_strMarkName.GetLength() > 0)
  1246. strName = lpItem->m_strMarkName;
  1247. else
  1248. strName = lpItem->m_strNickName;
  1249. if (m_nSelTeamIndex == nTeamIndex && m_nSelIndex == nIndex) // 选中状态
  1250. {
  1251. if (m_lpBuddyItemBgImgS != NULL && !m_lpBuddyItemBgImgS->IsNull())
  1252. m_lpBuddyItemBgImgS->Draw(pDC, rcItem);
  1253. }
  1254. else if (m_nHoverTeamIndex == nTeamIndex && m_nHoverIndex == nIndex) // 高亮状态
  1255. {
  1256. if (m_lpBuddyItemBgImgH != NULL && !m_lpBuddyItemBgImgH->IsNull())
  1257. m_lpBuddyItemBgImgH->Draw(pDC, rcItem);
  1258. }
  1259. else
  1260. {
  1261. }
  1262. if (lpItem->m_bHeadFlashAnim) // 头像闪动动画
  1263. {
  1264. POINT pt[] = {{-1,1},{0,0},{1,1},{0,0}};
  1265. if (lpItem->m_nHeadFlashAnimState >= 0 && lpItem->m_nHeadFlashAnimState < 4)
  1266. rcHead.OffsetRect(pt[lpItem->m_nHeadFlashAnimState]);
  1267. }
  1268. if (lpItem->m_lpHeadImg != NULL && !lpItem->m_lpHeadImg->IsNull()) // 绘制头像
  1269. lpItem->m_lpHeadImg->Draw(pDC, rcHead);
  1270. UINT nFormat = DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS;
  1271. int nMode = pDC->SetBkMode(TRANSPARENT);
  1272. HFONT hFont = (HFONT)SendMessage(WM_GETFONT, 0, 0);
  1273. if (NULL == hFont)
  1274. hFont = (HFONT)::GetStockObject(DEFAULT_GUI_FONT);
  1275. HFONT hOldFont = (HFONT)pDC->SelectObject(hFont);
  1276. CRect rcName, rcSign;
  1277. if (strName.GetLength() > 0)
  1278. {
  1279. CRect rcText(0,0,0,0); // 计算文字宽高
  1280. pDC->DrawText(strName, &rcText, DT_SINGLELINE | DT_CALCRECT);
  1281. rcName.left = nHeadRight + 6;
  1282. rcName.right = rcName.left + rcText.Width();
  1283. rcName.top = rcItem.top;
  1284. rcName.bottom = rcItem.bottom;
  1285. if (rcName.right > rcItem.right - 10)
  1286. rcName.right = rcItem.right - 10;
  1287. COLORREF clrText;
  1288. if (lpItem->m_bOnlineAnim)
  1289. {
  1290. COLORREF colors[] = {RGB(255,0,0), RGB(255,192,0), RGB(37,228,226), RGB(28,197,28), RGB(0,111,225)};
  1291. clrText = colors[lpItem->m_nOnlineAnimState % 5];
  1292. }
  1293. else
  1294. clrText = RGB(0, 0, 0);
  1295. pDC->SetTextColor(clrText);
  1296. pDC->DrawText(strName, &rcName, nFormat);
  1297. }
  1298. if (lpItem->m_strSign.GetLength() > 0)
  1299. {
  1300. CRect rcText(0,0,0,0); // 计算文字宽高
  1301. pDC->DrawText(lpItem->m_strSign, &rcText, DT_SINGLELINE | DT_CALCRECT);
  1302. rcSign.left = rcName.right + 6;
  1303. rcSign.right = rcSign.left + rcText.Width();
  1304. rcSign.top = rcItem.top;
  1305. rcSign.bottom = rcItem.bottom;
  1306. if (rcSign.right > rcItem.right - 10)
  1307. rcSign.right = rcItem.right - 10;
  1308. COLORREF clrText;
  1309. if (lpItem->m_bOnlineAnim)
  1310. {
  1311. COLORREF colors[] = {RGB(255,0,0), RGB(255,192,0), RGB(37,228,226), RGB(28,197,28), RGB(0,111,225)};
  1312. clrText = colors[lpItem->m_nOnlineAnimState % 5];
  1313. }
  1314. else
  1315. clrText = RGB(128, 128, 128);
  1316. pDC->SetTextColor(clrText);
  1317. pDC->DrawText(lpItem->m_strSign, &rcSign, nFormat);
  1318. }
  1319. pDC->SelectObject(hOldFont);
  1320. pDC->SetBkMode(nMode);
  1321. }
  1322. void CBuddyListBox::DrawBuddyItemInStdIcon(CDC*pDC, int nTeamIndex, int nIndex)
  1323. {
  1324. CBuddyItem * lpItem = GetBuddyItemByIndex(nTeamIndex, nIndex);
  1325. if (NULL == lpItem)
  1326. return;
  1327. CRect rcItem;
  1328. GetItemRectByIndex(nTeamIndex, nIndex, rcItem);
  1329. CImageEx * lpHeadImg;
  1330. if (lpItem->m_bGender)
  1331. lpHeadImg = m_lpStdGGHeadImg;
  1332. else
  1333. lpHeadImg = m_lpStdMMHeadImg;
  1334. int nHeadWidth = 16, nHeadHeight = 16;
  1335. CRect rcHead;
  1336. CalcCenterRect(rcItem, nHeadWidth, nHeadHeight, rcHead);
  1337. rcHead.left = rcItem.left + 6;
  1338. rcHead.right = rcHead.left + nHeadWidth;
  1339. int nHeadRight = rcHead.right;
  1340. if (lpItem->m_bHeadFlashAnim) // 头像闪动动画
  1341. {
  1342. POINT pt[] = {{-1,1},{0,0},{1,1},{0,0}};
  1343. if (lpItem->m_nHeadFlashAnimState >= 0 && lpItem->m_nHeadFlashAnimState < 4)
  1344. rcHead.OffsetRect(pt[lpItem->m_nHeadFlashAnimState]);
  1345. }
  1346. CString strName;
  1347. if (lpItem->m_strMarkName.GetLength() > 0)
  1348. strName = lpItem->m_strMarkName;
  1349. else
  1350. strName = lpItem->m_strNickName;
  1351. if (m_nSelTeamIndex == nTeamIndex && m_nSelIndex == nIndex)
  1352. {
  1353. if (m_lpBuddyItemBgImgS != NULL && !m_lpBuddyItemBgImgS->IsNull())
  1354. m_lpBuddyItemBgImgS->Draw(pDC, rcItem);
  1355. CRect rcHeadFrame(rcHead);
  1356. rcHeadFrame.left -= 2;
  1357. rcHeadFrame.right += 2;
  1358. rcHeadFrame.top -= 2;
  1359. rcHeadFrame.bottom += 2;
  1360. if (m_lpHeadFrameImg != NULL && !m_lpHeadFrameImg->IsNull())
  1361. m_lpHeadFrameImg->Draw(pDC, rcHeadFrame);
  1362. }
  1363. else if (m_nHoverTeamIndex == nTeamIndex && m_nHoverIndex == nIndex)
  1364. {
  1365. if (m_lpBuddyItemBgImgH != NULL && !m_lpBuddyItemBgImgH->IsNull())
  1366. m_lpBuddyItemBgImgH->Draw(pDC, rcItem);
  1367. }
  1368. else
  1369. {
  1370. }
  1371. if (lpHeadImg != NULL && !lpHeadImg->IsNull()) // 绘制头像
  1372. lpHeadImg->Draw(pDC, rcHead);
  1373. UINT nFormat = DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS;
  1374. int nMode = pDC->SetBkMode( TRANSPARENT);
  1375. HFONT hFont = (HFONT)SendMessage(WM_GETFONT, 0, 0);
  1376. if (NULL == hFont)
  1377. hFont = (HFONT)::GetStockObject(DEFAULT_GUI_FONT);
  1378. HFONT hOldFont = (HFONT)pDC->SelectObject(hFont);
  1379. CRect rcName, rcSign;
  1380. if (strName.GetLength() > 0)
  1381. {
  1382. CRect rcText(0,0,0,0); // 计算文字宽高
  1383. pDC->DrawText(strName, &rcText, DT_SINGLELINE | DT_CALCRECT);
  1384. rcName.left = nHeadRight + 6;
  1385. rcName.right = rcName.left + rcText.Width();
  1386. rcName.top = rcItem.top;
  1387. rcName.bottom = rcItem.bottom;
  1388. if (rcName.right > rcItem.right - 10)
  1389. rcName.right = rcItem.right - 10;
  1390. COLORREF clrText;
  1391. if (lpItem->m_bOnlineAnim)
  1392. {
  1393. COLORREF colors[] = {RGB(255,0,0), RGB(255,192,0), RGB(37,228,226), RGB(28,197,28), RGB(0,111,225)};
  1394. clrText = colors[lpItem->m_nOnlineAnimState % 5];
  1395. }
  1396. else
  1397. clrText = RGB(0, 0, 0);
  1398. pDC->SetTextColor(clrText);
  1399. pDC->DrawText(strName, strName.GetLength(), &rcName, nFormat);
  1400. }
  1401. if (lpItem->m_strSign.GetLength() > 0)
  1402. {
  1403. CRect rcText(0,0,0,0); // 计算文字宽高
  1404. pDC->DrawText(lpItem->m_strSign, &rcText, DT_SINGLELINE | DT_CALCRECT);
  1405. rcSign.left = rcName.right + 6;
  1406. rcSign.right = rcSign.left + rcText.Width();
  1407. rcSign.top = rcItem.top;
  1408. rcSign.bottom = rcItem.bottom;
  1409. if (rcSign.right > rcItem.right - 10)
  1410. rcSign.right = rcItem.right - 10;
  1411. COLORREF clrText;
  1412. if (lpItem->m_bOnlineAnim)
  1413. {
  1414. COLORREF colors[] = {RGB(255,0,0), RGB(255,192,0), RGB(37,228,226), RGB(28,197,28), RGB(0,111,225)};
  1415. clrText = colors[lpItem->m_nOnlineAnimState % 5];
  1416. }
  1417. else
  1418. clrText = RGB(128, 128, 128);
  1419. pDC->SetTextColor(clrText);
  1420. pDC->DrawText(lpItem->m_strSign, &rcSign, nFormat);
  1421. }
  1422. pDC->SelectObject(hOldFont);
  1423. pDC->SetBkMode(nMode);
  1424. }
  1425. void CBuddyListBox::HitTest(POINT pt, int& nTeamIndex, int& nIndex)
  1426. {
  1427. CBuddyRootItem * lpTeamItem;
  1428. CBuddyItem * lpItem;
  1429. int nLeft = m_rcMargin.left+m_nLeft, nTop = m_nTop;
  1430. int nBuddyTeamWidth, nBuddyItemWidth, nBuddyItemHeight;
  1431. CRect rcItem;
  1432. nTeamIndex = -1;
  1433. nIndex = -1;
  1434. CRect rcClient;
  1435. GetClientRect(&rcClient);
  1436. int nVScrollBarWidth = 0;
  1437. if (m_VScrollBar.IsVisible())
  1438. {
  1439. CRect rcVScrollBar;
  1440. m_VScrollBar.GetRect(&rcVScrollBar);
  1441. nVScrollBarWidth = rcVScrollBar.Width();
  1442. }
  1443. nBuddyTeamWidth = rcClient.Width() - m_rcMargin.left - m_rcMargin.right - nVScrollBarWidth;
  1444. nBuddyItemWidth = nBuddyTeamWidth;
  1445. if (BLC_BIG_ICON_STYLE == m_nStyle)
  1446. nBuddyItemHeight = m_nBuddyItemHeightInBig;
  1447. else if (BLC_SMALL_ICON_STYLE == m_nStyle)
  1448. nBuddyItemHeight = m_nBuddyItemHeightInSmall;
  1449. else
  1450. nBuddyItemHeight = m_nBuddyItemHeightInStd;
  1451. for (int i = 0; i < (int)m_arrBuddyTeamItems.size(); i++)
  1452. {
  1453. lpTeamItem = m_arrBuddyTeamItems[i];
  1454. if (lpTeamItem != NULL)
  1455. {
  1456. rcItem = CRect(nLeft, nTop, nLeft+nBuddyTeamWidth, nTop+m_nBuddyTeamHeight);
  1457. if (rcItem.PtInRect(pt))
  1458. {
  1459. nTeamIndex = i;
  1460. nIndex = -1;
  1461. return;
  1462. }
  1463. nTop += m_nBuddyTeamHeight;
  1464. nTop += m_nBuddyTeamPadding;
  1465. if (lpTeamItem->m_bExpand)
  1466. {
  1467. for (int j = 0; j < (int)lpTeamItem->m_arrBuddys.size(); j++)
  1468. {
  1469. lpItem = lpTeamItem->m_arrBuddys[j];
  1470. if (lpItem != NULL)
  1471. {
  1472. if (BLC_SMALL_ICON_STYLE == m_nStyle && m_bShowBigIconInSel
  1473. && (m_nSelTeamIndex == i && m_nSelIndex == j))
  1474. nBuddyItemHeight = m_nBuddyItemHeightInBig;
  1475. rcItem = CRect(nLeft, nTop, nLeft+nBuddyItemWidth, nTop+nBuddyItemHeight);
  1476. if (rcItem.PtInRect(pt))
  1477. {
  1478. nTeamIndex = i;
  1479. nIndex = j;
  1480. return;
  1481. }
  1482. nTop += nBuddyItemHeight;
  1483. nTop += m_nBuddyItemPadding;
  1484. if (BLC_SMALL_ICON_STYLE == m_nStyle && m_bShowBigIconInSel
  1485. && (m_nSelTeamIndex == i && m_nSelIndex == j))
  1486. nBuddyItemHeight = m_nBuddyItemHeightInSmall;
  1487. }
  1488. }
  1489. }
  1490. }
  1491. }
  1492. }
  1493. CBuddyRootItem * CBuddyListBox::GetBuddyTeamByIndex(int nIndex)
  1494. {
  1495. if (nIndex >= 0 && nIndex < (int)m_arrBuddyTeamItems.size())
  1496. return m_arrBuddyTeamItems[nIndex];
  1497. else
  1498. return NULL;
  1499. }
  1500. CBuddyItem * CBuddyListBox::GetBuddyItemByIndex(int nTeamIndex, int nIndex)
  1501. {
  1502. CBuddyRootItem * lpTeamItem;
  1503. if (nTeamIndex >= 0 && nTeamIndex < (int)m_arrBuddyTeamItems.size())
  1504. {
  1505. lpTeamItem = m_arrBuddyTeamItems[nTeamIndex];
  1506. if (lpTeamItem != NULL)
  1507. {
  1508. if (nIndex >= 0 && nIndex < (int)lpTeamItem->m_arrBuddys.size())
  1509. return lpTeamItem->m_arrBuddys[nIndex];
  1510. }
  1511. }
  1512. return NULL;
  1513. }
  1514. void CBuddyListBox::CheckScrollBarStatus()
  1515. {
  1516. if (!GetSafeHwnd())
  1517. return;
  1518. CBuddyRootItem * lpTeamItem;
  1519. int nLeft = m_rcMargin.left+m_nLeft, nTop = m_nTop;
  1520. int nBuddyTeamWidth, nBuddyItemWidth, nBuddyItemHeight;
  1521. CRect rcItem;
  1522. CRect rcClient;
  1523. GetClientRect(&rcClient);
  1524. int nVScrollBarWidth = 0;
  1525. if (m_VScrollBar.IsVisible())
  1526. {
  1527. CRect rcVScrollBar;
  1528. m_VScrollBar.GetRect(&rcVScrollBar);
  1529. nVScrollBarWidth = rcVScrollBar.Width();
  1530. }
  1531. nBuddyTeamWidth = rcClient.Width() - m_rcMargin.left - m_rcMargin.right - nVScrollBarWidth;
  1532. nBuddyItemWidth = nBuddyTeamWidth;
  1533. if (BLC_BIG_ICON_STYLE == m_nStyle)
  1534. nBuddyItemHeight = m_nBuddyItemHeightInBig;
  1535. else if (BLC_SMALL_ICON_STYLE == m_nStyle)
  1536. nBuddyItemHeight = m_nBuddyItemHeightInSmall;
  1537. else
  1538. nBuddyItemHeight = m_nBuddyItemHeightInStd;
  1539. int nHeight = (m_nBuddyTeamHeight + m_nBuddyTeamPadding) * (int)m_arrBuddyTeamItems.size();
  1540. for (int i = 0; i < (int)m_arrBuddyTeamItems.size(); i++)
  1541. {
  1542. lpTeamItem = m_arrBuddyTeamItems[i];
  1543. if (lpTeamItem != NULL)
  1544. {
  1545. if (lpTeamItem->m_bExpand)
  1546. {
  1547. nHeight += ((nBuddyItemHeight + m_nBuddyItemPadding) * (int)lpTeamItem->m_arrBuddys.size());
  1548. if (BLC_SMALL_ICON_STYLE == m_nStyle && m_bShowBigIconInSel
  1549. && (m_nSelTeamIndex == i && m_nSelIndex != -1))
  1550. {
  1551. nHeight -= nBuddyItemHeight;
  1552. nHeight += m_nBuddyItemHeightInBig;
  1553. }
  1554. }
  1555. }
  1556. }
  1557. if (nHeight > rcClient.Height())
  1558. {
  1559. m_VScrollBar.SetScrollRange(nHeight - rcClient.Height());
  1560. Scroll(0, 0);
  1561. m_VScrollBar.SetVisible(TRUE);
  1562. }
  1563. else
  1564. {
  1565. m_nTop = 0;
  1566. m_VScrollBar.SetScrollPos(0);
  1567. m_VScrollBar.SetVisible(FALSE);
  1568. }
  1569. }
  1570. void CBuddyListBox::Scroll(int cx, int cy)
  1571. {
  1572. if (m_VScrollBar.IsVisible() && m_VScrollBar.IsEnabled())
  1573. {
  1574. int nPos = m_VScrollBar.GetScrollPos();
  1575. m_VScrollBar.SetScrollPos(nPos + cy);
  1576. nPos = m_VScrollBar.GetScrollPos();
  1577. m_nTop = 0 - nPos;
  1578. }
  1579. }
  1580. void CBuddyListBox::EnsureVisible(int nTeamIndex, int nIndex)
  1581. {
  1582. CRect rcClient;
  1583. GetClientRect(&rcClient);
  1584. CRect rcItem;
  1585. GetItemRectByIndex(nTeamIndex, nIndex, rcItem);
  1586. if (rcItem.top < rcClient.top || rcItem.bottom >= rcClient.bottom)
  1587. {
  1588. int cy = 0;
  1589. if (rcItem.top < rcClient.top)
  1590. cy = rcItem.top - rcClient.top;
  1591. if (rcItem.bottom > rcClient.bottom)
  1592. cy = rcItem.bottom - rcClient.bottom;
  1593. Scroll(0, cy);
  1594. }
  1595. }
  1596. void CBuddyListBox::SortBuddyTeam(int nTeamIndex, int nIndex)
  1597. {
  1598. CBuddyRootItem * lpBuddyTeam = GetBuddyTeamByIndex(nTeamIndex); // 获取要排序的分组
  1599. if (NULL == lpBuddyTeam)
  1600. return;
  1601. int nItemCnt = (int)lpBuddyTeam->m_arrBuddys.size(); // 分组的好友数小于2则不用再排序
  1602. if (nItemCnt < 2)
  1603. return;
  1604. CBuddyItem * lpBuddyItem1 = GetBuddyItemByIndex(nTeamIndex, nIndex); // 获取要排序的好友
  1605. if (NULL == lpBuddyItem1)
  1606. return;
  1607. lpBuddyTeam->m_arrBuddys.erase(lpBuddyTeam->m_arrBuddys.begin()+nIndex);// 先删除
  1608. nItemCnt = (int)lpBuddyTeam->m_arrBuddys.size();
  1609. int nInsert = nItemCnt-1;
  1610. for (int i = 0; i < nItemCnt; i++)
  1611. {
  1612. CBuddyItem * lpBuddyItem2 = lpBuddyTeam->m_arrBuddys[i];
  1613. if (lpBuddyItem2 != NULL)
  1614. {
  1615. if (lpBuddyItem1->m_bOnline > lpBuddyItem2->m_bOnline)
  1616. {
  1617. nInsert = i;
  1618. break;
  1619. }
  1620. else if (lpBuddyItem1->m_bOnline == lpBuddyItem2->m_bOnline)
  1621. {
  1622. if (lpBuddyItem1->m_nID <= lpBuddyItem2->m_nID)
  1623. {
  1624. nInsert = i;
  1625. break;
  1626. }
  1627. }
  1628. }
  1629. }
  1630. lpBuddyTeam->m_arrBuddys.insert(lpBuddyTeam->m_arrBuddys.begin()+nInsert, lpBuddyItem1);
  1631. }
  1632. // 头像闪动动画
  1633. void CBuddyListBox::OnTimer_HeadFlashAnim(UINT_PTR nIDEvent)
  1634. {
  1635. if (nIDEvent != m_dwHeadFlashAnimTimerId)
  1636. return;
  1637. int nTeamCnt = GetBuddyTeamCount();
  1638. for (int i = 0; i < nTeamCnt; i++)
  1639. {
  1640. CBuddyRootItem * lpBuddyTeam = GetBuddyTeamByIndex(i);
  1641. if (lpBuddyTeam != NULL)
  1642. {
  1643. if (lpBuddyTeam->m_nHeadFlashAnim > 0)
  1644. {
  1645. if (!lpBuddyTeam->m_bExpand)
  1646. {
  1647. lpBuddyTeam->m_nHeadFlashAnimState++;
  1648. if (lpBuddyTeam->m_nHeadFlashAnimState >= 2)
  1649. lpBuddyTeam->m_nHeadFlashAnimState = 0;
  1650. }
  1651. else
  1652. {
  1653. int nItemCnt = GetBuddyItemCount(i);
  1654. for (int j = 0; j < nItemCnt; j++)
  1655. {
  1656. CBuddyItem * lpBuddyItem = GetBuddyItemByIndex(i, j);
  1657. if (lpBuddyItem != NULL && lpBuddyItem->m_bHeadFlashAnim)
  1658. {
  1659. lpBuddyItem->m_nHeadFlashAnimState++;
  1660. if (lpBuddyItem->m_nHeadFlashAnimState >= 4)
  1661. lpBuddyItem->m_nHeadFlashAnimState = 0;
  1662. }
  1663. }
  1664. }
  1665. }
  1666. }
  1667. }
  1668. Invalidate(FALSE);
  1669. }
  1670. // 上线动画
  1671. void CBuddyListBox::OnTimer_OnlineAnim(UINT_PTR nIDEvent)
  1672. {
  1673. if (nIDEvent != m_dwOnlineAnimTimerId)
  1674. return;
  1675. int nAnimCnt = 0;
  1676. int nTeamCnt = GetBuddyTeamCount();
  1677. for (int i = 0; i < nTeamCnt; i++)
  1678. {
  1679. int nItemCnt = GetBuddyItemCount(i);
  1680. for (int j = 0; j < nItemCnt; j++)
  1681. {
  1682. CBuddyItem * lpBuddyItem = GetBuddyItemByIndex(i, j);
  1683. if (lpBuddyItem != NULL && lpBuddyItem->m_bOnlineAnim)
  1684. {
  1685. nAnimCnt++;
  1686. lpBuddyItem->m_nOnlineAnimState++;
  1687. if (lpBuddyItem->m_nOnlineAnimState == 5)
  1688. {
  1689. SortBuddyTeam(i, j);
  1690. }
  1691. else if (lpBuddyItem->m_nOnlineAnimState >= 5 * 5)
  1692. {
  1693. lpBuddyItem->m_bOnlineAnim = FALSE;
  1694. lpBuddyItem->m_nOnlineAnimState = 0;
  1695. }
  1696. }
  1697. }
  1698. }
  1699. if (nAnimCnt <= 0)
  1700. {
  1701. KillTimer(m_dwOnlineAnimTimerId);
  1702. m_dwOnlineAnimTimerId = NULL;
  1703. }
  1704. Invalidate(FALSE);
  1705. }
  1706. // 下线动画
  1707. void CBuddyListBox::OnTimer_OfflineAnim(UINT_PTR nIDEvent)
  1708. {
  1709. if (nIDEvent != m_dwOfflineAnimTimerId)
  1710. return;
  1711. int nTeamCnt = GetBuddyTeamCount();
  1712. for (int i = 0; i < nTeamCnt; i++)
  1713. {
  1714. int nItemCnt = GetBuddyItemCount(i);
  1715. for (int j = 0; j < nItemCnt; j++)
  1716. {
  1717. CBuddyItem * lpBuddyItem = GetBuddyItemByIndex(i, j);
  1718. if (lpBuddyItem != NULL && lpBuddyItem->m_bOfflineAnim)
  1719. {
  1720. lpBuddyItem->m_bOfflineAnim = FALSE;
  1721. SortBuddyTeam(i, j);
  1722. }
  1723. }
  1724. }
  1725. KillTimer(m_dwOfflineAnimTimerId);
  1726. m_dwOfflineAnimTimerId = NULL;
  1727. Invalidate(FALSE);
  1728. }
  1729. void CBuddyListBox::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
  1730. {
  1731. CRect rcClient;
  1732. GetClientRect(&rcClient);
  1733. int nLineSize = 24;
  1734. int nPageSize = rcClient.Height();
  1735. switch (nSBCode)
  1736. {
  1737. case SB_LINEUP:
  1738. Scroll(0, -nLineSize);
  1739. break;
  1740. case SB_LINEDOWN:
  1741. Scroll(0, nLineSize);
  1742. break;
  1743. case SB_PAGEUP:
  1744. Scroll(0, -nPageSize);
  1745. break;
  1746. case SB_PAGEDOWN:
  1747. Scroll(0, nPageSize);
  1748. break;
  1749. case SB_THUMBTRACK:
  1750. Scroll(0, 0);
  1751. break;
  1752. default:
  1753. return;
  1754. }
  1755. Invalidate(FALSE);
  1756. __super::OnVScroll(nSBCode, nPos, pScrollBar);
  1757. }
  1758. UINT CBuddyListBox::OnGetDlgCode()
  1759. {
  1760. return DLGC_HASSETSEL | DLGC_WANTARROWS | DLGC_WANTCHARS | DLGC_WANTTAB;
  1761. return __super::OnGetDlgCode();
  1762. }
  1763. BOOL CBuddyListBox::PreTranslateMessage(MSG* pMsg)
  1764. {
  1765. if (m_ToolTipCtrl.GetSafeHwnd())
  1766. m_ToolTipCtrl.RelayEvent(pMsg);
  1767. return __super::PreTranslateMessage(pMsg);
  1768. }