protected bool HandleNotify(ref Message m)
{
bool isMsgHandled = false;
const int NM_CUSTOMDRAW = -12;
const int HDN_FIRST = (0 - 300);
const int HDN_ITEMCHANGINGA = (HDN_FIRST - 0);
const int HDN_ITEMCHANGINGW = (HDN_FIRST - 20);
const int HDN_ITEMCLICKA = (HDN_FIRST - 2);
const int HDN_ITEMCLICKW = (HDN_FIRST - 22);
const int HDN_DIVIDERDBLCLICKA = (HDN_FIRST - 5);
const int HDN_DIVIDERDBLCLICKW = (HDN_FIRST - 25);
const int HDN_BEGINTRACKA = (HDN_FIRST - 6);
const int HDN_BEGINTRACKW = (HDN_FIRST - 26);
const int HDN_ENDTRACKA = (HDN_FIRST - 7);
const int HDN_ENDTRACKW = (HDN_FIRST - 27);
const int HDN_TRACKA = (HDN_FIRST - 8);
const int HDN_TRACKW = (HDN_FIRST - 28);
// Handle the notification, remembering to handle both ANSI and Unicode versions
NativeMethods.NMHEADER nmheader = (NativeMethods.NMHEADER)m.GetLParam(typeof(NativeMethods.NMHEADER));
//System.Diagnostics.Debug.WriteLine(String.Format("not: {0}", nmhdr->code));
//if (nmhdr.code < HDN_FIRST)
// System.Diagnostics.Debug.WriteLine(nmhdr.code);
// In KB Article #183258, MS states that when a header control has the HDS_FULLDRAG style, it will receive
// ITEMCHANGING events rather than TRACK events. Under XP SP2 (at least) this is not always true, which may be
// why MS has withdrawn that particular KB article. It is true that the header is always given the HDS_FULLDRAG
// style. But even while window style set, the control doesn't always received ITEMCHANGING events.
// The controlling setting seems to be the Explorer option "Show Window Contents While Dragging"!
// In the category of "truly bizarre side effects", if the this option is turned on, we will receive
// ITEMCHANGING events instead of TRACK events. But if it is turned off, we receive lots of TRACK events and
// only one ITEMCHANGING event at the very end of the process.
// If we receive HDN_TRACK messages, it's harder to control the resizing process. If we return a result of 1, we
// cancel the whole drag operation, not just that particular track event, which is clearly not what we want.
// If we are willing to compile with unsafe code enabled, we can modify the size of the column in place, using the
// commented out code below. But without unsafe code, the best we can do is allow the user to drag the column to
// any width, and then spring it back to within bounds once they release the mouse button. UI-wise it's very ugly.
switch (nmheader.nhdr.code) {
case NM_CUSTOMDRAW:
if (!this.OwnerDrawnHeader)
isMsgHandled = this.HeaderControl.HandleHeaderCustomDraw(ref m);
break;
case HDN_ITEMCLICKA:
case HDN_ITEMCLICKW:
if (!this.PossibleFinishCellEditing()) {
m.Result = (IntPtr)1; // prevent the change from happening
isMsgHandled = true;
}
break;
case HDN_DIVIDERDBLCLICKA:
case HDN_DIVIDERDBLCLICKW:
case HDN_BEGINTRACKA:
case HDN_BEGINTRACKW:
if (!this.PossibleFinishCellEditing()) {
m.Result = (IntPtr)1; // prevent the change from happening
isMsgHandled = true;
break;
}
if (nmheader.iItem >= 0 && nmheader.iItem < this.Columns.Count) {
OLVColumn column = this.GetColumn(nmheader.iItem);
// Space filling columns can't be dragged or double-click resized
if (column.FillsFreeSpace) {
m.Result = (IntPtr)1; // prevent the change from happening
isMsgHandled = true;
}
}
break;
case HDN_ENDTRACKA:
case HDN_ENDTRACKW:
//if (this.ShowGroups)
// this.ResizeLastGroup();
break;
case HDN_TRACKA:
case HDN_TRACKW:
if (nmheader.iItem >= 0 && nmheader.iItem < this.Columns.Count) {
NativeMethods.HDITEM hditem = (NativeMethods.HDITEM)Marshal.PtrToStructure(nmheader.pHDITEM, typeof(NativeMethods.HDITEM));
OLVColumn column = this.GetColumn(nmheader.iItem);
if (hditem.cxy < column.MinimumWidth)
hditem.cxy = column.MinimumWidth;
else if (column.MaximumWidth != -1 && hditem.cxy > column.MaximumWidth)
hditem.cxy = column.MaximumWidth;
Marshal.StructureToPtr(hditem, nmheader.pHDITEM, false);
}
break;
case HDN_ITEMCHANGINGA:
case HDN_ITEMCHANGINGW:
nmheader = (NativeMethods.NMHEADER)m.GetLParam(typeof(NativeMethods.NMHEADER));
if (nmheader.iItem >= 0 && nmheader.iItem < this.Columns.Count) {
NativeMethods.HDITEM hditem = (NativeMethods.HDITEM)Marshal.PtrToStructure(nmheader.pHDITEM, typeof(NativeMethods.HDITEM));
OLVColumn column = this.GetColumn(nmheader.iItem);
// Check the mask to see if the width field is valid, and if it is, make sure it's within range
if ((hditem.mask & 1) == 1) {
if (hditem.cxy < column.MinimumWidth ||
(column.MaximumWidth != -1 && hditem.cxy > column.MaximumWidth)) {
m.Result = (IntPtr)1; // prevent the change from happening
isMsgHandled = true;
}
}
}
break;
case ToolTipControl.TTN_SHOW:
//System.Diagnostics.Debug.WriteLine("olv TTN_SHOW");
if (this.CellToolTip.Handle == nmheader.nhdr.hwndFrom)
isMsgHandled = this.CellToolTip.HandleShow(ref m);
break;
case ToolTipControl.TTN_POP:
//System.Diagnostics.Debug.WriteLine("olv TTN_POP");
if (this.CellToolTip.Handle == nmheader.nhdr.hwndFrom)
isMsgHandled = this.CellToolTip.HandlePop(ref m);
break;
case ToolTipControl.TTN_GETDISPINFO:
//System.Diagnostics.Debug.WriteLine("olv TTN_GETDISPINFO");
if (this.CellToolTip.Handle == nmheader.nhdr.hwndFrom)
isMsgHandled = this.CellToolTip.HandleGetDispInfo(ref m);
break;
default:
//System.Diagnostics.Debug.WriteLine(String.Format("notify: {0}", nmheader.nhdr.code));
break;
}
return isMsgHandled;
}