Module: wine Branch: master Commit: 59148d0bb549ff8690f15f14571a715e3fdd43a5 URL: http://source.winehq.org/git/wine.git/?a=commit;h=59148d0bb549ff8690f15f1457...
Author: Nikolay Sivov bunglehead@gmail.com Date: Tue Apr 7 12:15:21 2009 -0400
comctl32/listview: Implement delayed header creation for ListView control.
---
dlls/comctl32/listview.c | 96 ++++++++++++++++++++++++++++++++------- dlls/comctl32/tests/listview.c | 20 ++++---- 2 files changed, 88 insertions(+), 28 deletions(-)
diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c index 9d1b4ff..f06095b 100644 --- a/dlls/comctl32/listview.c +++ b/dlls/comctl32/listview.c @@ -1374,7 +1374,34 @@ static inline COLUMN_INFO * LISTVIEW_GetColumnInfo(const LISTVIEW_INFO *infoPtr, assert (nSubItem >= 0 && nSubItem < DPA_GetPtrCount(infoPtr->hdpaColumns)); return DPA_GetPtr(infoPtr->hdpaColumns, nSubItem); } - + +static INT LISTVIEW_CreateHeader(LISTVIEW_INFO *infoPtr) +{ + DWORD dFlags = WS_CHILD | HDS_HORZ | HDS_FULLDRAG | HDS_DRAGDROP; + HINSTANCE hInst; + + if (infoPtr->hwndHeader) return 0; + + /* setup creation flags */ + dFlags |= (LVS_NOSORTHEADER & infoPtr->dwStyle) ? 0 : HDS_BUTTONS; + dFlags |= (LVS_NOCOLUMNHEADER & infoPtr->dwStyle) ? HDS_HIDDEN : 0; + + hInst = (HINSTANCE)GetWindowLongPtrW(infoPtr->hwndSelf, GWLP_HINSTANCE); + + /* create header */ + infoPtr->hwndHeader = CreateWindowW(WC_HEADERW, NULL, dFlags, + 0, 0, 0, 0, infoPtr->hwndSelf, NULL, hInst, NULL); + if (!infoPtr->hwndHeader) return -1; + + /* set header unicode format */ + SendMessageW(infoPtr->hwndHeader, HDM_SETUNICODEFORMAT, TRUE, 0); + + /* set header font */ + SendMessageW(infoPtr->hwndHeader, WM_SETFONT, (WPARAM)infoPtr->hFont, (LPARAM)TRUE); + + return 0; +} + static inline void LISTVIEW_GetHeaderRect(const LISTVIEW_INFO *infoPtr, INT nSubItem, LPRECT lprc) { *lprc = LISTVIEW_GetColumnInfo(infoPtr, nSubItem)->rcHeader; @@ -6859,6 +6886,7 @@ static INT LISTVIEW_InsertColumnT(LISTVIEW_INFO *infoPtr, INT nColumn, COLUMN_INFO *lpColumnInfo; INT nNewColumn; HDITEMW hdi; + UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
TRACE("(nColumn=%d, lpColumn=%s, isW=%d)\n", nColumn, debuglvcolumn_t(lpColumn, isW), isW);
@@ -6887,6 +6915,14 @@ static INT LISTVIEW_InsertColumnT(LISTVIEW_INFO *infoPtr, INT nColumn, hdi.lParam = lpColumn->iSubItem; }
+ /* create header if not present */ + LISTVIEW_CreateHeader(infoPtr); + if (!(LVS_NOCOLUMNHEADER & infoPtr->dwStyle) && + (LVS_REPORT == uView) && (WS_VISIBLE & infoPtr->dwStyle)) + { + ShowWindow(infoPtr->hwndHeader, SW_SHOWNORMAL); + } + /* insert item in header control */ nNewColumn = SendMessageW(infoPtr->hwndHeader, isW ? HDM_INSERTITEMW : HDM_INSERTITEMA, @@ -8079,7 +8115,6 @@ static LRESULT LISTVIEW_Create(HWND hwnd, const CREATESTRUCTW *lpcs) { LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongPtrW(hwnd, 0); UINT uView = lpcs->style & LVS_TYPEMASK; - DWORD dFlags = WS_CHILD | HDS_HORZ | HDS_FULLDRAG | HDS_DRAGDROP;
TRACE("(lpcs=%p)\n", lpcs);
@@ -8087,28 +8122,19 @@ static LRESULT LISTVIEW_Create(HWND hwnd, const CREATESTRUCTW *lpcs) infoPtr->notifyFormat = SendMessageW(infoPtr->hwndNotify, WM_NOTIFYFORMAT, (WPARAM)infoPtr->hwndSelf, (LPARAM)NF_QUERY);
- /* setup creation flags */ - dFlags |= (LVS_NOSORTHEADER & lpcs->style) ? 0 : HDS_BUTTONS; - dFlags |= (LVS_NOCOLUMNHEADER & lpcs->style) ? HDS_HIDDEN : 0; - - /* create header */ - infoPtr->hwndHeader = CreateWindowW(WC_HEADERW, NULL, dFlags, - 0, 0, 0, 0, hwnd, NULL, - lpcs->hInstance, NULL); - if (!infoPtr->hwndHeader) return -1; - - /* set header unicode format */ - SendMessageW(infoPtr->hwndHeader, HDM_SETUNICODEFORMAT, TRUE, 0); - - /* set header font */ - SendMessageW(infoPtr->hwndHeader, WM_SETFONT, (WPARAM)infoPtr->hFont, (LPARAM)TRUE); + if ((uView == LVS_REPORT) && (lpcs->style & WS_VISIBLE)) + { + if (LISTVIEW_CreateHeader(infoPtr) < 0) return -1; + } + else + infoPtr->hwndHeader = 0;
/* init item size to avoid division by 0 */ LISTVIEW_UpdateItemSize (infoPtr);
if (uView == LVS_REPORT) { - if (!(LVS_NOCOLUMNHEADER & lpcs->style)) + if (!(LVS_NOCOLUMNHEADER & lpcs->style) && (WS_VISIBLE & lpcs->style)) { ShowWindow(infoPtr->hwndHeader, SW_SHOWNORMAL); } @@ -9553,6 +9579,8 @@ static INT LISTVIEW_StyleChanged(LISTVIEW_INFO *infoPtr, WPARAM wStyleType, HDLAYOUT hl; WINDOWPOS wp;
+ LISTVIEW_CreateHeader( infoPtr ); + hl.prc = &infoPtr->rcList; hl.pwpos = ℘ SendMessageW( infoPtr->hwndHeader, HDM_LAYOUT, 0, (LPARAM)&hl ); @@ -9603,6 +9631,34 @@ static INT LISTVIEW_StyleChanged(LISTVIEW_INFO *infoPtr, WPARAM wStyleType,
/*** * DESCRIPTION: + * Processes WM_SHOWWINDOW messages. + * + * PARAMETER(S): + * [I] infoPtr : valid pointer to the listview structure + * [I] bShown : window is being shown (FALSE when hidden) + * [I] iStatus : window show status + * + * RETURN: + * Zero + */ +static LRESULT LISTVIEW_ShowWindow(LISTVIEW_INFO *infoPtr, BOOL bShown, INT iStatus) +{ + UINT uView = infoPtr->dwStyle & LVS_TYPEMASK; + + /* header delayed creation */ + if ((uView == LVS_REPORT) && bShown) + { + LISTVIEW_CreateHeader(infoPtr); + + if (!(LVS_NOCOLUMNHEADER & infoPtr->dwStyle)) + ShowWindow(infoPtr->hwndHeader, SW_SHOWNORMAL); + } + + return 0; +} + +/*** + * DESCRIPTION: * Window procedure of the listview control. * */ @@ -10064,6 +10120,10 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case WM_SETREDRAW: return LISTVIEW_SetRedraw(infoPtr, (BOOL)wParam);
+ case WM_SHOWWINDOW: + LISTVIEW_ShowWindow(infoPtr, (BOOL)wParam, (INT)lParam); + return DefWindowProcW(hwnd, uMsg, wParam, lParam); + case WM_SIZE: return LISTVIEW_Size(infoPtr, (short)LOWORD(lParam), (short)HIWORD(lParam));
diff --git a/dlls/comctl32/tests/listview.c b/dlls/comctl32/tests/listview.c index 84db3d2..6f3524b 100644 --- a/dlls/comctl32/tests/listview.c +++ b/dlls/comctl32/tests/listview.c @@ -787,8 +787,8 @@ static void test_create(void) hList = CreateWindow("SysListView32", "Test", WS_VISIBLE, 0, 0, 100, 100, NULL, NULL, GetModuleHandle(NULL), 0); hHeader = (HWND)SendMessage(hList, LVM_GETHEADER, 0, 0); - todo_wine ok(!IsWindow(hHeader), "Header shouldn't be created\n"); - todo_wine ok(NULL == GetDlgItem(hList, 0), "NULL dialog item expected\n"); + ok(!IsWindow(hHeader), "Header shouldn't be created\n"); + ok(NULL == GetDlgItem(hList, 0), "NULL dialog item expected\n"); /* insert column */ memset(&col, 0, sizeof(LVCOLUMNA)); col.mask = LVCF_WIDTH; @@ -803,8 +803,8 @@ static void test_create(void) hList = CreateWindow("SysListView32", "Test", WS_VISIBLE|LVS_LIST, 0, 0, 100, 100, NULL, NULL, GetModuleHandle(NULL), 0); hHeader = (HWND)SendMessage(hList, LVM_GETHEADER, 0, 0); - todo_wine ok(!IsWindow(hHeader), "Header shouldn't be created\n"); - todo_wine ok(NULL == GetDlgItem(hList, 0), "NULL dialog item expected\n"); + ok(!IsWindow(hHeader), "Header shouldn't be created\n"); + ok(NULL == GetDlgItem(hList, 0), "NULL dialog item expected\n"); /* insert column */ memset(&col, 0, sizeof(LVCOLUMNA)); col.mask = LVCF_WIDTH; @@ -851,8 +851,8 @@ static void test_create(void) hList = CreateWindow("SysListView32", "Test", LVS_REPORT, 0, 0, 100, 100, NULL, NULL, GetModuleHandle(NULL), 0); hHeader = (HWND)SendMessage(hList, LVM_GETHEADER, 0, 0); - todo_wine ok(!IsWindow(hHeader), "Header shouldn't be created\n"); - todo_wine ok(NULL == GetDlgItem(hList, 0), "NULL dialog item expected\n"); + ok(!IsWindow(hHeader), "Header shouldn't be created\n"); + ok(NULL == GetDlgItem(hList, 0), "NULL dialog item expected\n"); /* insert column */ memset(&col, 0, sizeof(LVCOLUMNA)); col.mask = LVCF_WIDTH; @@ -868,12 +868,12 @@ static void test_create(void) hList = CreateWindow("SysListView32", "Test", LVS_REPORT, 0, 0, 100, 100, NULL, NULL, GetModuleHandle(NULL), 0); hHeader = (HWND)SendMessage(hList, LVM_GETHEADER, 0, 0); - todo_wine ok(!IsWindow(hHeader), "Header shouldn't be created\n"); - todo_wine ok(NULL == GetDlgItem(hList, 0), "NULL dialog item expected\n"); + ok(!IsWindow(hHeader), "Header shouldn't be created\n"); + ok(NULL == GetDlgItem(hList, 0), "NULL dialog item expected\n"); ShowWindow(hList, SW_SHOW); hHeader = (HWND)SendMessage(hList, LVM_GETHEADER, 0, 0); - ok(IsWindow(hHeader), "Header shouldn't be created\n"); - ok(hHeader == GetDlgItem(hList, 0), "NULL dialog item expected\n"); + ok(IsWindow(hHeader), "Header should be created\n"); + ok(hHeader == GetDlgItem(hList, 0), "Expected header as dialog item\n"); DestroyWindow(hList); }