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