private bool HandleLVCUSTOMDRAW(ref System.Windows.Forms.Message msg) {
            // TODO this needs to be cleaned
            if(QTUtility.CheckConfig(Settings.AlternateRowColors) && (GetCurrentViewMode() == FVM.DETAILS)) {
                NMLVCUSTOMDRAW structure = (NMLVCUSTOMDRAW)Marshal.PtrToStructure(msg.LParam, typeof(NMLVCUSTOMDRAW));
                int dwItemSpec = (int)structure.nmcd.dwItemSpec;
                switch(structure.nmcd.dwDrawStage) {
                    case CDDS.SUBITEM | CDDS.ITEMPREPAINT:
                        iListViewItemState = (int)PInvoke.SendMessage(
                                ListViewController.Handle, LVM.GETITEMSTATE, (IntPtr)dwItemSpec,
                                (IntPtr)(LVIS.FOCUSED | LVIS.SELECTED | LVIS.DROPHILITED));

                        if(QTUtility.IsVista) {
                            int num4 = lstColumnFMT[structure.iSubItem];
                            structure.clrTextBk = QTUtility.ShellViewRowCOLORREF_Background;
                            structure.clrText = QTUtility.ShellViewRowCOLORREF_Text;
                            Marshal.StructureToPtr(structure, msg.LParam, false);
                            bool drawingHotItem = (dwItemSpec == GetHotItem());
                            bool fullRowSel = !QTUtility.CheckConfig(Settings.NoFullRowSelect);

                            msg.Result = (IntPtr)(CDRF.NEWFONT);
                            if(structure.iSubItem == 0 && !drawingHotItem) {
                                if(iListViewItemState == 0 && (num4 & 0x600) != 0) {
                                    msg.Result = (IntPtr)(CDRF.NEWFONT | CDRF.NOTIFYPOSTPAINT);
                                }
                                else if(iListViewItemState == LVIS.FOCUSED && !fullRowSel) {
                                    msg.Result = (IntPtr)(CDRF.NEWFONT | CDRF.NOTIFYPOSTPAINT);
                                }
                            }

                            if(structure.iSubItem > 0 && (!fullRowSel || !drawingHotItem)) {
                                if(!fullRowSel || (iListViewItemState & (LVIS.SELECTED | LVIS.DROPHILITED)) == 0) {
                                    using(Graphics graphics = Graphics.FromHdc(structure.nmcd.hdc)) {
                                        if(QTUtility.sbAlternate == null) {
                                            QTUtility.sbAlternate = new SolidBrush(QTUtility2.MakeColor(QTUtility.ShellViewRowCOLORREF_Background));
                                        }
                                        graphics.FillRectangle(QTUtility.sbAlternate, structure.nmcd.rc.ToRectangle());
                                    }
                                }
                            }
                        }
                        else {
                            msg.Result = (IntPtr)(CDRF.NOTIFYPOSTPAINT);
                        }
                        return true;

                    case CDDS.SUBITEM | CDDS.ITEMPOSTPAINT: {
                            RECT rc = structure.nmcd.rc;
                            if(!QTUtility.IsVista) {
                                rc = PInvoke.ListView_GetItemRect(ListViewController.Handle, dwItemSpec, structure.iSubItem, 2);
                            }
                            else {
                                rc.left += 0x10;
                            }
                            bool flag3 = false;
                            bool flag4 = false;
                            bool flag5 = QTUtility.CheckConfig(Settings.DetailsGridLines);
                            bool flag6 = QTUtility.CheckConfig(Settings.NoFullRowSelect) ^ QTUtility.IsVista;
                            bool flag7 = false;
                            if(!QTUtility.IsVista && QTUtility.fSingleClick) {
                                flag7 = (dwItemSpec == GetHotItem());
                            }
                            LVITEM lvitem = new LVITEM();
                            lvitem.pszText = Marshal.AllocHGlobal(520);
                            lvitem.cchTextMax = 260;
                            lvitem.iSubItem = structure.iSubItem;
                            lvitem.iItem = dwItemSpec;
                            lvitem.mask = 1;
                            IntPtr ptr3 = Marshal.AllocHGlobal(Marshal.SizeOf(lvitem));
                            Marshal.StructureToPtr(lvitem, ptr3, false);
                            PInvoke.SendMessage(ListViewController.Handle, LVM.GETITEM, IntPtr.Zero, ptr3);
                            if(QTUtility.sbAlternate == null) {
                                QTUtility.sbAlternate = new SolidBrush(QTUtility2.MakeColor(QTUtility.ShellViewRowCOLORREF_Background));
                            }
                            using(Graphics graphics2 = Graphics.FromHdc(structure.nmcd.hdc)) {
                                Rectangle rect = rc.ToRectangle();
                                if(flag5) {
                                    rect = new Rectangle(rc.left + 1, rc.top, rc.Width - 1, rc.Height - 1);
                                }
                                graphics2.FillRectangle(QTUtility.sbAlternate, rect);
                                if(!QTUtility.IsVista && ((structure.iSubItem == 0) || flag6)) {
                                    flag4 = (iListViewItemState & 8) == 8;
                                    if((iListViewItemState != 0) && (((iListViewItemState == 1) && fListViewHasFocus) || (iListViewItemState != 1))) {
                                        int width = 0;
                                        if(flag6) {
                                            width = rc.Width;
                                        }
                                        else {
                                            width = 8 + ((int)PInvoke.SendMessage(ListViewController.Handle, LVM.GETSTRINGWIDTH, IntPtr.Zero, lvitem.pszText));
                                            if(width > rc.Width) {
                                                width = rc.Width;
                                            }
                                        }
                                        Rectangle rectangle2 = new Rectangle(rc.left, rc.top, width, flag5 ? (rc.Height - 1) : rc.Height);
                                        if(((iListViewItemState & 2) == 2) || flag4) {
                                            if(flag4) {
                                                graphics2.FillRectangle(SystemBrushes.Highlight, rectangle2);
                                            }
                                            else if(QTUtility.fSingleClick && flag7) {
                                                graphics2.FillRectangle(fListViewHasFocus ? SystemBrushes.HotTrack : SystemBrushes.Control, rectangle2);
                                            }
                                            else {
                                                graphics2.FillRectangle(fListViewHasFocus ? SystemBrushes.Highlight : SystemBrushes.Control, rectangle2);
                                            }
                                            flag3 = true;
                                        }
                                        if((fListViewHasFocus && ((iListViewItemState & 1) == 1)) && !flag6) {
                                            ControlPaint.DrawFocusRectangle(graphics2, rectangle2);
                                        }
                                    }
                                }
                                if(QTUtility.IsVista && ((iListViewItemState & 1) == 1)) {
                                    int num6 = rc.Width;
                                    if(!flag6) {
                                        num6 = 4 + ((int)PInvoke.SendMessage(ListViewController.Handle, LVM.GETSTRINGWIDTH, IntPtr.Zero, lvitem.pszText));
                                        if(num6 > rc.Width) {
                                            num6 = rc.Width;
                                        }
                                    }
                                    Rectangle rectangle = new Rectangle(rc.left + 1, rc.top + 1, num6, flag5 ? (rc.Height - 2) : (rc.Height - 1));
                                    ControlPaint.DrawFocusRectangle(graphics2, rectangle);
                                }
                            }
                            IntPtr zero = IntPtr.Zero;
                            IntPtr hgdiobj = IntPtr.Zero;
                            if(!QTUtility.IsVista && QTUtility.fSingleClick) {
                                LOGFONT logfont;
                                zero = PInvoke.GetCurrentObject(structure.nmcd.hdc, 6);
                                PInvoke.GetObject(zero, Marshal.SizeOf(typeof(LOGFONT)), out logfont);
                                if((structure.iSubItem == 0) || flag6) {
                                    logfont.lfUnderline = ((QTUtility.iIconUnderLineVal == 3) || flag7) ? ((byte)1) : ((byte)0);
                                }
                                else {
                                    logfont.lfUnderline = 0;
                                }
                                hgdiobj = PInvoke.CreateFontIndirect(ref logfont);
                                PInvoke.SelectObject(structure.nmcd.hdc, hgdiobj);
                            }
                            PInvoke.SetBkMode(structure.nmcd.hdc, 1);
                            int dwDTFormat = 0x8824;
                            if(QTUtility.IsRTL ? ((lstColumnFMT[structure.iSubItem] & 1) == 0) : ((lstColumnFMT[structure.iSubItem] & 1) == 1)) {
                                if(QTUtility.IsRTL) {
                                    dwDTFormat &= -3;
                                }
                                else {
                                    dwDTFormat |= 2;
                                }
                                rc.right -= 6;
                            }
                            else if(structure.iSubItem == 0) {
                                rc.left += 2;
                                rc.right -= 2;
                            }
                            else {
                                rc.left += 6;
                            }
                            if(flag3) {
                                PInvoke.SetTextColor(structure.nmcd.hdc, QTUtility2.MakeCOLORREF((fListViewHasFocus || flag4) ? SystemColors.HighlightText : SystemColors.WindowText));
                            }
                            else {
                                PInvoke.SetTextColor(structure.nmcd.hdc, QTUtility.ShellViewRowCOLORREF_Text);
                            }
                            PInvoke.DrawTextExW(structure.nmcd.hdc, lvitem.pszText, -1, ref rc, dwDTFormat, IntPtr.Zero);
                            Marshal.FreeHGlobal(lvitem.pszText);
                            Marshal.FreeHGlobal(ptr3);
                            msg.Result = IntPtr.Zero;
                            if(zero != IntPtr.Zero) {
                                PInvoke.SelectObject(structure.nmcd.hdc, zero);
                            }
                            if(hgdiobj != IntPtr.Zero) {
                                PInvoke.DeleteObject(hgdiobj);
                            }
                            return true;
                        }
                    case CDDS.ITEMPREPAINT:
                        if((dwItemSpec % 2) == 0) {
                            msg.Result = (IntPtr)0x20;
                            return true;
                        }
                        msg.Result = IntPtr.Zero;
                        return false;

                    case CDDS.PREPAINT: {
                            HDITEM hditem = new HDITEM();
                            hditem.mask = 4;
                            IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(hditem));
                            Marshal.StructureToPtr(hditem, ptr, false);
                            IntPtr hWnd = PInvoke.SendMessage(ListViewController.Handle, LVM.GETHEADER, IntPtr.Zero, IntPtr.Zero);
                            int num2 = (int)PInvoke.SendMessage(hWnd, 0x1200, IntPtr.Zero, IntPtr.Zero);
                            if(lstColumnFMT == null) {
                                lstColumnFMT = new List<int>();
                            }
                            else {
                                lstColumnFMT.Clear();
                            }
                            for(int i = 0; i < num2; i++) {
                                PInvoke.SendMessage(hWnd, 0x120b, (IntPtr)i, ptr);
                                hditem = (HDITEM)Marshal.PtrToStructure(ptr, typeof(HDITEM));
                                lstColumnFMT.Add(hditem.fmt);
                            }
                            Marshal.FreeHGlobal(ptr);
                            fListViewHasFocus = ListViewController.Handle == PInvoke.GetFocus();
                            msg.Result = (IntPtr)0x20;
                            return true;
                        }
                }
            }
            return false;
        }
        protected override Point GetSubDirTipPoint(bool fByKey) {
            int iItem = fByKey ? ShellBrowser.GetFocusedIndex() : GetHotItem();
            int x, y;
            Point ret;
            RECT rect;
            switch(ShellBrowser.ViewMode) {
                case FVM.DETAILS:
                    rect = GetItemRect(iItem, LVIR.LABEL);
                    x = rect.right;
                    y = rect.top;
                    y += (rect.bottom - y)/2;
                    ret = new Point(x - 19, y - 7);
                    break;

                case FVM.SMALLICON:
                    rect = GetItemRect(iItem);
                    x = rect.right;
                    y = rect.top;
                    x -= (rect.bottom - y) / 2;
                    y += (rect.bottom - y) / 2;
                    ret = new Point(x - 9, y - 7);
                    break;

                case FVM.CONTENT:
                case FVM.TILE:
                    rect = GetItemRect(iItem, LVIR.ICON);
                    y = rect.bottom;
                    x = rect.right;
                    ret = new Point(x - 16, y - 16);
                    break;

                case FVM.THUMBSTRIP:
                case FVM.THUMBNAIL:
                    rect = GetItemRect(iItem, LVIR.ICON);
                    if(QTUtility.IsXP) rect.right -= 13;
                    y = rect.bottom;
                    x = rect.right;
                    ret = new Point(x - 16, y - 16);
                    break;

                case FVM.ICON:
                    rect = GetItemRect(iItem, LVIR.ICON);
                    if(QTUtility.IsXP) {
                        int num3 = (int)PInvoke.SendMessage(Handle, LVM.GETITEMSPACING, IntPtr.Zero, IntPtr.Zero);
                        Size iconSize = SystemInformation.IconSize;
                        rect.right = ((rect.left + (((num3 & 0xffff) - iconSize.Width) / 2)) + iconSize.Width) + 8;
                        rect.bottom = (rect.top + iconSize.Height) + 6;
                    }
                    y = rect.bottom;
                    x = rect.right;
                    ret = new Point(x - 16, y - 16);
                    break;

                case FVM.LIST:
                    if(QTUtility.IsXP) {
                        rect = GetItemRect(iItem, LVIR.ICON);
                        using(SafePtr pszText = new SafePtr(520)) {
                            LVITEM structure = new LVITEM {
                                pszText = pszText,
                                cchTextMax = 260,
                                iItem = iItem,
                                mask = 1
                            };
                            PInvoke.SendMessage(Handle, LVM.GETITEM, IntPtr.Zero, ref structure);
                            int num4 = (int)PInvoke.SendMessage(Handle, LVM.GETSTRINGWIDTH, IntPtr.Zero, pszText);
                            num4 += 20;
                            rect.right += num4;
                            rect.top += 2;
                            rect.bottom += 2;                            
                        }
                    }
                    else {
                        rect = GetItemRect(iItem, LVIR.LABEL);
                    }                    
                    y = rect.bottom;
                    x = rect.right;
                    ret = new Point(x - 16, y - 16);
                    break;

                default:
                    rect = GetItemRect(iItem);
                    y = rect.bottom;
                    x = rect.right;
                    ret = new Point(x - 16, y - 16);
                    break;

            }
            PInvoke.ClientToScreen(Handle, ref ret);
            return ret;
        }
        private RECT GetLVITEMRECT(IntPtr hwnd, int iItem, bool fSubDirTip, int fvm) {
            RECT rect;
            int code;
            bool flag = false;
            bool flag2 = false;
            if(fSubDirTip) {
                switch(fvm) {
                    case FVM.ICON:
                        flag = !QTUtility.IsVista;
                        code = LVIR.ICON;
                        break;

                    case FVM.DETAILS:
                        code = LVIR.LABEL;
                        break;

                    case FVM.LIST:
                        if(QTUtility.IsVista) {
                            code = LVIR.LABEL;
                        }
                        else {
                            flag2 = true;
                            code = LVIR.ICON;
                        }
                        break;

                    case FVM.TILE:
                        code = LVIR.ICON;
                        break;

                    default:
                        code = LVIR.BOUNDS;
                        break;
                }
            }
            else {
                code = (fvm == FVM.DETAILS) ? LVIR.LABEL : LVIR.BOUNDS;
            }

            rect = new RECT();
            rect.left = code;
            IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(rect));
            Marshal.StructureToPtr(rect, ptr, false);
            PInvoke.SendMessage(ListViewController.Handle, LVM.GETITEMRECT, (IntPtr)iItem, ptr);
            rect = (RECT)Marshal.PtrToStructure(ptr, typeof(RECT));
            Marshal.FreeHGlobal(ptr);
            PInvoke.MapWindowPoints(ListViewController.Handle, IntPtr.Zero, ref rect, 2);

            if(flag) {
                if((fvm == FVM.THUMBNAIL) || (fvm == FVM.THUMBSTRIP)) {
                    rect.right -= 13;
                    return rect;
                }
                int num3 = (int)PInvoke.SendMessage(hwnd, LVM.GETITEMSPACING, IntPtr.Zero, IntPtr.Zero);
                Size iconSize = SystemInformation.IconSize;
                rect.right = ((rect.left + (((num3 & 0xffff) - iconSize.Width) / 2)) + iconSize.Width) + 8;
                rect.bottom = (rect.top + iconSize.Height) + 6;
                return rect;
            }
            if(flag2) {
                LVITEM structure = new LVITEM();
                IntPtr zero = IntPtr.Zero;
                structure.pszText = Marshal.AllocHGlobal(520);
                structure.cchTextMax = 260;
                structure.iItem = iItem;
                structure.mask = 1;
                zero = Marshal.AllocHGlobal(Marshal.SizeOf(structure));
                Marshal.StructureToPtr(structure, zero, false);
                PInvoke.SendMessage(hwnd, LVM.GETITEM, IntPtr.Zero, zero);
                int num4 = (int)PInvoke.SendMessage(hwnd, LVM.GETSTRINGWIDTH, IntPtr.Zero, structure.pszText);
                num4 += 20;
                Marshal.FreeHGlobal(structure.pszText);
                Marshal.FreeHGlobal(zero);
                rect.right += num4;
                rect.top += 2;
                rect.bottom += 2;
            }
            return rect;
        }
 protected void OnEndLabelEdit(LVITEM item) {
     if(EndLabelEdit != null) {
         EndLabelEdit(item);
     }
 }