In report view mode of the listview control, implemented the

horizontal scrollbar functionality.
This commit is contained in:
Pierre Mageau 1999-10-31 17:35:47 +00:00 committed by Alexandre Julliard
parent 458719dc20
commit 382060dcb2
1 changed files with 131 additions and 77 deletions

View File

@ -78,6 +78,9 @@ DEFAULT_DEBUG_CHANNEL(listview)
/* default column width for items in list display mode */ /* default column width for items in list display mode */
#define DEFAULT_COLUMN_WIDTH 96 #define DEFAULT_COLUMN_WIDTH 96
/* Increment size of the horizontal scroll bar */
#define REPORT_HSCROLL_INC_SIZE 10
/* /*
* macros * macros
*/ */
@ -144,6 +147,43 @@ static HWND LISTVIEW_EditLabelA(HWND hwnd, INT nItem);
static BOOL LISTVIEW_EndEditLabel(HWND hwnd, LPSTR pszText, DWORD nItem); static BOOL LISTVIEW_EndEditLabel(HWND hwnd, LPSTR pszText, DWORD nItem);
static LRESULT LISTVIEW_Command(HWND hwnd, WPARAM wParam, LPARAM lParam); static LRESULT LISTVIEW_Command(HWND hwnd, WPARAM wParam, LPARAM lParam);
/*************************************************************************
* LISTVIEW_UpdateHeaderSize [Internal]
*
* Function to resize the header control
*
* PARAMS
* hwnd [I] handle to a window
* nNewScrollPos [I] Scroll Pos to Set
* nOldScrollPos [I] Previous Scroll Pos
*
* RETURNS
* nothing
*
* NOTES
*/
static VOID LISTVIEW_UpdateHeaderSize(HWND hwnd, INT nNewScrollPos, INT nOldScrollPos)
{
LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
INT nDiff = nOldScrollPos-nNewScrollPos;
RECT winRect;
POINT point[2];
GetWindowRect(infoPtr->hwndHeader, &winRect);
point[0].x = winRect.left;
point[0].y = winRect.top;
point[1].x = winRect.right;
point[1].y = winRect.bottom;
MapWindowPoints(HWND_DESKTOP, hwnd, point, 2);
point[0].x += (nDiff * REPORT_HSCROLL_INC_SIZE );
point[1].x -= point[0].x;
SetWindowPos(infoPtr->hwndHeader,0,
point[0].x,point[0].y,point[1].x,point[1].y,
SWP_NOZORDER | SWP_NOACTIVATE);
}
/*** /***
* DESCRIPTION: * DESCRIPTION:
* Update the scrollbars. This functions should be called whenever * Update the scrollbars. This functions should be called whenever
@ -174,19 +214,18 @@ static VOID LISTVIEW_UpdateScroll(HWND hwnd)
if (nCountPerPage < GETITEMCOUNT(infoPtr)) if (nCountPerPage < GETITEMCOUNT(infoPtr))
{ {
/* calculate new scrollbar range */ /* calculate new scrollbar range */
INT nHiddenItemCount = GETITEMCOUNT(infoPtr) - nCountPerPage; if((GETITEMCOUNT(infoPtr) % nCountPerPage) == 0)
if (nHiddenItemCount % nCountPerColumn == 0)
{ {
scrollInfo.nMax = nHiddenItemCount / nCountPerColumn; scrollInfo.nMax = GETITEMCOUNT(infoPtr) / nCountPerPage * LISTVIEW_GetCountPerRow(hwnd)-1;
} }
else else
{ {
scrollInfo.nMax = nHiddenItemCount / nCountPerColumn + 1; scrollInfo.nMax = (GETITEMCOUNT(infoPtr) / nCountPerPage)* LISTVIEW_GetCountPerRow(hwnd);
} }
scrollInfo.nPos = ListView_GetTopIndex(hwnd) / nCountPerColumn; scrollInfo.nPos = ListView_GetTopIndex(hwnd) / nCountPerColumn;
/*scrollInfo.nPage = LISTVIEW_GetCountPerRow(hwnd);*/ scrollInfo.nPage = LISTVIEW_GetCountPerRow(hwnd);
scrollInfo.fMask = SIF_RANGE | SIF_POS /*| SIF_PAGE*/; scrollInfo.fMask = SIF_RANGE | SIF_POS | SIF_PAGE;
SetScrollInfo(hwnd, SB_HORZ, &scrollInfo, TRUE); SetScrollInfo(hwnd, SB_HORZ, &scrollInfo, TRUE);
} }
else else
@ -200,23 +239,53 @@ static VOID LISTVIEW_UpdateScroll(HWND hwnd)
} }
else if (uView == LVS_REPORT) else if (uView == LVS_REPORT)
{ {
RECT clientRect;
/* update vertical scrollbar */ /* update vertical scrollbar */
scrollInfo.nMin = 0; scrollInfo.nMin = 0;
scrollInfo.nMax = GETITEMCOUNT(infoPtr) - LISTVIEW_GetCountPerColumn(hwnd); scrollInfo.nMax = GETITEMCOUNT(infoPtr) - 1;
scrollInfo.nPos = ListView_GetTopIndex(hwnd); scrollInfo.nPos = ListView_GetTopIndex(hwnd);
/*scrollInfo.nPage = nCountPerColumn;*/ scrollInfo.nPage = LISTVIEW_GetCountPerColumn(hwnd);
scrollInfo.fMask = SIF_RANGE | SIF_POS /*| SIF_PAGE*/; scrollInfo.fMask = SIF_RANGE | SIF_POS | SIF_PAGE;
SetScrollInfo(hwnd, SB_VERT, &scrollInfo, TRUE); SetScrollInfo(hwnd, SB_VERT, &scrollInfo, TRUE);
/* update horizontal scrollbar */ /* update horizontal scrollbar */
/* if (infoPtr->nItemWidth > nListWidth) */ infoPtr->nItemWidth = LISTVIEW_GetItemWidth(hwnd);
/* { */ GetClientRect(hwnd, &clientRect);
/* scrollInfo.fMask = SIF_RANGE | SIF_POS | SIF_PAGE; */
/* SetScrollInfo(hwnd, SB_HORZ, &scrollInfo, TRUE); */
/* } */
/* horizontal scrolling has not been implemented yet! I experienced some if (GetScrollInfo(hwnd, SB_HORZ, &scrollInfo) == FALSE)
problems when performing child window scrolling. */ {
scrollInfo.nPos = 0;
}
scrollInfo.nMin = 0;
scrollInfo.fMask = SIF_RANGE | SIF_POS | SIF_PAGE ;
scrollInfo.nPage = (clientRect.right - clientRect.left) / REPORT_HSCROLL_INC_SIZE;
scrollInfo.nMax = infoPtr->nItemWidth;
/* Check to see if we need the scroll bar */
if(scrollInfo.nMax < 0)
{
scrollInfo.nMax = 0;
}
else
{
/* Even up the max */
scrollInfo.nMax -= (scrollInfo.nMax % REPORT_HSCROLL_INC_SIZE);
scrollInfo.nMax = (scrollInfo.nMax / REPORT_HSCROLL_INC_SIZE)-1;
}
/* Set the scroll pos to the max if the current scroll pos is greater */
if((scrollInfo.nPos+scrollInfo.nPage) > scrollInfo.nMax
&& scrollInfo.nMax > scrollInfo.nPage)
{
UINT nOldScrollPos = scrollInfo.nPos;
scrollInfo.nPos = scrollInfo.nMax;
SetScrollInfo(hwnd, SB_HORZ, &scrollInfo, TRUE);
GetScrollInfo(hwnd, SB_HORZ, &scrollInfo);
LISTVIEW_UpdateHeaderSize(hwnd, scrollInfo.nPos, nOldScrollPos);
}
else
{
SetScrollInfo(hwnd, SB_HORZ, &scrollInfo, TRUE);
}
} }
else else
{ {
@ -258,8 +327,8 @@ static VOID LISTVIEW_UpdateScroll(HWND hwnd)
} }
scrollInfo.nMin = 0; scrollInfo.nMin = 0;
/*scrollInfo.nPage = 10;*/ scrollInfo.nPage = 10;
scrollInfo.fMask = SIF_RANGE | SIF_POS /*| SIF_PAGE*/; scrollInfo.fMask = SIF_RANGE | SIF_POS | SIF_PAGE;
SetScrollInfo(hwnd, SB_HORZ, &scrollInfo, TRUE); SetScrollInfo(hwnd, SB_HORZ, &scrollInfo, TRUE);
} }
else else
@ -301,8 +370,8 @@ static VOID LISTVIEW_UpdateScroll(HWND hwnd)
} }
scrollInfo.nMin = 0; scrollInfo.nMin = 0;
/*scrollInfo.nPage = 10;*/ scrollInfo.nPage = 10;
scrollInfo.fMask = SIF_RANGE | SIF_POS /*| SIF_PAGE*/; scrollInfo.fMask = SIF_RANGE | SIF_POS | SIF_PAGE;
SetScrollInfo(hwnd, SB_VERT, &scrollInfo, TRUE); SetScrollInfo(hwnd, SB_VERT, &scrollInfo, TRUE);
} }
else else
@ -1951,6 +2020,7 @@ bottom=%d)\n", hwnd, hdc, nItem, rcItem.left, rcItem.top, rcItem.right,
static VOID LISTVIEW_RefreshReport(HWND hwnd, HDC hdc) static VOID LISTVIEW_RefreshReport(HWND hwnd, HDC hdc)
{ {
LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd,0); LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd,0);
SCROLLINFO scrollInfo;
INT nDrawPosY = infoPtr->rcList.top; INT nDrawPosY = infoPtr->rcList.top;
INT nColumnCount; INT nColumnCount;
RECT rcItem; RECT rcItem;
@ -1958,6 +2028,10 @@ static VOID LISTVIEW_RefreshReport(HWND hwnd, HDC hdc)
INT nItem; INT nItem;
INT nLast; INT nLast;
ZeroMemory(&scrollInfo, sizeof(SCROLLINFO));
scrollInfo.cbSize = sizeof(SCROLLINFO);
scrollInfo.fMask = SIF_POS;
nItem = ListView_GetTopIndex(hwnd); nItem = ListView_GetTopIndex(hwnd);
/* add 1 for displaying a partial item at the bottom */ /* add 1 for displaying a partial item at the bottom */
@ -1973,6 +2047,14 @@ static VOID LISTVIEW_RefreshReport(HWND hwnd, HDC hdc)
rcItem.right = max(rcItem.left, rcItem.right - REPORT_MARGINX); rcItem.right = max(rcItem.left, rcItem.right - REPORT_MARGINX);
rcItem.top = nDrawPosY; rcItem.top = nDrawPosY;
rcItem.bottom = rcItem.top + infoPtr->nItemHeight; rcItem.bottom = rcItem.top + infoPtr->nItemHeight;
/* Offset the Scroll Bar Pos */
if (GetScrollInfo(hwnd, SB_HORZ, &scrollInfo) != FALSE)
{
rcItem.left -= (scrollInfo.nPos * REPORT_HSCROLL_INC_SIZE);
rcItem.right -= (scrollInfo.nPos * REPORT_HSCROLL_INC_SIZE);
}
if (j == 0) if (j == 0)
{ {
LISTVIEW_DrawItem(hwnd, hdc, nItem, rcItem); LISTVIEW_DrawItem(hwnd, hdc, nItem, rcItem);
@ -5776,12 +5858,11 @@ static LRESULT LISTVIEW_GetFont(HWND hwnd)
static LRESULT LISTVIEW_VScroll(HWND hwnd, INT nScrollCode, SHORT nCurrentPos, static LRESULT LISTVIEW_VScroll(HWND hwnd, INT nScrollCode, SHORT nCurrentPos,
HWND hScrollWnd) HWND hScrollWnd)
{ {
UINT uView = GetWindowLongA(hwnd, GWL_STYLE) & LVS_TYPEMASK;
SCROLLINFO scrollInfo; SCROLLINFO scrollInfo;
ZeroMemory(&scrollInfo, sizeof(SCROLLINFO)); ZeroMemory(&scrollInfo, sizeof(SCROLLINFO));
scrollInfo.cbSize = sizeof(SCROLLINFO); scrollInfo.cbSize = sizeof(SCROLLINFO);
scrollInfo.fMask = /*SIF_PAGE |*/ SIF_POS | SIF_RANGE; scrollInfo.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
if (GetScrollInfo(hwnd, SB_VERT, &scrollInfo) != FALSE) if (GetScrollInfo(hwnd, SB_VERT, &scrollInfo) != FALSE)
{ {
@ -5805,20 +5886,10 @@ static LRESULT LISTVIEW_VScroll(HWND hwnd, INT nScrollCode, SHORT nCurrentPos,
case SB_PAGEUP: case SB_PAGEUP:
if (scrollInfo.nPos > scrollInfo.nMin) if (scrollInfo.nPos > scrollInfo.nMin)
{ {
INT nPage = 0;
if (uView == LVS_REPORT) if (scrollInfo.nPos >= scrollInfo.nPage)
{ {
nPage = LISTVIEW_GetCountPerColumn(hwnd); scrollInfo.nPos -= scrollInfo.nPage;
}
else if ((uView == LVS_ICON) || (uView == LVS_SMALLICON))
{
nPage = 10;
}
if (scrollInfo.nPos >= nPage)
{
scrollInfo.nPos -= nPage;
} }
else else
{ {
@ -5830,20 +5901,9 @@ static LRESULT LISTVIEW_VScroll(HWND hwnd, INT nScrollCode, SHORT nCurrentPos,
case SB_PAGEDOWN: case SB_PAGEDOWN:
if (scrollInfo.nPos < scrollInfo.nMax) if (scrollInfo.nPos < scrollInfo.nMax)
{ {
INT nPage = 0; if (scrollInfo.nPos <= scrollInfo.nMax - scrollInfo.nPage)
if (uView == LVS_REPORT)
{ {
nPage = LISTVIEW_GetCountPerColumn(hwnd); scrollInfo.nPos += scrollInfo.nPage;
}
else if ((uView == LVS_ICON) || (uView == LVS_SMALLICON))
{
nPage = 10;
}
if (scrollInfo.nPos <= scrollInfo.nMax - nPage)
{
scrollInfo.nPos += nPage;
} }
else else
{ {
@ -5885,12 +5945,11 @@ static LRESULT LISTVIEW_VScroll(HWND hwnd, INT nScrollCode, SHORT nCurrentPos,
static LRESULT LISTVIEW_HScroll(HWND hwnd, INT nScrollCode, SHORT nCurrentPos, static LRESULT LISTVIEW_HScroll(HWND hwnd, INT nScrollCode, SHORT nCurrentPos,
HWND hScrollWnd) HWND hScrollWnd)
{ {
UINT uView = GetWindowLongA(hwnd, GWL_STYLE) & LVS_TYPEMASK;
SCROLLINFO scrollInfo; SCROLLINFO scrollInfo;
ZeroMemory(&scrollInfo, sizeof(SCROLLINFO)); ZeroMemory(&scrollInfo, sizeof(SCROLLINFO));
scrollInfo.cbSize = sizeof(SCROLLINFO); scrollInfo.cbSize = sizeof(SCROLLINFO);
scrollInfo.fMask = /*SIF_PAGE |*/ SIF_POS | SIF_RANGE; scrollInfo.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
if (GetScrollInfo(hwnd, SB_HORZ, &scrollInfo) != FALSE) if (GetScrollInfo(hwnd, SB_HORZ, &scrollInfo) != FALSE)
{ {
@ -5915,20 +5974,9 @@ static LRESULT LISTVIEW_HScroll(HWND hwnd, INT nScrollCode, SHORT nCurrentPos,
case SB_PAGELEFT: case SB_PAGELEFT:
if (scrollInfo.nPos > scrollInfo.nMin) if (scrollInfo.nPos > scrollInfo.nMin)
{ {
INT nPage = 0; if (scrollInfo.nPos >= scrollInfo.nPage)
if (uView == LVS_LIST)
{ {
nPage = LISTVIEW_GetCountPerRow(hwnd); scrollInfo.nPos -= scrollInfo.nPage;
}
else if ((uView == LVS_ICON) || (uView == LVS_SMALLICON))
{
nPage = 10;
}
if (scrollInfo.nPos >= nPage)
{
scrollInfo.nPos -= nPage;
} }
else else
{ {
@ -5940,20 +5988,9 @@ static LRESULT LISTVIEW_HScroll(HWND hwnd, INT nScrollCode, SHORT nCurrentPos,
case SB_PAGERIGHT: case SB_PAGERIGHT:
if (scrollInfo.nPos < scrollInfo.nMax) if (scrollInfo.nPos < scrollInfo.nMax)
{ {
INT nPage = 0; if (scrollInfo.nPos <= scrollInfo.nMax - scrollInfo.nPage)
if (uView == LVS_LIST)
{ {
nPage = LISTVIEW_GetCountPerRow(hwnd); scrollInfo.nPos += scrollInfo.nPage;
}
else if ((uView == LVS_ICON) || (uView == LVS_SMALLICON))
{
nPage = 10;
}
if (scrollInfo.nPos <= scrollInfo.nMax - nPage)
{
scrollInfo.nPos += nPage;
} }
else else
{ {
@ -5969,8 +6006,15 @@ static LRESULT LISTVIEW_HScroll(HWND hwnd, INT nScrollCode, SHORT nCurrentPos,
if (nOldScrollPos != scrollInfo.nPos) if (nOldScrollPos != scrollInfo.nPos)
{ {
UINT uView = GetWindowLongA(hwnd, GWL_STYLE) & LVS_TYPEMASK;
scrollInfo.fMask = SIF_POS; scrollInfo.fMask = SIF_POS;
SetScrollInfo(hwnd, SB_HORZ, &scrollInfo, TRUE); SetScrollInfo(hwnd, SB_HORZ, &scrollInfo, TRUE);
scrollInfo.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
GetScrollInfo(hwnd, SB_HORZ, &scrollInfo);
if(uView == LVS_REPORT)
{
LISTVIEW_UpdateHeaderSize(hwnd, scrollInfo.nPos, nOldScrollPos);
}
InvalidateRect(hwnd, NULL, TRUE); InvalidateRect(hwnd, NULL, TRUE);
} }
} }
@ -6369,7 +6413,7 @@ static LRESULT LISTVIEW_Notify(HWND hwnd, INT nCtrlId, LPNMHDR lpnmh)
infoPtr->nItemWidth = LISTVIEW_GetItemWidth(hwnd); infoPtr->nItemWidth = LISTVIEW_GetItemWidth(hwnd);
InvalidateRect(hwnd, NULL, TRUE); InvalidateRect(hwnd, NULL, TRUE);
} }
if(lpnmh->code == HDN_ITEMCLICKA) else if(lpnmh->code == HDN_ITEMCLICKA)
{ {
/* Handle sorting by Header Column */ /* Handle sorting by Header Column */
NMLISTVIEW nmlv; NMLISTVIEW nmlv;
@ -6384,9 +6428,19 @@ static LRESULT LISTVIEW_Notify(HWND hwnd, INT nCtrlId, LPNMHDR lpnmh)
nmlv.iSubItem = pnmHeader->iItem; nmlv.iSubItem = pnmHeader->iItem;
ListView_LVNotify(GetParent(hwnd),lCtrlId, &nmlv); ListView_LVNotify(GetParent(hwnd),lCtrlId, &nmlv);
InvalidateRect(hwnd, NULL, TRUE);
} }
else if(lpnmh->code == NM_RELEASEDCAPTURE)
{
/* Idealy this should be done in HDN_ENDTRACKA
* but since SetItemBounds in Header.c is called after
* the notification is sent, it is neccessary to handle the
* update of the scroll bar here (Header.c works fine as it is,
* no need to disturb it)
*/
LISTVIEW_UpdateScroll(hwnd);
InvalidateRect(hwnd, NULL, TRUE);
}
} }