comctl32/listview: Implement LVS_EX_HEADERINALLVIEWS.

This commit is contained in:
Nikolay Sivov 2009-11-27 15:38:05 +03:00 committed by Alexandre Julliard
parent dcd54f08fc
commit 999810566b
2 changed files with 134 additions and 27 deletions

View File

@ -1588,6 +1588,13 @@ static inline void LISTVIEW_GetHeaderRect(const LISTVIEW_INFO *infoPtr, INT nSub
{
*lprc = LISTVIEW_GetColumnInfo(infoPtr, nSubItem)->rcHeader;
}
static inline BOOL LISTVIEW_IsHeaderEnabled(const LISTVIEW_INFO *infoPtr)
{
return (infoPtr->uView == LV_VIEW_DETAILS ||
infoPtr->dwLvExStyle & LVS_EX_HEADERINALLVIEWS) &&
!(infoPtr->dwStyle & LVS_NOCOLUMNHEADER);
}
static inline BOOL LISTVIEW_GetItemW(const LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem)
{
@ -1926,7 +1933,23 @@ static void LISTVIEW_UpdateScroll(const LISTVIEW_INFO *infoPtr)
if (LISTVIEW_GetViewRect(infoPtr, &rcView)) horzInfo.nMax = rcView.right - rcView.left;
}
if (LISTVIEW_IsHeaderEnabled(infoPtr))
{
if (DPA_GetPtrCount(infoPtr->hdpaColumns))
{
RECT rcHeader;
INT index;
index = SendMessageW(infoPtr->hwndHeader, HDM_ORDERTOINDEX,
DPA_GetPtrCount(infoPtr->hdpaColumns) - 1, 0);
LISTVIEW_GetHeaderRect(infoPtr, index, &rcHeader);
horzInfo.nMax = rcHeader.right;
TRACE("horzInfo.nMax=%d\n", horzInfo.nMax);
}
}
horzInfo.fMask = SIF_RANGE | SIF_PAGE;
horzInfo.nMax = max(horzInfo.nMax - 1, 0);
dx = GetScrollPos(infoPtr->hwndSelf, SB_HORZ);
@ -1976,7 +1999,7 @@ static void LISTVIEW_UpdateScroll(const LISTVIEW_INFO *infoPtr)
}
/* Update the Header Control */
if (infoPtr->uView == LV_VIEW_DETAILS)
if (infoPtr->hwndHeader)
{
horzInfo.fMask = SIF_POS;
GetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &horzInfo);
@ -8171,6 +8194,16 @@ static DWORD LISTVIEW_SetExtendedListViewStyle(LISTVIEW_INFO *infoPtr, DWORD dwM
LISTVIEW_SetBkColor(infoPtr, CLR_NONE);
}
if((infoPtr->dwLvExStyle ^ dwOldExStyle) & LVS_EX_HEADERINALLVIEWS)
{
if (infoPtr->dwLvExStyle & LVS_EX_HEADERINALLVIEWS)
LISTVIEW_CreateHeader(infoPtr);
else
ShowWindow(infoPtr->hwndHeader, SW_HIDE);
LISTVIEW_UpdateSize(infoPtr);
LISTVIEW_UpdateScroll(infoPtr);
}
LISTVIEW_InvalidateList(infoPtr);
return dwOldExStyle;
}
@ -9412,21 +9445,20 @@ static LRESULT LISTVIEW_HScroll(LISTVIEW_INFO *infoPtr, INT nScrollCode,
scrollInfo.fMask = SIF_POS;
scrollInfo.nPos = nNewScrollPos;
nNewScrollPos = SetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &scrollInfo, TRUE);
/* carry on only if it really changed */
if (nNewScrollPos == nOldScrollPos) return 0;
if (infoPtr->uView == LV_VIEW_DETAILS)
LISTVIEW_UpdateHeaderSize(infoPtr, nNewScrollPos);
if (infoPtr->hwndHeader) LISTVIEW_UpdateHeaderSize(infoPtr, nNewScrollPos);
/* now adjust to client coordinates */
nScrollDiff = nOldScrollPos - nNewScrollPos;
if (infoPtr->uView == LV_VIEW_LIST) nScrollDiff *= infoPtr->nItemWidth;
/* and scroll the window */
scroll_list(infoPtr, nScrollDiff, 0);
return 0;
return 0;
}
static LRESULT LISTVIEW_MouseWheel(LISTVIEW_INFO *infoPtr, INT wheelDelta)
@ -10077,6 +10109,9 @@ static LRESULT LISTVIEW_HeaderNotification(LISTVIEW_INFO *infoPtr, const NMHEADE
case HDN_DIVIDERDBLCLICKW:
case HDN_DIVIDERDBLCLICKA:
/* FIXME: for LVS_EX_HEADERINALLVIEWS and not LV_VIEW_DETAILS
we should use LVSCW_AUTOSIZE_USEHEADER, helper rework or
split needed for that */
LISTVIEW_SetColumnWidth(infoPtr, lpnmh->iItem, LVSCW_AUTOSIZE);
notify_forward_header(infoPtr, lpnmh);
break;
@ -10568,27 +10603,34 @@ static void LISTVIEW_UpdateSize(LISTVIEW_INFO *infoPtr)
infoPtr->rcList.bottom -= GetSystemMetrics(SM_CYHSCROLL);
infoPtr->rcList.bottom = max (infoPtr->rcList.bottom - 2, 0);
}
else if (infoPtr->uView == LV_VIEW_DETAILS)
/* if control created invisible header isn't created */
if (infoPtr->hwndHeader)
{
/* if control created invisible header isn't created */
if (infoPtr->hwndHeader)
HDLAYOUT hl;
WINDOWPOS wp;
hl.prc = &infoPtr->rcList;
hl.pwpos = ℘
SendMessageW( infoPtr->hwndHeader, HDM_LAYOUT, 0, (LPARAM)&hl );
TRACE(" wp.flags=0x%08x, wp=%d,%d (%dx%d)\n", wp.flags, wp.x, wp.y, wp.cx, wp.cy);
if (LISTVIEW_IsHeaderEnabled(infoPtr))
wp.flags |= SWP_SHOWWINDOW;
else
{
HDLAYOUT hl;
WINDOWPOS wp;
hl.prc = &infoPtr->rcList;
hl.pwpos = ℘
SendMessageW( infoPtr->hwndHeader, HDM_LAYOUT, 0, (LPARAM)&hl );
TRACE(" wp.flags=0x%08x, wp=%d,%d (%dx%d)\n", wp.flags, wp.x, wp.y, wp.cx, wp.cy);
SetWindowPos(wp.hwnd, wp.hwndInsertAfter, wp.x, wp.y, wp.cx, wp.cy,
wp.flags | ((infoPtr->dwStyle & LVS_NOCOLUMNHEADER)
? SWP_HIDEWINDOW : SWP_SHOWWINDOW));
TRACE(" after SWP wp=%d,%d (%dx%d)\n", wp.x, wp.y, wp.cx, wp.cy);
infoPtr->rcList.top = max(wp.cy, 0);
wp.flags |= SWP_HIDEWINDOW;
wp.cy = 0;
}
infoPtr->rcList.top += (infoPtr->dwLvExStyle & LVS_EX_GRIDLINES) ? 2 : 0;
SetWindowPos(wp.hwnd, wp.hwndInsertAfter, wp.x, wp.y, wp.cx, wp.cy, wp.flags);
TRACE(" after SWP wp=%d,%d (%dx%d)\n", wp.x, wp.y, wp.cx, wp.cy);
infoPtr->rcList.top = max(wp.cy, 0);
}
/* extra padding for grid */
if (infoPtr->uView == LV_VIEW_DETAILS && infoPtr->dwLvExStyle & LVS_EX_GRIDLINES)
infoPtr->rcList.top += 2;
TRACE(" rcList=%s\n", wine_dbgstr_rect(&infoPtr->rcList));
}
@ -10669,7 +10711,7 @@ static INT LISTVIEW_StyleChanged(LISTVIEW_INFO *infoPtr, WPARAM wStyleType,
LISTVIEW_UpdateItemSize(infoPtr);
}
if (uNewView == LVS_REPORT)
if (uNewView == LVS_REPORT || infoPtr->dwLvExStyle & LVS_EX_HEADERINALLVIEWS)
{
if ((lpss->styleOld ^ lpss->styleNew) & LVS_NOCOLUMNHEADER)
{

View File

@ -1253,6 +1253,8 @@ static void test_create(void)
LVCOLUMNA col;
RECT rect;
WNDCLASSEX cls;
DWORD style;
cls.cbSize = sizeof(WNDCLASSEX);
ok(GetClassInfoEx(GetModuleHandle(NULL), "SysListView32", &cls), "GetClassInfoEx failed\n");
listviewWndProc = cls.lpfnWndProc;
@ -1292,6 +1294,8 @@ static void test_create(void)
hHeader = (HWND)SendMessage(hList, LVM_GETHEADER, 0, 0);
ok(IsWindow(hHeader), "Header should be created\n");
ok(hHeader == GetDlgItem(hList, 0), "Expected header as dialog item\n");
style = GetWindowLong(hHeader, GWL_STYLE);
ok(!(style & HDS_HIDDEN), "Not expected HDS_HIDDEN\n");
DestroyWindow(hList);
hList = CreateWindow("SysListView32", "Test", WS_VISIBLE|LVS_LIST, 0, 0, 100, 100, NULL, NULL,
@ -4183,6 +4187,66 @@ static void test_finditem(void)
DestroyWindow(hwnd);
}
static void test_LVS_EX_HEADERINALLVIEWS(void)
{
HWND hwnd, header;
DWORD style;
hwnd = create_custom_listview_control(LVS_ICON);
SendMessage(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_HEADERINALLVIEWS,
LVS_EX_HEADERINALLVIEWS);
header = (HWND)SendMessage(hwnd, LVM_GETHEADER, 0, 0);
if (!IsWindow(header))
{
win_skip("LVS_EX_HEADERINALLVIEWS unsupported\n");
DestroyWindow(hwnd);
return;
}
/* LVS_NOCOLUMNHEADER works as before */
style = GetWindowLongA(hwnd, GWL_STYLE);
SetWindowLongW(hwnd, GWL_STYLE, style | LVS_NOCOLUMNHEADER);
style = GetWindowLongA(header, GWL_STYLE);
ok(style & HDS_HIDDEN, "Expected HDS_HIDDEN\n");
style = GetWindowLongA(hwnd, GWL_STYLE);
SetWindowLongW(hwnd, GWL_STYLE, style & ~LVS_NOCOLUMNHEADER);
style = GetWindowLongA(header, GWL_STYLE);
ok(!(style & HDS_HIDDEN), "Expected HDS_HIDDEN to be unset\n");
/* try to remove style */
SendMessage(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_HEADERINALLVIEWS, 0);
header = (HWND)SendMessage(hwnd, LVM_GETHEADER, 0, 0);
ok(IsWindow(header), "Expected header to be created\n");
style = GetWindowLongA(header, GWL_STYLE);
ok(!(style & HDS_HIDDEN), "HDS_HIDDEN not expected\n");
DestroyWindow(hwnd);
/* check other styles */
hwnd = create_custom_listview_control(LVS_LIST);
SendMessage(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_HEADERINALLVIEWS,
LVS_EX_HEADERINALLVIEWS);
header = (HWND)SendMessage(hwnd, LVM_GETHEADER, 0, 0);
ok(IsWindow(header), "Expected header to be created\n");
DestroyWindow(hwnd);
hwnd = create_custom_listview_control(LVS_SMALLICON);
SendMessage(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_HEADERINALLVIEWS,
LVS_EX_HEADERINALLVIEWS);
header = (HWND)SendMessage(hwnd, LVM_GETHEADER, 0, 0);
ok(IsWindow(header), "Expected header to be created\n");
DestroyWindow(hwnd);
hwnd = create_custom_listview_control(LVS_REPORT);
SendMessage(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_HEADERINALLVIEWS,
LVS_EX_HEADERINALLVIEWS);
header = (HWND)SendMessage(hwnd, LVM_GETHEADER, 0, 0);
ok(IsWindow(header), "Expected header to be created\n");
DestroyWindow(hwnd);
}
START_TEST(listview)
{
HMODULE hComctl32;
@ -4270,6 +4334,7 @@ START_TEST(listview)
test_mapidindex();
test_scrollnotify();
test_LVS_EX_TRANSPARENTBKGND();
test_LVS_EX_HEADERINALLVIEWS();
unload_v6_module(ctx_cookie, hCtx);