]> git.saurik.com Git - wxWidgets.git/blame - src/msw/headerctrl.cpp
set correct properties
[wxWidgets.git] / src / msw / headerctrl.cpp
CommitLineData
56873923
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: src/msw/headerctrl.cpp
3// Purpose: implementation of wxHeaderCtrl for wxMSW
4// Author: Vadim Zeitlin
5// Created: 2008-12-01
6// RCS-ID: $Id$
7// Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
8// Licence: wxWindows licence
9///////////////////////////////////////////////////////////////////////////////
10
11// ============================================================================
12// declarations
13// ============================================================================
14
15// ----------------------------------------------------------------------------
16// headers
17// ----------------------------------------------------------------------------
18
19// for compilers that support precompilation, includes "wx.h".
20#include "wx/wxprec.h"
21
22#ifdef __BORLANDC__
23 #pragma hdrstop
24#endif
25
e721a2a2
VZ
26#if wxUSE_HEADERCTRL
27
56873923 28#ifndef WX_PRECOMP
9485b24f 29 #include "wx/app.h"
9ef3e400 30 #include "wx/log.h"
56873923
VZ
31#endif // WX_PRECOMP
32
33#include "wx/headerctrl.h"
3bfaa5a7
VZ
34
35#ifndef wxHAS_GENERIC_HEADERCTRL
36
56873923
VZ
37#include "wx/imaglist.h"
38
39#include "wx/msw/wrapcctl.h"
9ef3e400 40#include "wx/msw/private.h"
56873923 41
9b66a1d3
VZ
42#ifndef HDM_SETBITMAPMARGIN
43 #define HDM_SETBITMAPMARGIN 0x1234
44#endif
45
46#ifndef Header_SetBitmapMargin
47 #define Header_SetBitmapMargin(hwnd, margin) \
48 ::SendMessage((hwnd), HDM_SETBITMAPMARGIN, (WPARAM)(margin), 0)
49#endif
50
fa3d4aaf
VZ
51// from src/msw/listctrl.cpp
52extern int WXDLLIMPEXP_CORE wxMSWGetColumnClicked(NMHDR *nmhdr, POINT *ptClick);
53
56873923
VZ
54// ============================================================================
55// wxHeaderCtrl implementation
56// ============================================================================
57
58// ----------------------------------------------------------------------------
59// wxHeaderCtrl construction/destruction
60// ----------------------------------------------------------------------------
61
62void wxHeaderCtrl::Init()
63{
040b9528 64 m_numColumns = 0;
56873923 65 m_imageList = NULL;
38cd07c4 66 m_scrollOffset = 0;
56873923
VZ
67}
68
69bool wxHeaderCtrl::Create(wxWindow *parent,
70 wxWindowID id,
71 const wxPoint& pos,
72 const wxSize& size,
73 long style,
74 const wxString& name)
75{
76 // notice that we don't need InitCommonControlsEx(ICC_LISTVIEW_CLASSES)
77 // here as we already call InitCommonControls() in wxApp initialization
78 // code which covers this
79
80 if ( !CreateControl(parent, id, pos, size, style, wxDefaultValidator, name) )
81 return false;
82
83 if ( !MSWCreateControl(WC_HEADER, _T(""), pos, size) )
84 return false;
85
9485b24f
VZ
86 // special hack for margins when using comctl32.dll v6 or later: the
87 // default margin is too big and results in label truncation when the
88 // column width is just about right to show it together with the sort
89 // indicator, so reduce it to a smaller value (in principle we could even
90 // use 0 here but this starts to look ugly)
91 if ( wxApp::GetComCtl32Version() >= 600 )
92 {
93 Header_SetBitmapMargin(GetHwnd(), ::GetSystemMetrics(SM_CXEDGE));
94 }
95
56873923
VZ
96 return true;
97}
98
99WXDWORD wxHeaderCtrl::MSWGetStyle(long style, WXDWORD *exstyle) const
100{
101 WXDWORD msStyle = wxControl::MSWGetStyle(style, exstyle);
102
613de0e8 103 if ( style & wxHD_ALLOW_REORDER )
56873923
VZ
104 msStyle |= HDS_DRAGDROP;
105
106 // the control looks nicer with these styles and there doesn't seem to be
107 // any reason to not use them so we always do (as for HDS_HORZ it is 0
108 // anyhow but include it for clarity)
109 msStyle |= HDS_HORZ | HDS_BUTTONS | HDS_FLAT | HDS_FULLDRAG | HDS_HOTTRACK;
110
111 return msStyle;
112}
113
114wxHeaderCtrl::~wxHeaderCtrl()
115{
116 delete m_imageList;
117}
118
f24f6579
VZ
119// ----------------------------------------------------------------------------
120// wxHeaderCtrl scrolling
121// ----------------------------------------------------------------------------
122
38cd07c4
VZ
123void wxHeaderCtrl::DoSetSize(int x, int y,
124 int w, int h,
125 int sizeFlags)
126{
127 wxHeaderCtrlBase::DoSetSize(x + m_scrollOffset, y, w - m_scrollOffset, h,
128 sizeFlags);
129}
130
d8fc3398 131void wxHeaderCtrl::DoScrollHorz(int dx)
f24f6579 132{
d8fc3398
VZ
133 // as the native control doesn't support offsetting its contents, we use a
134 // hack here to make it appear correctly when the parent is scrolled:
135 // instead of scrolling or repainting we simply move the control window
136 // itself: to be precise, offset it by the scroll increment to the left and
137 // increment its width to still extend to the right boundary to compensate
138 // for it (notice that dx is negative when scrolling to the right)
38cd07c4
VZ
139 m_scrollOffset += dx;
140
141 wxHeaderCtrlBase::DoSetSize(GetPosition().x + dx, -1,
142 GetSize().x - dx, -1,
143 wxSIZE_USE_EXISTING);
f24f6579
VZ
144}
145
56873923
VZ
146// ----------------------------------------------------------------------------
147// wxHeaderCtrl geometry calculation
148// ----------------------------------------------------------------------------
149
150wxSize wxHeaderCtrl::DoGetBestSize() const
151{
152 RECT rc = wxGetClientRect(GetHwndOf(GetParent()));
153 WINDOWPOS wpos;
154 HDLAYOUT layout = { &rc, &wpos };
155 if ( !Header_Layout(GetHwnd(), &layout) )
156 {
157 wxLogLastError(_T("Header_Layout"));
158 return wxControl::DoGetBestSize();
159 }
160
161 return wxSize(wpos.cx, wpos.cy);
162}
163
164// ----------------------------------------------------------------------------
165// wxHeaderCtrl columns managements
166// ----------------------------------------------------------------------------
167
168unsigned int wxHeaderCtrl::DoGetCount() const
169{
040b9528
VZ
170 // we can't use Header_GetItemCount() here because it doesn't take the
171 // hidden columns into account and we can't find the hidden columns after
172 // the last shown one in MSWFromNativeIdx() without knowing where to stop
173 // so we have to store the columns count internally
174 return m_numColumns;
175}
176
177int wxHeaderCtrl::GetShownColumnsCount() const
178{
179 const int numItems = Header_GetItemCount(GetHwnd());
180
181 wxASSERT_MSG( numItems >= 0 && (unsigned)numItems <= m_numColumns,
182 "unexpected number of items in the native control" );
183
184 return numItems;
56873923
VZ
185}
186
e2bfe673 187void wxHeaderCtrl::DoSetCount(unsigned int count)
56873923 188{
e2bfe673
VZ
189 unsigned n;
190
191 // first delete all old columns
040b9528 192 const unsigned countOld = GetShownColumnsCount();
e2bfe673
VZ
193 for ( n = 0; n < countOld; n++ )
194 {
195 if ( !Header_DeleteItem(GetHwnd(), 0) )
196 {
197 wxLogLastError(_T("Header_DeleteItem"));
198 }
199 }
200
040b9528
VZ
201 // update the column indices order array before changing m_numColumns
202 DoResizeColumnIndices(m_colIndices, count);
203
e2bfe673 204 // and add the new ones
040b9528
VZ
205 m_numColumns = count;
206 m_isHidden.resize(m_numColumns);
e2bfe673
VZ
207 for ( n = 0; n < count; n++ )
208 {
040b9528
VZ
209 const wxHeaderColumn& col = GetColumn(n);
210 if ( col.IsShown() )
211 {
212 m_isHidden[n] = false;
213
214 DoInsertItem(col, n);
215 }
216 else // hidden initially
217 {
218 m_isHidden[n] = true;
219 }
e2bfe673
VZ
220 }
221}
222
223void wxHeaderCtrl::DoUpdate(unsigned int idx)
224{
4de60a27
VZ
225 // the native control does provide Header_SetItem() but it's inconvenient
226 // to use it because it sends HDN_ITEMCHANGING messages and we'd have to
227 // arrange not to block setting the width from there and the logic would be
228 // more complicated as we'd have to reset the old values as well as setting
229 // the new ones -- so instead just recreate the column
702f5349 230
040b9528
VZ
231 const wxHeaderColumn& col = GetColumn(idx);
232 if ( col.IsHidden() )
233 {
234 // column is hidden now
235 if ( !m_isHidden[idx] )
236 {
237 // but it wasn't hidden before, so remove it
238 Header_DeleteItem(GetHwnd(), MSWToNativeIdx(idx));
239
240 m_isHidden[idx] = true;
241 }
242 //else: nothing to do, updating hidden column doesn't have any effect
243 }
244 else // column is shown now
245 {
246 if ( m_isHidden[idx] )
247 {
248 m_isHidden[idx] = false;
249 }
250 else // and it was shown before as well
251 {
252 // we need to remove the old column
253 Header_DeleteItem(GetHwnd(), MSWToNativeIdx(idx));
254 }
255
256 DoInsertItem(col, idx);
257 }
e2bfe673
VZ
258}
259
040b9528 260void wxHeaderCtrl::DoInsertItem(const wxHeaderColumn& col, unsigned int idx)
e2bfe673 261{
040b9528 262 wxASSERT_MSG( !col.IsHidden(), "should only be called for shown columns" );
e2bfe673
VZ
263
264 wxHDITEM hdi;
265
266 // notice that we need to store the string we use the pointer to until we
267 // pass it to the control
89c73d54
VZ
268 hdi.mask |= HDI_TEXT;
269 wxWxCharBuffer buf = col.GetTitle().wx_str();
270 hdi.pszText = buf.data();
271 hdi.cchTextMax = wxStrlen(buf);
56873923
VZ
272
273 const wxBitmap bmp = col.GetBitmap();
4de60a27 274 if ( bmp.IsOk() )
56873923 275 {
89c73d54 276 hdi.mask |= HDI_IMAGE;
56873923 277
89c73d54 278 if ( bmp.IsOk() )
56873923 279 {
89c73d54
VZ
280 const int bmpWidth = bmp.GetWidth(),
281 bmpHeight = bmp.GetHeight();
282
283 if ( !m_imageList )
284 {
285 m_imageList = new wxImageList(bmpWidth, bmpHeight);
286 Header_SetImageList(GetHwnd(), GetHimagelistOf(m_imageList));
287 }
288 else // already have an image list
289 {
290 // check that all bitmaps we use have the same size
291 int imageWidth,
292 imageHeight;
293 m_imageList->GetSize(0, imageWidth, imageHeight);
294
295 wxASSERT_MSG( imageWidth == bmpWidth && imageHeight == bmpHeight,
296 "all column bitmaps must have the same size" );
297 }
298
299 m_imageList->Add(bmp);
300 hdi.iImage = m_imageList->GetImageCount() - 1;
56873923 301 }
89c73d54 302 else // no bitmap but we still need to update the item
56873923 303 {
89c73d54 304 hdi.iImage = I_IMAGENONE;
56873923 305 }
56873923
VZ
306 }
307
4de60a27 308 if ( col.GetAlignment() != wxALIGN_NOT )
a0009205 309 {
9485b24f 310 hdi.mask |= HDI_FORMAT | HDF_LEFT;
e2bfe673
VZ
311 switch ( col.GetAlignment() )
312 {
313 case wxALIGN_LEFT:
314 hdi.fmt |= HDF_LEFT;
315 break;
56873923 316
e2bfe673
VZ
317 case wxALIGN_CENTER:
318 case wxALIGN_CENTER_HORIZONTAL:
319 hdi.fmt |= HDF_CENTER;
320 break;
56873923 321
e2bfe673
VZ
322 case wxALIGN_RIGHT:
323 hdi.fmt |= HDF_RIGHT;
324 break;
56873923 325
e2bfe673
VZ
326 default:
327 wxFAIL_MSG( "invalid column header alignment" );
328 }
329 }
a0009205 330
e2bfe673 331 if ( col.IsSortKey() )
a0009205 332 {
e2bfe673
VZ
333 hdi.mask |= HDI_FORMAT;
334 hdi.fmt |= col.IsSortOrderAscending() ? HDF_SORTUP : HDF_SORTDOWN;
a0009205
VZ
335 }
336
040b9528 337 if ( col.GetWidth() != wxCOL_WIDTH_DEFAULT )
a0009205 338 {
e2bfe673 339 hdi.mask |= HDI_WIDTH;
040b9528 340 hdi.cxy = col.GetWidth();
a0009205 341 }
a0009205 342
040b9528 343 hdi.mask |= HDI_ORDER;
2e733ec7 344 hdi.iOrder = MSWToNativeOrder(m_colIndices.Index(idx));
702f5349 345
040b9528
VZ
346 if ( ::SendMessage(GetHwnd(), HDM_INSERTITEM,
347 MSWToNativeIdx(idx), (LPARAM)&hdi) == -1 )
56873923 348 {
4de60a27 349 wxLogLastError(_T("Header_InsertItem()"));
56873923
VZ
350 }
351}
352
702f5349
VZ
353void wxHeaderCtrl::DoSetColumnsOrder(const wxArrayInt& order)
354{
040b9528
VZ
355 wxArrayInt orderShown;
356 orderShown.reserve(m_numColumns);
357
358 for ( unsigned n = 0; n < m_numColumns; n++ )
359 {
360 const int idx = order[n];
361 if ( GetColumn(idx).IsShown() )
362 orderShown.push_back(MSWToNativeIdx(idx));
363 }
364
365 if ( !Header_SetOrderArray(GetHwnd(), orderShown.size(), &orderShown[0]) )
702f5349
VZ
366 {
367 wxLogLastError(_T("Header_GetOrderArray"));
368 }
040b9528
VZ
369
370 m_colIndices = order;
702f5349
VZ
371}
372
373wxArrayInt wxHeaderCtrl::DoGetColumnsOrder() const
374{
040b9528
VZ
375 // we don't use Header_GetOrderArray() here because it doesn't return
376 // information about the hidden columns, instead we just save the columns
377 // order array in DoSetColumnsOrder() and update it when they're reordered
378 return m_colIndices;
379}
380
2e733ec7
VZ
381// ----------------------------------------------------------------------------
382// wxHeaderCtrl indexes and positions translation
383// ----------------------------------------------------------------------------
384
040b9528
VZ
385int wxHeaderCtrl::MSWToNativeIdx(int idx)
386{
387 // don't check for GetColumn(idx).IsShown() as it could have just became
388 // false and we may be called from DoUpdate() to delete the old column
389 wxASSERT_MSG( !m_isHidden[idx],
390 "column must be visible to have an "
391 "index in the native control" );
392
2e733ec7 393 int item = idx;
040b9528 394 for ( int i = 0; i < idx; i++ )
702f5349 395 {
040b9528 396 if ( GetColumn(i).IsHidden() )
2e733ec7 397 item--; // one less column the native control knows about
040b9528
VZ
398 }
399
2e733ec7
VZ
400 wxASSERT_MSG( item >= 0 && item <= GetShownColumnsCount(), "logic error" );
401
402 return item;
040b9528
VZ
403}
404
405int wxHeaderCtrl::MSWFromNativeIdx(int item)
406{
407 wxASSERT_MSG( item >= 0 && item < GetShownColumnsCount(),
408 "column index out of range" );
409
410 // reverse the above function
2e733ec7
VZ
411
412 unsigned idx = item;
413 for ( unsigned n = 0; n < m_numColumns; n++ )
040b9528 414 {
2e733ec7
VZ
415 if ( n > idx )
416 break;
417
418 if ( GetColumn(n).IsHidden() )
419 idx++;
040b9528
VZ
420 }
421
2e733ec7
VZ
422 wxASSERT_MSG( MSWToNativeIdx(idx) == item, "logic error" );
423
424 return idx;
040b9528
VZ
425}
426
2e733ec7 427int wxHeaderCtrl::MSWToNativeOrder(int pos)
040b9528 428{
2e733ec7 429 wxASSERT_MSG( pos >= 0 && static_cast<unsigned>(pos) < m_numColumns,
040b9528
VZ
430 "column position out of range" );
431
2e733ec7
VZ
432 int order = pos;
433 for ( int n = 0; n < pos; n++ )
040b9528 434 {
2e733ec7
VZ
435 if ( GetColumn(m_colIndices[n]).IsHidden() )
436 order--;
702f5349
VZ
437 }
438
2e733ec7
VZ
439 wxASSERT_MSG( order >= 0 && order <= GetShownColumnsCount(), "logic error" );
440
702f5349
VZ
441 return order;
442}
443
2e733ec7
VZ
444int wxHeaderCtrl::MSWFromNativeOrder(int order)
445{
446 wxASSERT_MSG( order >= 0 && order < GetShownColumnsCount(),
447 "native column position out of range" );
448
449 unsigned pos = order;
450 for ( unsigned n = 0; n < m_numColumns; n++ )
451 {
452 if ( n > pos )
453 break;
454
455 if ( GetColumn(m_colIndices[n]).IsHidden() )
456 pos++;
457 }
458
459 wxASSERT_MSG( MSWToNativeOrder(pos) == order, "logic error" );
460
461 return pos;
462}
463
fa3d4aaf
VZ
464// ----------------------------------------------------------------------------
465// wxHeaderCtrl events
466// ----------------------------------------------------------------------------
467
aef252d9 468wxEventType wxHeaderCtrl::GetClickEventType(bool dblclk, int button)
fa3d4aaf
VZ
469{
470 wxEventType evtType;
471 switch ( button )
472 {
473 case 0:
474 evtType = dblclk ? wxEVT_COMMAND_HEADER_DCLICK
475 : wxEVT_COMMAND_HEADER_CLICK;
476 break;
477
478 case 1:
479 evtType = dblclk ? wxEVT_COMMAND_HEADER_RIGHT_DCLICK
480 : wxEVT_COMMAND_HEADER_RIGHT_CLICK;
481 break;
482
483 case 2:
484 evtType = dblclk ? wxEVT_COMMAND_HEADER_MIDDLE_DCLICK
485 : wxEVT_COMMAND_HEADER_MIDDLE_CLICK;
486 break;
487
488 default:
489 wxFAIL_MSG( wxS("unexpected event type") );
aef252d9 490 evtType = wxEVT_NULL;
fa3d4aaf
VZ
491 }
492
aef252d9 493 return evtType;
fa3d4aaf
VZ
494}
495
496bool wxHeaderCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
497{
498 NMHEADER * const nmhdr = (NMHEADER *)lParam;
499
aef252d9 500 wxEventType evtType = wxEVT_NULL;
aef252d9 501 int width = 0;
702f5349 502 int order = -1;
702f5349 503 bool veto = false;
0c9c5b43 504 const UINT code = nmhdr->hdr.code;
040b9528
VZ
505
506 // we don't have the index for all events, e.g. not for NM_RELEASEDCAPTURE
507 // so only access for header control events (and yes, the direction of
508 // comparisons with FIRST/LAST is correct even if it seems inverted)
509 int idx = code <= HDN_FIRST && code > HDN_LAST ? nmhdr->iItem : -1;
510 if ( idx != -1 )
511 {
512 // we also get bogus HDN_BEGINDRAG with -1 index so don't call
513 // MSWFromNativeIdx() unconditionally for nmhdr->iItem
514 idx = MSWFromNativeIdx(idx);
515 }
516
0c9c5b43 517 switch ( code )
fa3d4aaf 518 {
aef252d9
VZ
519 // click events
520 // ------------
521
fa3d4aaf
VZ
522 case HDN_ITEMCLICK:
523 case HDN_ITEMDBLCLICK:
aef252d9 524 evtType = GetClickEventType(code == HDN_ITEMDBLCLICK, nmhdr->iButton);
fa3d4aaf
VZ
525 break;
526
527 // although we should get the notifications about the right clicks
528 // via HDN_ITEM[DBL]CLICK too according to MSDN this simply doesn't
529 // happen in practice on any Windows system up to 2003
530 case NM_RCLICK:
531 case NM_RDBLCLK:
532 {
533 POINT pt;
aef252d9
VZ
534 idx = wxMSWGetColumnClicked(&nmhdr->hdr, &pt);
535 if ( idx != wxNOT_FOUND )
040b9528
VZ
536 {
537 idx = MSWFromNativeIdx(idx);
36e5a9a7
VZ
538
539 // due to a bug in mingw32 headers NM_RDBLCLK is signed
540 // there so we need a cast to avoid warnings about signed/
541 // unsigned comparison
542 evtType = GetClickEventType(
543 code == static_cast<UINT>(NM_RDBLCLK), 1);
040b9528 544 }
fa3d4aaf
VZ
545 //else: ignore clicks outside any column
546 }
547 break;
3bfaa5a7
VZ
548
549 case HDN_DIVIDERDBLCLICK:
aef252d9
VZ
550 evtType = wxEVT_COMMAND_HEADER_SEPARATOR_DCLICK;
551 break;
552
553
554 // column resizing events
555 // ----------------------
556
557 // see comments in wxListCtrl::MSWOnNotify() for why we catch both
558 // ASCII and Unicode versions of this message
559 case HDN_BEGINTRACKA:
560 case HDN_BEGINTRACKW:
0b2e1483
VZ
561 // non-resizeable columns can't be resized no matter what, don't
562 // even generate any events for them
563 if ( !GetColumn(idx).IsResizeable() )
564 {
702f5349
VZ
565 veto = true;
566 break;
0b2e1483
VZ
567 }
568
396825dc 569 evtType = wxEVT_COMMAND_HEADER_BEGIN_RESIZE;
aef252d9
VZ
570 // fall through
571
aef252d9
VZ
572 case HDN_ENDTRACKA:
573 case HDN_ENDTRACKW:
a45caa71
VZ
574 width = nmhdr->pitem->cxy;
575
aef252d9 576 if ( evtType == wxEVT_NULL )
a45caa71 577 {
396825dc 578 evtType = wxEVT_COMMAND_HEADER_END_RESIZE;
aef252d9 579
a45caa71
VZ
580 // don't generate events with invalid width
581 const int minWidth = GetColumn(idx).GetMinWidth();
582 if ( width < minWidth )
583 width = minWidth;
584 }
585 break;
586
587 case HDN_ITEMCHANGING:
588 if ( nmhdr->pitem && (nmhdr->pitem->mask & HDI_WIDTH) )
589 {
590 // prevent the column from being shrunk beneath its min width
93e4e62b
VZ
591 width = nmhdr->pitem->cxy;
592 if ( width < GetColumn(idx).GetMinWidth() )
593 {
594 // don't generate any events and prevent the change from
595 // happening
702f5349 596 veto = true;
93e4e62b
VZ
597 }
598 else // width is acceptable
599 {
600 // generate the resizing event from here as we don't seem
601 // to be getting HDN_TRACK events at all, at least with
602 // comctl32.dll v6
603 evtType = wxEVT_COMMAND_HEADER_RESIZING;
604 }
702f5349
VZ
605 }
606 break;
607
608
609 // column reordering events
610 // ------------------------
611
612 case HDN_BEGINDRAG:
613 // Windows sometimes sends us events with invalid column indices
040b9528 614 if ( nmhdr->iItem == -1 )
702f5349 615 break;
a45caa71 616
702f5349
VZ
617 // column must have the appropriate flag to be draggable
618 if ( !GetColumn(idx).IsReorderable() )
619 {
620 veto = true;
621 break;
a45caa71 622 }
702f5349
VZ
623
624 evtType = wxEVT_COMMAND_HEADER_BEGIN_REORDER;
625 break;
626
627 case HDN_ENDDRAG:
702f5349
VZ
628 wxASSERT_MSG( nmhdr->pitem->mask & HDI_ORDER, "should have order" );
629 order = nmhdr->pitem->iOrder;
040b9528
VZ
630
631 // we also get messages with invalid order when column reordering
632 // is cancelled (e.g. by pressing Esc)
633 if ( order == -1 )
634 break;
635
636 order = MSWFromNativeOrder(order);
637
638 evtType = wxEVT_COMMAND_HEADER_END_REORDER;
a45caa71
VZ
639 break;
640
641 case NM_RELEASEDCAPTURE:
565804f2 642 evtType = wxEVT_COMMAND_HEADER_DRAGGING_CANCELLED;
3bfaa5a7 643 break;
fa3d4aaf
VZ
644 }
645
aef252d9
VZ
646
647 // do generate the corresponding wx event
648 if ( evtType != wxEVT_NULL )
649 {
650 wxHeaderCtrlEvent event(evtType, GetId());
651 event.SetEventObject(this);
652 event.SetColumn(idx);
653 event.SetWidth(width);
702f5349
VZ
654 if ( order != -1 )
655 event.SetNewOrder(order);
aef252d9
VZ
656
657 if ( GetEventHandler()->ProcessEvent(event) )
658 {
702f5349 659 if ( event.IsAllowed() )
040b9528 660 return true; // skip default message handling below
aef252d9 661
702f5349
VZ
662 // we need to veto the default handling of this message, don't
663 // return to execute the code in the "if veto" branch below
664 veto = true;
aef252d9 665 }
040b9528
VZ
666 else // not processed
667 {
668 // special post-processing for HDN_ENDDRAG: we need to update the
669 // internal column indices array if this is allowed to go ahead as
670 // the native control is going to reorder its columns now
671 if ( evtType == wxEVT_COMMAND_HEADER_END_REORDER )
672 MoveColumnInOrderArray(m_colIndices, idx, order);
673 }
aef252d9
VZ
674 }
675
702f5349
VZ
676 if ( veto )
677 {
678 // all of HDN_BEGIN{DRAG,TRACK}, HDN_TRACK and HDN_ITEMCHANGING
679 // interpret TRUE return value as meaning to stop the control
680 // default handling of the message
681 *result = TRUE;
682
683 return true;
684 }
685
fa3d4aaf
VZ
686 return wxHeaderCtrlBase::MSWOnNotify(idCtrl, lParam, result);
687}
3bfaa5a7
VZ
688
689#endif // wxHAS_GENERIC_HEADERCTRL
e721a2a2
VZ
690
691#endif // wxUSE_HEADERCTRL