skinnedlistview.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. #include "./skinnedlistview.h"
  2. #include "../winamp/gen.h"
  3. #include "../winamp/wa_dlg.h"
  4. #include "./skinning.h"
  5. #include "../nu/trace.h"
  6. #include "config.h"
  7. #ifndef LVS_EX_DOUBLEBUFFER //this will work XP only
  8. #define LVS_EX_DOUBLEBUFFER 0x00010000
  9. #endif
  10. // internal flags
  11. #define LVIF_ENABLED 0x0001
  12. #define LVIF_FOCUSED 0x0002
  13. #define LVIF_HEADERATTACHED 0x0100
  14. #define LVIF_REMOVEREFLECTOR 0x0200
  15. extern "C" winampGeneralPurposePlugin plugin;
  16. SkinnedListView::SkinnedListView(void) : SkinnedScrollWnd(FALSE), listFlags(0), currentItem(-1)
  17. {
  18. currentColor = SendMessageW(plugin.hwndParent, WM_WA_IPC, 4, IPC_GET_GENSKINBITMAP);
  19. }
  20. SkinnedListView::~SkinnedListView(void)
  21. {
  22. if (NULL != hwnd &&
  23. 0 != (LVIF_REMOVEREFLECTOR & listFlags))
  24. {
  25. HWND hParent = GetParent(hwnd);
  26. RemoveReflector(hParent);
  27. }
  28. }
  29. BOOL SkinnedListView::Attach(HWND hwndListView)
  30. {
  31. HWND hwndParent;
  32. listFlags = 0x000;
  33. if(!SkinnedScrollWnd::Attach(hwndListView)) return FALSE;
  34. SetType(SKINNEDWND_TYPE_LISTVIEW);
  35. SetMode(SCROLLMODE_LISTVIEW);
  36. hwndParent = GetParent(hwndListView);
  37. if (NULL != hwndParent && S_OK == InstallReflector(hwndParent))
  38. listFlags |= LVIF_REMOVEREFLECTOR;
  39. TryAttachHeader();
  40. SendMessageW(hwnd, CCM_SETVERSION, 5, 80);
  41. return TRUE;
  42. }
  43. void SkinnedListView::OnSkinChanged(BOOL bNotifyChildren, BOOL bRedraw)
  44. {
  45. if (SWS_USESKINCOLORS & style)
  46. {
  47. DisableRedraw();
  48. currentColor = SendMessageW(plugin.hwndParent, WM_WA_IPC, 4, IPC_GET_GENSKINBITMAP);
  49. SendMessageW(hwnd, LVM_SETTEXTCOLOR, 0, (LPARAM)WADlg_getColor(WADLG_ITEMFG));
  50. SendMessageW(hwnd, LVM_SETTEXTBKCOLOR, 0, (LPARAM)WADlg_getColor(WADLG_ITEMBG));
  51. SendMessageW(hwnd, LVM_SETBKCOLOR, 0, (LPARAM)WADlg_getColor(WADLG_ITEMBG));
  52. EnableRedraw(SWR_NONE);
  53. }
  54. __super::OnSkinChanged(bNotifyChildren, bRedraw);
  55. }
  56. BOOL SkinnedListView::SetStyle(UINT newStyle, BOOL bRedraw)
  57. {
  58. BOOL succeeded;
  59. succeeded = __super::SetStyle(newStyle, bRedraw);
  60. if (hwnd)
  61. {
  62. UINT lvStyle(0);
  63. if(SWLVS_FULLROWSELECT & newStyle) lvStyle |= LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP;
  64. if(SWLVS_DOUBLEBUFFER & newStyle) lvStyle |= LVS_EX_DOUBLEBUFFER;
  65. if (0 != lvStyle)
  66. ListView_SetExtendedListViewStyleEx(hwnd, lvStyle, lvStyle);
  67. if (0 != (SWS_USESKINCOLORS & style))
  68. {
  69. HWND tooltipWindow;
  70. tooltipWindow = (HWND)SendMessageW(hwnd, LVM_GETTOOLTIPS, 0, 0L);
  71. if (NULL != tooltipWindow)
  72. {
  73. unsigned int skinStyle;
  74. skinStyle = SWS_USESKINCOLORS;
  75. skinStyle |= ((SWS_USESKINFONT | SWS_USESKINCURSORS) & style);
  76. SkinWindowEx(tooltipWindow, SKINNEDWND_TYPE_TOOLTIP, skinStyle);
  77. }
  78. }
  79. }
  80. return succeeded;
  81. }
  82. BOOL SkinnedListView::OnCustomDraw(HWND hwndFrom, NMLVCUSTOMDRAW *plvcd, LRESULT *pResult)
  83. {
  84. static COLORREF rgbBk, rgbFg, rgbBkSel, rgbFgSel;
  85. static BOOL restoreSelect(FALSE), bFullRowSelect(FALSE);
  86. BOOL bSelected;
  87. switch(plvcd->nmcd.dwDrawStage)
  88. {
  89. case CDDS_PREPAINT:
  90. listFlags &= ~0x00FF;
  91. if (IsWindowEnabled(hwnd)) listFlags |= LVIF_ENABLED;
  92. if (GetFocus() == hwnd || GetForegroundWindow() == hwnd)
  93. listFlags |= LVIF_FOCUSED;
  94. if (MLSkinnedWnd_EnableReflection(hwndFrom, FALSE))
  95. {
  96. *pResult = SendMessageW(hwndFrom, WM_NOTIFY, (WPARAM)plvcd->nmcd.hdr.idFrom, (LPARAM)plvcd);
  97. MLSkinnedWnd_EnableReflection(hwndFrom, TRUE);
  98. }
  99. else *pResult = CDRF_DODEFAULT;
  100. if (plvcd->nmcd.rc.bottom != 0 && plvcd->nmcd.rc.right != 0) *pResult |= CDRF_NOTIFYITEMDRAW;
  101. bFullRowSelect = ( LVS_REPORT != (LVS_TYPEMASK & GetWindowLongPtrW(hwnd, GWL_STYLE)) ||
  102. 0 != (LVS_EX_FULLROWSELECT & CallPrevWndProc(LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0L)));
  103. return TRUE;
  104. // Modify item text and or background
  105. case CDDS_ITEMPREPAINT:
  106. bSelected = FALSE;
  107. if(LVIF_ENABLED & listFlags)
  108. {
  109. bSelected = (LVIS_SELECTED == CallPrevWndProc(LVM_GETITEMSTATE, plvcd->nmcd.dwItemSpec, LVIS_SELECTED));
  110. if (bSelected)
  111. {
  112. if(LVIF_FOCUSED & listFlags)
  113. {
  114. rgbFgSel = WADlg_getColor(WADLG_SELBAR_FGCOLOR);
  115. rgbBkSel = WADlg_getColor(WADLG_SELBAR_BGCOLOR);
  116. }
  117. else
  118. {
  119. rgbFgSel = WADlg_getColor(WADLG_INACT_SELBAR_FGCOLOR);
  120. rgbBkSel = WADlg_getColor(WADLG_INACT_SELBAR_BGCOLOR);
  121. }
  122. if (bFullRowSelect)
  123. {
  124. rgbBk = rgbBkSel;
  125. rgbFg = rgbFgSel;
  126. }
  127. }
  128. else
  129. {
  130. if (plvcd->nmcd.dwItemSpec%2 && (style&SWLVS_ALTERNATEITEMS) && config_use_alternate_colors)
  131. {
  132. rgbFg = WADlg_getColor(WADLG_ITEMFG2);
  133. rgbBk = WADlg_getColor(WADLG_ITEMBG2);
  134. }
  135. else
  136. {
  137. rgbBk = plvcd->clrTextBk;
  138. rgbFg = plvcd->clrText;
  139. }
  140. }
  141. }
  142. else
  143. {
  144. #define BLENDER(fg,bg) (RGB((GetRValue(fg)+GetRValue(bg))/2,(GetGValue(fg)+GetGValue(bg))/2,(GetBValue(fg)+GetBValue(bg))/2))
  145. rgbFg = BLENDER(WADlg_getColor(WADLG_INACT_SELBAR_FGCOLOR),WADlg_getColor(WADLG_WNDBG));
  146. rgbBk = WADlg_getColor(WADLG_ITEMBG);
  147. }
  148. plvcd->clrTextBk = rgbBk;
  149. if (plvcd->nmcd.dwItemSpec == currentItem)
  150. plvcd->clrText = currentColor;
  151. else
  152. plvcd->clrText = rgbFg;
  153. if (MLSkinnedWnd_EnableReflection(hwndFrom, FALSE))
  154. {
  155. *pResult = SendMessageW(hwndFrom, WM_NOTIFY, (WPARAM)plvcd->nmcd.hdr.idFrom, (LPARAM)plvcd);
  156. MLSkinnedWnd_EnableReflection(hwndFrom, TRUE);
  157. }
  158. else *pResult = CDRF_DODEFAULT;
  159. if (!bFullRowSelect) *pResult |= CDRF_NOTIFYSUBITEMDRAW;
  160. if (bSelected && 0 == (CDRF_SKIPDEFAULT & *pResult))
  161. {
  162. plvcd->nmcd.uItemState &= ~CDIS_SELECTED;
  163. restoreSelect = TRUE;
  164. *pResult |= CDRF_NOTIFYPOSTPAINT;
  165. }
  166. return TRUE;
  167. case CDDS_ITEMPOSTPAINT:
  168. if(restoreSelect)
  169. {
  170. plvcd->nmcd.uItemState |= CDIS_SELECTED;
  171. restoreSelect = FALSE;
  172. }
  173. break;
  174. case (CDDS_SUBITEM | CDDS_ITEMPREPAINT):
  175. if (restoreSelect && (bFullRowSelect || 0 == plvcd->iSubItem))
  176. {
  177. plvcd->clrTextBk = rgbBkSel;
  178. plvcd->clrText = rgbFgSel;
  179. }
  180. else
  181. {
  182. plvcd->clrTextBk = rgbBk;
  183. plvcd->clrText = rgbFg;
  184. }
  185. if (plvcd->nmcd.dwItemSpec == currentItem)
  186. plvcd->clrText = currentColor;
  187. break;
  188. }
  189. return FALSE;
  190. }
  191. BOOL SkinnedListView::OnReflectedNotify(HWND hwndFrom, INT idCtrl, NMHDR *pnmh, LRESULT *pResult)
  192. {
  193. switch(pnmh->code)
  194. {
  195. case NM_CUSTOMDRAW:
  196. return OnCustomDraw(hwndFrom, (NMLVCUSTOMDRAW*)pnmh, pResult);
  197. case LVN_ITEMCHANGED:
  198. {
  199. NMLISTVIEW *plv = (NMLISTVIEW*)pnmh;
  200. if (((LVIS_SELECTED | LVIS_FOCUSED) & plv->uNewState) != ((LVIS_SELECTED | LVIS_FOCUSED) & plv->uOldState) &&
  201. plv->iSubItem == 0 && plv->iItem >= 0 &&
  202. LVS_REPORT == (LVS_TYPEMASK & GetWindowLongPtrW(hwnd, GWL_STYLE)) &&
  203. 0 == (LVS_EX_FULLROWSELECT & CallPrevWndProc(LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0L)))
  204. {
  205. RECT rc;
  206. ListView_GetItemRect(hwnd, plv->iItem, &rc, LVIR_ICON | ((LVIS_FOCUSED & plv->uNewState) ? LVIR_LABEL : 0));
  207. if (rc.left != rc.right) InvalidateRect(hwnd, &rc, FALSE);
  208. }
  209. }
  210. break;
  211. }
  212. return FALSE;
  213. }
  214. LRESULT SkinnedListView::OnEraseBackground(HDC hdc)
  215. {
  216. HWND hwndHeader;
  217. hwndHeader = ListView_GetHeader(hwnd);
  218. if (hdc && hwndHeader && IsWindowVisible(hwndHeader))
  219. {
  220. RECT rc;
  221. if(GetClientRect(hwndHeader, &rc))
  222. {
  223. MapWindowPoints(hwndHeader, hwnd, (POINT*)&rc, 2);
  224. ExcludeClipRect(hdc, rc.left, rc.top, rc.right, rc.bottom);
  225. }
  226. }
  227. return __super::OnEraseBackground(hdc);
  228. }
  229. BOOL SkinnedListView::OnMediaLibraryIPC(INT msg, INT_PTR param, LRESULT *pResult)
  230. {
  231. HWND hwndHeader;
  232. switch(msg)
  233. {
  234. case ML_IPC_SKINNEDLISTVIEW_DISPLAYSORT:
  235. hwndHeader = (HWND)CallPrevWndProc(LVM_GETHEADER, 0, 0L);
  236. *pResult = (hwndHeader) ? SENDMLIPC(hwndHeader, ML_IPC_SKINNEDHEADER_DISPLAYSORT, (WPARAM)param) : 0L;
  237. return TRUE;
  238. case ML_IPC_SKINNEDLISTVIEW_GETSORT:
  239. hwndHeader = (HWND)CallPrevWndProc(LVM_GETHEADER, 0, 0L);
  240. *pResult = (hwndHeader) ? SENDMLIPC(hwndHeader, ML_IPC_SKINNEDHEADER_GETSORT, 0) : 0L;
  241. return TRUE;
  242. case ML_IPC_SKINNEDLISTVIEW_SETCURRENT:
  243. currentItem = (INT)param;
  244. InvalidateRect(hwnd, NULL, FALSE);
  245. UpdateWindow(hwnd);
  246. return TRUE;
  247. }
  248. return __super::OnMediaLibraryIPC(msg, param, pResult);
  249. }
  250. static BOOL
  251. SkinnedListView_OverrideEdgeItemNavigation(HWND hwnd, unsigned int vkCode)
  252. {
  253. int iItem, iNextItem, iTest;
  254. iItem = (int)SendMessageW(hwnd, LVM_GETNEXTITEM, (WPARAM)-1, (LPARAM)(LVNI_ALL | LVNI_FOCUSED));
  255. if (-1 == iItem)
  256. return FALSE;
  257. if (VK_RIGHT == vkCode)
  258. {
  259. iNextItem = (int)SendMessageW(hwnd, LVM_GETNEXTITEM, (WPARAM)iItem, (LPARAM)(LVNI_TORIGHT));
  260. if (iNextItem != iItem)
  261. return FALSE;
  262. iNextItem = iItem;
  263. for(;;)
  264. {
  265. iTest = (int)SendMessageW(hwnd, LVM_GETNEXTITEM, (WPARAM)iNextItem, (LPARAM)(LVNI_TOLEFT));
  266. if (-1 == iTest || iTest == iNextItem)
  267. break;
  268. iNextItem = iTest;
  269. }
  270. iNextItem = (int)SendMessageW(hwnd, LVM_GETNEXTITEM, (WPARAM)iNextItem, (LPARAM)(LVNI_BELOW));
  271. if (iNextItem == iTest)
  272. return FALSE;
  273. }
  274. else if (VK_LEFT == vkCode)
  275. {
  276. iNextItem = (int)SendMessageW(hwnd, LVM_GETNEXTITEM, (WPARAM)iItem, (LPARAM)(LVNI_TOLEFT));
  277. if (iNextItem != iItem)
  278. return FALSE;
  279. iNextItem = (int)SendMessageW(hwnd, LVM_GETNEXTITEM, (WPARAM)iItem, (LPARAM)(LVNI_ABOVE));
  280. if (-1 != iNextItem && iItem != iNextItem)
  281. {
  282. for(;;)
  283. {
  284. iTest = (int)SendMessageW(hwnd, LVM_GETNEXTITEM, (WPARAM)iNextItem, (LPARAM)(LVNI_TORIGHT));
  285. if (-1 == iTest || iTest == iNextItem)
  286. break;
  287. iNextItem = iTest;
  288. }
  289. }
  290. }
  291. else
  292. return FALSE;
  293. if (-1 == iNextItem || iItem == iNextItem)
  294. return FALSE;
  295. else
  296. {
  297. LVITEM item;
  298. BOOL ctrlPressed, shiftPressed;
  299. ctrlPressed = (0 != (0x8000 & GetAsyncKeyState(VK_CONTROL)));
  300. shiftPressed = (0 != (0x8000 & GetAsyncKeyState(VK_SHIFT)));
  301. if (FALSE == shiftPressed && FALSE == ctrlPressed)
  302. {
  303. item.state = 0;
  304. item.stateMask = LVIS_SELECTED;
  305. SendMessageW(hwnd, LVM_SETITEMSTATE, (WPARAM)-1, (LPARAM)&item);
  306. }
  307. item.stateMask = LVIS_FOCUSED;
  308. item.state = 0;
  309. SendMessageW(hwnd, LVM_SETITEMSTATE, (WPARAM)iItem, (LPARAM)&item);
  310. item.state = LVIS_FOCUSED;
  311. if (FALSE == ctrlPressed)
  312. {
  313. item.state |= LVIS_SELECTED;
  314. item.stateMask |= LVIS_SELECTED;
  315. }
  316. SendMessageW(hwnd, LVM_SETITEMSTATE, (WPARAM)iNextItem, (LPARAM)&item);
  317. SendMessageW(hwnd, LVM_ENSUREVISIBLE, (WPARAM)iNextItem, (LPARAM)FALSE);
  318. }
  319. return TRUE;
  320. }
  321. void SkinnedListView::OnKeyDown(UINT vkCode, UINT flags)
  322. {
  323. switch(vkCode)
  324. {
  325. case VK_LEFT:
  326. case VK_RIGHT:
  327. {
  328. unsigned long windowStyle;
  329. windowStyle = GetWindowLongPtrW(hwnd, GWL_STYLE);
  330. if (LVS_REPORT == (LVS_TYPEMASK & windowStyle))
  331. {
  332. if (0 != IsHorzBarHidden())
  333. {
  334. HWND hParent = GetParent(hwnd);
  335. if (NULL != hParent)
  336. {
  337. NMLVKEYDOWN lvkd;
  338. lvkd.hdr.code = LVN_KEYDOWN;
  339. lvkd.hdr.hwndFrom = hwnd;
  340. lvkd.hdr.idFrom = (UINT)(UINT_PTR)GetWindowLongPtr(hwnd, GWLP_ID);
  341. lvkd.wVKey = vkCode;
  342. SendMessage(hParent, WM_NOTIFY, (WPARAM)lvkd.hdr.idFrom, (LPARAM)&lvkd);
  343. }
  344. vkCode = 0;
  345. }
  346. }
  347. else if (LVS_ICON == (LVS_TYPEMASK & windowStyle))
  348. {
  349. if (FALSE != SkinnedListView_OverrideEdgeItemNavigation(hwnd, vkCode))
  350. {
  351. vkCode = 0;
  352. }
  353. }
  354. }
  355. break;
  356. case VK_SPACE:
  357. if (0 != (SWLVS_SELALWAYS & style))
  358. {
  359. UINT windowStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
  360. if (0 != (LVS_SINGLESEL & windowStyle) &&
  361. 0 != (0x8000 & GetAsyncKeyState(VK_CONTROL)))
  362. {
  363. vkCode = 0;
  364. }
  365. }
  366. break;
  367. }
  368. __super::WindowProc(WM_KEYDOWN, (WPARAM)vkCode, (LPARAM)flags);
  369. }
  370. void SkinnedListView::TryAttachHeader(void)
  371. {
  372. if (0 != (LVIF_HEADERATTACHED & listFlags)) return;
  373. DWORD ws = GetWindowLongPtrW(hwnd, GWL_STYLE);
  374. if (LVS_REPORT == (LVS_TYPEMASK & ws) && 0 == (LVS_NOCOLUMNHEADER & ws))
  375. {
  376. HWND hHeader = (HWND)CallPrevWndProc(LVM_GETHEADER, 0, 0L);
  377. if (hHeader)
  378. {
  379. SkinWindow(hHeader, SWS_USESKINFONT | SWS_USESKINCOLORS | SWS_USESKINCURSORS);
  380. listFlags |= LVIF_HEADERATTACHED;
  381. }
  382. }
  383. }
  384. void SkinnedListView::OnLButtonDown(UINT uFlags, POINTS pts)
  385. {
  386. if (0 != (SWLVS_SELALWAYS & style))
  387. {
  388. LVHITTESTINFO ht;
  389. POINTSTOPOINT(ht.pt, pts);
  390. INT index = (INT)CallPrevWndProc(LVM_HITTEST, 0, (LPARAM)&ht);
  391. if (-1 == index)
  392. {
  393. if (hwnd != GetFocus() &&
  394. 0 != (LVS_EX_FULLROWSELECT & CallPrevWndProc(LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0L)))
  395. {
  396. SetFocus(hwnd);
  397. }
  398. return;
  399. }
  400. }
  401. __super::WindowProc(WM_LBUTTONDOWN, (WPARAM)uFlags, *((LPARAM*)&pts));
  402. }
  403. void SkinnedListView::OnRButtonDown(UINT uFlags, POINTS pts)
  404. {
  405. if (0 != (SWLVS_SELALWAYS & style))
  406. {
  407. LVHITTESTINFO ht;
  408. POINTSTOPOINT(ht.pt, pts);
  409. INT index = (INT)CallPrevWndProc(LVM_HITTEST, 0, (LPARAM)&ht);
  410. if (-1 == index)
  411. {
  412. return;
  413. }
  414. }
  415. __super::WindowProc(WM_RBUTTONDOWN, (WPARAM)uFlags, *((LPARAM*)&pts));
  416. }
  417. LRESULT SkinnedListView::OnGetDlgCode(UINT vkCode, MSG* pMsg)
  418. {
  419. if (NULL != pMsg)
  420. {
  421. switch(vkCode)
  422. {
  423. case VK_RETURN:
  424. SendMessage(hwnd, pMsg->message, pMsg->wParam, pMsg->lParam);
  425. return 0;
  426. }
  427. }
  428. LRESULT result = __super::WindowProc(WM_GETDLGCODE, (WPARAM)vkCode, (LPARAM)pMsg);
  429. if (NULL == pMsg)
  430. {
  431. result |= DLGC_WANTMESSAGE;
  432. }
  433. return result;
  434. }
  435. LRESULT SkinnedListView::WindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
  436. {
  437. switch(uMsg)
  438. {
  439. case REFLECTED_NOTIFY: return OnReflectedNotify(((REFLECTPARAM*)lParam)->hwndFrom, (INT)wParam, (NMHDR*)((REFLECTPARAM*)lParam)->lParam, &((REFLECTPARAM*)lParam)->result);
  440. // custom handling of this allows us to handle disabled listview controls correctly
  441. // so we don't have the part skinned / part OS colouring which happened before
  442. case WM_ENABLE: InvalidateRect(hwnd, NULL, TRUE); return 1;
  443. case WM_SETFONT:
  444. HWND hwndHeader;
  445. hwndHeader = ListView_GetHeader(hwnd);
  446. if (hwndHeader)
  447. {
  448. SendMessageW(hwndHeader, WM_SETFONT, wParam, lParam);
  449. MLSkinnedHeader_SetHeight(hwndHeader, -1);
  450. }
  451. break;
  452. case WM_LBUTTONDOWN: OnLButtonDown((UINT)wParam, MAKEPOINTS(lParam)); return 0;
  453. case WM_RBUTTONDOWN: OnRButtonDown((UINT)wParam, MAKEPOINTS(lParam)); return 0;
  454. case WM_KEYDOWN: OnKeyDown((UINT)wParam, (UINT)lParam); return 0;
  455. case LVM_INSERTCOLUMNA:
  456. case LVM_INSERTCOLUMNW:
  457. {
  458. LRESULT r = __super::WindowProc(uMsg, wParam, lParam);
  459. TryAttachHeader();
  460. return r;
  461. }
  462. break;
  463. case WM_GETDLGCODE: return OnGetDlgCode((UINT)wParam, (MSG*)lParam);
  464. }
  465. return __super::WindowProc(uMsg, wParam, lParam);
  466. }