"tests/hlsl/cast-componentwise-compatible.shader_test" did not exist on "fcef2693474d427caf75d16b3a4ed07bb02f6205"
Newer
Older
/*
* ListView tests
*
* Copyright 2006 Mike McCormack for CodeWeavers
* Copyright 2009-2014 Nikolay Sivov
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdio.h>
#include <windows.h>
#include <commctrl.h>
#include "wine/test.h"
#include "v6util.h"
#include "msg.h"
static HIMAGELIST (WINAPI *pImageList_Create)(int, int, UINT, int, int);
static BOOL (WINAPI *pImageList_Destroy)(HIMAGELIST);
static int (WINAPI *pImageList_Add)(HIMAGELIST, HBITMAP, HBITMAP);
static BOOL (WINAPI *p_TrackMouseEvent)(TRACKMOUSEEVENT *);
enum seq_index {
PARENT_SEQ_INDEX,
PARENT_FULL_SEQ_INDEX,
PARENT_CD_SEQ_INDEX,
LISTVIEW_SEQ_INDEX,
EDITBOX_SEQ_INDEX,
COMBINED_SEQ_INDEX,
NUM_MSG_SEQUENCES
};
#define LISTVIEW_ID 0
#define HEADER_ID 1
#define expect(expected, got) ok(got == expected, "Expected %d, got %d\n", expected, got)
#define expect2(expected1, expected2, got1, got2) ok(expected1 == got1 && expected2 == got2, \
"expected (%d,%d), got (%d,%d)\n", expected1, expected2, got1, got2)
static const WCHAR testparentclassW[] =
{'L','i','s','t','v','i','e','w',' ','t','e','s','t',' ','p','a','r','e','n','t','W', 0};
static HWND hwndparent, hwndparentW;
Nikolay Sivov
committed
/* prevents edit box creation, LVN_BEGINLABELEDIT return value */
static BOOL blockEdit;
/* return nonzero on NM_HOVER */
static BOOL g_block_hover;
Nikolay Sivov
committed
/* notification data for LVN_ITEMCHANGED */
static NMLISTVIEW g_nmlistview;
Nikolay Sivov
committed
/* notification data for LVN_ITEMCHANGING */
static NMLISTVIEW g_nmlistview_changing;
/* format reported to control:
-1 falls to defproc, anything else returned */
Nikolay Sivov
committed
static INT notifyFormat;
/* indicates we're running < 5.80 version */
static BOOL g_is_below_5;
/* item data passed to LVN_GETDISPINFOA */
static LVITEMA g_itema;
Nikolay Sivov
committed
/* alter notification code A->W */
static BOOL g_disp_A_to_W;
Nikolay Sivov
committed
/* dispinfo data sent with LVN_LVN_ENDLABELEDIT */
static NMLVDISPINFOA g_editbox_disp_info;
/* when this is set focus will be tested on LVN_DELETEITEM */
static BOOL g_focus_test_LVN_DELETEITEM;
Fabian Maurer
committed
/* Whether to send WM_KILLFOCUS to the edit control during LVN_ENDLABELEDIT */
static BOOL g_WM_KILLFOCUS_on_LVN_ENDLABELEDIT;
Nikolay Sivov
committed
static HWND subclass_editbox(HWND hwndListview);
static void init_functions(void)
{
HMODULE hComCtl32 = LoadLibraryA("comctl32.dll");
#define X(f) p##f = (void*)GetProcAddress(hComCtl32, #f);
X(ImageList_Create);
X(ImageList_Destroy);
X(ImageList_Add);
X(_TrackMouseEvent);
#undef X
}
static struct msg_sequence *sequences[NUM_MSG_SEQUENCES];
Nikolay Sivov
committed
static const struct message create_ownerdrawfixed_parent_seq[] = {
{ WM_NOTIFYFORMAT, sent },
{ WM_QUERYUISTATE, sent|optional }, /* Win2K and higher */
{ WM_MEASUREITEM, sent },
{ WM_PARENTNOTIFY, sent },
{ 0 }
};
static const struct message redraw_listview_seq[] = {
{ WM_PAINT, sent|id, 0, 0, LISTVIEW_ID },
{ WM_PAINT, sent|id, 0, 0, HEADER_ID },
{ WM_NCPAINT, sent|id|defwinproc, 0, 0, HEADER_ID },
{ WM_ERASEBKGND, sent|id|defwinproc|optional, 0, 0, HEADER_ID },
{ WM_NOTIFY, sent|id|defwinproc, 0, 0, LISTVIEW_ID },
{ WM_NCPAINT, sent|id|defwinproc, 0, 0, LISTVIEW_ID },
{ WM_ERASEBKGND, sent|id|defwinproc|optional, 0, 0, LISTVIEW_ID },
{ 0 }
};
static const struct message listview_icon_spacing_seq[] = {
{ LVM_SETICONSPACING, sent|lparam, 0, MAKELPARAM(20, 30) },
{ LVM_SETICONSPACING, sent|lparam, 0, MAKELPARAM(25, 35) },
{ LVM_SETICONSPACING, sent|lparam, 0, MAKELPARAM(-1, -1) },
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
{ 0 }
};
static const struct message listview_color_seq[] = {
{ LVM_SETBKCOLOR, sent|lparam, 0, RGB(0,0,0) },
{ LVM_GETBKCOLOR, sent },
{ LVM_SETTEXTCOLOR, sent|lparam, 0, RGB(0,0,0) },
{ LVM_GETTEXTCOLOR, sent },
{ LVM_SETTEXTBKCOLOR, sent|lparam, 0, RGB(0,0,0) },
{ LVM_GETTEXTBKCOLOR, sent },
{ LVM_SETBKCOLOR, sent|lparam, 0, RGB(100,50,200) },
{ LVM_GETBKCOLOR, sent },
{ LVM_SETTEXTCOLOR, sent|lparam, 0, RGB(100,50,200) },
{ LVM_GETTEXTCOLOR, sent },
{ LVM_SETTEXTBKCOLOR, sent|lparam, 0, RGB(100,50,200) },
{ LVM_GETTEXTBKCOLOR, sent },
{ LVM_SETBKCOLOR, sent|lparam, 0, CLR_NONE },
{ LVM_GETBKCOLOR, sent },
{ LVM_SETTEXTCOLOR, sent|lparam, 0, CLR_NONE },
{ LVM_GETTEXTCOLOR, sent },
{ LVM_SETTEXTBKCOLOR, sent|lparam, 0, CLR_NONE },
{ LVM_GETTEXTBKCOLOR, sent },
{ LVM_SETBKCOLOR, sent|lparam, 0, RGB(255,255,255) },
{ LVM_GETBKCOLOR, sent },
{ LVM_SETTEXTCOLOR, sent|lparam, 0, RGB(255,255,255) },
{ LVM_GETTEXTCOLOR, sent },
{ LVM_SETTEXTBKCOLOR, sent|lparam, 0, RGB(255,255,255) },
{ LVM_GETTEXTBKCOLOR, sent },
{ 0 }
};
static const struct message listview_item_count_seq[] = {
{ LVM_GETITEMCOUNT, sent },
{ LVM_INSERTITEMA, sent },
{ LVM_INSERTITEMA, sent },
{ LVM_INSERTITEMA, sent },
{ LVM_GETITEMCOUNT, sent },
{ LVM_DELETEITEM, sent|wparam, 2 },
{ WM_NCPAINT, sent|optional },
{ WM_ERASEBKGND, sent|optional },
{ LVM_GETITEMCOUNT, sent },
{ LVM_DELETEALLITEMS, sent },
{ LVM_GETITEMCOUNT, sent },
{ LVM_INSERTITEMA, sent },
{ LVM_INSERTITEMA, sent },
{ LVM_INSERTITEMA, sent },
{ LVM_GETITEMCOUNT, sent },
{ 0 }
};
static const struct message listview_itempos_seq[] = {
{ LVM_INSERTITEMA, sent },
{ LVM_INSERTITEMA, sent },
{ LVM_INSERTITEMA, sent },
{ LVM_SETITEMPOSITION, sent|wparam|lparam, 1, MAKELPARAM(10,5) },
{ WM_NCPAINT, sent|optional },
{ WM_ERASEBKGND, sent|optional },
{ LVM_GETITEMPOSITION, sent|wparam, 1 },
{ LVM_SETITEMPOSITION, sent|wparam|lparam, 2, MAKELPARAM(0,0) },
{ LVM_GETITEMPOSITION, sent|wparam, 2 },
{ LVM_SETITEMPOSITION, sent|wparam|lparam, 0, MAKELPARAM(20,20) },
{ LVM_GETITEMPOSITION, sent|wparam, 0 },
{ 0 }
};
Nikolay Sivov
committed
static const struct message listview_ownerdata_switchto_seq[] = {
{ WM_STYLECHANGING, sent },
{ WM_STYLECHANGED, sent },
{ 0 }
};
Nikolay Sivov
committed
static const struct message listview_getorderarray_seq[] = {
{ LVM_GETCOLUMNORDERARRAY, sent|id|wparam, 2, 0, LISTVIEW_ID },
{ HDM_GETORDERARRAY, sent|id|wparam, 2, 0, HEADER_ID },
{ LVM_GETCOLUMNORDERARRAY, sent|id|wparam, 0, 0, LISTVIEW_ID },
{ HDM_GETORDERARRAY, sent|id|wparam, 0, 0, HEADER_ID },
Nikolay Sivov
committed
{ 0 }
};
static const struct message listview_setorderarray_seq[] = {
{ LVM_SETCOLUMNORDERARRAY, sent|id|wparam, 2, 0, LISTVIEW_ID },
{ HDM_SETORDERARRAY, sent|id|wparam, 2, 0, HEADER_ID },
{ LVM_SETCOLUMNORDERARRAY, sent|id|wparam, 0, 0, LISTVIEW_ID },
{ HDM_SETORDERARRAY, sent|id|wparam, 0, 0, HEADER_ID },
{ 0 }
};
static const struct message empty_seq[] = {
{ 0 }
};
static const struct message parent_focus_change_ownerdata_seq[] = {
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED },
{ WM_NOTIFY, sent|id, 0, 0, LVN_GETDISPINFOA },
{ 0 }
};
Nikolay Sivov
committed
static const struct message forward_erasebkgnd_parent_seq[] = {
{ WM_ERASEBKGND, sent },
{ 0 }
};
static const struct message ownerdata_select_focus_parent_seq[] = {
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED },
{ WM_NOTIFY, sent|id, 0, 0, LVN_GETDISPINFOA },
{ WM_NOTIFY, sent|id|optional, 0, 0, LVN_GETDISPINFOA }, /* version 4.7x */
{ 0 }
};
static const struct message ownerdata_setstate_all_parent_seq[] = {
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED },
{ 0 }
};
static const struct message ownerdata_defocus_all_parent_seq[] = {
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED },
{ WM_NOTIFY, sent|id, 0, 0, LVN_GETDISPINFOA },
{ WM_NOTIFY, sent|id|optional, 0, 0, LVN_GETDISPINFOA },
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED },
{ 0 }
};
static const struct message ownerdata_deselect_all_parent_seq[] = {
{ WM_NOTIFY, sent|id, 0, 0, LVN_ODCACHEHINT },
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED },
{ 0 }
};
Nikolay Sivov
committed
static const struct message change_all_parent_seq[] = {
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING },
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED },
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING },
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED },
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING },
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED },
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING },
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED },
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING },
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED },
{ 0 }
};
Nikolay Sivov
committed
static const struct message changing_all_parent_seq[] = {
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING },
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING },
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING },
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING },
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING },
{ 0 }
};
static const struct message textcallback_set_again_parent_seq[] = {
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING },
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED },
{ 0 }
};
Nikolay Sivov
committed
static const struct message single_getdispinfo_parent_seq[] = {
{ WM_NOTIFY, sent|id, 0, 0, LVN_GETDISPINFOA },
{ 0 }
};
static const struct message getitemposition_seq1[] = {
{ LVM_GETITEMPOSITION, sent|id, 0, 0, LISTVIEW_ID },
{ 0 }
};
static const struct message getitemposition_seq2[] = {
{ LVM_GETITEMPOSITION, sent|id, 0, 0, LISTVIEW_ID },
{ HDM_GETITEMRECT, sent|id, 0, 0, HEADER_ID },
{ 0 }
};
Nikolay Sivov
committed
static const struct message getsubitemrect_seq[] = {
{ LVM_GETSUBITEMRECT, sent|id|wparam, -1, 0, LISTVIEW_ID },
{ HDM_GETITEMRECT, sent|id, 0, 0, HEADER_ID },
{ LVM_GETSUBITEMRECT, sent|id|wparam, 0, 0, LISTVIEW_ID },
{ HDM_GETITEMRECT, sent|id, 0, 0, HEADER_ID },
{ LVM_GETSUBITEMRECT, sent|id|wparam, -10, 0, LISTVIEW_ID },
{ HDM_GETITEMRECT, sent|id, 0, 0, HEADER_ID },
{ LVM_GETSUBITEMRECT, sent|id|wparam, 20, 0, LISTVIEW_ID },
{ HDM_GETITEMRECT, sent|id, 0, 0, HEADER_ID },
{ 0 }
};
Nikolay Sivov
committed
static const struct message editbox_create_pos[] = {
/* sequence sent after LVN_BEGINLABELEDIT */
/* next two are 4.7x specific */
Nikolay Sivov
committed
{ WM_WINDOWPOSCHANGING, sent },
{ WM_WINDOWPOSCHANGED, sent|optional },
{ WM_WINDOWPOSCHANGING, sent|optional },
Nikolay Sivov
committed
{ WM_NCCALCSIZE, sent },
{ WM_WINDOWPOSCHANGED, sent },
{ WM_MOVE, sent|defwinproc },
{ WM_SIZE, sent|defwinproc },
/* the rest is todo, skipped in 4.7x */
{ WM_WINDOWPOSCHANGING, sent|optional },
{ WM_WINDOWPOSCHANGED, sent|optional },
Nikolay Sivov
committed
{ 0 }
};
static const struct message scroll_parent_seq[] = {
{ WM_NOTIFY, sent|id, 0, 0, LVN_BEGINSCROLL },
{ WM_NOTIFY, sent|id, 0, 0, LVN_ENDSCROLL },
{ 0 }
};
static const struct message setredraw_seq[] = {
{ WM_SETREDRAW, sent|id|wparam, FALSE, 0, LISTVIEW_ID },
{ 0 }
};
static const struct message lvs_ex_transparentbkgnd_seq[] = {
{ WM_PRINTCLIENT, sent|lparam, 0, PRF_ERASEBKGND },
{ 0 }
};
Nikolay Sivov
committed
static const struct message edit_end_nochange[] = {
Nikolay Sivov
committed
{ WM_NOTIFY, sent|id, 0, 0, LVN_ENDLABELEDITA },
Nikolay Sivov
committed
{ WM_NOTIFY, sent|id, 0, 0, NM_CUSTOMDRAW }, /* todo */
{ WM_NOTIFY, sent|id, 0, 0, NM_SETFOCUS },
{ 0 }
};
static const struct message hover_parent[] = {
{ WM_GETDLGCODE, sent }, /* todo_wine */
{ WM_NOTIFY, sent|id, 0, 0, NM_HOVER },
{ 0 }
};
static const struct message listview_destroy[] = {
{ 0x0090, sent|optional }, /* Vista */
{ WM_PARENTNOTIFY, sent },
{ WM_SHOWWINDOW, sent },
{ WM_WINDOWPOSCHANGING, sent },
{ WM_WINDOWPOSCHANGED, sent|optional },
{ WM_DESTROY, sent },
{ WM_NOTIFY, sent|id, 0, 0, LVN_DELETEALLITEMS },
{ WM_NCDESTROY, sent },
{ 0 }
};
static const struct message listview_ownerdata_destroy[] = {
{ 0x0090, sent|optional }, /* Vista */
{ WM_PARENTNOTIFY, sent },
{ WM_SHOWWINDOW, sent },
{ WM_WINDOWPOSCHANGING, sent },
{ WM_WINDOWPOSCHANGED, sent|optional },
{ WM_DESTROY, sent },
{ WM_NCDESTROY, sent },
{ 0 }
};
static const struct message listview_ownerdata_deleteall[] = {
{ LVM_DELETEALLITEMS, sent },
{ WM_NOTIFY, sent|id, 0, 0, LVN_DELETEALLITEMS },
{ 0 }
};
Nikolay Sivov
committed
static const struct message listview_header_changed_seq[] = {
{ LVM_SETCOLUMNA, sent },
{ WM_NOTIFY, sent|id|defwinproc, 0, 0, LISTVIEW_ID },
{ WM_NOTIFY, sent|id|defwinproc, 0, 0, LISTVIEW_ID },
{ 0 }
};
static const struct message parent_header_click_seq[] = {
{ WM_NOTIFY, sent|id, 0, 0, LVN_COLUMNCLICK },
{ WM_NOTIFY, sent|id, 0, 0, HDN_ITEMCLICKA },
{ 0 }
};
static const struct message parent_header_divider_dclick_seq[] = {
{ WM_NOTIFY, sent|id, 0, 0, HDN_ITEMCHANGINGA },
{ WM_NOTIFY, sent|id, 0, 0, NM_CUSTOMDRAW },
{ WM_NOTIFY, sent|id, 0, 0, NM_CUSTOMDRAW },
{ WM_NOTIFY, sent|id, 0, 0, HDN_ITEMCHANGEDA },
{ WM_NOTIFY, sent|id, 0, 0, HDN_DIVIDERDBLCLICKA },
{ 0 }
};
static const struct message listview_set_imagelist[] = {
{ LVM_SETIMAGELIST, sent|id, 0, 0, LISTVIEW_ID },
{ 0 }
};
static const struct message listview_header_set_imagelist[] = {
{ LVM_SETIMAGELIST, sent|id, 0, 0, LISTVIEW_ID },
{ HDM_SETIMAGELIST, sent|id, 0, 0, HEADER_ID },
{ 0 }
};
static const struct message parent_insert_focused_seq[] = {
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING },
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING },
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED },
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED },
{ WM_NOTIFY, sent|id, 0, 0, LVN_INSERTITEM },
{ 0 }
};
static const struct message parent_report_cd_seq[] = {
{ WM_NOTIFY, sent|id|custdraw, 0, 0, NM_CUSTOMDRAW, CDDS_PREPAINT },
{ WM_NOTIFY, sent|id|custdraw, 0, 0, NM_CUSTOMDRAW, CDDS_ITEMPREPAINT },
{ WM_NOTIFY, sent|id|custdraw, 0, 0, NM_CUSTOMDRAW, CDDS_ITEMPREPAINT|CDDS_SUBITEM },
{ WM_NOTIFY, sent|id|custdraw, 0, 0, NM_CUSTOMDRAW, CDDS_ITEMPOSTPAINT|CDDS_SUBITEM },
{ WM_NOTIFY, sent|id|custdraw, 0, 0, NM_CUSTOMDRAW, CDDS_ITEMPREPAINT|CDDS_SUBITEM },
{ WM_NOTIFY, sent|id|custdraw, 0, 0, NM_CUSTOMDRAW, CDDS_ITEMPOSTPAINT|CDDS_SUBITEM },
{ WM_NOTIFY, sent|id|custdraw, 0, 0, NM_CUSTOMDRAW, CDDS_ITEMPOSTPAINT },
{ WM_NOTIFY, sent|id|custdraw, 0, 0, NM_CUSTOMDRAW, CDDS_POSTPAINT },
{ 0 }
};
static const struct message parent_list_cd_seq[] = {
{ WM_NOTIFY, sent|id|custdraw, 0, 0, NM_CUSTOMDRAW, CDDS_PREPAINT },
{ WM_NOTIFY, sent|id|custdraw, 0, 0, NM_CUSTOMDRAW, CDDS_ITEMPREPAINT },
{ WM_NOTIFY, sent|id|custdraw, 0, 0, NM_CUSTOMDRAW, CDDS_ITEMPOSTPAINT },
{ WM_NOTIFY, sent|id|custdraw, 0, 0, NM_CUSTOMDRAW, CDDS_POSTPAINT },
{ 0 }
};
Fabian Maurer
committed
static const struct message listview_end_label_edit[] = {
{ WM_NOTIFY, sent|id, 0, 0, LVN_ENDLABELEDITA },
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING},
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED },
{ WM_NOTIFY, sent|id|optional, 0, 0, NM_CUSTOMDRAW }, /* XP */
{ WM_NOTIFY, sent|id, 0, 0, NM_SETFOCUS },
{ 0 }
};
static const struct message listview_end_label_edit_kill_focus[] = {
{ WM_NOTIFY, sent|id, 0, 0, LVN_ENDLABELEDITA },
{ WM_COMMAND, sent|id|optional, 0, 0, EN_KILLFOCUS }, /* todo: not sent by wine yet */
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING },
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED },
{ WM_NOTIFY, sent|id|optional, 0, 0, NM_CUSTOMDRAW }, /* XP */
{ WM_NOTIFY, sent|id, 0, 0, NM_SETFOCUS },
{ 0 }
};
static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static LONG defwndproc_counter = 0;
LRESULT ret;
struct message msg;
Nikolay Sivov
committed
msg.message = message;
msg.flags = sent|wparam|lparam;
if (defwndproc_counter) msg.flags |= defwinproc;
msg.wParam = wParam;
msg.lParam = lParam;
if (message == WM_NOTIFY && lParam) msg.id = ((NMHDR*)lParam)->code;
Fabian Maurer
committed
if (message == WM_COMMAND) msg.id = HIWORD(wParam);
Nikolay Sivov
committed
/* log system messages, except for painting */
if (message < WM_USER &&
message != WM_PAINT &&
message != WM_ERASEBKGND &&
message != WM_NCPAINT &&
message != WM_NCHITTEST &&
message != WM_GETTEXT &&
message != WM_GETICON &&
message != WM_DEVICECHANGE)
{
add_message(sequences, PARENT_SEQ_INDEX, &msg);
add_message(sequences, COMBINED_SEQ_INDEX, &msg);
Nikolay Sivov
committed
add_message(sequences, PARENT_FULL_SEQ_INDEX, &msg);
switch (message)
Nikolay Sivov
committed
{
case WM_NOTIFY:
{
switch (((NMHDR*)lParam)->code)
{
case LVN_BEGINLABELEDITA:
{
HWND edit = NULL;
/* subclass edit box */
if (!blockEdit)
edit = subclass_editbox(((NMHDR*)lParam)->hwndFrom);
if (edit)
{
INT len = SendMessageA(edit, EM_GETLIMITTEXT, 0, 0);
ok(len == 259 || broken(len == 260) /* includes NULL in NT4 */,
"text limit %d, expected 259\n", len);
}
return blockEdit;
}
case LVN_ENDLABELEDITA:
Nikolay Sivov
committed
{
Nikolay Sivov
committed
HWND edit;
/* always accept new item text */
NMLVDISPINFOA *di = (NMLVDISPINFOA*)lParam;
Nikolay Sivov
committed
g_editbox_disp_info = *di;
/* edit control still available from this notification */
edit = (HWND)SendMessageA(((NMHDR*)lParam)->hwndFrom, LVM_GETEDITCONTROL, 0, 0);
ok(IsWindow(edit), "expected valid edit control handle\n");
ok((GetWindowLongA(edit, GWL_STYLE) & ES_MULTILINE) == 0, "edit is multiline\n");
Nikolay Sivov
committed
Fabian Maurer
committed
if (g_WM_KILLFOCUS_on_LVN_ENDLABELEDIT)
SendMessageA(edit, WM_KILLFOCUS, 0, 0);
return TRUE;
Nikolay Sivov
committed
}
Nikolay Sivov
committed
case LVN_ITEMCHANGING:
{
NMLISTVIEW *nmlv = (NMLISTVIEW*)lParam;
g_nmlistview_changing = *nmlv;
}
break;
case LVN_ITEMCHANGED:
{
NMLISTVIEW *nmlv = (NMLISTVIEW*)lParam;
Nikolay Sivov
committed
g_nmlistview = *nmlv;
}
break;
case LVN_GETDISPINFOA:
{
NMLVDISPINFOA *dispinfo = (NMLVDISPINFOA*)lParam;
g_itema = dispinfo->item;
Nikolay Sivov
committed
if (g_disp_A_to_W && (dispinfo->item.mask & LVIF_TEXT))
{
static const WCHAR testW[] = {'T','E','S','T',0};
dispinfo->hdr.code = LVN_GETDISPINFOW;
memcpy(dispinfo->item.pszText, testW, sizeof(testW));
}
/* test control buffer size for text, 10 used to mask cases when control
is using caller buffer to process LVM_GETITEM for example */
if (dispinfo->item.mask & LVIF_TEXT && dispinfo->item.cchTextMax > 10)
ok(dispinfo->item.cchTextMax == 260 ||
broken(dispinfo->item.cchTextMax == 264) /* NT4 reports aligned size */,
"buffer size %d\n", dispinfo->item.cchTextMax);
}
break;
case LVN_DELETEITEM:
if (g_focus_test_LVN_DELETEITEM)
{
NMLISTVIEW *nmlv = (NMLISTVIEW*)lParam;
UINT state;
state = SendMessageA(((NMHDR*)lParam)->hwndFrom, LVM_GETITEMSTATE, nmlv->iItem, LVIS_FOCUSED);
ok(state == 0, "got state %x\n", state);
}
break;
case NM_HOVER:
if (g_block_hover) return 1;
break;
}
break;
}
case WM_NOTIFYFORMAT:
{
/* force to return format */
if (lParam == NF_QUERY && notifyFormat != -1) return notifyFormat;
break;
}
Nikolay Sivov
committed
}
defwndproc_counter++;
Nikolay Sivov
committed
if (IsWindowUnicode(hwnd))
ret = DefWindowProcW(hwnd, message, wParam, lParam);
else
ret = DefWindowProcA(hwnd, message, wParam, lParam);
defwndproc_counter--;
return ret;
}
static BOOL register_parent_wnd_class(BOOL Unicode)
WNDCLASSA clsA;
WNDCLASSW clsW;
if (Unicode)
{
clsW.style = 0;
clsW.lpfnWndProc = parent_wnd_proc;
clsW.cbClsExtra = 0;
clsW.cbWndExtra = 0;
clsW.hInstance = GetModuleHandleW(NULL);
clsW.hIcon = 0;
clsW.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW);
clsW.hbrBackground = GetStockObject(WHITE_BRUSH);
clsW.lpszMenuName = NULL;
clsW.lpszClassName = testparentclassW;
}
else
{
clsA.style = 0;
clsA.lpfnWndProc = parent_wnd_proc;
clsA.cbClsExtra = 0;
clsA.cbWndExtra = 0;
clsA.hInstance = GetModuleHandleA(NULL);
clsA.hIcon = 0;
clsA.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW);
clsA.hbrBackground = GetStockObject(WHITE_BRUSH);
clsA.lpszMenuName = NULL;
clsA.lpszClassName = "Listview test parent class";
}
return Unicode ? RegisterClassW(&clsW) : RegisterClassA(&clsA);
static HWND create_parent_window(BOOL Unicode)
static const WCHAR nameW[] = {'t','e','s','t','p','a','r','e','n','t','n','a','m','e','W',0};
HWND hwnd;
if (!register_parent_wnd_class(Unicode))
return NULL;
Nikolay Sivov
committed
blockEdit = FALSE;
notifyFormat = -1;
if (Unicode)
hwnd = CreateWindowExW(0, testparentclassW, nameW,
WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX |
WS_MAXIMIZEBOX | WS_VISIBLE,
0, 0, 100, 100,
GetDesktopWindow(), NULL, GetModuleHandleW(NULL), NULL);
else
hwnd = CreateWindowExA(0, "Listview test parent class",
"Listview test parent window",
WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX |
WS_MAXIMIZEBOX | WS_VISIBLE,
0, 0, 100, 100,
GetDesktopWindow(), NULL, GetModuleHandleA(NULL), NULL);
SetWindowPos( hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE );
return hwnd;
}
static LRESULT WINAPI listview_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
Nikolay Sivov
committed
WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
static LONG defwndproc_counter = 0;
LRESULT ret;
struct message msg;
msg.message = message;
msg.flags = sent|wparam|lparam;
if (defwndproc_counter) msg.flags |= defwinproc;
msg.wParam = wParam;
msg.lParam = lParam;
msg.id = LISTVIEW_ID;
add_message(sequences, LISTVIEW_SEQ_INDEX, &msg);
add_message(sequences, COMBINED_SEQ_INDEX, &msg);
defwndproc_counter++;
Nikolay Sivov
committed
ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam);
defwndproc_counter--;
return ret;
}
Nikolay Sivov
committed
static HWND create_listview_control(DWORD style)
Nikolay Sivov
committed
WNDPROC oldproc;
HWND hwnd;
RECT rect;
GetClientRect(hwndparent, &rect);
hwnd = CreateWindowExA(0, WC_LISTVIEWA, "foo",
WS_CHILD | WS_BORDER | WS_VISIBLE | style,
0, 0, rect.right, rect.bottom,
hwndparent, NULL, GetModuleHandleA(NULL), NULL);
ok(hwnd != NULL, "gle=%d\n", GetLastError());
Nikolay Sivov
committed
if (!hwnd) return NULL;
Nikolay Sivov
committed
oldproc = (WNDPROC)SetWindowLongPtrA(hwnd, GWLP_WNDPROC,
(LONG_PTR)listview_subclass_proc);
SetWindowLongPtrA(hwnd, GWLP_USERDATA, (LONG_PTR)oldproc);
return hwnd;
}
/* unicode listview window with specified parent */
static HWND create_listview_controlW(DWORD style, HWND parent)
{
Nikolay Sivov
committed
WNDPROC oldproc;
HWND hwnd;
RECT rect;
static const WCHAR nameW[] = {'f','o','o',0};
GetClientRect(parent, &rect);
hwnd = CreateWindowExW(0, WC_LISTVIEWW, nameW,
WS_CHILD | WS_BORDER | WS_VISIBLE | style,
0, 0, rect.right, rect.bottom,
parent, NULL, GetModuleHandleW(NULL), NULL);
ok(hwnd != NULL, "gle=%d\n", GetLastError());
Nikolay Sivov
committed
if (!hwnd) return NULL;
Nikolay Sivov
committed
oldproc = (WNDPROC)SetWindowLongPtrW(hwnd, GWLP_WNDPROC,
(LONG_PTR)listview_subclass_proc);
SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR)oldproc);
return hwnd;
}
static BOOL is_win_xp(void)
{
HWND hwnd, header;
BOOL ret;
hwnd = create_listview_control(LVS_ICON);
SendMessageA(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_HEADERINALLVIEWS, LVS_EX_HEADERINALLVIEWS);
header = (HWND)SendMessageA(hwnd, LVM_GETHEADER, 0, 0);
ret = !IsWindow(header);
DestroyWindow(hwnd);
return ret;
}
static LRESULT WINAPI header_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
Nikolay Sivov
committed
WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
static LONG defwndproc_counter = 0;
struct message msg = { 0 };
LRESULT ret;
msg.message = message;
msg.flags = sent|wparam|lparam;
if (defwndproc_counter) msg.flags |= defwinproc;
msg.wParam = wParam;
msg.lParam = lParam;
msg.id = HEADER_ID;
add_message(sequences, LISTVIEW_SEQ_INDEX, &msg);
defwndproc_counter++;
Nikolay Sivov
committed
ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam);
defwndproc_counter--;
return ret;
}
static HWND subclass_header(HWND hwndListview)
{
Nikolay Sivov
committed
WNDPROC oldproc;
HWND hwnd;
hwnd = (HWND)SendMessageA(hwndListview, LVM_GETHEADER, 0, 0);
Nikolay Sivov
committed
oldproc = (WNDPROC)SetWindowLongPtrA(hwnd, GWLP_WNDPROC,
(LONG_PTR)header_subclass_proc);
SetWindowLongPtrA(hwnd, GWLP_USERDATA, (LONG_PTR)oldproc);
return hwnd;
}
Nikolay Sivov
committed
static LRESULT WINAPI editbox_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
Nikolay Sivov
committed
WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
Nikolay Sivov
committed
static LONG defwndproc_counter = 0;
struct message msg = { 0 };
Nikolay Sivov
committed
LRESULT ret;
msg.message = message;
msg.flags = sent|wparam|lparam;
if (defwndproc_counter) msg.flags |= defwinproc;
msg.wParam = wParam;
msg.lParam = lParam;
/* all we need is sizing */
if (message == WM_WINDOWPOSCHANGING ||
message == WM_NCCALCSIZE ||
message == WM_WINDOWPOSCHANGED ||
message == WM_MOVE ||
message == WM_SIZE)
{
add_message(sequences, EDITBOX_SEQ_INDEX, &msg);
}
defwndproc_counter++;
Nikolay Sivov
committed
ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam);
Nikolay Sivov
committed
defwndproc_counter--;
return ret;
}
static HWND subclass_editbox(HWND hwndListview)
{
Nikolay Sivov
committed
WNDPROC oldproc;
Nikolay Sivov
committed
HWND hwnd;
hwnd = (HWND)SendMessageA(hwndListview, LVM_GETEDITCONTROL, 0, 0);
Nikolay Sivov
committed
oldproc = (WNDPROC)SetWindowLongPtrA(hwnd, GWLP_WNDPROC,
(LONG_PTR)editbox_subclass_proc);
SetWindowLongPtrA(hwnd, GWLP_USERDATA, (LONG_PTR)oldproc);
Nikolay Sivov
committed
return hwnd;
}
/* Performs a single LVM_HITTEST test */
Nikolay Sivov
committed
static void test_lvm_hittest_(HWND hwnd, INT x, INT y, INT item, UINT flags, UINT broken_flags,
BOOL todo_item, BOOL todo_flags, int line)
{
LVHITTESTINFO lpht;
INT ret;
lpht.pt.x = x;
lpht.pt.y = y;
lpht.iSubItem = 10;
ret = SendMessageA(hwnd, LVM_HITTEST, 0, (LPARAM)&lpht);
todo_wine_if(todo_item)
Nikolay Sivov
committed
ok_(__FILE__, line)(ret == item, "Expected %d retval, got %d\n", item, ret);
ok_(__FILE__, line)(lpht.iItem == item, "Expected %d item, got %d\n", item, lpht.iItem);
ok_(__FILE__, line)(lpht.iSubItem == 10, "Expected subitem not overwrited\n");
}
if (todo_flags)
{
todo_wine
Nikolay Sivov
committed
ok_(__FILE__, line)(lpht.flags == flags, "Expected flags 0x%x, got 0x%x\n", flags, lpht.flags);
else if (broken_flags)
ok_(__FILE__, line)(lpht.flags == flags || broken(lpht.flags == broken_flags),
"Expected flags %x, got %x\n", flags, lpht.flags);
Nikolay Sivov
committed
ok_(__FILE__, line)(lpht.flags == flags, "Expected flags 0x%x, got 0x%x\n", flags, lpht.flags);
Nikolay Sivov
committed
#define test_lvm_hittest(a,b,c,d,e,f,g,h) test_lvm_hittest_(a,b,c,d,e,f,g,h,__LINE__)
/* Performs a single LVM_SUBITEMHITTEST test */
Nikolay Sivov
committed
static void test_lvm_subitemhittest_(HWND hwnd, INT x, INT y, INT item, INT subitem, UINT flags,
BOOL todo_item, BOOL todo_subitem, BOOL todo_flags, int line)
{
LVHITTESTINFO lpht;
INT ret;
lpht.pt.x = x;
lpht.pt.y = y;
ret = SendMessageA(hwnd, LVM_SUBITEMHITTEST, 0, (LPARAM)&lpht);
todo_wine_if(todo_item)
Nikolay Sivov
committed
ok_(__FILE__, line)(ret == item, "Expected %d retval, got %d\n", item, ret);
ok_(__FILE__, line)(lpht.iItem == item, "Expected %d item, got %d\n", item, lpht.iItem);
}
todo_wine_if(todo_subitem)
ok_(__FILE__, line)(lpht.iSubItem == subitem, "Expected subitem %d, got %d\n", subitem, lpht.iSubItem);
todo_wine_if(todo_flags)
Nikolay Sivov
committed
ok_(__FILE__, line)(lpht.flags == flags, "Expected flags 0x%x, got 0x%x\n", flags, lpht.flags);
Nikolay Sivov
committed
#define test_lvm_subitemhittest(a,b,c,d,e,f,g,h,i) test_lvm_subitemhittest_(a,b,c,d,e,f,g,h,i,__LINE__)
Huw Davies
committed
static void test_images(void)
INT r;
HIMAGELIST himl;
HBITMAP hbmp;
RECT r1, r2;
static CHAR hello[] = "hello";
himl = pImageList_Create(40, 40, 0, 4, 4);
ok(himl != NULL, "failed to create imagelist\n");
hbmp = CreateBitmap(40, 40, 1, 1, NULL);
ok(hbmp != NULL, "failed to create bitmap\n");
r = pImageList_Add(himl, hbmp, 0);
ok(r == 0, "should be zero\n");
hwnd = CreateWindowExA(0, WC_LISTVIEWA, "foo", LVS_OWNERDRAWFIXED,
10, 10, 100, 200, hwndparent, NULL, NULL, NULL);
ok(hwnd != NULL, "failed to create listview window\n");
r = SendMessageA(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, 0,
LVS_EX_UNDERLINEHOT | LVS_EX_FLATSB | LVS_EX_ONECLICKACTIVATE);
ok(r == 0, "should return zero\n");
r = SendMessageA(hwnd, LVM_SETIMAGELIST, 0, (LPARAM)himl);
ok(r == 0, "should return zero\n");
r = SendMessageA(hwnd, LVM_SETICONSPACING, 0, MAKELONG(100,50));
ok(r != 0, "got 0\n");
/* returns dimensions */
r = SendMessageA(hwnd, LVM_GETITEMCOUNT, 0, 0);
ok(r == 0, "should be zero items\n");
item.mask = LVIF_IMAGE | LVIF_TEXT;
item.iItem = 0;
item.iSubItem = 1;
item.iImage = 0;
item.pszText = 0;
r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item);
ok(r == -1, "should fail\n");
item.iSubItem = 0;
r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item);
ok(r == 0, "should not fail\n");
SetRect(&r1, LVIR_ICON, 0, 0, 0);
r = SendMessageA(hwnd, LVM_GETITEMRECT, 0, (LPARAM) &r1);
r = SendMessageA(hwnd, LVM_DELETEALLITEMS, 0, 0);
ok(r == TRUE, "should not fail\n");
item.iSubItem = 0;
r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item);
ok(r == 0, "should not fail\n");
SetRect(&r2, LVIR_ICON, 0, 0, 0);
r = SendMessageA(hwnd, LVM_GETITEMRECT, 0, (LPARAM) &r2);
ok(EqualRect(&r1, &r2), "rectangle should be the same\n");
DestroyWindow(hwnd);
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
/* I_IMAGECALLBACK set for item, try to get image with invalid subitem. */
hwnd = create_listview_control(LVS_REPORT);
ok(hwnd != NULL, "Failed to create listview.\n");
memset(&item, 0, sizeof(item));
item.mask = LVIF_IMAGE;
item.iImage = I_IMAGECALLBACK;
r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM)&item);
ok(!r, "Failed to insert item.\n");
flush_sequences(sequences, NUM_MSG_SEQUENCES);
memset(&item, 0, sizeof(item));
item.mask = LVIF_IMAGE;
r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM)&item);
ok(r, "Failed to get item.\n");
ok_sequence(sequences, PARENT_SEQ_INDEX, single_getdispinfo_parent_seq, "get image dispinfo 1", FALSE);
flush_sequences(sequences, NUM_MSG_SEQUENCES);
memset(&item, 0, sizeof(item));
item.mask = LVIF_IMAGE;
item.iSubItem = 1;
r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM)&item);
ok(r, "Failed to get item.\n");
ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "get image dispinfo 2", FALSE);
DestroyWindow(hwnd);
Huw Davies
committed
static void test_checkboxes(void)
{
Huw Davies
committed
LVITEMA item;
DWORD r;
static CHAR text[] = "Text",
text2[] = "Text2",
text3[] = "Text3";