]> git.saurik.com Git - wxWidgets.git/blame - src/msw/listctrl.cpp
For use when build samples under wxOS2
[wxWidgets.git] / src / msw / listctrl.cpp
CommitLineData
2bda0e17
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: listctrl.cpp
3// Purpose: wxListCtrl
4// Author: Julian Smart
5// Modified by:
6// Created: 04/01/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart and Markus Holzem
acb62b84 9// Licence: wxWindows license
2bda0e17
KB
10/////////////////////////////////////////////////////////////////////////////
11
edccf428
VZ
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
2bda0e17 20#ifdef __GNUG__
0b5efdc7 21 #pragma implementation "listctrl.h"
2bda0e17
KB
22#endif
23
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
0b5efdc7 28 #pragma hdrstop
2bda0e17
KB
29#endif
30
31#ifndef WX_PRECOMP
0b5efdc7 32 #include "wx/wx.h"
2bda0e17
KB
33#endif
34
edccf428 35#ifdef __WIN95__
2bda0e17
KB
36
37#include "wx/listctrl.h"
f8352807 38#include "wx/log.h"
2bda0e17
KB
39
40#include "wx/msw/private.h"
41
65fd5cb0 42#if defined(__GNUWIN32__) && !defined(wxUSE_NORLANDER_HEADERS)
edccf428
VZ
43 #include "wx/msw/gnuwin32/extra.h"
44#else
0b5efdc7 45 #include <commctrl.h>
2bda0e17
KB
46#endif
47
bdc72a22
VZ
48#ifndef LVHT_ONITEM
49 #define LVHT_ONITEM \
50 (LVHT_ONITEMICON | LVHT_ONITEMLABEL | LVHT_ONITEMSTATEICON)
51#endif
52
edccf428
VZ
53// ----------------------------------------------------------------------------
54// private functions
55// ----------------------------------------------------------------------------
2bda0e17
KB
56
57static void wxConvertToMSWListItem(const wxListCtrl *ctrl, wxListItem& info, LV_ITEM& tvItem);
58static void wxConvertFromMSWListItem(const wxListCtrl *ctrl, wxListItem& info, LV_ITEM& tvItem, HWND getFullInfo = 0);
59
edccf428
VZ
60// ----------------------------------------------------------------------------
61// macros
62// ----------------------------------------------------------------------------
63
0b5efdc7
VZ
64 IMPLEMENT_DYNAMIC_CLASS(wxListCtrl, wxControl)
65 IMPLEMENT_DYNAMIC_CLASS(wxListItem, wxObject)
2bda0e17 66
edccf428
VZ
67// ============================================================================
68// implementation
69// ============================================================================
70
71// ----------------------------------------------------------------------------
72// wxListCtrl construction
73// ----------------------------------------------------------------------------
74
bdc72a22 75void wxListCtrl::Init()
2bda0e17 76{
0b5efdc7
VZ
77 m_imageListNormal = NULL;
78 m_imageListSmall = NULL;
79 m_imageListState = NULL;
80 m_baseStyle = 0;
2bda0e17 81 m_colCount = 0;
bbcdf8bc 82 m_textCtrl = NULL;
bdc72a22 83 m_hasAnyAttr = FALSE;
2bda0e17
KB
84}
85
0b5efdc7
VZ
86bool wxListCtrl::Create(wxWindow *parent,
87 wxWindowID id,
88 const wxPoint& pos,
89 const wxSize& size,
90 long style,
91 const wxValidator& validator,
92 const wxString& name)
2bda0e17 93{
0b5efdc7
VZ
94 SetValidator(validator);
95 SetName(name);
2bda0e17 96
0b5efdc7
VZ
97 int x = pos.x;
98 int y = pos.y;
99 int width = size.x;
100 int height = size.y;
2bda0e17 101
0b5efdc7 102 m_windowStyle = style;
2bda0e17 103
0b5efdc7 104 SetParent(parent);
2bda0e17 105
0b5efdc7
VZ
106 if (width <= 0)
107 width = 100;
108 if (height <= 0)
109 height = 30;
110 if (x < 0)
111 x = 0;
112 if (y < 0)
113 y = 0;
2bda0e17 114
0b5efdc7 115 m_windowId = (id == -1) ? NewControlId() : id;
2bda0e17 116
edccf428
VZ
117 DWORD wstyle = WS_VISIBLE | WS_CHILD | WS_TABSTOP |
118 LVS_SHAREIMAGELISTS | LVS_SHOWSELALWAYS;
119 if ( wxStyleHasBorder(m_windowStyle) )
120 wstyle |= WS_BORDER;
121 m_baseStyle = wstyle;
122
123 if ( !DoCreateControl(x, y, width, height) )
124 return FALSE;
125
126 if (parent)
127 parent->AddChild(this);
128
129 return TRUE;
130}
131
132bool wxListCtrl::DoCreateControl(int x, int y, int w, int h)
133{
134 DWORD wstyle = m_baseStyle;
2bda0e17 135
0b5efdc7 136 bool want3D;
edccf428 137 WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D);
2bda0e17 138
0b5efdc7
VZ
139 // Even with extended styles, need to combine with WS_BORDER
140 // for them to look right.
edccf428 141 if ( want3D )
0b5efdc7 142 wstyle |= WS_BORDER;
2bda0e17 143
0b5efdc7
VZ
144 long oldStyle = 0; // Dummy
145 wstyle |= ConvertToMSWStyle(oldStyle, m_windowStyle);
2bda0e17 146
0b5efdc7
VZ
147 // Create the ListView control.
148 m_hWnd = (WXHWND)CreateWindowEx(exStyle,
149 WC_LISTVIEW,
223d09f6 150 wxT(""),
0b5efdc7 151 wstyle,
edccf428
VZ
152 x, y, w, h,
153 GetWinHwnd(GetParent()),
0b5efdc7
VZ
154 (HMENU)m_windowId,
155 wxGetInstance(),
156 NULL);
f8352807 157
edccf428
VZ
158 if ( !m_hWnd )
159 {
223d09f6 160 wxLogError(wxT("Can't create list control window."));
0b5efdc7
VZ
161
162 return FALSE;
163 }
164
165 // for comctl32.dll v 4.70+ we want to have this attribute because it's
166 // prettier (and also because wxGTK does it like this)
167#ifdef ListView_SetExtendedListViewStyle
168 if ( wstyle & LVS_REPORT )
169 {
edccf428
VZ
170 ListView_SetExtendedListViewStyle(GetHwnd(),
171 LVS_EX_FULLROWSELECT);
0b5efdc7
VZ
172 }
173#endif // ListView_SetExtendedListViewStyle
f8352807 174
5aeeab14 175 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW));
edccf428 176 SetForegroundColour(GetParent()->GetForegroundColour());
2bda0e17 177
edccf428 178 SubclassWin(m_hWnd);
2bda0e17 179
0b5efdc7 180 return TRUE;
2bda0e17
KB
181}
182
edccf428
VZ
183void wxListCtrl::UpdateStyle()
184{
185 if ( GetHWND() )
186 {
187 // The new window view style
188 long dummy;
189 DWORD dwStyleNew = ConvertToMSWStyle(dummy, m_windowStyle);
190 dwStyleNew |= m_baseStyle;
191
910484a6 192 // Get the current window style.
edccf428
VZ
193 DWORD dwStyleOld = ::GetWindowLong(GetHwnd(), GWL_STYLE);
194
910484a6 195 // Only set the window style if the view bits have changed.
edccf428
VZ
196 if ( dwStyleOld != dwStyleNew )
197 {
198 ::SetWindowLong(GetHwnd(), GWL_STYLE, dwStyleNew);
199 }
200 }
201}
202
0b5efdc7 203wxListCtrl::~wxListCtrl()
2bda0e17 204{
d62228a6
VZ
205 if ( m_hasAnyAttr )
206 {
207 for ( wxNode *node = m_attrs.Next(); node; node = m_attrs.Next() )
208 {
209 delete (wxListItemAttr *)node->Data();
210 }
211 }
212
213 if ( m_textCtrl )
bbcdf8bc 214 {
0b5efdc7
VZ
215 m_textCtrl->UnsubclassWin();
216 m_textCtrl->SetHWND(0);
217 delete m_textCtrl;
218 m_textCtrl = NULL;
bbcdf8bc 219 }
2bda0e17
KB
220}
221
edccf428
VZ
222// ----------------------------------------------------------------------------
223// set/get/change style
224// ----------------------------------------------------------------------------
225
2bda0e17 226// Add or remove a single window style
debe6624 227void wxListCtrl::SetSingleStyle(long style, bool add)
2bda0e17 228{
0b5efdc7 229 long flag = GetWindowStyleFlag();
2bda0e17 230
0b5efdc7 231 // Get rid of conflicting styles
acb62b84
VZ
232 if ( add )
233 {
0b5efdc7 234 if ( style & wxLC_MASK_TYPE)
edccf428 235 flag = flag & ~wxLC_MASK_TYPE;
0b5efdc7 236 if ( style & wxLC_MASK_ALIGN )
edccf428 237 flag = flag & ~wxLC_MASK_ALIGN;
0b5efdc7 238 if ( style & wxLC_MASK_SORT )
edccf428 239 flag = flag & ~wxLC_MASK_SORT;
acb62b84 240 }
2bda0e17 241
0b5efdc7
VZ
242 if ( flag & style )
243 {
244 if ( !add )
245 flag -= style;
246 }
247 else
248 {
249 if ( add )
250 {
251 flag |= style;
252 }
253 }
254
255 m_windowStyle = flag;
2bda0e17 256
edccf428 257 UpdateStyle();
2bda0e17
KB
258}
259
260// Set the whole window style
debe6624 261void wxListCtrl::SetWindowStyleFlag(long flag)
2bda0e17 262{
0b5efdc7 263 m_windowStyle = flag;
2bda0e17 264
edccf428 265 UpdateStyle();
2bda0e17
KB
266}
267
0b5efdc7
VZ
268// Can be just a single style, or a bitlist
269long wxListCtrl::ConvertToMSWStyle(long& oldStyle, long style) const
2bda0e17 270{
0b5efdc7
VZ
271 long wstyle = 0;
272 if ( style & wxLC_ICON )
273 {
274 if ( (oldStyle & LVS_TYPEMASK) == LVS_SMALLICON )
275 oldStyle -= LVS_SMALLICON;
276 if ( (oldStyle & LVS_TYPEMASK) == LVS_REPORT )
277 oldStyle -= LVS_REPORT;
278 if ( (oldStyle & LVS_TYPEMASK) == LVS_LIST )
279 oldStyle -= LVS_LIST;
280 wstyle |= LVS_ICON;
281 }
282
283 if ( style & wxLC_SMALL_ICON )
284 {
285 if ( (oldStyle & LVS_TYPEMASK) == LVS_ICON )
286 oldStyle -= LVS_ICON;
287 if ( (oldStyle & LVS_TYPEMASK) == LVS_REPORT )
288 oldStyle -= LVS_REPORT;
289 if ( (oldStyle & LVS_TYPEMASK) == LVS_LIST )
290 oldStyle -= LVS_LIST;
291 wstyle |= LVS_SMALLICON;
292 }
293
294 if ( style & wxLC_LIST )
295 {
296 if ( (oldStyle & LVS_TYPEMASK) == LVS_ICON )
297 oldStyle -= LVS_ICON;
298 if ( (oldStyle & LVS_TYPEMASK) == LVS_REPORT )
299 oldStyle -= LVS_REPORT;
300 if ( (oldStyle & LVS_TYPEMASK) == LVS_SMALLICON )
301 oldStyle -= LVS_SMALLICON;
302 wstyle |= LVS_LIST;
303 }
2bda0e17 304
0b5efdc7
VZ
305 if ( style & wxLC_REPORT )
306 {
307 if ( (oldStyle & LVS_TYPEMASK) == LVS_ICON )
308 oldStyle -= LVS_ICON;
309 if ( (oldStyle & LVS_TYPEMASK) == LVS_LIST )
310 oldStyle -= LVS_LIST;
311 if ( (oldStyle & LVS_TYPEMASK) == LVS_SMALLICON )
312 oldStyle -= LVS_SMALLICON;
313
314 wstyle |= LVS_REPORT;
315 }
2bda0e17 316
0b5efdc7
VZ
317 if ( style & wxLC_ALIGN_LEFT )
318 {
319 if ( oldStyle & LVS_ALIGNTOP )
320 oldStyle -= LVS_ALIGNTOP;
321 wstyle |= LVS_ALIGNLEFT;
322 }
2bda0e17 323
0b5efdc7
VZ
324 if ( style & wxLC_ALIGN_TOP )
325 {
326 if ( oldStyle & LVS_ALIGNLEFT )
327 oldStyle -= LVS_ALIGNLEFT;
328 wstyle |= LVS_ALIGNTOP;
329 }
2bda0e17 330
0b5efdc7
VZ
331 if ( style & wxLC_AUTOARRANGE )
332 wstyle |= LVS_AUTOARRANGE;
2bda0e17 333
0b5efdc7
VZ
334 // Apparently, no such style (documentation wrong?)
335 /*
336 if ( style & wxLC_BUTTON )
337 wstyle |= LVS_BUTTON;
338 */
2bda0e17 339
0b5efdc7
VZ
340 if ( style & wxLC_NO_SORT_HEADER )
341 wstyle |= LVS_NOSORTHEADER;
2bda0e17 342
0b5efdc7
VZ
343 if ( style & wxLC_NO_HEADER )
344 wstyle |= LVS_NOCOLUMNHEADER;
345
346 if ( style & wxLC_EDIT_LABELS )
347 wstyle |= LVS_EDITLABELS;
348
349 if ( style & wxLC_SINGLE_SEL )
350 wstyle |= LVS_SINGLESEL;
351
352 if ( style & wxLC_SORT_ASCENDING )
353 {
354 if ( oldStyle & LVS_SORTDESCENDING )
355 oldStyle -= LVS_SORTDESCENDING;
356 wstyle |= LVS_SORTASCENDING;
357 }
358
359 if ( style & wxLC_SORT_DESCENDING )
360 {
361 if ( oldStyle & LVS_SORTASCENDING )
362 oldStyle -= LVS_SORTASCENDING;
363 wstyle |= LVS_SORTDESCENDING;
364 }
365
366 return wstyle;
2bda0e17
KB
367}
368
edccf428
VZ
369// ----------------------------------------------------------------------------
370// accessors
371// ----------------------------------------------------------------------------
372
2bda0e17
KB
373// Sets the background colour (GetBackgroundColour already implicit in
374// wxWindow class)
cc2b7472 375bool wxListCtrl::SetBackgroundColour(const wxColour& col)
2bda0e17 376{
cc2b7472
VZ
377 if ( !wxWindow::SetBackgroundColour(col) )
378 return FALSE;
2bda0e17 379
edccf428 380 ListView_SetBkColor(GetHwnd(), PALETTERGB(col.Red(), col.Green(), col.Blue()));
cc2b7472
VZ
381
382 return TRUE;
2bda0e17
KB
383}
384
385// Gets information about this column
debe6624 386bool wxListCtrl::GetColumn(int col, wxListItem& item) const
2bda0e17 387{
0b5efdc7
VZ
388 LV_COLUMN lvCol;
389 lvCol.mask = 0;
390 lvCol.fmt = 0;
391 lvCol.pszText = NULL;
392
393 if ( item.m_mask & wxLIST_MASK_TEXT )
394 {
395 lvCol.mask |= LVCF_TEXT;
837e5743 396 lvCol.pszText = new wxChar[513];
0b5efdc7
VZ
397 lvCol.cchTextMax = 512;
398 }
399
edccf428 400 bool success = (ListView_GetColumn(GetHwnd(), col, & lvCol) != 0);
0b5efdc7
VZ
401
402 // item.m_subItem = lvCol.iSubItem;
403 item.m_width = lvCol.cx;
404
405 if ( (item.m_mask & wxLIST_MASK_TEXT) && lvCol.pszText )
406 {
407 item.m_text = lvCol.pszText;
408 delete[] lvCol.pszText;
409 }
410
411 if ( item.m_mask & wxLIST_MASK_FORMAT )
412 {
413 if (lvCol.fmt == LVCFMT_LEFT)
414 item.m_format = wxLIST_FORMAT_LEFT;
415 else if (lvCol.fmt == LVCFMT_RIGHT)
416 item.m_format = wxLIST_FORMAT_RIGHT;
417 else if (lvCol.fmt == LVCFMT_CENTER)
418 item.m_format = wxLIST_FORMAT_CENTRE;
2bda0e17
KB
419 }
420
0b5efdc7 421 return success;
2bda0e17
KB
422}
423
424// Sets information about this column
debe6624 425bool wxListCtrl::SetColumn(int col, wxListItem& item)
2bda0e17 426{
0b5efdc7
VZ
427 LV_COLUMN lvCol;
428 lvCol.mask = 0;
429 lvCol.fmt = 0;
430 lvCol.pszText = NULL;
431
432 if ( item.m_mask & wxLIST_MASK_TEXT )
433 {
434 lvCol.mask |= LVCF_TEXT;
435 lvCol.pszText = WXSTRINGCAST item.m_text;
436 lvCol.cchTextMax = 0; // Ignored
437 }
438 if ( item.m_mask & wxLIST_MASK_FORMAT )
439 {
440 lvCol.mask |= LVCF_FMT;
441
442 if ( item.m_format == wxLIST_FORMAT_LEFT )
443 lvCol.fmt = LVCFMT_LEFT;
444 if ( item.m_format == wxLIST_FORMAT_RIGHT )
445 lvCol.fmt = LVCFMT_RIGHT;
446 if ( item.m_format == wxLIST_FORMAT_CENTRE )
447 lvCol.fmt = LVCFMT_CENTER;
2bda0e17
KB
448 }
449
0b5efdc7
VZ
450 if ( item.m_mask & wxLIST_MASK_WIDTH )
451 {
452 lvCol.mask |= LVCF_WIDTH;
453 lvCol.cx = item.m_width;
2bda0e17 454
0b5efdc7
VZ
455 if ( lvCol.cx == wxLIST_AUTOSIZE)
456 lvCol.cx = LVSCW_AUTOSIZE;
457 else if ( lvCol.cx == wxLIST_AUTOSIZE_USEHEADER)
458 lvCol.cx = LVSCW_AUTOSIZE_USEHEADER;
459 }
460 lvCol.mask |= LVCF_SUBITEM;
461 lvCol.iSubItem = col;
edccf428 462 return (ListView_SetColumn(GetHwnd(), col, & lvCol) != 0);
2bda0e17
KB
463}
464
465// Gets the column width
debe6624 466int wxListCtrl::GetColumnWidth(int col) const
2bda0e17 467{
edccf428 468 return ListView_GetColumnWidth(GetHwnd(), col);
2bda0e17
KB
469}
470
471// Sets the column width
debe6624 472bool wxListCtrl::SetColumnWidth(int col, int width)
2bda0e17 473{
0b5efdc7
VZ
474 int col2 = col;
475 if ( m_windowStyle & wxLC_LIST )
476 col2 = -1;
2bda0e17 477
0b5efdc7
VZ
478 int width2 = width;
479 if ( width2 == wxLIST_AUTOSIZE)
480 width2 = LVSCW_AUTOSIZE;
481 else if ( width2 == wxLIST_AUTOSIZE_USEHEADER)
482 width2 = LVSCW_AUTOSIZE_USEHEADER;
2bda0e17 483
edccf428 484 return (ListView_SetColumnWidth(GetHwnd(), col2, width2) != 0);
2bda0e17
KB
485}
486
487// Gets the number of items that can fit vertically in the
488// visible area of the list control (list or report view)
489// or the total number of items in the list control (icon
490// or small icon view)
491int wxListCtrl::GetCountPerPage(void) const
492{
edccf428 493 return ListView_GetCountPerPage(GetHwnd());
2bda0e17
KB
494}
495
496// Gets the edit control for editing labels.
bbcdf8bc 497wxTextCtrl* wxListCtrl::GetEditControl(void) const
2bda0e17 498{
bbcdf8bc 499 return m_textCtrl;
2bda0e17
KB
500}
501
502// Gets information about the item
503bool wxListCtrl::GetItem(wxListItem& info) const
504{
0b5efdc7 505 LV_ITEM lvItem;
11c7d5b6 506 wxZeroMemory(lvItem);
2bda0e17 507
0b5efdc7 508 lvItem.iItem = info.m_itemId;
fc5a93cd 509 lvItem.iSubItem = info.m_col;
0b5efdc7
VZ
510
511 if ( info.m_mask & wxLIST_MASK_TEXT )
512 {
513 lvItem.mask |= LVIF_TEXT;
837e5743 514 lvItem.pszText = new wxChar[513];
0b5efdc7
VZ
515 lvItem.cchTextMax = 512;
516 }
517 else
518 {
519 lvItem.pszText = NULL;
520 }
521
522 if (info.m_mask & wxLIST_MASK_DATA)
edccf428 523 lvItem.mask |= LVIF_PARAM;
0b5efdc7
VZ
524
525 if ( info.m_mask & wxLIST_MASK_STATE )
526 {
527 lvItem.mask |= LVIF_STATE;
528 // the other bits are hardly interesting anyhow
529 lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
530 }
531
532 bool success = ListView_GetItem((HWND)GetHWND(), &lvItem) != 0;
533 if ( !success )
534 {
535 wxLogError(_("Couldn't retrieve information about list control item %d."),
536 lvItem.iItem);
537 }
538 else
539 {
540 wxConvertFromMSWListItem(this, info, lvItem);
541 }
542
543 if (lvItem.pszText)
544 delete[] lvItem.pszText;
545
546 return success;
2bda0e17
KB
547}
548
549// Sets information about the item
550bool wxListCtrl::SetItem(wxListItem& info)
551{
0b5efdc7 552 LV_ITEM item;
2bda0e17 553 wxConvertToMSWListItem(this, info, item);
bdc72a22
VZ
554
555 // check whether it has any custom attributes
556 if ( info.HasAttributes() )
557 {
d62228a6 558 m_attrs.Put(item.iItem, (wxObject *)new wxListItemAttr(*info.GetAttributes()));
bdc72a22
VZ
559
560 m_hasAnyAttr = TRUE;
561 }
bdc72a22 562
0b5efdc7 563 item.cchTextMax = 0;
7cc98b3e
VZ
564 bool ok = ListView_SetItem(GetHwnd(), &item) != 0;
565 if ( ok && (info.m_mask & wxLIST_MASK_IMAGE) )
566 {
567 // make the change visible
568 ListView_Update(GetHwnd(), item.iItem);
569 }
570
571 return ok;
2bda0e17
KB
572}
573
debe6624 574long wxListCtrl::SetItem(long index, int col, const wxString& label, int imageId)
2bda0e17 575{
0b5efdc7
VZ
576 wxListItem info;
577 info.m_text = label;
578 info.m_mask = wxLIST_MASK_TEXT;
579 info.m_itemId = index;
580 info.m_col = col;
581 if ( imageId > -1 )
582 {
583 info.m_image = imageId;
584 info.m_mask |= wxLIST_MASK_IMAGE;
585 }
586 return SetItem(info);
2bda0e17
KB
587}
588
589
590// Gets the item state
debe6624 591int wxListCtrl::GetItemState(long item, long stateMask) const
2bda0e17 592{
0b5efdc7 593 wxListItem info;
2bda0e17 594
edccf428 595 info.m_mask = wxLIST_MASK_STATE;
0b5efdc7
VZ
596 info.m_stateMask = stateMask;
597 info.m_itemId = item;
2bda0e17 598
0b5efdc7
VZ
599 if (!GetItem(info))
600 return 0;
2bda0e17 601
0b5efdc7 602 return info.m_state;
2bda0e17
KB
603}
604
605// Sets the item state
debe6624 606bool wxListCtrl::SetItemState(long item, long state, long stateMask)
2bda0e17 607{
0b5efdc7 608 wxListItem info;
2bda0e17 609
edccf428 610 info.m_mask = wxLIST_MASK_STATE;
0b5efdc7
VZ
611 info.m_state = state;
612 info.m_stateMask = stateMask;
613 info.m_itemId = item;
2bda0e17 614
0b5efdc7 615 return SetItem(info);
2bda0e17
KB
616}
617
618// Sets the item image
debe6624 619bool wxListCtrl::SetItemImage(long item, int image, int selImage)
2bda0e17 620{
0b5efdc7 621 wxListItem info;
2bda0e17 622
edccf428 623 info.m_mask = wxLIST_MASK_IMAGE;
0b5efdc7
VZ
624 info.m_image = image;
625 info.m_itemId = item;
2bda0e17 626
0b5efdc7 627 return SetItem(info);
2bda0e17
KB
628}
629
630// Gets the item text
debe6624 631wxString wxListCtrl::GetItemText(long item) const
2bda0e17 632{
0b5efdc7 633 wxListItem info;
2bda0e17 634
edccf428 635 info.m_mask = wxLIST_MASK_TEXT;
0b5efdc7 636 info.m_itemId = item;
2bda0e17 637
0b5efdc7
VZ
638 if (!GetItem(info))
639 return wxString("");
640 return info.m_text;
2bda0e17
KB
641}
642
643// Sets the item text
debe6624 644void wxListCtrl::SetItemText(long item, const wxString& str)
2bda0e17 645{
0b5efdc7 646 wxListItem info;
2bda0e17 647
edccf428 648 info.m_mask = wxLIST_MASK_TEXT;
0b5efdc7
VZ
649 info.m_itemId = item;
650 info.m_text = str;
2bda0e17 651
0b5efdc7 652 SetItem(info);
2bda0e17
KB
653}
654
655// Gets the item data
debe6624 656long wxListCtrl::GetItemData(long item) const
2bda0e17 657{
0b5efdc7 658 wxListItem info;
2bda0e17 659
edccf428 660 info.m_mask = wxLIST_MASK_DATA;
0b5efdc7 661 info.m_itemId = item;
2bda0e17 662
0b5efdc7
VZ
663 if (!GetItem(info))
664 return 0;
665 return info.m_data;
2bda0e17
KB
666}
667
668// Sets the item data
debe6624 669bool wxListCtrl::SetItemData(long item, long data)
2bda0e17 670{
0b5efdc7 671 wxListItem info;
2bda0e17 672
edccf428 673 info.m_mask = wxLIST_MASK_DATA;
0b5efdc7
VZ
674 info.m_itemId = item;
675 info.m_data = data;
2bda0e17 676
0b5efdc7 677 return SetItem(info);
2bda0e17
KB
678}
679
680// Gets the item rectangle
16e93305 681bool wxListCtrl::GetItemRect(long item, wxRect& rect, int code) const
2bda0e17 682{
0b5efdc7 683 RECT rect2;
2bda0e17 684
0b5efdc7
VZ
685 int code2 = LVIR_BOUNDS;
686 if ( code == wxLIST_RECT_BOUNDS )
687 code2 = LVIR_BOUNDS;
688 else if ( code == wxLIST_RECT_ICON )
689 code2 = LVIR_ICON;
690 else if ( code == wxLIST_RECT_LABEL )
691 code2 = LVIR_LABEL;
2bda0e17 692
5ea105e0 693#ifdef __WXWINE__
edccf428 694 bool success = (ListView_GetItemRect(GetHwnd(), (int) item, &rect2 ) != 0);
5ea105e0 695#else
edccf428 696 bool success = (ListView_GetItemRect(GetHwnd(), (int) item, &rect2, code2) != 0);
5ea105e0 697#endif
2bda0e17 698
0b5efdc7
VZ
699 rect.x = rect2.left;
700 rect.y = rect2.top;
701 rect.width = rect2.right - rect2.left;
702 rect.height = rect2.bottom - rect2.left;
703 return success;
2bda0e17
KB
704}
705
706// Gets the item position
debe6624 707bool wxListCtrl::GetItemPosition(long item, wxPoint& pos) const
2bda0e17 708{
0b5efdc7 709 POINT pt;
2bda0e17 710
edccf428 711 bool success = (ListView_GetItemPosition(GetHwnd(), (int) item, &pt) != 0);
2bda0e17 712
0b5efdc7
VZ
713 pos.x = pt.x; pos.y = pt.y;
714 return success;
2bda0e17
KB
715}
716
717// Sets the item position.
debe6624 718bool wxListCtrl::SetItemPosition(long item, const wxPoint& pos)
2bda0e17 719{
edccf428 720 return (ListView_SetItemPosition(GetHwnd(), (int) item, pos.x, pos.y) != 0);
2bda0e17
KB
721}
722
723// Gets the number of items in the list control
724int wxListCtrl::GetItemCount(void) const
725{
edccf428 726 return ListView_GetItemCount(GetHwnd());
2bda0e17
KB
727}
728
729// Retrieves the spacing between icons in pixels.
730// If small is TRUE, gets the spacing for the small icon
731// view, otherwise the large icon view.
732int wxListCtrl::GetItemSpacing(bool isSmall) const
733{
edccf428 734 return ListView_GetItemSpacing(GetHwnd(), (BOOL) isSmall);
2bda0e17
KB
735}
736
737// Gets the number of selected items in the list control
738int wxListCtrl::GetSelectedItemCount(void) const
739{
edccf428 740 return ListView_GetSelectedCount(GetHwnd());
2bda0e17
KB
741}
742
743// Gets the text colour of the listview
744wxColour wxListCtrl::GetTextColour(void) const
745{
edccf428 746 COLORREF ref = ListView_GetTextColor(GetHwnd());
0b5efdc7
VZ
747 wxColour col(GetRValue(ref), GetGValue(ref), GetBValue(ref));
748 return col;
2bda0e17
KB
749}
750
751// Sets the text colour of the listview
752void wxListCtrl::SetTextColour(const wxColour& col)
753{
910484a6 754 ListView_SetTextColor(GetHwnd(), PALETTERGB(col.Red(), col.Green(), col.Blue()));
2bda0e17
KB
755}
756
757// Gets the index of the topmost visible item when in
758// list or report view
759long wxListCtrl::GetTopItem(void) const
760{
edccf428 761 return (long) ListView_GetTopIndex(GetHwnd());
2bda0e17
KB
762}
763
764// Searches for an item, starting from 'item'.
765// 'geometry' is one of
766// wxLIST_NEXT_ABOVE/ALL/BELOW/LEFT/RIGHT.
767// 'state' is a state bit flag, one or more of
768// wxLIST_STATE_DROPHILITED/FOCUSED/SELECTED/CUT.
769// item can be -1 to find the first item that matches the
770// specified flags.
771// Returns the item or -1 if unsuccessful.
debe6624 772long wxListCtrl::GetNextItem(long item, int geom, int state) const
2bda0e17 773{
0b5efdc7 774 long flags = 0;
2bda0e17 775
0b5efdc7
VZ
776 if ( geom == wxLIST_NEXT_ABOVE )
777 flags |= LVNI_ABOVE;
778 if ( geom == wxLIST_NEXT_ALL )
779 flags |= LVNI_ALL;
780 if ( geom == wxLIST_NEXT_BELOW )
781 flags |= LVNI_BELOW;
782 if ( geom == wxLIST_NEXT_LEFT )
783 flags |= LVNI_TOLEFT;
784 if ( geom == wxLIST_NEXT_RIGHT )
785 flags |= LVNI_TORIGHT;
2bda0e17 786
0b5efdc7
VZ
787 if ( state & wxLIST_STATE_CUT )
788 flags |= LVNI_CUT;
789 if ( state & wxLIST_STATE_DROPHILITED )
790 flags |= LVNI_DROPHILITED;
791 if ( state & wxLIST_STATE_FOCUSED )
792 flags |= LVNI_FOCUSED;
793 if ( state & wxLIST_STATE_SELECTED )
794 flags |= LVNI_SELECTED;
2bda0e17 795
edccf428 796 return (long) ListView_GetNextItem(GetHwnd(), item, flags);
2bda0e17
KB
797}
798
799
debe6624 800wxImageList *wxListCtrl::GetImageList(int which) const
2bda0e17 801{
0b5efdc7 802 if ( which == wxIMAGE_LIST_NORMAL )
2bda0e17 803 {
0b5efdc7
VZ
804 return m_imageListNormal;
805 }
806 else if ( which == wxIMAGE_LIST_SMALL )
2bda0e17 807 {
0b5efdc7
VZ
808 return m_imageListSmall;
809 }
810 else if ( which == wxIMAGE_LIST_STATE )
2bda0e17 811 {
0b5efdc7
VZ
812 return m_imageListState;
813 }
814 return NULL;
2bda0e17
KB
815}
816
debe6624 817void wxListCtrl::SetImageList(wxImageList *imageList, int which)
2bda0e17 818{
0b5efdc7
VZ
819 int flags = 0;
820 if ( which == wxIMAGE_LIST_NORMAL )
2bda0e17 821 {
0b5efdc7
VZ
822 flags = LVSIL_NORMAL;
823 m_imageListNormal = imageList;
824 }
825 else if ( which == wxIMAGE_LIST_SMALL )
2bda0e17 826 {
0b5efdc7
VZ
827 flags = LVSIL_SMALL;
828 m_imageListSmall = imageList;
829 }
830 else if ( which == wxIMAGE_LIST_STATE )
2bda0e17 831 {
0b5efdc7
VZ
832 flags = LVSIL_STATE;
833 m_imageListState = imageList;
834 }
edccf428 835 ListView_SetImageList(GetHwnd(), (HIMAGELIST) imageList ? imageList->GetHIMAGELIST() : 0, flags);
2bda0e17
KB
836}
837
edccf428 838// ----------------------------------------------------------------------------
2bda0e17 839// Operations
edccf428 840// ----------------------------------------------------------------------------
2bda0e17
KB
841
842// Arranges the items
debe6624 843bool wxListCtrl::Arrange(int flag)
2bda0e17 844{
0b5efdc7
VZ
845 UINT code = 0;
846 if ( flag == wxLIST_ALIGN_LEFT )
847 code = LVA_ALIGNLEFT;
848 else if ( flag == wxLIST_ALIGN_TOP )
849 code = LVA_ALIGNTOP;
850 else if ( flag == wxLIST_ALIGN_DEFAULT )
851 code = LVA_DEFAULT;
852 else if ( flag == wxLIST_ALIGN_SNAP_TO_GRID )
853 code = LVA_SNAPTOGRID;
2bda0e17 854
edccf428 855 return (ListView_Arrange(GetHwnd(), code) != 0);
2bda0e17
KB
856}
857
858// Deletes an item
debe6624 859bool wxListCtrl::DeleteItem(long item)
2bda0e17 860{
edccf428 861 return (ListView_DeleteItem(GetHwnd(), (int) item) != 0);
2bda0e17
KB
862}
863
864// Deletes all items
0b5efdc7 865bool wxListCtrl::DeleteAllItems()
2bda0e17 866{
edccf428 867 return (ListView_DeleteAllItems(GetHwnd()) != 0);
2bda0e17
KB
868}
869
870// Deletes all items
0b5efdc7 871bool wxListCtrl::DeleteAllColumns()
2bda0e17 872{
edccf428 873 while ( m_colCount > 0 )
2bda0e17 874 {
edccf428
VZ
875 if ( ListView_DeleteColumn(GetHwnd(), 0) == 0 )
876 {
877 wxLogLastError("ListView_DeleteColumn");
878
879 return FALSE;
880 }
881
882 m_colCount--;
2bda0e17 883 }
edccf428 884
223d09f6 885 wxASSERT_MSG( m_colCount == 0, wxT("no columns should be left") );
edccf428
VZ
886
887 return TRUE;
2bda0e17
KB
888}
889
890// Deletes a column
debe6624 891bool wxListCtrl::DeleteColumn(int col)
2bda0e17 892{
edccf428 893 bool success = (ListView_DeleteColumn(GetHwnd(), col) != 0);
2bda0e17
KB
894
895 if ( success && (m_colCount > 0) )
896 m_colCount --;
897 return success;
898}
899
900// Clears items, and columns if there are any.
0b5efdc7 901void wxListCtrl::ClearAll()
2bda0e17
KB
902{
903 DeleteAllItems();
904 if ( m_colCount > 0 )
905 DeleteAllColumns();
906}
907
bbcdf8bc
JS
908wxTextCtrl* wxListCtrl::EditLabel(long item, wxClassInfo* textControlClass)
909{
910 wxASSERT( (textControlClass->IsKindOf(CLASSINFO(wxTextCtrl))) );
911
edccf428 912 HWND hWnd = (HWND) ListView_EditLabel(GetHwnd(), item);
bbcdf8bc
JS
913
914 if (m_textCtrl)
915 {
0b5efdc7
VZ
916 m_textCtrl->UnsubclassWin();
917 m_textCtrl->SetHWND(0);
918 delete m_textCtrl;
919 m_textCtrl = NULL;
bbcdf8bc
JS
920 }
921
922 m_textCtrl = (wxTextCtrl*) textControlClass->CreateObject();
923 m_textCtrl->SetHWND((WXHWND) hWnd);
924 m_textCtrl->SubclassWin((WXHWND) hWnd);
925
926 return m_textCtrl;
927}
928
929// End label editing, optionally cancelling the edit
930bool wxListCtrl::EndEditLabel(bool cancel)
2bda0e17 931{
341287bf 932 wxFAIL;
bbcdf8bc 933
0b5efdc7
VZ
934 /* I don't know how to implement this: there's no such macro as ListView_EndEditLabelNow.
935 * ???
edccf428 936 bool success = (ListView_EndEditLabelNow(GetHwnd(), cancel) != 0);
0b5efdc7
VZ
937
938 if (m_textCtrl)
939 {
940 m_textCtrl->UnsubclassWin();
941 m_textCtrl->SetHWND(0);
942 delete m_textCtrl;
943 m_textCtrl = NULL;
944 }
945 return success;
946 */
947 return FALSE;
2bda0e17
KB
948}
949
bbcdf8bc 950
2bda0e17 951// Ensures this item is visible
debe6624 952bool wxListCtrl::EnsureVisible(long item)
2bda0e17 953{
edccf428 954 return (ListView_EnsureVisible(GetHwnd(), (int) item, FALSE) != 0);
2bda0e17
KB
955}
956
957// Find an item whose label matches this string, starting from the item after 'start'
958// or the beginning if 'start' is -1.
debe6624 959long wxListCtrl::FindItem(long start, const wxString& str, bool partial)
2bda0e17 960{
0b5efdc7 961 LV_FINDINFO findInfo;
2bda0e17 962
0b5efdc7
VZ
963 findInfo.flags = LVFI_STRING;
964 if ( partial )
965 findInfo.flags |= LVFI_STRING;
966 findInfo.psz = WXSTRINGCAST str;
2bda0e17 967
edccf428 968 return ListView_FindItem(GetHwnd(), (int) start, & findInfo);
2bda0e17
KB
969}
970
971// Find an item whose data matches this data, starting from the item after 'start'
972// or the beginning if 'start' is -1.
debe6624 973long wxListCtrl::FindItem(long start, long data)
2bda0e17 974{
0b5efdc7 975 LV_FINDINFO findInfo;
2bda0e17 976
0b5efdc7
VZ
977 findInfo.flags = LVFI_PARAM;
978 findInfo.lParam = data;
2bda0e17 979
edccf428 980 return ListView_FindItem(GetHwnd(), (int) start, & findInfo);
2bda0e17
KB
981}
982
983// Find an item nearest this position in the specified direction, starting from
984// the item after 'start' or the beginning if 'start' is -1.
debe6624 985long wxListCtrl::FindItem(long start, const wxPoint& pt, int direction)
2bda0e17 986{
0b5efdc7 987 LV_FINDINFO findInfo;
2bda0e17 988
0b5efdc7
VZ
989 findInfo.flags = LVFI_NEARESTXY;
990 findInfo.pt.x = pt.x;
991 findInfo.pt.y = pt.y;
acb62b84 992 findInfo.vkDirection = VK_RIGHT;
2bda0e17 993
0b5efdc7
VZ
994 if ( direction == wxLIST_FIND_UP )
995 findInfo.vkDirection = VK_UP;
996 else if ( direction == wxLIST_FIND_DOWN )
997 findInfo.vkDirection = VK_DOWN;
998 else if ( direction == wxLIST_FIND_LEFT )
999 findInfo.vkDirection = VK_LEFT;
1000 else if ( direction == wxLIST_FIND_RIGHT )
1001 findInfo.vkDirection = VK_RIGHT;
1002
edccf428 1003 return ListView_FindItem(GetHwnd(), (int) start, & findInfo);
2bda0e17
KB
1004}
1005
1006// Determines which item (if any) is at the specified point,
1007// giving details in 'flags' (see wxLIST_HITTEST_... flags above)
1008long wxListCtrl::HitTest(const wxPoint& point, int& flags)
1009{
1010 LV_HITTESTINFO hitTestInfo;
0b5efdc7
VZ
1011 hitTestInfo.pt.x = (int) point.x;
1012 hitTestInfo.pt.y = (int) point.y;
2bda0e17 1013
edccf428 1014 ListView_HitTest(GetHwnd(), & hitTestInfo);
2bda0e17 1015
0b5efdc7
VZ
1016 flags = 0;
1017 if ( hitTestInfo.flags & LVHT_ABOVE )
1018 flags |= wxLIST_HITTEST_ABOVE;
1019 if ( hitTestInfo.flags & LVHT_BELOW )
1020 flags |= wxLIST_HITTEST_BELOW;
1021 if ( hitTestInfo.flags & LVHT_NOWHERE )
1022 flags |= wxLIST_HITTEST_NOWHERE;
1023 if ( hitTestInfo.flags & LVHT_ONITEMICON )
1024 flags |= wxLIST_HITTEST_ONITEMICON;
1025 if ( hitTestInfo.flags & LVHT_ONITEMLABEL )
1026 flags |= wxLIST_HITTEST_ONITEMLABEL;
1027 if ( hitTestInfo.flags & LVHT_ONITEMSTATEICON )
1028 flags |= wxLIST_HITTEST_ONITEMSTATEICON;
1029 if ( hitTestInfo.flags & LVHT_TOLEFT )
1030 flags |= wxLIST_HITTEST_TOLEFT;
1031 if ( hitTestInfo.flags & LVHT_TORIGHT )
1032 flags |= wxLIST_HITTEST_TORIGHT;
1033
edccf428 1034 return (long) hitTestInfo.iItem;
2bda0e17
KB
1035}
1036
1037// Inserts an item, returning the index of the new item if successful,
1038// -1 otherwise.
2bda0e17
KB
1039long wxListCtrl::InsertItem(wxListItem& info)
1040{
0b5efdc7
VZ
1041 LV_ITEM item;
1042 wxConvertToMSWListItem(this, info, item);
2bda0e17 1043
bdc72a22
VZ
1044 // check whether it has any custom attributes
1045 if ( info.HasAttributes() )
1046 {
d62228a6 1047 m_attrs.Put(item.iItem, (wxObject *)new wxListItemAttr(*info.GetAttributes()));
bdc72a22
VZ
1048
1049 m_hasAnyAttr = TRUE;
1050 }
bdc72a22 1051
edccf428 1052 return (long) ListView_InsertItem(GetHwnd(), & item);
2bda0e17
KB
1053}
1054
debe6624 1055long wxListCtrl::InsertItem(long index, const wxString& label)
2bda0e17 1056{
0b5efdc7
VZ
1057 wxListItem info;
1058 info.m_text = label;
1059 info.m_mask = wxLIST_MASK_TEXT;
1060 info.m_itemId = index;
1061 return InsertItem(info);
2bda0e17
KB
1062}
1063
1064// Inserts an image item
debe6624 1065long wxListCtrl::InsertItem(long index, int imageIndex)
2bda0e17 1066{
0b5efdc7
VZ
1067 wxListItem info;
1068 info.m_image = imageIndex;
1069 info.m_mask = wxLIST_MASK_IMAGE;
1070 info.m_itemId = index;
1071 return InsertItem(info);
2bda0e17
KB
1072}
1073
1074// Inserts an image/string item
debe6624 1075long wxListCtrl::InsertItem(long index, const wxString& label, int imageIndex)
2bda0e17 1076{
0b5efdc7
VZ
1077 wxListItem info;
1078 info.m_image = imageIndex;
1079 info.m_text = label;
1080 info.m_mask = wxLIST_MASK_IMAGE | wxLIST_MASK_TEXT;
1081 info.m_itemId = index;
1082 return InsertItem(info);
2bda0e17
KB
1083}
1084
1085// For list view mode (only), inserts a column.
debe6624 1086long wxListCtrl::InsertColumn(long col, wxListItem& item)
2bda0e17 1087{
0b5efdc7
VZ
1088 LV_COLUMN lvCol;
1089 lvCol.mask = 0;
1090 lvCol.fmt = 0;
1091 lvCol.pszText = NULL;
1092
1093 if ( item.m_mask & wxLIST_MASK_TEXT )
1094 {
1095 lvCol.mask |= LVCF_TEXT;
1096 lvCol.pszText = WXSTRINGCAST item.m_text;
1097 lvCol.cchTextMax = 0; // Ignored
1098 }
1099 if ( item.m_mask & wxLIST_MASK_FORMAT )
1100 {
1101 lvCol.mask |= LVCF_FMT;
1102
1103 if ( item.m_format == wxLIST_FORMAT_LEFT )
1104 lvCol.fmt = LVCFMT_LEFT;
1105 if ( item.m_format == wxLIST_FORMAT_RIGHT )
1106 lvCol.fmt = LVCFMT_RIGHT;
1107 if ( item.m_format == wxLIST_FORMAT_CENTRE )
1108 lvCol.fmt = LVCFMT_CENTER;
2bda0e17
KB
1109 }
1110
e373f51b 1111 lvCol.mask |= LVCF_WIDTH;
0b5efdc7
VZ
1112 if ( item.m_mask & wxLIST_MASK_WIDTH )
1113 {
e373f51b 1114 if ( item.m_width == wxLIST_AUTOSIZE)
0b5efdc7 1115 lvCol.cx = LVSCW_AUTOSIZE;
e373f51b 1116 else if ( item.m_width == wxLIST_AUTOSIZE_USEHEADER)
0b5efdc7 1117 lvCol.cx = LVSCW_AUTOSIZE_USEHEADER;
e373f51b
VZ
1118 else
1119 lvCol.cx = item.m_width;
1120 }
1121 else
1122 {
1123 // always give some width to the new column: this one is compatible
1124 // with wxGTK
1125 lvCol.cx = 80;
0b5efdc7 1126 }
e373f51b 1127
0b5efdc7
VZ
1128 lvCol.mask |= LVCF_SUBITEM;
1129 lvCol.iSubItem = col;
2bda0e17 1130
edccf428 1131 bool success = ListView_InsertColumn(GetHwnd(), col, & lvCol) != -1;
2bda0e17 1132 if ( success )
e373f51b
VZ
1133 {
1134 m_colCount++;
1135 }
1136 else
1137 {
223d09f6 1138 wxLogDebug(wxT("Failed to insert the column '%s' into listview!"),
e373f51b
VZ
1139 lvCol.pszText);
1140 }
1141
2bda0e17
KB
1142 return success;
1143}
1144
bdc72a22
VZ
1145long wxListCtrl::InsertColumn(long col,
1146 const wxString& heading,
1147 int format,
1148 int width)
2bda0e17 1149{
0b5efdc7
VZ
1150 wxListItem item;
1151 item.m_mask = wxLIST_MASK_TEXT | wxLIST_MASK_FORMAT;
1152 item.m_text = heading;
1153 if ( width > -1 )
1154 {
1155 item.m_mask |= wxLIST_MASK_WIDTH;
1156 item.m_width = width;
1157 }
1158 item.m_format = format;
2bda0e17 1159
0b5efdc7 1160 return InsertColumn(col, item);
2bda0e17
KB
1161}
1162
1163// Scrolls the list control. If in icon, small icon or report view mode,
1164// x specifies the number of pixels to scroll. If in list view mode, x
1165// specifies the number of columns to scroll.
1166// If in icon, small icon or list view mode, y specifies the number of pixels
1167// to scroll. If in report view mode, y specifies the number of lines to scroll.
debe6624 1168bool wxListCtrl::ScrollList(int dx, int dy)
2bda0e17 1169{
edccf428 1170 return (ListView_Scroll(GetHwnd(), dx, dy) != 0);
2bda0e17
KB
1171}
1172
1173// Sort items.
1174
1175// fn is a function which takes 3 long arguments: item1, item2, data.
1176// item1 is the long data associated with a first item (NOT the index).
1177// item2 is the long data associated with a second item (NOT the index).
1178// data is the same value as passed to SortItems.
1179// The return value is a negative number if the first item should precede the second
1180// item, a positive number of the second item should precede the first,
1181// or zero if the two items are equivalent.
1182
1183// data is arbitrary data to be passed to the sort function.
1184bool wxListCtrl::SortItems(wxListCtrlCompare fn, long data)
1185{
edccf428 1186 return (ListView_SortItems(GetHwnd(), (PFNLVCOMPARE) fn, data) != 0);
2bda0e17
KB
1187}
1188
edccf428
VZ
1189// ----------------------------------------------------------------------------
1190// message processing
1191// ----------------------------------------------------------------------------
1192
debe6624 1193bool wxListCtrl::MSWCommand(WXUINT cmd, WXWORD id)
2bda0e17 1194{
0b5efdc7 1195 if (cmd == EN_UPDATE)
acb62b84 1196 {
0b5efdc7
VZ
1197 wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, id);
1198 event.SetEventObject( this );
1199 ProcessCommand(event);
1200 return TRUE;
acb62b84 1201 }
0b5efdc7 1202 else if (cmd == EN_KILLFOCUS)
acb62b84 1203 {
0b5efdc7
VZ
1204 wxCommandEvent event(wxEVT_KILL_FOCUS, id);
1205 event.SetEventObject( this );
1206 ProcessCommand(event);
1207 return TRUE;
acb62b84 1208 }
edccf428
VZ
1209 else
1210 return FALSE;
0b5efdc7
VZ
1211}
1212
a23fd0e1 1213bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
0b5efdc7 1214{
bdc72a22
VZ
1215 // prepare the event
1216 // -----------------
1217
0b5efdc7
VZ
1218 wxListEvent event(wxEVT_NULL, m_windowId);
1219 wxEventType eventType = wxEVT_NULL;
bdc72a22
VZ
1220 NMHDR *nmhdr = (NMHDR *)lParam;
1221 switch ( nmhdr->code )
acb62b84 1222 {
0b5efdc7 1223 case LVN_BEGINRDRAG:
bdc72a22 1224 eventType = wxEVT_COMMAND_LIST_BEGIN_RDRAG;
0b5efdc7 1225 // fall through
cb0f56f9 1226
0b5efdc7
VZ
1227 case LVN_BEGINDRAG:
1228 if ( eventType == wxEVT_NULL )
1229 {
1230 eventType = wxEVT_COMMAND_LIST_BEGIN_DRAG;
1231 }
1232
1233 {
1234 NM_LISTVIEW *hdr = (NM_LISTVIEW *)lParam;
1235 event.m_itemIndex = hdr->iItem;
1236 event.m_pointDrag.x = hdr->ptAction.x;
1237 event.m_pointDrag.y = hdr->ptAction.y;
1238 }
1239 break;
1240
1241 case LVN_BEGINLABELEDIT:
1242 {
1243 eventType = wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT;
1244 LV_DISPINFO *info = (LV_DISPINFO *)lParam;
edccf428 1245 wxConvertFromMSWListItem(this, event.m_item, info->item, GetHwnd());
0b5efdc7
VZ
1246 break;
1247 }
1248
1249 case LVN_COLUMNCLICK:
1250 {
1251 eventType = wxEVT_COMMAND_LIST_COL_CLICK;
1252 NM_LISTVIEW* hdr = (NM_LISTVIEW*)lParam;
1253 event.m_itemIndex = -1;
1254 event.m_col = hdr->iSubItem;
1255 break;
1256 }
5ea47806 1257
0b5efdc7 1258 case LVN_DELETEALLITEMS:
5ea47806
VZ
1259 // what's the sense of generating a wxWin event for this when
1260 // it's absolutely not portable?
1261#if 0
1262 eventType = wxEVT_COMMAND_LIST_DELETE_ALL_ITEMS;
1263 event.m_itemIndex = -1;
1264#endif // 0
1265
1266 // return TRUE to suppress all additional LVN_DELETEITEM
1267 // notifications - this makes deleting all items from a list ctrl
d62228a6
VZ
1268 // much faster
1269 *result = TRUE;
bdc72a22 1270
d62228a6 1271 return TRUE;
5ea47806 1272
0b5efdc7
VZ
1273 case LVN_DELETEITEM:
1274 {
1275 eventType = wxEVT_COMMAND_LIST_DELETE_ITEM;
1276 NM_LISTVIEW* hdr = (NM_LISTVIEW*)lParam;
1277 event.m_itemIndex = hdr->iItem;
bdc72a22
VZ
1278
1279 if ( m_hasAnyAttr )
1280 {
696e1ea0 1281 delete (wxListItemAttr *)m_attrs.Delete(hdr->iItem);
bdc72a22 1282 }
0b5efdc7 1283 }
bdc72a22
VZ
1284 break;
1285
0b5efdc7
VZ
1286 case LVN_ENDLABELEDIT:
1287 {
1288 eventType = wxEVT_COMMAND_LIST_END_LABEL_EDIT;
1289 LV_DISPINFO *info = (LV_DISPINFO *)lParam;
1ee4ead5 1290 wxConvertFromMSWListItem(this, event.m_item, info->item);
0b5efdc7 1291 if ( info->item.pszText == NULL || info->item.iItem == -1 )
1ee4ead5 1292 return FALSE;
0b5efdc7 1293 }
bdc72a22
VZ
1294 break;
1295
1296 case LVN_SETDISPINFO:
1297 {
1298 eventType = wxEVT_COMMAND_LIST_SET_INFO;
1299 LV_DISPINFO *info = (LV_DISPINFO *)lParam;
1300 wxConvertFromMSWListItem(this, event.m_item, info->item, GetHwnd());
1301 }
1302 break;
edccf428 1303
bdc72a22 1304 case LVN_GETDISPINFO:
edccf428
VZ
1305 // this provokes stack overflow: indeed, wxConvertFromMSWListItem()
1306 // sends us WM_NOTIFY! As it doesn't do anything for now, just leave
1307 // it out.
1308#if 0
0b5efdc7 1309 {
0b5efdc7
VZ
1310 // TODO: some text buffering here, I think
1311 // TODO: API for getting Windows to retrieve values
1312 // on demand.
1313 eventType = wxEVT_COMMAND_LIST_GET_INFO;
1314 LV_DISPINFO *info = (LV_DISPINFO *)lParam;
edccf428 1315 wxConvertFromMSWListItem(this, event.m_item, info->item, GetHwnd());
0b5efdc7
VZ
1316 break;
1317 }
edccf428 1318#endif // 0
bdc72a22
VZ
1319 return FALSE;
1320
edccf428 1321
0b5efdc7
VZ
1322 case LVN_INSERTITEM:
1323 {
1324 eventType = wxEVT_COMMAND_LIST_INSERT_ITEM;
1325 NM_LISTVIEW* hdr = (NM_LISTVIEW*)lParam;
1326 event.m_itemIndex = hdr->iItem;
1327 break;
1328 }
bdc72a22 1329
0b5efdc7
VZ
1330 case LVN_ITEMCHANGED:
1331 {
1332 // This needs to be sent to wxListCtrl as a rather more
1333 // concrete event. For now, just detect a selection
1334 // or deselection.
1335 NM_LISTVIEW* hdr = (NM_LISTVIEW*)lParam;
1336 if ( (hdr->uNewState & LVIS_SELECTED) && !(hdr->uOldState & LVIS_SELECTED) )
1337 {
1338 eventType = wxEVT_COMMAND_LIST_ITEM_SELECTED;
1339 event.m_itemIndex = hdr->iItem;
1340 }
1341 else if ( !(hdr->uNewState & LVIS_SELECTED) && (hdr->uOldState & LVIS_SELECTED) )
1342 {
1343 eventType = wxEVT_COMMAND_LIST_ITEM_DESELECTED;
1344 event.m_itemIndex = hdr->iItem;
1345 }
1346 else
1347 return FALSE;
1348 break;
1349 }
edccf428 1350
0b5efdc7
VZ
1351 case LVN_KEYDOWN:
1352 {
0b5efdc7 1353 LV_KEYDOWN *info = (LV_KEYDOWN *)lParam;
edccf428
VZ
1354 WORD wVKey = info->wVKey;
1355
1356 // get the current selection
1357 long lItem = GetNextItem(-1,
1358 wxLIST_NEXT_ALL,
1359 wxLIST_STATE_SELECTED);
1360
1361 // <Enter> or <Space> activate the selected item if any
1362 if ( lItem != -1 && (wVKey == VK_RETURN || wVKey == VK_SPACE) )
1363 {
1364 // TODO this behaviour probably should be optional
1365 eventType = wxEVT_COMMAND_LIST_ITEM_ACTIVATED;
1366 event.m_itemIndex = lItem;
1367 }
1368 else
1369 {
1370 eventType = wxEVT_COMMAND_LIST_KEY_DOWN;
1371 event.m_code = wxCharCodeMSWToWX(wVKey);
1372 }
0b5efdc7
VZ
1373 break;
1374 }
edccf428
VZ
1375
1376 case NM_DBLCLK:
1377 // if the user processes it in wxEVT_COMMAND_LEFT_CLICK(), don't do
1378 // anything else
1379 if ( wxControl::MSWOnNotify(idCtrl, lParam, result) )
1380 {
1381 return TRUE;
1382 }
1383
1384 // else translate it into wxEVT_COMMAND_LIST_ITEM_ACTIVATED event
1ee4ead5
VZ
1385 {
1386 eventType = wxEVT_COMMAND_LIST_ITEM_ACTIVATED;
1387 NM_LISTVIEW* hdr = (NM_LISTVIEW*)lParam;
1388 event.m_itemIndex = hdr->iItem;
1389 }
edccf428 1390 break;
cb0f56f9
VZ
1391
1392 case NM_RCLICK:
1393 /* TECH NOTE: NM_RCLICK isn't really good enough here. We want to
1394 subclass and check for the actual WM_RBUTTONDOWN message, because
1395 NM_RCLICK waits for the WM_RBUTTONUP message as well before firing off.
1396 We want to have notify events for both down -and- up. */
1397 {
1398 // if the user processes it in wxEVT_COMMAND_RIGHT_CLICK(), don't do
1399 // anything else
1400 if ( wxControl::MSWOnNotify(idCtrl, lParam, result) ) {
1401 return TRUE;
1402 }
1403
1404 // else translate it into wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK event
1405 LV_HITTESTINFO lvhti;
11c7d5b6
VZ
1406 wxZeroMemory(lvhti);
1407
cb0f56f9
VZ
1408 ::GetCursorPos(&(lvhti.pt));
1409 ::ScreenToClient(GetHwnd(),&(lvhti.pt));
1410 if ( ListView_HitTest(GetHwnd(),&lvhti) != -1 )
1411 {
cb0f56f9
VZ
1412 if ( lvhti.flags & LVHT_ONITEM )
1413 {
1414 eventType = wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK;
1415 event.m_itemIndex = lvhti.iItem;
1416 }
9bfa7bfc 1417 }
cb0f56f9
VZ
1418 }
1419 break;
1420
bdc72a22
VZ
1421#if 0
1422 case NM_MCLICK: // ***** THERE IS NO NM_MCLICK. Subclass anyone? ******
1423 {
1424 // if the user processes it in wxEVT_COMMAND_MIDDLE_CLICK(), don't do
1425 // anything else
1426 if ( wxControl::MSWOnNotify(idCtrl, lParam, result) )
1427 {
1428 return TRUE;
1429 }
cb0f56f9 1430
bdc72a22
VZ
1431 // else translate it into wxEVT_COMMAND_LIST_ITEM_MIDDLE_CLICK event
1432 eventType = wxEVT_COMMAND_LIST_ITEM_MIDDLE_CLICK;
1433 NMITEMACTIVATE* hdr = (NMITEMACTIVATE*)lParam;
1434 event.m_itemIndex = hdr->iItem;
1435 }
1436 break;
1437#endif // 0
1438
1439#ifdef NM_CUSTOMDRAW
1440 case NM_CUSTOMDRAW:
0b5efdc7 1441 {
bdc72a22
VZ
1442 LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)lParam;
1443 NMCUSTOMDRAW& nmcd = lplvcd->nmcd;
1444 switch( nmcd.dwDrawStage )
1445 {
d62228a6 1446 case CDDS_PREPAINT:
bdc72a22
VZ
1447 // if we've got any items with non standard attributes,
1448 // notify us before painting each item
1449 *result = m_hasAnyAttr ? CDRF_NOTIFYITEMDRAW
1450 : CDRF_DODEFAULT;
1451 return TRUE;
1452
1453 case CDDS_ITEMPREPAINT:
1454 {
d62228a6
VZ
1455 wxListItemAttr *attr =
1456 (wxListItemAttr *)m_attrs.Get(nmcd.dwItemSpec);
1457
1458 if ( !attr )
bdc72a22
VZ
1459 {
1460 // nothing to do for this item
1461 return CDRF_DODEFAULT;
1462 }
1463
d62228a6
VZ
1464 HFONT hFont;
1465 wxColour colText, colBack;
1466 if ( attr->HasFont() )
1467 {
1468 wxFont font = attr->GetFont();
1469 hFont = (HFONT)font.GetResourceHandle();
1470 }
1471 else
1472 {
1473 hFont = 0;
1474 }
1475
1476 if ( attr->HasTextColour() )
1477 {
1478 colText = attr->GetTextColour();
1479 }
1480 else
1481 {
1482 colText = GetTextColour();
1483 }
1484
1485 if ( attr->HasBackgroundColour() )
1486 {
1487 colBack = attr->GetBackgroundColour();
1488 }
1489 else
1490 {
1491 colBack = GetBackgroundColour();
1492 }
1493
1494 // note that if we wanted to set colours for
1495 // individual columns (subitems), we would have
1496 // returned CDRF_NOTIFYSUBITEMREDRAW from here
1497 if ( hFont )
1498 {
1499 ::SelectObject(nmcd.hdc, hFont);
bdc72a22 1500
d62228a6
VZ
1501 *result = CDRF_NEWFONT;
1502 }
1503 else
1504 {
1505 *result = CDRF_DODEFAULT;
1506 }
bdc72a22 1507
d62228a6
VZ
1508 lplvcd->clrText = wxColourToRGB(colText);
1509 lplvcd->clrTextBk = wxColourToRGB(colBack);
bdc72a22
VZ
1510
1511 return TRUE;
1512 }
d62228a6
VZ
1513
1514 default:
1515 *result = CDRF_DODEFAULT;
1516 return TRUE;
bdc72a22 1517 }
0b5efdc7 1518 }
bdc72a22
VZ
1519 break;
1520#endif // NM_CUSTOMDRAW
0b5efdc7 1521
edccf428 1522 default:
a23fd0e1 1523 return wxControl::MSWOnNotify(idCtrl, lParam, result);
acb62b84
VZ
1524 }
1525
bdc72a22
VZ
1526 // process the event
1527 // -----------------
1528
0b5efdc7
VZ
1529 event.SetEventObject( this );
1530 event.SetEventType(eventType);
acb62b84 1531
0b5efdc7
VZ
1532 if ( !GetEventHandler()->ProcessEvent(event) )
1533 return FALSE;
acb62b84 1534
bdc72a22
VZ
1535 // post processing
1536 // ---------------
1537
1538 switch ( (int)nmhdr->code )
acb62b84 1539 {
1ee4ead5 1540 case LVN_GETDISPINFO:
0b5efdc7 1541 {
1ee4ead5
VZ
1542 LV_DISPINFO *info = (LV_DISPINFO *)lParam;
1543 if ( info->item.mask & LVIF_TEXT )
1544 {
1545 if ( !event.m_item.m_text.IsNull() )
1546 {
1547 info->item.pszText = AddPool(event.m_item.m_text);
1548 info->item.cchTextMax = wxStrlen(info->item.pszText) + 1;
1549 }
1550 }
1551 // wxConvertToMSWListItem(this, event.m_item, info->item);
1552 break;
0b5efdc7 1553 }
1ee4ead5
VZ
1554 case LVN_ENDLABELEDIT:
1555 {
1556 *result = event.IsAllowed();
1557 return TRUE;
1558 }
1559 default:
1560 break;
acb62b84 1561 }
acb62b84 1562
0b5efdc7 1563 *result = !event.IsAllowed();
fd3f686c 1564
0b5efdc7 1565 return TRUE;
2bda0e17
KB
1566}
1567
837e5743 1568wxChar *wxListCtrl::AddPool(const wxString& str)
2bda0e17 1569{
0b5efdc7
VZ
1570 // Remove the first element if 3 strings exist
1571 if ( m_stringPool.Number() == 3 )
1572 {
1573 wxNode *node = m_stringPool.First();
1574 delete[] (char *)node->Data();
1575 delete node;
1576 }
837e5743
OK
1577 wxNode *node = m_stringPool.Add(WXSTRINGCAST str);
1578 return (wxChar *)node->Data();
2bda0e17
KB
1579}
1580
edccf428
VZ
1581// ----------------------------------------------------------------------------
1582// wxListItem
1583// ----------------------------------------------------------------------------
1584
2bda0e17 1585// List item structure
0b5efdc7 1586wxListItem::wxListItem()
2bda0e17
KB
1587{
1588 m_mask = 0;
1589 m_itemId = 0;
1590 m_col = 0;
1591 m_state = 0;
1592 m_stateMask = 0;
1593 m_image = 0;
0b5efdc7 1594 m_data = 0;
2bda0e17 1595
0b5efdc7
VZ
1596 m_format = wxLIST_FORMAT_CENTRE;
1597 m_width = 0;
bdc72a22
VZ
1598
1599 m_attr = NULL;
2bda0e17
KB
1600}
1601
9b00bb16
RR
1602void wxListItem::Clear()
1603{
1604 m_mask = 0;
1605 m_itemId = 0;
1606 m_col = 0;
1607 m_state = 0;
1608 m_stateMask = 0;
1609 m_image = 0;
1610 m_data = 0;
1611 m_format = wxLIST_FORMAT_CENTRE;
1612 m_width = 0;
1613 m_text = wxEmptyString;
1614
1615 if (m_attr) delete m_attr;
1616 m_attr = NULL;
1617}
1618
1619void wxListItem::ClearAttributes()
1620{
1621 if (m_attr) delete m_attr;
1622 m_attr = NULL;
1623}
1624
2bda0e17
KB
1625static void wxConvertFromMSWListItem(const wxListCtrl *ctrl, wxListItem& info, LV_ITEM& lvItem, HWND getFullInfo)
1626{
0b5efdc7
VZ
1627 info.m_data = lvItem.lParam;
1628 info.m_mask = 0;
1629 info.m_state = 0;
1630 info.m_stateMask = 0;
1631 info.m_itemId = lvItem.iItem;
acb62b84 1632
0b5efdc7 1633 long oldMask = lvItem.mask;
acb62b84 1634
0b5efdc7
VZ
1635 bool needText = FALSE;
1636 if (getFullInfo != 0)
acb62b84 1637 {
0b5efdc7
VZ
1638 if ( lvItem.mask & LVIF_TEXT )
1639 needText = FALSE;
1640 else
1641 needText = TRUE;
acb62b84 1642
0b5efdc7
VZ
1643 if ( needText )
1644 {
837e5743 1645 lvItem.pszText = new wxChar[513];
0b5efdc7
VZ
1646 lvItem.cchTextMax = 512;
1647 }
edccf428
VZ
1648 // lvItem.mask |= TVIF_HANDLE | TVIF_STATE | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN | TVIF_PARAM;
1649 lvItem.mask |= LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
1650 ::SendMessage(getFullInfo, LVM_GETITEM, 0, (LPARAM)& lvItem);
0b5efdc7 1651 }
acb62b84 1652
0b5efdc7 1653 if ( lvItem.mask & LVIF_STATE )
acb62b84 1654 {
0b5efdc7
VZ
1655 info.m_mask |= wxLIST_MASK_STATE;
1656
1657 if ( lvItem.stateMask & LVIS_CUT)
1658 {
edccf428 1659 info.m_stateMask |= wxLIST_STATE_CUT;
0b5efdc7 1660 if ( lvItem.state & LVIS_CUT )
edccf428 1661 info.m_state |= wxLIST_STATE_CUT;
0b5efdc7
VZ
1662 }
1663 if ( lvItem.stateMask & LVIS_DROPHILITED)
1664 {
edccf428 1665 info.m_stateMask |= wxLIST_STATE_DROPHILITED;
0b5efdc7 1666 if ( lvItem.state & LVIS_DROPHILITED )
edccf428 1667 info.m_state |= wxLIST_STATE_DROPHILITED;
0b5efdc7
VZ
1668 }
1669 if ( lvItem.stateMask & LVIS_FOCUSED)
1670 {
edccf428 1671 info.m_stateMask |= wxLIST_STATE_FOCUSED;
0b5efdc7 1672 if ( lvItem.state & LVIS_FOCUSED )
edccf428 1673 info.m_state |= wxLIST_STATE_FOCUSED;
0b5efdc7
VZ
1674 }
1675 if ( lvItem.stateMask & LVIS_SELECTED)
1676 {
edccf428 1677 info.m_stateMask |= wxLIST_STATE_SELECTED;
0b5efdc7 1678 if ( lvItem.state & LVIS_SELECTED )
edccf428 1679 info.m_state |= wxLIST_STATE_SELECTED;
0b5efdc7 1680 }
acb62b84 1681 }
0b5efdc7
VZ
1682
1683 if ( lvItem.mask & LVIF_TEXT )
acb62b84 1684 {
0b5efdc7
VZ
1685 info.m_mask |= wxLIST_MASK_TEXT;
1686 info.m_text = lvItem.pszText;
acb62b84 1687 }
0b5efdc7 1688 if ( lvItem.mask & LVIF_IMAGE )
acb62b84 1689 {
0b5efdc7
VZ
1690 info.m_mask |= wxLIST_MASK_IMAGE;
1691 info.m_image = lvItem.iImage;
acb62b84 1692 }
0b5efdc7
VZ
1693 if ( lvItem.mask & LVIF_PARAM )
1694 info.m_mask |= wxLIST_MASK_DATA;
1695 if ( lvItem.mask & LVIF_DI_SETITEM )
1696 info.m_mask |= wxLIST_SET_ITEM;
1697 info.m_col = lvItem.iSubItem;
1698
1699 if (needText)
acb62b84 1700 {
0b5efdc7
VZ
1701 if (lvItem.pszText)
1702 delete[] lvItem.pszText;
acb62b84 1703 }
edccf428 1704 lvItem.mask = oldMask;
2bda0e17
KB
1705}
1706
1707static void wxConvertToMSWListItem(const wxListCtrl *ctrl, wxListItem& info, LV_ITEM& lvItem)
1708{
edccf428 1709 lvItem.iItem = (int) info.m_itemId;
acb62b84 1710
edccf428 1711 lvItem.iImage = info.m_image;
0b5efdc7
VZ
1712 lvItem.lParam = info.m_data;
1713 lvItem.stateMask = 0;
1714 lvItem.state = 0;
1715 lvItem.mask = 0;
1716 lvItem.iSubItem = info.m_col;
acb62b84 1717
0b5efdc7 1718 if (info.m_mask & wxLIST_MASK_STATE)
acb62b84 1719 {
edccf428 1720 lvItem.mask |= LVIF_STATE;
0b5efdc7
VZ
1721 if (info.m_stateMask & wxLIST_STATE_CUT)
1722 {
edccf428 1723 lvItem.stateMask |= LVIS_CUT;
0b5efdc7
VZ
1724 if (info.m_state & wxLIST_STATE_CUT)
1725 lvItem.state |= LVIS_CUT;
1726 }
1727 if (info.m_stateMask & wxLIST_STATE_DROPHILITED)
1728 {
1729 lvItem.stateMask |= LVIS_DROPHILITED;
1730 if (info.m_state & wxLIST_STATE_DROPHILITED)
1731 lvItem.state |= LVIS_DROPHILITED;
1732 }
1733 if (info.m_stateMask & wxLIST_STATE_FOCUSED)
1734 {
1735 lvItem.stateMask |= LVIS_FOCUSED;
1736 if (info.m_state & wxLIST_STATE_FOCUSED)
1737 lvItem.state |= LVIS_FOCUSED;
1738 }
1739 if (info.m_stateMask & wxLIST_STATE_SELECTED)
1740 {
1741 lvItem.stateMask |= LVIS_SELECTED;
1742 if (info.m_state & wxLIST_STATE_SELECTED)
1743 lvItem.state |= LVIS_SELECTED;
1744 }
acb62b84 1745 }
acb62b84 1746
0b5efdc7 1747 if (info.m_mask & wxLIST_MASK_TEXT)
acb62b84 1748 {
edccf428 1749 lvItem.mask |= LVIF_TEXT;
0b5efdc7
VZ
1750 if ( ctrl->GetWindowStyleFlag() & wxLC_USER_TEXT )
1751 {
1752 lvItem.pszText = LPSTR_TEXTCALLBACK;
1753 }
1754 else
1755 {
edccf428 1756 lvItem.pszText = WXSTRINGCAST info.m_text;
0b5efdc7
VZ
1757 if ( lvItem.pszText )
1758 lvItem.cchTextMax = info.m_text.Length();
1759 else
1760 lvItem.cchTextMax = 0;
1761 }
acb62b84 1762 }
0b5efdc7 1763 if (info.m_mask & wxLIST_MASK_IMAGE)
edccf428 1764 lvItem.mask |= LVIF_IMAGE;
0b5efdc7 1765 if (info.m_mask & wxLIST_MASK_DATA)
edccf428 1766 lvItem.mask |= LVIF_PARAM;
2bda0e17
KB
1767}
1768
edccf428 1769// ----------------------------------------------------------------------------
2bda0e17 1770// List event
edccf428
VZ
1771// ----------------------------------------------------------------------------
1772
92976ab6 1773IMPLEMENT_DYNAMIC_CLASS(wxListEvent, wxNotifyEvent)
2bda0e17 1774
fd3f686c 1775wxListEvent::wxListEvent(wxEventType commandType, int id)
edccf428 1776 : wxNotifyEvent(commandType, id)
2bda0e17 1777{
0b5efdc7
VZ
1778 m_code = 0;
1779 m_itemIndex = 0;
5d47c8a0 1780 m_oldItemIndex = 0;
0b5efdc7
VZ
1781 m_col = 0;
1782 m_cancelled = FALSE;
2bda0e17
KB
1783}
1784
edccf428 1785#endif // __WIN95__
2bda0e17 1786