void RecalcScrollBar(HWND hwnd,struct ClcData *dat) { SCROLLINFO si = {0}; RECT clRect; NMCLISTCONTROL nm; boolean sbar = FALSE; GetClientRect(hwnd,&clRect); si.cbSize = sizeof(si); si.fMask = SIF_ALL; si.nMin = 0; si.nMax = dat->rowHeight*GetGroupContentsCount(&dat->list,2)-1; si.nPage = clRect.bottom; si.nPos = dat->yScroll; nm.hdr.code = CLN_LISTSIZECHANGE; nm.hdr.hwndFrom = hwnd; nm.hdr.idFrom = GetDlgCtrlID(hwnd); nm.pt.y = si.nMax; SendMessage(GetParent(hwnd),WM_NOTIFY,0,(LPARAM)&nm); GetClientRect(hwnd,&clRect); si.cbSize = sizeof(si); si.fMask = SIF_ALL; si.nMin = 0; si.nMax = dat->rowHeight*GetGroupContentsCount(&dat->list,2)-1; si.nPage = clRect.bottom; si.nPos = dat->yScroll; sbar = (dat->noVScrollbar == 1||(int)si.nPage>si.nMax); ShowScrollBar(hwnd,SB_VERT,sbar? FALSE : TRUE); if ( !sbar) { if ( GetWindowLongPtr(hwnd,GWL_STYLE)&CLS_CONTACTLIST ) { if ( dat->noVScrollbar == 0 ) SetScrollInfo(hwnd,SB_VERT,&si,TRUE); else SetScrollInfo(hwnd,SB_VERT,&si,FALSE); } else SetScrollInfo(hwnd,SB_VERT,&si,TRUE); } ScrollTo(hwnd,dat,dat->yScroll,1); }
void ScrollTo(HWND hwnd,struct ClcData *dat,int desty,int noSmooth) { DWORD startTick,nowTick; int oldy = dat->yScroll; RECT clRect,rcInvalidate; int maxy,previousy; if (dat->iHotTrack != -1 && dat->yScroll != desty) { pcli->pfnInvalidateItem(hwnd,dat,dat->iHotTrack); dat->iHotTrack = -1; ReleaseCapture(); } GetClientRect(hwnd,&clRect); rcInvalidate = clRect; maxy = dat->rowHeight*GetGroupContentsCount(&dat->list,2)-clRect.bottom; if (desty>maxy) desty = maxy; if (desty<0) desty = 0; if (abs(desty-dat->yScroll)<4) noSmooth = 1; if ( !noSmooth && dat->exStyle&CLS_EX_NOSMOOTHSCROLLING) noSmooth = 1; previousy = dat->yScroll; if ( !noSmooth) { startTick = GetTickCount(); for (;;) { nowTick = GetTickCount(); if (nowTick>=startTick+dat->scrollTime) break; dat->yScroll = oldy+(desty-oldy)*(int)(nowTick-startTick)/dat->scrollTime; if (dat->backgroundBmpUse&CLBF_SCROLL || dat->hBmpBackground == NULL) ScrollWindowEx(hwnd,0,previousy-dat->yScroll,NULL,NULL,NULL,NULL,SW_INVALIDATE); else InvalidateRect(hwnd,NULL,FALSE); previousy = dat->yScroll; SetScrollPos(hwnd,SB_VERT,dat->yScroll,TRUE); UpdateWindow(hwnd); } } dat->yScroll = desty; if (dat->backgroundBmpUse&CLBF_SCROLL || dat->hBmpBackground == NULL) ScrollWindowEx(hwnd,0,previousy-dat->yScroll,NULL,NULL,NULL,NULL,SW_INVALIDATE); else InvalidateRect(hwnd,NULL,FALSE); SetScrollPos(hwnd,SB_VERT,dat->yScroll,TRUE); }
void SetGroupExpand(HWND hwnd,struct ClcData *dat,struct ClcGroup *group,int newState) { int contentCount; int groupy; int newy; int posy; RECT clRect; NMCLISTCONTROL nm; if(newState==-1) group->expanded^=1; else { if(group->expanded==(newState!=0)) return; group->expanded=newState!=0; } InvalidateRectZ(hwnd,NULL,FALSE); if (group->expanded) contentCount=GetGroupContentsCount(group,1); else contentCount=0; groupy=GetRowsPriorTo(&dat->list,group,-1); if(dat->selection>groupy && dat->selection<groupy+contentCount) dat->selection=groupy; RecalcScrollBar(hwnd,dat); GetClientRect(hwnd,&clRect); newy=dat->yScroll; posy = RowHeights_GetItemBottomY(dat, groupy+contentCount); if(posy>=newy+clRect.bottom) newy=posy-clRect.bottom; posy = RowHeights_GetItemTopY(dat, groupy); if(newy>posy) newy=posy; ScrollTo(hwnd,dat,newy,0); nm.hdr.code=CLN_EXPANDED; nm.hdr.hwndFrom=hwnd; nm.hdr.idFrom=GetDlgCtrlID(hwnd); nm.hItem=(HANDLE)group->groupId; nm.action=group->expanded; SendMessage(GetParent(hwnd),WM_NOTIFY,0,(LPARAM)&nm); }