comctl32/treeview: Always return state from TVM_GETITEM handler.

oldstable
Nikolay Sivov 2011-05-14 15:12:06 +04:00 committed by Alexandre Julliard
parent 3174ea94c1
commit 1fa1c72d90
2 changed files with 106 additions and 25 deletions

View File

@ -39,6 +39,7 @@ static TVITEMA g_item_expanding, g_item_expanded;
static BOOL g_get_from_expand;
static BOOL g_get_rect_in_expand;
static BOOL g_disp_A_to_W;
static BOOL g_disp_set_stateimage;
#define NUM_MSG_SEQUENCES 2
#define TREEVIEW_SEQ_INDEX 0
@ -211,6 +212,11 @@ static const struct message parent_singleexpand_seq[] = {
{ 0 }
};
static const struct message parent_get_dispinfo_seq[] = {
{ WM_NOTIFY, sent|id, 0, 0, TVN_GETDISPINFOA },
{ 0 }
};
static const struct message empty_seq[] = {
{ 0 }
};
@ -349,13 +355,13 @@ static void test_callback(void)
CHAR test_string[] = "Test_string";
static const CHAR test2A[] = "TEST2";
CHAR buf[128];
LRESULT ret;
HWND hTree;
DWORD ret;
hTree = create_treeview_control();
ret = TreeView_DeleteAllItems(hTree);
ok(ret == TRUE, "ret\n");
expect(TRUE, ret);
ins.hParent = TVI_ROOT;
ins.hInsertAfter = TVI_ROOT;
U(ins).item.mask = TVIF_TEXT;
@ -368,7 +374,7 @@ static void test_callback(void)
tvi.pszText = buf;
tvi.cchTextMax = sizeof(buf)/sizeof(buf[0]);
ret = TreeView_GetItem(hTree, &tvi);
ok(ret == 1, "ret\n");
expect(TRUE, ret);
ok(strcmp(tvi.pszText, TEST_CALLBACK_TEXT) == 0, "Callback item text mismatch %s vs %s\n",
tvi.pszText, TEST_CALLBACK_TEXT);
@ -381,17 +387,17 @@ static void test_callback(void)
tvi.hItem = hItem1;
ret = TreeView_GetItem(hTree, &tvi);
ok(ret == TRUE, "ret\n");
expect(TRUE, ret);
ok(strcmp(tvi.pszText, test_string) == 0, "Item text mismatch %s vs %s\n",
tvi.pszText, test_string);
/* undocumented: pszText of NULL also means LPSTR_CALLBACK: */
tvi.pszText = NULL;
ret = TreeView_SetItem(hTree, &tvi);
ok(ret == 1, "Expected SetItem return 1, got %ld\n", ret);
expect(TRUE, ret);
tvi.pszText = buf;
ret = TreeView_GetItem(hTree, &tvi);
ok(ret == TRUE, "Expected GetItem return TRUE, got %ld\n", ret);
expect(TRUE, ret);
ok(strcmp(tvi.pszText, TEST_CALLBACK_TEXT) == 0, "Item text mismatch %s vs %s\n",
tvi.pszText, TEST_CALLBACK_TEXT);
@ -401,7 +407,7 @@ static void test_callback(void)
tvi.hItem = hItem2;
memset(buf, 0, sizeof(buf));
ret = TreeView_GetItem(hTree, &tvi);
ok(ret == TRUE, "Expected GetItem return TRUE, got %ld\n", ret);
expect(TRUE, ret);
ok(strcmp(tvi.pszText, TEST_CALLBACK_TEXT) == 0, "Item text mismatch %s vs %s\n",
tvi.pszText, TEST_CALLBACK_TEXT);
@ -410,11 +416,67 @@ static void test_callback(void)
tvi.hItem = hItem2;
memset(buf, 0, sizeof(buf));
ret = TreeView_GetItem(hTree, &tvi);
ok(ret == TRUE, "got %ld\n", ret);
expect(TRUE, ret);
ok(strcmp(tvi.pszText, test2A) == 0, "got %s, expected %s\n",
tvi.pszText, test2A);
g_disp_A_to_W = FALSE;
/* handler changes state image index */
SetWindowLongA(hTree, GWL_STYLE, GetWindowLongA(hTree, GWL_STYLE) | TVS_CHECKBOXES);
/* clear selection, handler will set selected state */
ret = SendMessageA(hTree, TVM_SELECTITEM, TVGN_CARET, 0);
expect(TRUE, ret);
flush_sequences(sequences, NUM_MSG_SEQUENCES);
tvi.hItem = hRoot;
tvi.mask = TVIF_STATE;
tvi.state = TVIS_SELECTED;
ret = TreeView_GetItem(hTree, &tvi);
expect(TRUE, ret);
todo_wine ok(tvi.state == INDEXTOSTATEIMAGEMASK(1), "got 0x%x\n", tvi.state);
ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq,
"no TVN_GETDISPINFO for a state seq", FALSE);
tvi.hItem = hRoot;
tvi.mask = TVIF_IMAGE | TVIF_STATE;
tvi.state = TVIS_FOCUSED;
tvi.stateMask = TVIS_FOCUSED;
tvi.iImage = I_IMAGECALLBACK;
ret = TreeView_SetItem(hTree, &tvi);
expect(TRUE, ret);
/* ask for item image index through callback - state is also set with state image index */
flush_sequences(sequences, NUM_MSG_SEQUENCES);
tvi.hItem = hRoot;
tvi.mask = TVIF_IMAGE;
tvi.state = 0;
ret = TreeView_GetItem(hTree, &tvi);
expect(TRUE, ret);
todo_wine ok(tvi.state == (INDEXTOSTATEIMAGEMASK(1) | TVIS_FOCUSED), "got 0x%x\n", tvi.state);
ok_sequence(sequences, PARENT_SEQ_INDEX, parent_get_dispinfo_seq,
"callback for state/overlay image index, noop seq", FALSE);
/* ask for image again and overwrite state to some value in handler */
flush_sequences(sequences, NUM_MSG_SEQUENCES);
g_disp_set_stateimage = TRUE;
tvi.hItem = hRoot;
tvi.mask = TVIF_IMAGE;
tvi.state = INDEXTOSTATEIMAGEMASK(1);
ret = TreeView_GetItem(hTree, &tvi);
expect(TRUE, ret);
/* handler sets TVIS_SELECTED as well */
todo_wine ok(tvi.state == (TVIS_FOCUSED | TVIS_SELECTED | INDEXTOSTATEIMAGEMASK(2) | INDEXTOOVERLAYMASK(3)), "got 0x%x\n", tvi.state);
g_disp_set_stateimage = FALSE;
ok_sequence(sequences, PARENT_SEQ_INDEX, parent_get_dispinfo_seq,
"callback for state/overlay image index seq", FALSE);
DestroyWindow(hTree);
}
@ -668,32 +730,47 @@ static void test_get_set_item(void)
TVITEMA tviRoot = {0};
int nBufferSize = 80;
char szBuffer[80] = {0};
DWORD ret;
HWND hTree;
hTree = create_treeview_control();
fill_tree(hTree);
tviRoot.hItem = hRoot;
tviRoot.mask = TVIF_STATE;
tviRoot.state = TVIS_FOCUSED;
tviRoot.stateMask = TVIS_FOCUSED;
ret = SendMessage( hTree, TVM_SETITEMA, 0, (LPARAM)&tviRoot );
expect(TRUE, ret);
flush_sequences(sequences, NUM_MSG_SEQUENCES);
/* Test the root item */
/* Test the root item, state is set even when not requested */
tviRoot.hItem = hRoot;
tviRoot.mask = TVIF_TEXT;
tviRoot.state = 0;
tviRoot.stateMask = 0;
tviRoot.cchTextMax = nBufferSize;
tviRoot.pszText = szBuffer;
SendMessage( hTree, TVM_GETITEMA, 0, (LPARAM)&tviRoot );
ret = SendMessage( hTree, TVM_GETITEMA, 0, (LPARAM)&tviRoot );
expect(TRUE, ret);
ok(!strcmp("Root", szBuffer), "GetItem: szBuffer=\"%s\", expected \"Root\"\n", szBuffer);
ok(tviRoot.state == TVIS_FOCUSED, "got 0x%0x\n", tviRoot.state);
/* Change the root text */
strncpy(szBuffer, "Testing123", nBufferSize);
SendMessage( hTree, TVM_SETITEMA, 0, (LPARAM)&tviRoot );
ret = SendMessage( hTree, TVM_SETITEMA, 0, (LPARAM)&tviRoot );
expect(TRUE, ret);
memset(szBuffer, 0, nBufferSize);
SendMessage( hTree, TVM_GETITEMA, 0, (LPARAM)&tviRoot );
ret = SendMessage( hTree, TVM_GETITEMA, 0, (LPARAM)&tviRoot );
expect(TRUE, ret);
ok(!strcmp("Testing123", szBuffer), "GetItem: szBuffer=\"%s\", expected \"Testing123\"\n", szBuffer);
/* Reset the root text */
memset(szBuffer, 0, nBufferSize);
strncpy(szBuffer, "Root", nBufferSize);
SendMessage( hTree, TVM_SETITEMA, 0, (LPARAM)&tviRoot );
ret = SendMessage( hTree, TVM_SETITEMA, 0, (LPARAM)&tviRoot );
expect(TRUE, ret);
ok_sequence(sequences, TREEVIEW_SEQ_INDEX, test_get_set_item_seq,
"test get set item", FALSE);
@ -936,6 +1013,15 @@ static LRESULT CALLBACK parent_wnd_proc(HWND hWnd, UINT message, WPARAM wParam,
memcpy(disp->item.pszText, testW, sizeof(testW));
}
if (g_disp_set_stateimage)
{
ok(disp->item.mask == TVIF_IMAGE, "got %x\n", disp->item.mask);
/* both masks set here are necessary to change state bits */
disp->item.mask |= TVIF_STATE;
disp->item.state = TVIS_SELECTED | INDEXTOSTATEIMAGEMASK(2) | INDEXTOOVERLAYMASK(3);
disp->item.stateMask = TVIS_SELECTED | TVIS_OVERLAYMASK | TVIS_STATEIMAGEMASK;
}
break;
}
case TVN_ENDLABELEDIT: return TRUE;

View File

@ -704,7 +704,7 @@ TREEVIEW_UpdateDispInfo(const TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem,
NMTVDISPINFOEXW callback;
HWND hwnd = infoPtr->hwnd;
TRACE("mask %x callbackMask %x\n", mask, wineItem->callbackMask);
TRACE("mask=0x%x, callbackmask=0x%x\n", mask, wineItem->callbackMask);
mask &= wineItem->callbackMask;
if (mask == 0) return;
@ -735,7 +735,7 @@ TREEVIEW_UpdateDispInfo(const TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem,
if ((mask & TVIF_TEXT) && callback.item.pszText != wineItem->pszText)
{
/* Instead of copying text into our buffer user specified its own */
/* Instead of copying text into our buffer user specified his own */
if (!infoPtr->bNtfUnicode && (callback.hdr.code == TVN_GETDISPINFOA)) {
LPWSTR newText;
int buflen;
@ -2100,9 +2100,7 @@ TREEVIEW_GetItemT(const TREEVIEW_INFO *infoPtr, LPTVITEMEXW tvItem, BOOL isW)
if (tvItem->mask & TVIF_INTEGRAL)
tvItem->iIntegral = wineItem->iIntegral;
/* undocumented: windows ignores TVIF_PARAM and
* * always sets lParam
*/
/* undocumented: (mask & TVIF_PARAM) ignored and lParam is always set */
tvItem->lParam = wineItem->lParam;
if (tvItem->mask & TVIF_SELECTEDIMAGE)
@ -2111,11 +2109,8 @@ TREEVIEW_GetItemT(const TREEVIEW_INFO *infoPtr, LPTVITEMEXW tvItem, BOOL isW)
if (tvItem->mask & TVIF_EXPANDEDIMAGE)
tvItem->iExpandedImage = wineItem->iExpandedImage;
if (tvItem->mask & TVIF_STATE)
/* Careful here - Windows ignores the stateMask when you get the state
That contradicts the documentation, but makes more common sense, masking
retrieval in this way seems overkill */
tvItem->state = wineItem->state;
/* undocumented: stateMask and (state & TVIF_STATE) ignored, so state is always set */
tvItem->state = wineItem->state;
if (tvItem->mask & TVIF_TEXT)
{
@ -2157,8 +2152,8 @@ TREEVIEW_GetItemT(const TREEVIEW_INFO *infoPtr, LPTVITEMEXW tvItem, BOOL isW)
tvItem->uStateEx = 0;
}
TRACE("item <%p>, txt %p, img %p, mask %x\n",
wineItem, tvItem->pszText, &tvItem->iImage, tvItem->mask);
TRACE("item <%p>, txt %p, img %d, mask %x\n",
wineItem, tvItem->pszText, tvItem->iImage, tvItem->mask);
return TRUE;
}