1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837 |
- #include "main.h"
- #include "../Winamp/gen.h"
- #include "../gen_ml/ml.h"
- #include "../gen_ml/ml_ipc_0313.h"
- #define WM_EX_GETREALLIST (WM_USER + 0x01)
- #define WM_EX_UNLOCKREDRAW (WM_USER + 0x02)
- #define WM_EX_UPDATESCROLLINFO (WM_USER + 0x03)
- #define WM_EX_GETCOUNTPERPAGE (WM_USER + 0x04)
- #define LVN_EX_SIZECHANGED (LVN_LAST)
- #define IWF_NORMAL 0x0000
- #define IWF_ERASE 0x0001
- #define IWF_UPDATENOW 0x0002
- #define IWF_FRAME 0x0004
- typedef enum ScrollPosFlags
- {
- SPF_NORMAL = 0,
- SPF_NOREDRAW = (1 << 0),
- SPF_FORCE = (1 << 1),
- SPF_RELATIVE = (1 << 2),
- } ScrollPosFlags;
- DEFINE_ENUM_FLAG_OPERATORS(ScrollPosFlags);
- BOOL
- CopyListColumnToHeaderItem(const LVCOLUMNW *column, HDITEMW *item);
- BOOL
- CopyHeaderItemToListColumn(const HDITEMW *item, LVCOLUMNW *column);
- typedef enum PostProcessKeyCommands
- {
- PostProcessKeyCmd_Nothing = 0,
- PostProcessKeyCmd_UpdateScrollPos = (1 << 0),
- PostProcessKeyCmd_EnsureFocusVisible = (1 << 1),
- } PostProcessKeyCommands;
- DEFINE_ENUM_FLAG_OPERATORS(PostProcessKeyCommands);
- typedef struct SmoothScrollList
- {
- unsigned int itemHeight;
- unsigned int textHeight;
- long viewHeight;
- unsigned int listFontHeight;
- unsigned int headerFontHeight;
- int wheelCarryover;
- } SmoothScrollList;
- #define GetUserData(hwnd) ((SmoothScrollList*)(LONG_PTR)GetWindowLongPtrW(hwnd, GWLP_USERDATA))
- static LRESULT
- SubclassedListView_CallPrevWndProc(HWND hwnd, unsigned int message, WPARAM wParam, LPARAM lParam)
- {
- WNDPROC windowProc;
- windowProc = (WNDPROC)(LONG_PTR)GetWindowLongPtrW(hwnd,GWLP_USERDATA);
- if (NULL == windowProc)
- return DefWindowProcW(hwnd, message, wParam, lParam);
- return CallWindowProcW(windowProc, hwnd, message,wParam,lParam);
- }
- static BOOL
- GetViewRect(HWND hwnd, RECT *prc)
- {
- HWND headerWindow;
- GetClientRect(hwnd, prc);
- headerWindow = GetDlgItem(hwnd, 3);
- if (NULL != headerWindow)
- {
- RECT rh;
- GetWindowRect(headerWindow, &rh);
- MapWindowPoints(HWND_DESKTOP, headerWindow, ((POINT*)&rh) + 1, 1);
- prc->top = rh.bottom;
- }
- if (prc->right < prc->left)
- prc->right = prc->left;
- if (prc->bottom < prc->top)
- prc->bottom = prc->top;
-
- return TRUE;
- }
- static int
- SmoothScrollList_GetScrollPosFromItem(HWND hwnd, int iItem)
- {
- HWND listWindow;
- RECT listRect, viewRect;
- int pos;
- int count;
- pos = 0;
-
- if (FALSE == GetViewRect(hwnd, &viewRect))
- return 0;
- listWindow = GetDlgItem(hwnd, 2);
- if (NULL == listWindow ||
- FALSE == GetWindowRect(listWindow, &listRect))
- {
- return 0;
- }
- MapWindowPoints(HWND_DESKTOP, hwnd, (POINT*)&listRect, 2);
- count = (int)SendMessageW(listWindow, LVM_GETITEMCOUNT, 0, 0L);
- if (0 != count)
- {
- SmoothScrollList *self;
- if (iItem < 0)
- iItem = 0;
-
- if (iItem >= count)
- iItem = count - 1;
- self = GetUserData(hwnd);
- if (NULL != self)
- pos = iItem * self->itemHeight;
- }
-
- pos += (viewRect.top - listRect.top);
- return pos;
- }
- static BOOL
- UpdateScrollInfo(HWND hwndView, UINT fFlags, BOOL bRedraw)
- {
- RECT rv;
- HWND hwndList;
- SCROLLINFO si;
- BOOL needUpdate;
- BOOL needRedraw;
- HRGN regionUpdate, regionTemp;
- SmoothScrollList* s = GetUserData(hwndView);
- hwndList = GetDlgItem(hwndView, 2);
- if (!s || !hwndList ) return FALSE;
- if (FALSE!= bRedraw)
- {
- GetWindowRect(hwndView, &rv);
- MapWindowPoints(HWND_DESKTOP, hwndView, (POINT*)&rv, 2);
- regionUpdate = CreateRectRgnIndirect(&rv);
- GetClientRect(hwndView, &rv);
- regionTemp = CreateRectRgnIndirect(&rv);
- CombineRgn(regionUpdate, regionUpdate, regionTemp, RGN_DIFF);
- }
- else
- {
- regionUpdate = NULL;
- regionTemp = NULL;
- }
- si.cbSize = sizeof(SCROLLINFO);
- si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
-
- if (!GetScrollInfo(hwndView, SB_VERT, &si))
- return FALSE;
-
- if (FALSE == GetViewRect(hwndView, &rv))
- SetRectEmpty(&rv);
- needUpdate = FALSE;
- needRedraw = FALSE;
-
- if (SIF_RANGE & fFlags)
- {
- unsigned int count, nPage, nMax;
- nPage = rv.bottom - rv.top;
- count = (INT)SendMessageW(hwndList, LVM_GETITEMCOUNT, 0, 0L);
- nMax = count * s->itemHeight;
- if (si.nPage != nPage || si.nMax != nMax)
- {
- BOOL forcePos;
- unsigned int windowStyle;
- si.fMask = SIF_PAGE | SIF_RANGE;
- si.nPage = nPage;
- si.nMax = nMax;
- windowStyle = GetWindowLongPtrW(hwndView, GWL_STYLE);
- SetScrollInfo(hwndView, SB_VERT, &si, FALSE);
- needUpdate = TRUE;
- needRedraw = FALSE;
- forcePos = FALSE;
- if (nPage >= nMax &&
- 0 != (WS_VSCROLL & windowStyle))
- {
- SetWindowLongPtrW(hwndView, GWL_STYLE, windowStyle & ~WS_VSCROLL);
- RECT rc;
- HWND hwndHeader;
- // MLSkinnedScrollWnd_UpdateBars(hwndView, bRedraw);
- GetClientRect(hwndView, &rc);
- hwndHeader = GetDlgItem(hwndView, 3);
- if (hwndHeader)
- {
- HDLAYOUT headerLayout;
- WINDOWPOS headerPos;
- headerLayout.prc = &rc;
- headerLayout.pwpos = &headerPos;
-
- if (FALSE != SendMessageW(hwndHeader, HDM_LAYOUT, 0, (LPARAM)&headerLayout))
- {
- headerPos.flags |= SWP_NOREDRAW | SWP_NOCOPYBITS;
- headerPos.flags &= ~SWP_NOZORDER;
- headerPos.hwndInsertAfter = HWND_TOP;
- SetWindowPos(hwndHeader, headerPos.hwndInsertAfter, headerPos.x, headerPos.y,
- headerPos.cx, headerPos.cy, headerPos.flags);
- InvalidateRect(hwndHeader, NULL, FALSE);
- }
- }
- rv.right = rc.right;
- forcePos = TRUE;
- needUpdate = FALSE;
- needRedraw = TRUE;
- }
- if (nPage >= nMax || forcePos)
- {
- RECT rl;
- GetWindowRect(hwndList, &rl);
- MapWindowPoints(HWND_DESKTOP, hwndView, (POINT*)&rl, 2);
- if (rv.top != rl.top || forcePos)
- {
- SetWindowPos(hwndList, NULL, rv.left, rv.top, rv.right - rv.left, rv.bottom - rv.top,
- SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW | SWP_NOCOPYBITS);
- needRedraw = TRUE;
- }
- }
- }
- }
- if (SIF_POS & fFlags)
- {
- INT nTop;
- nTop = (INT)SendMessageW(hwndList, LVM_GETTOPINDEX, 0, 0L);
- nTop = SmoothScrollList_GetScrollPosFromItem(hwndView, nTop);
- if(si.nMax > 0)
- {
- if (nTop >= (si.nMax - (int)si.nPage))
- nTop = (si.nMax - si.nPage) + 1;
- }
- else
- nTop = 0;
- if (nTop < si.nMin)
- nTop = si.nMin;
-
- if (si.nPos != nTop)
- {
- si.fMask = SIF_POS;
- si.nPos = nTop;
-
- SetScrollInfo(hwndView, SB_VERT, &si, (FALSE == needRedraw && FALSE != bRedraw));
- needUpdate = TRUE;
- }
- }
- if (FALSE != needUpdate)
- MLSkinnedScrollWnd_UpdateBars(hwndView, (FALSE == needRedraw && FALSE != bRedraw));
- if (FALSE != bRedraw && FALSE != needRedraw)
- {
- HRGN regionTemp2;
- GetWindowRect(hwndView, &rv);
- MapWindowPoints(HWND_DESKTOP, hwndView, (POINT*)&rv, 2);
- SetRectRgn(regionTemp, rv.left, rv.top, rv.right, rv.bottom);
- GetClientRect(hwndView, &rv);
- regionTemp2 = CreateRectRgnIndirect(&rv);
- CombineRgn(regionTemp, regionTemp, regionTemp2, RGN_DIFF);
- CombineRgn(regionUpdate, regionUpdate, regionTemp, RGN_OR);
- DeleteObject(regionTemp2);
- RedrawWindow(hwndView, NULL, regionUpdate, RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_FRAME);
- }
- if (NULL != regionUpdate)
- DeleteObject(regionUpdate);
- if (NULL != regionTemp)
- DeleteObject(regionTemp);
- return TRUE;
- }
- static BOOL
- SmoothScrollList_SetScrollPos(HWND hwnd, int position, ScrollPosFlags flags)
- {
- SmoothScrollList *self;
- HWND listWindow;
- BOOL invalidate, failed;
- unsigned long viewStyle;
- int y, scrollPos;
- RECT rv, rl;
- SCROLLINFO si;
-
- listWindow = GetDlgItem(hwnd, 2);
- if (NULL == listWindow)
- return FALSE;
- self = GetUserData(hwnd);
- if (NULL == self)
- return FALSE;
-
- si.cbSize = sizeof(si);
- si.fMask = SIF_POS | SIF_RANGE | SIF_PAGE;
- if (FALSE == GetScrollInfo(hwnd, SB_VERT, &si))
- return FALSE;
- scrollPos = si.nPos;
-
- viewStyle = GetWindowLongPtrW(hwnd, GWL_STYLE);
-
- invalidate = FALSE;
- failed = FALSE;
- y = 0;
- if (0 != (SPF_RELATIVE & flags))
- {
- position = si.nPos + position;
- if (si.nPos > (si.nMax - (int)si.nPage))
- position -= (si.nPos - (si.nMax - (int)si.nPage));
- }
- if (position < si.nMin)
- position = si.nMin;
-
- if (position > (si.nMax - (INT)si.nPage + 1))
- position = si.nMax - si.nPage + 1;
-
- if (position == si.nPos && 0 == (SPF_FORCE & flags))
- return TRUE;
- if (FALSE == GetViewRect(hwnd, &rv))
- SetRectEmpty(&rv);
- if (FALSE == GetWindowRect(listWindow, &rl))
- SetRectEmpty(&rl);
- MapWindowPoints(HWND_DESKTOP, hwnd, (POINT*)&rl, 2);
- if (0 != (WS_VISIBLE & viewStyle))
- SetWindowLongPtrW(hwnd, GWL_STYLE, viewStyle & ~WS_VISIBLE);
-
- if (si.nMin == position)
- {
- if (rl.top != rv.top || rl.bottom != rv.bottom || rl.left != rv.left || rl.right != rv.right)
- {
- SetWindowPos(listWindow, NULL, rv.left, rv.top, rv.right - rv.left, rv.bottom - rv.top,
- SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW | SWP_NOCOPYBITS);
- invalidate = TRUE;
- }
- if (0 != (int)SendMessageW(listWindow, LVM_GETITEMCOUNT, 0, 0L))
- {
- RECT rect;
- rect.left = LVIR_BOUNDS;
- if (FALSE != SendMessageW(listWindow, LVM_GETITEMRECT, 0, (LPARAM)&rect) &&
- 0 != rect.top)
- {
- int scrollY;
- scrollY = rect.top;
- failed = !SendMessageW(listWindow, LVM_SCROLL, 0, scrollY);
- invalidate = TRUE;
- }
- }
- }
- else
- {
- int iTop, iPos;
-
- iTop = (int)SendMessageW(listWindow, LVM_GETTOPINDEX, 0, 0L);
- if (position > (si.nMax - (int)si.nPage))
- position = (si.nMax - si.nPage);
-
- iPos = position/self->itemHeight;
- y = (position - iPos*self->itemHeight);
- if (iTop > iPos)
- {
- failed = !SendMessageW(listWindow, LVM_SCROLL, 0, (iPos - iTop) * self->itemHeight);
- invalidate = TRUE;
- }
- if (rl.top != rv.top + y || rl.bottom != rv.bottom || rl.left != rv.left || rl.right != rv.right)
- {
- SetWindowPos(listWindow, NULL, rv.left, rv.top - y, rv.right - rv.left, rv.bottom - rv.top + y,
- SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW | SWP_NOCOPYBITS);
- invalidate = TRUE;
- }
- if (iTop < iPos)
- {
- failed = !SendMessageW(listWindow, LVM_SCROLL, 0, (iPos - iTop)*self->itemHeight);
- invalidate = TRUE;
- }
- }
- if (FALSE == failed)
- {
- if (position == si.nMax - si.nPage && 0 != si.nMax)
- position++;
- if (scrollPos != position)
- {
- si.nPos = position;
- si.fMask = SIF_POS;
- SetScrollInfo(hwnd, SB_VERT, &si, (0 == (SPF_NOREDRAW & flags)));
- }
-
- }
- if (0 != (WS_VISIBLE & viewStyle))
- {
- viewStyle = GetWindowLongPtrW(hwnd, GWL_STYLE);
- if (0 == (WS_VISIBLE & viewStyle))
- {
- viewStyle |= WS_VISIBLE;
- SetWindowLongPtrW(hwnd, GWL_STYLE, viewStyle);
- }
- if (0 == (SPF_NOREDRAW & flags) &&
- FALSE != invalidate)
- {
- InvalidateRect(listWindow, NULL, TRUE);
- }
- }
-
- return TRUE;
- }
- static BOOL
- SmoothScrollList_EnsureVisible(HWND hwnd, int iItem, BOOL partialOk)
- {
- int itemTop, itemBottom;
- int pageTop, pageBottom, delta;
- SCROLLINFO scrollInfo;
- SmoothScrollList *self;
- if (NULL == hwnd || iItem < 0)
- return FALSE;
- self = GetUserData(hwnd);
- if (NULL == self)
- return FALSE;
-
- scrollInfo.cbSize = sizeof(scrollInfo);
- scrollInfo.fMask = SIF_POS | SIF_PAGE;
- if (FALSE == GetScrollInfo(hwnd, SB_VERT, &scrollInfo))
- return FALSE;
- itemTop = iItem * self->itemHeight;
- itemBottom = itemTop + self->itemHeight;
- pageTop = scrollInfo.nPos;
- pageBottom = pageTop + scrollInfo.nPage;
- if (FALSE != partialOk)
- {
- if (itemTop < pageBottom &&
- itemBottom > pageTop)
- {
- return TRUE;
- }
- }
- else
- {
- if (itemTop >= pageTop &&
- itemBottom <= pageBottom)
- {
- return TRUE;
- }
- }
- if (itemTop < pageTop)
- delta = itemTop - pageTop;
- else
- {
- delta = itemBottom - pageBottom;
- if ((itemTop - delta) < pageTop)
- delta = itemTop - pageTop;
- }
- if (FALSE == SmoothScrollList_SetScrollPos(hwnd, delta, SPF_RELATIVE | SPF_FORCE))
- return FALSE;
- MLSkinnedScrollWnd_UpdateBars(hwnd, TRUE);
- return TRUE;
- }
- static BOOL
- SmoothScrollList_PreProcessKey(HWND hwnd, unsigned int vKey, unsigned int keyFlags, PostProcessKeyCommands *postProcessCommands)
- {
- HWND listWindow;
- RECT viewRect;
- SmoothScrollList *self;
- int iItem, iNextItem, count;
- BOOL shortView;
- if (NULL != postProcessCommands)
- *postProcessCommands = PostProcessKeyCmd_Nothing;
- switch(vKey)
- {
- case VK_UP:
- case VK_DOWN:
- case VK_HOME:
- case VK_END:
- case VK_PRIOR:
- case VK_NEXT:
- break;
- default:
- return TRUE;
- }
- if (NULL == hwnd || FALSE == GetViewRect(hwnd, &viewRect))
- return FALSE;
-
- self = GetUserData(hwnd);
- if (NULL == self)
- return FALSE;
- listWindow = GetDlgItem(hwnd, 2);
- if (NULL == listWindow)
- return FALSE;
- iItem = (int)SendMessageW(listWindow, LVM_GETNEXTITEM, (WPARAM)-1, (LPARAM)(LVNI_ALL | LVNI_FOCUSED));
- if (-1 == iItem)
- return FALSE;
- count = (int)SendMessageW(listWindow, LVM_GETITEMCOUNT, 0, 0L);
- iNextItem = iItem;
- shortView = ((viewRect.bottom - viewRect.top) < (long)self->itemHeight);
- switch(vKey)
- {
- case VK_UP:
- if (iNextItem > 0)
- iNextItem--;
-
- if (FALSE != shortView)
- {
- if (NULL != postProcessCommands)
- *postProcessCommands |= PostProcessKeyCmd_EnsureFocusVisible;
- }
- break;
-
- case VK_DOWN:
- if (FALSE == shortView)
- {
- if ((iNextItem + 1) < count)
- iNextItem++;
- }
- else
- {
- if (NULL != postProcessCommands)
- *postProcessCommands |= PostProcessKeyCmd_EnsureFocusVisible;
- }
- break;
- case VK_HOME:
-
- if (FALSE == shortView)
- {
- iNextItem = 0;
- }
- else
- {
- iNextItem = 1;
- if (NULL != postProcessCommands)
- *postProcessCommands |= PostProcessKeyCmd_UpdateScrollPos;
- }
- break;
- case VK_END:
- if (FALSE == shortView)
- {
- iNextItem = count - 1;
- }
- else
- {
- iNextItem = -1;
- if (NULL != postProcessCommands)
- *postProcessCommands |= PostProcessKeyCmd_EnsureFocusVisible;
- }
- break;
- case VK_PRIOR:
- {
- RECT listRect;
-
- GetWindowRect(listWindow, &listRect);
- MapWindowPoints(HWND_DESKTOP, hwnd, (POINT*)&listRect, 2);
- if (listRect.top != viewRect.top)
- SmoothScrollList_SetScrollPos(hwnd, listRect.top - viewRect.top, SPF_RELATIVE);
-
- if (FALSE == shortView)
- {
- iNextItem = (viewRect.bottom - viewRect.top)/self->itemHeight;
- iNextItem = iItem - iNextItem;
- if (iNextItem < 0)
- iNextItem = 0;
- }
- else
- {
- if (0 == iItem)
- iNextItem = 1;
- if (NULL != postProcessCommands)
- *postProcessCommands |= PostProcessKeyCmd_UpdateScrollPos;
- }
-
- }
- break;
- case VK_NEXT:
- {
- RECT listRect;
- int reminder;
-
- GetWindowRect(listWindow, &listRect);
- MapWindowPoints(HWND_DESKTOP, hwnd, (POINT*)&listRect, 2);
- reminder = (listRect.bottom - listRect.top)%self->itemHeight;
- if (0 != reminder)
- SmoothScrollList_SetScrollPos(hwnd, self->itemHeight - reminder, SPF_RELATIVE);
- if (FALSE == shortView)
- {
- iNextItem = (viewRect.bottom - viewRect.top)/self->itemHeight;
- iNextItem = iItem + iNextItem;
- if (iNextItem >= count)
- iNextItem = count - 1;
- }
- else
- {
- if (NULL != postProcessCommands)
- *postProcessCommands |= (PostProcessKeyCmd_UpdateScrollPos | PostProcessKeyCmd_EnsureFocusVisible);
- }
-
- }
- break;
- }
- if (iNextItem >= 0 && iNextItem < count)
- SmoothScrollList_EnsureVisible(hwnd, iNextItem, FALSE);
-
- return TRUE;
- }
- static void
- SmoothScrollList_PostProcessKey(HWND hwnd, unsigned int vKey, unsigned int keyFlags, PostProcessKeyCommands processCommands)
- {
- if (0 != (PostProcessKeyCmd_UpdateScrollPos & processCommands))
- UpdateScrollInfo(hwnd, SIF_POS, TRUE);
- if (0 != (PostProcessKeyCmd_EnsureFocusVisible & processCommands))
- {
- HWND listWindow = GetDlgItem(hwnd, 2);
- if (NULL != listWindow)
- {
- int iItem = (int)SendMessageW(listWindow, LVM_GETNEXTITEM, (WPARAM)-1, (LPARAM)(LVNI_ALL | LVNI_FOCUSED));
- if (-1 != iItem)
- {
- SmoothScrollList_EnsureVisible(hwnd, iItem, FALSE);
- }
- }
- }
- }
- static void
- SmoothScrollList_UpdateFontMetrics(HWND hwnd, BOOL redraw)
- {
- SmoothScrollList *self;
- HWND controlWindow;
- unsigned int windowStyle;
- HFONT font, prevFont;
- HDC hdc;
- TEXTMETRICW textMetrics;
- unsigned int fontHeight;
- self = GetUserData(hwnd);
- if (NULL == self)
- return;
- windowStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
- if(0 != (WS_VISIBLE & windowStyle))
- SetWindowLongPtrW(hwnd, GWL_STYLE, windowStyle & ~WS_VISIBLE);
-
- hdc = GetDCEx(hwnd, NULL, DCX_CACHE | DCX_NORESETATTRS);
- if (NULL != hdc)
- prevFont = (HFONT)GetCurrentObject(hdc, OBJ_FONT);
- else
- prevFont = NULL;
-
- controlWindow = GetDlgItem(hwnd, 3);
- if (NULL != controlWindow)
- {
- font = (HFONT)SendMessageW(controlWindow, WM_GETFONT, 0, 0L);
- fontHeight = 0;
- if (NULL != hdc)
- {
- SelectObject(hdc, font);
- if (FALSE != GetTextMetricsW(hdc, &textMetrics))
- fontHeight = textMetrics.tmHeight;
- }
- if (self->headerFontHeight != fontHeight)
- {
- self->headerFontHeight = fontHeight;
- MLSkinnedHeader_SetHeight(controlWindow, -1);
- }
- }
- controlWindow = GetDlgItem(hwnd, 2);
- if (NULL != controlWindow)
- {
- font = (HFONT)SendMessageW(controlWindow, WM_GETFONT, 0, 0L);
- fontHeight = 0;
- if (NULL != hdc)
- {
- SelectObject(hdc, font);
- if (FALSE != GetTextMetricsW(hdc, &textMetrics))
- fontHeight = textMetrics.tmHeight;
- }
- if (self->listFontHeight != fontHeight)
- {
- self->listFontHeight = fontHeight;
- SmoothScrollList_SetScrollPos(hwnd, 0, SPF_NOREDRAW | SPF_FORCE);
- MLSkinnedScrollWnd_UpdateBars(hwnd, FALSE);
- }
- }
-
- if (NULL != hdc)
- {
- SelectObject(hdc, prevFont);
- ReleaseDC(hwnd, hdc);
- }
- if (0 != (WS_VISIBLE & windowStyle))
- {
- windowStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
- if (0 == (WS_VISIBLE & windowStyle))
- {
- windowStyle |= WS_VISIBLE;
- SetWindowLongPtrW(hwnd, GWL_STYLE, windowStyle);
- }
- if (FALSE != redraw)
- RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN);
- }
- }
- static HHOOK hook = NULL;
- static HWND hwndToMonitor = NULL;
- static LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
- {
- MSG *pMsg = (MSG*)lParam;
- if (pMsg->hwnd == hwndToMonitor)
- {
- static INT lastScrollPos = -1;
- switch(pMsg->message)
- {
- case WM_LBUTTONUP:
- case WM_RBUTTONUP:
- {
- LRESULT result = CallNextHookEx(hook, nCode, wParam, lParam);
- UnhookWindowsHookEx(hook);
- hwndToMonitor = NULL;
- hook = NULL;
- lastScrollPos = -1;
- return result;
- }
- case WM_MOUSEMOVE:
- if ((MK_LBUTTON | MK_RBUTTON) & pMsg->wParam)
- {
- RECT rw;
- POINTS pts(MAKEPOINTS(pMsg->lParam));
- POINT pt;
- POINTSTOPOINT(pt, pts);
- MapWindowPoints(pMsg->hwnd, HWND_DESKTOP, &pt, 1);
- GetWindowRect(pMsg->hwnd, &rw);
- if (pt.y < rw.top || pt.y > rw.bottom)
- {
- HWND hwndParent = GetParent(pMsg->hwnd);
- if (hwndParent)
- {
- SCROLLINFO si;
- si.cbSize = sizeof(SCROLLINFO);
- si.fMask = SIF_RANGE | SIF_POS | SIF_PAGE;
- if (GetScrollInfo(hwndParent, SB_VERT, &si))
- {
- if ((si.nPos > si.nMin && pt.y < rw.top) || (si.nPos <= (si.nMax - (INT)si.nPage) && pt.y > rw.bottom))
- {
- LRESULT result;
- if (lastScrollPos == si.nPos)
- {
- result = CallNextHookEx(hook, nCode, wParam, lParam);
- SmoothScrollList_SetScrollPos(hwndParent, (pt.y < rw.top) ? --si.nPos : ++si.nPos, SPF_NORMAL);
- }
- else
- {
- unsigned long windowStyle;
- windowStyle = GetWindowLongPtrW(hwndParent, GWL_STYLE);
- if (0 != (WS_VISIBLE & windowStyle))
- SetWindowLongPtrW(hwndParent, GWL_STYLE, windowStyle & ~WS_VISIBLE);
- result = CallNextHookEx(hook, nCode, wParam, lParam);
- PostMessageW(hwndParent, WM_EX_UPDATESCROLLINFO, SIF_POS, TRUE);
- if (0 != (WS_VISIBLE & windowStyle))
- PostMessageW(hwndParent, WM_EX_UNLOCKREDRAW, IWF_UPDATENOW | IWF_FRAME, 0L);
- }
- lastScrollPos = si.nPos;
- return result;
- }
- }
- }
- }
- SleepEx(1, TRUE);
- }
- break;
- }
- }
- return CallNextHookEx(hook, nCode, wParam, lParam);
- }
- static LRESULT CALLBACK ListViewSubclass(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- if(uMsg == WM_MOUSEMOVE ||
- uMsg == WM_LBUTTONDOWN)
- {
- LVHITTESTINFO ht = {{LOWORD(lParam),HIWORD(lParam)},LVHT_ONITEM,-1,0};
- int item = ListView_SubItemHitTest(hwnd, &ht);
- {
- RECT r={0};
- ListView_GetItemRect(hwnd,item,&r,LVIR_BOUNDS);
- ht.pt.x -= r.left;
- ht.pt.y -= r.top;
- typedef struct {
- int x,y,item;
- HWND hwnd;
- UINT msg;
- } hitinfo;
- hitinfo info = {
- ht.pt.x, ht.pt.y, item, hwnd, uMsg,
- };
- SendMessage(GetParent(GetParent(hwnd)),WM_USER+700,(WPARAM)&info,0);
- }
- }
- switch(uMsg)
- {
- case WM_HSCROLL:
- case WM_VSCROLL:
- case WM_MOUSEWHEEL:
- {
- HWND parentWindow;
- KillTimer(hwnd, 43);
- parentWindow = GetAncestor(hwnd, GA_PARENT);
- if (NULL != parentWindow)
- return SendMessageW(parentWindow, uMsg, wParam, lParam);
- }
- break;
- case WM_TIMER:
- if (43 == wParam)
- {
- HWND parentWindow;
- KillTimer(hwnd, wParam);
-
- parentWindow = GetAncestor(hwnd, GA_PARENT);
- if (NULL != parentWindow)
- {
- int iFocused = (int)SendMessageW(hwnd, LVM_GETNEXTITEM, (WPARAM)-1, (LPARAM)(LVNI_ALL | LVNI_FOCUSED));
- if (-1 != iFocused)
- SmoothScrollList_EnsureVisible(parentWindow, iFocused, FALSE);
- return 0;
- }
- }
- break;
- case WM_LBUTTONDOWN:
- case WM_RBUTTONDOWN:
- case WM_MBUTTONDOWN:
- case WM_XBUTTONDOWN:
- hwndToMonitor = hwnd;
- hook = SetWindowsHookEx(WH_MSGFILTER, HookProc, NULL, GetCurrentThreadId());
-
- {
- unsigned int windowStyle;
- windowStyle = GetWindowLongPtrW(hwnd, GWL_STYLE);
- if (0 != (LVS_OWNERDRAWFIXED & windowStyle))
- {
- LRESULT result;
-
- SetWindowLongPtrW(hwnd, GWL_STYLE, windowStyle & ~LVS_OWNERDRAWFIXED);
-
- result = SubclassedListView_CallPrevWndProc(hwnd, uMsg, wParam, lParam);
- windowStyle = GetWindowLongPtrW(hwnd, GWL_STYLE);
- if (0 == (LVS_OWNERDRAWFIXED & windowStyle))
- {
- windowStyle |= LVS_OWNERDRAWFIXED;
- SetWindowLongPtrW(hwnd, GWL_STYLE, windowStyle);
- }
- return result;
- }
- }
- break;
-
- case WM_KEYDOWN:
- {
- HWND parentWindow;
- parentWindow = GetAncestor(hwnd, GA_PARENT);
- if (NULL != parentWindow)
- {
- PostProcessKeyCommands postProcessKeyCommands;
- if (FALSE == SmoothScrollList_PreProcessKey(parentWindow,
- (unsigned int)wParam,
- (unsigned int)lParam,
- &postProcessKeyCommands))
- {
- postProcessKeyCommands = PostProcessKeyCmd_UpdateScrollPos;
- }
-
- SubclassedListView_CallPrevWndProc(hwnd, uMsg, wParam, lParam);
-
- SmoothScrollList_PostProcessKey(parentWindow,
- (unsigned int)wParam,
- (unsigned int)lParam,
- postProcessKeyCommands);
- return 0;
- }
- }
- break;
- case WM_CHAR:
- case WM_UNICHAR:
- {
- HWND parentWindow;
- parentWindow = GetAncestor(hwnd, GA_PARENT);
- if (NULL != parentWindow)
- {
- int iFocused;
- unsigned int windowStyle;
-
- windowStyle = GetWindowLongPtrW(hwnd, GWL_STYLE);
-
- if (0 != (WS_VISIBLE & windowStyle))
- SetWindowLongPtr(hwnd, GWL_STYLE, windowStyle & ~WS_VISIBLE);
- SubclassedListView_CallPrevWndProc(hwnd, uMsg, wParam, lParam);
- iFocused = (int)SendMessageW(hwnd, LVM_GETNEXTITEM, (WPARAM)-1, (LPARAM)(LVNI_ALL | LVNI_FOCUSED));
-
- if (-1 != iFocused)
- SmoothScrollList_EnsureVisible(parentWindow, iFocused, FALSE);
- if (0 != (WS_VISIBLE & windowStyle))
- {
- windowStyle = GetWindowLongPtrW(hwnd, GWL_STYLE);
- windowStyle |= WS_VISIBLE;
- SetWindowLongPtr(hwnd, GWL_STYLE, windowStyle);
- }
- InvalidateRect(hwnd, NULL, FALSE);
- return 0;
- }
- }
- break;
- case LVM_ENSUREVISIBLE:
- {
- HWND parentWindow = GetAncestor(hwnd, GA_PARENT);
- if (NULL != parentWindow)
- return SmoothScrollList_EnsureVisible(parentWindow, (int)wParam, (BOOL)lParam);
- }
- break;
-
-
- }
- return SubclassedListView_CallPrevWndProc(hwnd, uMsg, wParam, lParam);
- }
- static LRESULT
- SmoothScrollList_OnCreate(HWND hwnd, CREATESTRUCT *createStruct)
- {
- HWND hwndList, hwndHeader;
- MLSKINWINDOW m = {0};
- RECT rc;
- DWORD style;
- SmoothScrollList *self = (SmoothScrollList *)calloc(1, sizeof(SmoothScrollList));
- if (NULL == self)
- return -1;
- self->itemHeight = 1;
- self->textHeight = 1;
- SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONGX86)(LONG_PTR)self);
- m.skinType = SKINNEDWND_TYPE_SCROLLWND;
- m.style = SWS_USESKINFONT | SWS_USESKINCOLORS | SWS_USESKINCURSORS;
- m.hwndToSkin = hwnd;
- MLSkinWindow(g_hwnd, &m);
-
- SetScrollRange(hwnd, SB_VERT, 0, 0, FALSE);
- MLSkinnedScrollWnd_UpdateBars(hwnd, FALSE);
-
- if (FALSE == GetClientRect(hwnd, &rc))
- SetRectEmpty(&rc);
- style = WS_CLIPSIBLINGS | WS_CHILD | WS_VISIBLE | HDS_BUTTONS | HDS_FULLDRAG;
- hwndHeader = CreateWindowExW(WS_EX_NOPARENTNOTIFY, WC_HEADERW, NULL, style,
- 0, 0, rc.right - rc.left, 0, hwnd, (HMENU)3,0,0);
- if (NULL != hwndHeader)
- {
- m.hwndToSkin = hwndHeader;
- m.skinType = SKINNEDWND_TYPE_HEADER;
- m.style = SWS_USESKINFONT | SWS_USESKINCOLORS | SWS_USESKINCURSORS;
- MLSkinWindow(g_hwnd, &m);
- }
-
- style = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_CHILD | WS_TABSTOP | WS_VISIBLE |
- LVS_REPORT | LVS_SHOWSELALWAYS | LVS_OWNERDRAWFIXED | LVS_OWNERDATA | LVS_NOCOLUMNHEADER;
-
- hwndList = CreateWindowExW(WS_EX_NOPARENTNOTIFY, WC_LISTVIEWW, NULL, style,
- 0, 0, rc.right - rc.left, rc.bottom - rc.top, hwnd,(HMENU)2,0,0);
- if (NULL != hwndList)
- {
- WNDPROC oldp = (WNDPROC)(LONG_PTR)SetWindowLongPtrW(hwndList, GWLP_WNDPROC, (LONGX86)(LONG_PTR)ListViewSubclass);
- SetWindowLongPtrW(hwndList,GWLP_USERDATA, (LONGX86)(LONG_PTR)oldp);
- if(NULL != hwndHeader)
- SetWindowPos(hwndHeader, hwndList, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
-
- m.skinType = SKINNEDWND_TYPE_LISTVIEW;
- m.hwndToSkin = hwndList;
- m.style = SWS_USESKINFONT | SWS_USESKINCOLORS | SWS_USESKINCURSORS |
- SWLVS_FULLROWSELECT | SWLVS_DOUBLEBUFFER | SWLVS_ALTERNATEITEMS;
- MLSkinWindow(g_hwnd, &m);
- MLSkinnedScrollWnd_SetMode(hwndList, SCROLLMODE_STANDARD);
- MLSkinnedScrollWnd_ShowHorzBar(hwndList, FALSE);
- MLSkinnedScrollWnd_ShowVertBar(hwndList, FALSE);
- }
- SmoothScrollList_UpdateFontMetrics(hwnd, FALSE);
- return 0;
- }
- static void
- SmoothScrollList_OnDestroy(HWND hwnd)
- {
- SmoothScrollList *self;
- self = (SmoothScrollList*)(LONG_PTR)SetWindowLongPtrW(hwnd, GWLP_USERDATA, 0);
- if (NULL == self)
- return;
-
- free(self);
- }
- static void
- SmoothScrollList_OnWindowPosChanged(HWND hwnd, WINDOWPOS *windowPos)
- {
- HWND controlWindow;
- RECT rect;
- long clientWidth;
- HWND parentWindow;
- SmoothScrollList *self;
- if ((SWP_NOSIZE | SWP_NOMOVE) == ((SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED) & windowPos->flags))
- return;
-
- self = GetUserData(hwnd);
- if (NULL == self)
- return;
- if (FALSE == GetClientRect(hwnd, &rect))
- return;
- clientWidth = rect.right - rect.left;
-
- controlWindow = GetDlgItem(hwnd, 3);
- if (NULL != controlWindow)
- {
- HDLAYOUT headerLayout;
- WINDOWPOS headerPos;
-
- headerLayout.prc = ▭
- headerLayout.pwpos = &headerPos;
-
- if (FALSE != SendMessageW(controlWindow, HDM_LAYOUT, 0, (LPARAM)&headerLayout))
- {
- headerPos.flags |= ((SWP_NOREDRAW | SWP_NOCOPYBITS) & windowPos->flags);
- headerPos.flags &= ~SWP_NOZORDER;
- headerPos.hwndInsertAfter = HWND_TOP;
- SetWindowPos(controlWindow, headerPos.hwndInsertAfter, headerPos.x, headerPos.y,
- headerPos.cx, headerPos.cy, headerPos.flags);
- }
- }
- if (self->viewHeight != windowPos->cy ||
- 0 != (SWP_FRAMECHANGED & windowPos->flags))
- {
- ScrollPosFlags scrollFlags;
- scrollFlags = SPF_FORCE | SPF_RELATIVE;
- if (0 != (SWP_NOREDRAW & windowPos->flags))
- scrollFlags |= SPF_NOREDRAW;
- self->viewHeight = windowPos->cy;
-
- UpdateScrollInfo(hwnd, SIF_RANGE | SIF_POS, TRUE);
- SmoothScrollList_SetScrollPos(hwnd, 0, scrollFlags);
- }
- else
- {
- controlWindow = GetDlgItem(hwnd, 2);
- if (NULL != controlWindow)
- {
- if (FALSE != GetWindowRect(controlWindow, &rect) &&
- (rect.right - rect.left) != clientWidth)
- {
- SetWindowPos(controlWindow, NULL, 0, 0, clientWidth, rect.bottom - rect.top,
- SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | ((SWP_NOREDRAW | SWP_NOCOPYBITS) & windowPos->flags));
- }
- }
- }
-
- parentWindow = GetAncestor(hwnd, GA_PARENT);
- if (NULL != parentWindow)
- {
- NMHDR hdr;
- hdr.code = LVN_EX_SIZECHANGED;
- hdr.hwndFrom = hwnd;
- hdr.idFrom = GetWindowLongPtrW(hwnd, GWLP_ID);
- SendMessageW(parentWindow, WM_NOTIFY, hdr.idFrom, (LPARAM)&hdr);
- }
- }
- static void
- SmoothScrollList_OnMouseWheel(HWND hwnd, INT virtualKeys, INT distance, LONG pointer_s)
- {
- SmoothScrollList *self;
- int pos;
- unsigned int wheelScroll;
- int scrollLines;
- KillTimer(hwnd, 43);
- self = GetUserData(hwnd);
- if (NULL == self)
- return;
-
- if (FALSE == SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &wheelScroll, 0))
- wheelScroll = 3;
- if (0 == wheelScroll)
- return;
- if (WHEEL_PAGESCROLL == wheelScroll)
- {
- SendMessageW(hwnd, WM_VSCROLL, MAKEWPARAM(((distance > 0) ? SB_PAGEUP : SB_PAGEDOWN), 0), 0L);
- SendMessageW(hwnd, WM_VSCROLL, MAKEWPARAM(SB_ENDSCROLL, 0), 0L);
- return;
- }
- distance += self->wheelCarryover;
- scrollLines = distance * (int)wheelScroll / WHEEL_DELTA;
- self->wheelCarryover = distance - scrollLines * WHEEL_DELTA / (int)wheelScroll;
- pos = scrollLines * (int)self->textHeight;
-
- SmoothScrollList_SetScrollPos(hwnd, -pos, SPF_RELATIVE | SPF_NORMAL);
- MLSkinnedScrollWnd_UpdateBars(hwnd, TRUE);
- }
- static void
- SmoothScrollList_OnVertScroll(HWND hwnd, INT actionLayout, INT trackPosition, HWND scrollBar)
- {
- SmoothScrollList *s;
- SCROLLINFO si;
- int pos;
- ScrollPosFlags scrollFlags;
- unsigned int lineHeight;
- KillTimer(hwnd, 43);
- s = GetUserData(hwnd);
- if (NULL == s)
- return;
-
- si.cbSize =sizeof(si);
- si.fMask = SIF_PAGE | SIF_POS | SIF_TRACKPOS | SIF_RANGE;
-
- if (FALSE == GetScrollInfo(hwnd, SB_VERT, &si))
- return;
-
- scrollFlags = SPF_NORMAL;
- if (si.nPos > (si.nMax - (INT)si.nPage))
- si.nPos = si.nMax - si.nPage;
- lineHeight = s->textHeight * 3;
- if (lineHeight > s->itemHeight)
- lineHeight = s->itemHeight;
- if (lineHeight > si.nPage)
- lineHeight = si.nPage;
- switch(actionLayout)
- {
- case SB_TOP: pos = si.nMin; break;
- case SB_BOTTOM: pos = si.nMax; break;
- case SB_LINEDOWN: pos = si.nPos + lineHeight; break;
- case SB_LINEUP: pos = si.nPos - lineHeight; break;
- case SB_PAGEDOWN: pos = si.nPos + (si.nPage / s->itemHeight) * s->itemHeight; break;
- case SB_PAGEUP: pos = si.nPos - (si.nPage / s->itemHeight) * s->itemHeight; break;
- case SB_THUMBPOSITION:
- case SB_THUMBTRACK: pos = si.nTrackPos; scrollFlags |= SPF_FORCE; break;
- case SB_ENDSCROLL: MLSkinnedScrollWnd_UpdateBars(hwnd, TRUE); return;
- default: pos = si.nPos;
- }
- SmoothScrollList_SetScrollPos(hwnd, pos, scrollFlags);
- }
- static LRESULT
- SmoothScrollList_OnMeasureItem(HWND hwnd, MEASUREITEMSTRUCT *measureItem)
- {
- LRESULT result;
- HWND parentWindow;
- SmoothScrollList *self;
- unsigned int itemHeight, textHeight;
- BOOL updateScroll;
- if(2 != measureItem->CtlID)
- return FALSE;
-
- self = GetUserData(hwnd);
-
- updateScroll = FALSE;
- itemHeight = measureItem->itemHeight;
- parentWindow = GetAncestor(hwnd, GA_PARENT);
- if (NULL != parentWindow)
- {
- measureItem->CtlID = GetWindowLongPtrW(hwnd, GWLP_ID);
- result = SendMessageW(parentWindow, WM_MEASUREITEM, measureItem->CtlID, (LPARAM)measureItem);
- itemHeight = measureItem->itemHeight;
- }
- else
- result = 0;
-
- textHeight = 12;
- HDC hdc = GetDCEx(hwnd, NULL, DCX_CACHE | DCX_NORESETATTRS);
- if (NULL != hdc)
- {
- HFONT font, fontPrev;
- TEXTMETRIC textMetrics;
- font = (HFONT)SendMessageW(hwnd, WM_GETFONT, 0, 0L);
- fontPrev = (HFONT)SelectObject(hdc, font);
- if (FALSE != GetTextMetrics(hdc, &textMetrics))
- textHeight = textMetrics.tmHeight;
- SelectObject(hdc, fontPrev);
- ReleaseDC(hwnd, hdc);
- }
-
- if (NULL != self)
- {
- if (self->itemHeight != itemHeight)
- {
- SmoothScrollList_SetScrollPos(hwnd, 0, SPF_NOREDRAW);
- self->itemHeight = itemHeight;
- updateScroll = TRUE;
- }
- if (self->textHeight != textHeight)
- {
- self->textHeight = textHeight;
- updateScroll = TRUE;
- }
- }
-
- if (FALSE != updateScroll)
- {
- UpdateScrollInfo(hwnd, SIF_RANGE | SIF_POS, TRUE);
- }
- return result;
- }
- static void
- SmoothScrollList_OnSetFont(HWND hwnd, HFONT font, BOOL redraw)
- {
- if (0 == (SWS_USESKINFONT & MLSkinnedWnd_GetStyle(hwnd)))
- {
- HWND controlWindow;
-
- controlWindow = GetDlgItem(hwnd,3);
- if (NULL != controlWindow)
- SendMessageW(controlWindow, WM_SETFONT, (WPARAM)font, MAKELPARAM(0, 0L));
- controlWindow = GetDlgItem(hwnd,2);
- if (NULL != controlWindow)
- SendMessageW(controlWindow, WM_SETFONT, (WPARAM)font, MAKELPARAM(0, 0L));
-
- SmoothScrollList_UpdateFontMetrics(hwnd, redraw);
- }
- }
- static LRESULT
- SmoothScrollList_OnGetFont(HWND hwnd)
- {
- HWND listWindow;
- listWindow = GetDlgItem(hwnd, 2);
- if (NULL != listWindow)
- return SendMessageW(listWindow, WM_GETFONT, 0, 0L);
-
- return DefWindowProcW(hwnd, WM_GETFONT, 0, 0L);
- }
- static void
- SmoothScrollList_OnSetRedraw(HWND hwnd, BOOL enableRedraw)
- {
- HWND childWindow;
- DefWindowProcW(hwnd, WM_SETREDRAW, enableRedraw, 0L);
-
- childWindow = GetDlgItem(hwnd, 3);
- if (NULL != childWindow)
- {
- SendMessage(childWindow, WM_SETREDRAW, enableRedraw, 0L);
- if (FALSE != enableRedraw)
- InvalidateRect(childWindow, NULL, TRUE);
- }
- childWindow = GetDlgItem(hwnd, 2);
- if (NULL != childWindow)
- {
- SendMessage(childWindow, WM_SETREDRAW, enableRedraw, 0L);
- if (FALSE != enableRedraw)
- InvalidateRect(childWindow, NULL, TRUE);
- }
- }
- static void
- SmoothScrollList_OnSkinUpdated(HWND hwnd, BOOL notifyChildren, BOOL redraw)
- {
- SmoothScrollList_UpdateFontMetrics(hwnd, redraw);
- }
- static LRESULT
- SmoothScrollList_OnDisplaySort(HWND hwnd, int sortIndex, BOOL ascendingOrder)
- {
- HWND headerWindow;
- headerWindow = GetDlgItem(hwnd, 3);
- if (NULL == headerWindow)
- return 0;
- return SENDMLIPC(headerWindow, ML_IPC_SKINNEDHEADER_DISPLAYSORT, MAKEWPARAM(sortIndex, ascendingOrder));
- }
- static LRESULT
- SmoothScrollList_OnGetSort(HWND hwnd)
- {
- HWND headerWindow;
- headerWindow = GetDlgItem(hwnd, 3);
- if (NULL == headerWindow)
- return 0;
- return SENDMLIPC(headerWindow, ML_IPC_SKINNEDHEADER_GETSORT, 0);
- }
- static void
- SmoothScrollList_OnKeyDown(HWND hwnd, unsigned int vKey, unsigned int keyFlags)
- {
- HWND listWindow;
- listWindow = GetDlgItem(hwnd, 2);
-
- if (NULL != listWindow &&
- WS_VISIBLE == ((WS_VISIBLE | WS_DISABLED) & GetWindowLongPtrW(listWindow, GWL_STYLE)))
- {
- SendMessageW(listWindow, WM_KEYDOWN, vKey, (LPARAM)keyFlags);
- }
- DefWindowProcW(hwnd, WM_KEYDOWN, vKey, (LPARAM)keyFlags);
- }
- static LRESULT
- SmoothScrollList_OnMediaLibraryIPC(HWND hwnd, INT msg, INT_PTR param)
- {
- switch(msg)
- {
- case ML_IPC_SKINNEDWND_SKINUPDATED: SmoothScrollList_OnSkinUpdated(hwnd, LOWORD(param), HIWORD(param)); break;
- case ML_IPC_SKINNEDLISTVIEW_DISPLAYSORT: return SmoothScrollList_OnDisplaySort(hwnd, LOWORD(param), HIWORD(param));
- case ML_IPC_SKINNEDLISTVIEW_GETSORT: return SmoothScrollList_OnGetSort(hwnd);
- }
- return 0;
- }
- static LRESULT CALLBACK SmoothScrollMsgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- switch(uMsg)
- {
- case WM_CREATE: return SmoothScrollList_OnCreate(hwnd, (CREATESTRUCT*)lParam);
- case WM_DESTROY: SmoothScrollList_OnDestroy(hwnd); return 0;
- case WM_WINDOWPOSCHANGED: SmoothScrollList_OnWindowPosChanged(hwnd, (WINDOWPOS*)lParam); return 0;
- case WM_MOUSEWHEEL: SmoothScrollList_OnMouseWheel(hwnd, LOWORD(wParam), (short)HIWORD(wParam), (LONG)lParam); return 0;
- case WM_VSCROLL: SmoothScrollList_OnVertScroll(hwnd, LOWORD(wParam), (short)HIWORD(wParam), (HWND)lParam); return 0;
- case WM_ERASEBKGND: return 1;
- case WM_MEASUREITEM: return SmoothScrollList_OnMeasureItem(hwnd, (MEASUREITEMSTRUCT*)lParam);
- case WM_SETFONT: SmoothScrollList_OnSetFont(hwnd, (HFONT)wParam, LOWORD(lParam)); return 0;
- case WM_GETFONT: return SmoothScrollList_OnGetFont(hwnd);
- case WM_SETREDRAW: SmoothScrollList_OnSetRedraw(hwnd, (BOOL)wParam); return 0;
-
- case LVM_GETHEADER:
- return (LRESULT)GetDlgItem(hwnd,3);
- case LVM_INSERTCOLUMNA:
- case LVM_INSERTCOLUMNW:
- {
- LVCOLUMNW *listColumn = (LVCOLUMNW*)lParam;
- HWND controlWindow;
- LRESULT result;
- result = -1;
- controlWindow = GetDlgItem(hwnd,3);
- if (NULL != controlWindow)
- {
- HDITEMW headerItem;
-
- if (FALSE == CopyListColumnToHeaderItem(listColumn, &headerItem))
- return -1;
- if (0 == (HDI_FORMAT & headerItem.mask))
- {
- headerItem.mask |= HDI_FORMAT;
- headerItem.fmt = HDF_LEFT;
- }
- result = SendMessageW(controlWindow,
- (LVM_INSERTCOLUMNW == uMsg) ? HDM_INSERTITEMW : HDM_INSERTITEMA,
- wParam, (LPARAM)&headerItem);
- if (-1 == result)
- return result;
- }
- controlWindow = GetDlgItem(hwnd, 2);
- if (NULL != controlWindow)
- result = SendMessageW(controlWindow, uMsg, wParam, lParam);
- return result;
- }
- break;
- case LVM_DELETECOLUMN:
- {
- HWND controlWindow;
- controlWindow = GetDlgItem(hwnd,3);
- if (NULL != controlWindow &&
- FALSE ==SendMessageW(controlWindow, HDM_DELETEITEM, wParam, 0L))
- {
- return FALSE;
- }
-
- controlWindow = GetDlgItem(hwnd,2);
- if (NULL != controlWindow)
- return SendMessageW(controlWindow ,uMsg,wParam,lParam);
- }
- return FALSE;
- case LVM_GETCOLUMNW:
- case LVM_GETCOLUMNA:
- {
- LVCOLUMNW *l = (LVCOLUMNW *)lParam;
- HDITEMW h;
- HWND headerWindow;
-
- headerWindow = GetDlgItem(hwnd, 3);
- if (NULL == headerWindow)
- return FALSE;
- if (FALSE == CopyListColumnToHeaderItem(l, &h))
- return FALSE;
- if(!SendMessageW(headerWindow,
- (LVM_GETCOLUMNW == uMsg) ? HDM_GETITEMW : HDM_GETITEMA,
- wParam,
- (LPARAM)&h))
- {
- return FALSE;
- }
-
- if (FALSE == CopyHeaderItemToListColumn(&h, l))
- return FALSE;
- }
- return TRUE;
- case LVM_GETCOLUMNWIDTH:
- {
- HWND controlWindow;
- controlWindow = GetDlgItem(hwnd,3);
- if (NULL != controlWindow)
- {
- HDITEMW h;
- h.mask = HDI_WIDTH;
- if (FALSE == SendMessageW(controlWindow, HDM_GETITEM, wParam, (LPARAM)&h))
- return 0;
- return h.cxy;
- }
- controlWindow = GetDlgItem(hwnd, 2);
- if (NULL != controlWindow)
- return SendMessageW(controlWindow, uMsg, wParam, lParam);
- }
- break;
- case LVM_SETCOLUMNW:
- case LVM_SETCOLUMNA:
- {
- LVCOLUMNW *l = (LVCOLUMNW *)lParam;
- HWND controlWindow;
- LRESULT result;
-
- controlWindow = GetDlgItem(hwnd, 3);
- if (NULL != controlWindow)
- {
- HDITEMW h;
- if (FALSE == CopyListColumnToHeaderItem(l, &h))
- return FALSE;
- if(!SendMessageW(controlWindow,
- (LVM_SETCOLUMNW == uMsg) ? HDM_SETITEMW : HDM_SETITEMA,
- wParam, (LPARAM)&h))
- {
- return FALSE;
- }
-
- if (FALSE == CopyHeaderItemToListColumn(&h, l))
- return FALSE;
- result = TRUE;
- }
- else result = FALSE;
- controlWindow = GetDlgItem(hwnd,2);
- if (NULL != controlWindow)
- result = SendMessageW(controlWindow, uMsg, wParam, lParam);
- return result;
- }
- break;
- case LVM_SETCOLUMNWIDTH:
- {
- HWND controlWindow;
- LRESULT result;
- controlWindow = GetDlgItem(hwnd, 3);
- if (NULL != controlWindow)
- {
- HDITEMW headerItem;
- if (LVSCW_AUTOSIZE == lParam)
- return FALSE;
- if (LVSCW_AUTOSIZE_USEHEADER == lParam)
- return FALSE;
- headerItem.mask = HDI_WIDTH;
- headerItem.cxy = (int)lParam;
- result = SendMessageW(controlWindow, HDM_SETITEMW, (WPARAM)wParam, (LPARAM)&headerItem);
- if (FALSE == result)
- return FALSE;
- }
- else
- result = FALSE;
- controlWindow = GetDlgItem(hwnd,2);
- if (NULL != controlWindow)
- result = SendMessageW(controlWindow, uMsg, wParam, lParam);
- return result;
- }
- break;
-
- case LVM_SETITEMCOUNT:
- {
- LRESULT result;
- HWND controlWindow = GetDlgItem(hwnd,2);
-
- result = (NULL != controlWindow) ?
- SendMessageW(controlWindow, uMsg, wParam,lParam) :
- 0;
- UpdateScrollInfo(hwnd, SIF_RANGE | SIF_POS, TRUE);
- return result;
- }
- break;
- case LVM_ENSUREVISIBLE:
- return SmoothScrollList_EnsureVisible(hwnd, (int)wParam, (BOOL)lParam);
-
- case WM_EX_UPDATESCROLLINFO:
- return UpdateScrollInfo(hwnd, (UINT)wParam, (BOOL)lParam);
-
- case WM_EX_UNLOCKREDRAW:
- {
- unsigned long windowStyle;
- unsigned int redrawFlags;
- HRGN regionInvalid;
- RECT rect;
- windowStyle = GetWindowLongPtrW(hwnd, GWL_STYLE);
- if (0 == (WS_VISIBLE & windowStyle))
- SetWindowLongPtrW(hwnd, GWL_STYLE, windowStyle | WS_VISIBLE);
-
- redrawFlags = RDW_INVALIDATE | RDW_ALLCHILDREN;
-
- if (0 != (IWF_FRAME & wParam))
- {
- redrawFlags |= RDW_FRAME;
- GetWindowRect(hwnd, &rect);
- MapWindowPoints(HWND_DESKTOP, hwnd, (POINT*)&rect, 2);
- }
- else
- GetClientRect(hwnd, &rect);
- if (0 != (IWF_ERASE & wParam))
- redrawFlags |= RDW_ERASE;
-
- if (0 != (IWF_UPDATENOW & wParam))
- {
- redrawFlags |= RDW_UPDATENOW;
- if (0 != (IWF_ERASE & wParam))
- redrawFlags |= RDW_ERASENOW;
- }
-
- regionInvalid = CreateRectRgnIndirect(&rect);
- if (NULL != regionInvalid)
- {
- HWND headerWindow;
- headerWindow = GetDlgItem(hwnd, 3);
- if (NULL != headerWindow &&
- 0 != (WS_VISIBLE & GetWindowLongPtrW(headerWindow, GWL_STYLE)))
- {
- HRGN regionHeader;
- GetWindowRect(headerWindow, &rect);
- MapWindowPoints(HWND_DESKTOP, hwnd, (POINT*)&rect, 2);
- regionHeader = CreateRectRgnIndirect(&rect);
- if (NULL != regionHeader)
- {
- CombineRgn(regionInvalid, regionInvalid, regionHeader, RGN_DIFF);
- DeleteObject(regionHeader);
- }
- }
- }
- RedrawWindow(hwnd, NULL, regionInvalid, redrawFlags);
- if (NULL != regionInvalid)
- DeleteObject(regionInvalid);
- }
- break;
- case WM_NOTIFY:
- {
- LPNMHDR l=(LPNMHDR)lParam;
- if(l->idFrom == 2)
- {
- l->idFrom = GetWindowLongPtrW(hwnd,GWLP_ID);
- l->hwndFrom = hwnd; // this is prevents double reflecting
- return SendMessageW(GetParent(hwnd),uMsg,l->idFrom,lParam);
- }
- else if(l->idFrom == 3)
- {
- switch(l->code)
- {
- case HDN_ITEMCLICKA:
- case HDN_ITEMCLICKW:
- {
- NMHEADER *nm = (NMHEADER*)lParam;
- HWND hwndParent;
- hwndParent = GetParent(hwnd);
- if (hwndParent)
- {
- wParam = GetWindowLongPtrW(hwnd,GWLP_ID);
- if(nm->iButton == 0) { // left click
- NMLISTVIEW p = {{hwnd, wParam, LVN_COLUMNCLICK},-1,nm->iItem,0};
- return SendMessageW(hwndParent,WM_NOTIFY,wParam,(LPARAM)&p);
- } else if(nm->iButton == 1) { // right click
- NMHDR p = {nm->hdr.hwndFrom,wParam,NM_RCLICK};
- return SendMessageW(hwndParent,WM_NOTIFY,wParam,(LPARAM)&p);
- }
- }
- }
- break;
- case HDN_ITEMCHANGINGA:
- case HDN_ITEMCHANGINGW:
- case HDN_ITEMCHANGEDA:
- case HDN_ITEMCHANGEDW:
- {
- LRESULT result;
- NMHEADER *nm = (NMHEADER*)lParam;
- result = SendMessageW(GetParent(hwnd),uMsg, wParam,lParam);
- if (FALSE != result &&
- (HDN_ITEMCHANGINGW == l->code || HDN_ITEMCHANGINGA == l->code))
- {
- return result;
- }
- if (NULL != nm->pitem &&
- 0 != (HDI_WIDTH & nm->pitem->mask))
- {
- HWND hwndList;
- hwndList = GetDlgItem(hwnd,2);
- if (hwndList)
- {
- unsigned long windowStyle;
- windowStyle = GetWindowLongPtrW(hwnd, GWL_STYLE);
- if (0 != (WS_VISIBLE & windowStyle))
- SetWindowLongPtrW(hwnd, GWL_STYLE, windowStyle & ~WS_VISIBLE);
- ListView_SetColumnWidth(hwndList, nm->iItem,nm->pitem->cxy);
- if (0 != (WS_VISIBLE & windowStyle))
- {
- windowStyle = GetWindowLongPtrW(hwnd, GWL_STYLE);
- if (0 == (WS_VISIBLE & windowStyle))
- {
- windowStyle |= WS_VISIBLE;
- SetWindowLongPtrW(hwnd, GWL_STYLE, windowStyle);
- }
- InvalidateRect(hwndList, NULL, FALSE);
- }
- }
- }
- return result;
- }
- break;
- }
- return SendMessageW(GetParent(hwnd),uMsg, wParam,lParam);
- }
- }
- break;
- case WM_EX_GETREALLIST:
- return (LRESULT)GetDlgItem(hwnd, 2);
- case WM_EX_GETCOUNTPERPAGE:
- return SendMessageW(GetDlgItem(hwnd, 2), LVM_GETCOUNTPERPAGE, 0, 0L) + 1;
-
- case WM_KEYDOWN: SmoothScrollList_OnKeyDown(hwnd, (unsigned int)wParam, (unsigned int)lParam); return 0;
-
- case WM_ML_IPC:
- return SmoothScrollList_OnMediaLibraryIPC(hwnd, (INT)lParam, (INT_PTR)wParam);
- default:
- if(uMsg >= LVM_FIRST && uMsg < LVM_FIRST + 0x100)
- {
- HWND hwndList = GetDlgItem(hwnd,2);
- if (hwndList) return ListViewSubclass(hwndList, uMsg, wParam, lParam);
- }
- break;
- }
- return DefWindowProcW(hwnd,uMsg,wParam,lParam);
- }
- void InitSmoothScrollList() {
- WNDCLASSW wc = {0, };
- if (GetClassInfoW(plugin.hDllInstance, L"SmoothScrollList", &wc)) return;
- wc.style = CS_DBLCLKS;
- wc.lpfnWndProc = SmoothScrollMsgProc;
- wc.hInstance = plugin.hDllInstance;
- wc.lpszClassName = L"SmoothScrollList";
- RegisterClassW(&wc);
- }
|