⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 headercontrol.cs

📁 Linux 恢复盘制作工具 process调用busybox dd实现写*.img镜像
💻 CS
字号:
/*
 * HeaderControl - A limited implementation of HeaderControl
 *
 * Author: Phillip Piper
 * Date: 25/11/2008 17:15 
 *
 * Change log:
 * 2008-11-25  JPP  Initial version
 *
 * TO DO:
 *
 * Copyright (C) 2006-2008 Phillip Piper
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * If you wish to use this code in a closed source application, please contact phillip_piper@bigfoot.com.
 */

using System;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace BrightIdeasSoftware
{
    /// <summary>
    /// Class used to capture window messages for the header of the list view
    /// control.
    /// </summary>
    public class HeaderControl : NativeWindow
    {
        private ObjectListView parentListView;
        private MyToolTip tooltip;

        public HeaderControl(ObjectListView olv)
        {
            this.parentListView = olv;
            this.AssignHandle(NativeMethods.GetHeaderControl(olv));
            this.tooltip = new MyToolTip();
            this.tooltip.AddTool(this);
        }

        /// <summary>
        /// Return the Windows handle behind this control
        /// </summary>
        /// <remarks>
        /// When an ObjectListView is initialized as part of a UserControl, the
        /// GetHeaderControl() method returns 0 until the UserControl is
        /// completely initialized. So the AssignHandle() call in the constructor
        /// doesn't work. So we override the Handle property so value is always
        /// current.
        /// </remarks>
        public new IntPtr Handle
        {
            get { return NativeMethods.GetHeaderControl(this.parentListView); }
        }
        //TODO: The Handle property may no longer be necessary. CHECK! 2008/11/28

        protected override void WndProc(ref Message m)
        {
            const int WM_SETCURSOR = 0x20;
            const int WM_NOTIFY = 0x4E;
            const int WM_MOUSEMOVE = 0x200;

            switch (m.Msg) {
                case WM_SETCURSOR:
                    if (this.IsCursorOverLockedDivider) {
                        m.Result = (IntPtr)1;	// Don't change the cursor
                        return;
                    }
                    break;

                case WM_NOTIFY:
                    if (!this.HandleNotify(ref m))
                        return;
                    break;

                case WM_MOUSEMOVE:
                    this.HandleMouseMove(ref m);
                    break;
            }

            base.WndProc(ref m);
        }

        protected void HandleMouseMove(ref Message m)
        {
            int columnIndex = this.ColumnIndexUnderCursor;

            // If the mouse has moved to a different header, pop the current tip (if any)
            if (columnIndex != this.columnShowingTip) {
                this.tooltip.PopToolTip(this);
                this.columnShowingTip = columnIndex;
            }
        }
        private int columnShowingTip = -1;

        unsafe protected bool HandleNotify(ref Message m)
        {
            //const int TTN_SHOW = -521;
            //const int TTN_POP = -522;
            const int TTN_GETDISPINFO = -530;

            if (m.LParam == IntPtr.Zero)
                return false;

            NativeMethods.NMHDR* lParam = (NativeMethods.NMHDR*)m.LParam;
            switch (lParam->code) {
                case TTN_GETDISPINFO:
                    return HandleGetDispInfo(ref m);
            }

            return false;
        }

        protected bool HandleGetDispInfo(ref Message m)
        {
            int columnIndex = this.ColumnIndexUnderCursor;
            if (columnIndex < 0)
                return false;

            string text = this.parentListView.GetHeaderToolTip(columnIndex);
            if (String.IsNullOrEmpty(text))
                return false;

            NativeMethods.TOOLTIPTEXT tooltipText = (NativeMethods.TOOLTIPTEXT)m.GetLParam(typeof(NativeMethods.TOOLTIPTEXT));
            tooltipText.lpszText = text;
            if (this.parentListView.RightToLeft == RightToLeft.Yes)
                tooltipText.uFlags |= 4;

            Marshal.StructureToPtr(tooltipText, m.LParam, false);
            return true;
        }

        protected bool IsCursorOverLockedDivider
        {
            get {
                Point pt = this.parentListView.PointToClient(Cursor.Position);
                pt.X += NativeMethods.GetScrollPosition(this.parentListView.Handle, true);
                int dividerIndex = NativeMethods.GetDividerUnderPoint(this.Handle, pt);
                if (dividerIndex >= 0 && dividerIndex < this.parentListView.Columns.Count) {
                    OLVColumn column = this.parentListView.GetColumn(dividerIndex);
                    return column.IsFixedWidth || column.FillsFreeSpace;
                } else
                    return false;
            }
        }

        /// <summary>
        /// Return the index of the column under the current cursor position,
        /// or -1 if the cursor is not over a column
        /// </summary>
        /// <returns>Index of the column under the cursor, or -1</returns>
        public int ColumnIndexUnderCursor
        {
            get {
                Point pt = this.parentListView.PointToClient(Cursor.Position);
                pt.X += NativeMethods.GetScrollPosition(this.parentListView.Handle, true);
                return NativeMethods.GetColumnUnderPoint(this.Handle, pt);
            }
        }
    }

    /// <summary>
    /// A limited wrapper around a Windows tooltip window.
    /// </summary>
    public class MyToolTip
    {
        public MyToolTip()
        {
            this.window = new MyToolTipNativeWindow(this);
        }
        private MyToolTipNativeWindow window;

        public IntPtr Handle
        {
            get {
                if (!this.IsHandleCreated) {
                    this.CreateHandle();
                }
                return this.window.Handle;
            }
        }

        public void AddTool(IWin32Window window)
        {
            const int TTM_ADDTOOL = 0x432;

            NativeMethods.SendMessage(this.Handle, 0x418, 0, SystemInformation.MaxWindowTrackSize.Width);

            NativeMethods.TOOLINFO lParam = this.GetTOOLINFO(window);
            IntPtr result = NativeMethods.SendMessageTOOLINFO(this.Handle, TTM_ADDTOOL, 0, lParam);
        }

        public void PopToolTip(IWin32Window window)
        {
            const int TTM_POP = 0x41c;
            NativeMethods.SendMessage(this.Handle, TTM_POP, 0, 0);
        }

        public void RemoveToolTip(IWin32Window window)
        {
            const int TTM_DELTOOL = 0x433;
            NativeMethods.TOOLINFO lParam = this.GetTOOLINFO(window);
            NativeMethods.SendMessageTOOLINFO(this.Handle, TTM_DELTOOL, 0, lParam);
        }

        internal NativeMethods.TOOLINFO GetTOOLINFO(IWin32Window window)
        {
            const int TTF_IDISHWND = 1;
            //const int TTF_ABSOLUTE = 0x80;
            //const int TTF_CENTERTIP = 2;
            const int TTF_SUBCLASS = 0x10;
            //const int TTF_TRACK = 0x20;
            //const int TTF_TRANSPARENT = 0x100;

            NativeMethods.TOOLINFO toolinfo_tooltip = new NativeMethods.TOOLINFO();
            toolinfo_tooltip.hwnd = window.Handle;
            toolinfo_tooltip.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
            toolinfo_tooltip.uId = window.Handle;
            toolinfo_tooltip.lpszText = (IntPtr)(-1); // LPSTR_TEXTCALLBACK

            return toolinfo_tooltip;
        }

        protected void CreateHandle()
        {
            if (this.IsHandleCreated)
                return;

            const int TTS_BALLOON = 0x40;
            const int TTS_NOPREFIX = 2;

            CreateParams p = new CreateParams();
            p.ClassName = "tooltips_class32";
            p.Style = TTS_NOPREFIX;
            p.Style = TTS_NOPREFIX | TTS_BALLOON;
            this.window.CreateHandle(p);
        }

        protected bool IsHandleCreated
        {
            get {
                return (this.window != null && this.window.Handle != IntPtr.Zero);
            }
        }

        public void WndProc(ref Message msg)
        {
            //System.Diagnostics.Debug.WriteLine(String.Format("xx {0:x}", m.Msg));
            //switch (m.Msg) {
            //    case 0x4E: // WM_NOTIFY
            //        if (!this.HandleNotify(ref m))
            //            return;
            //        break;
            //    case 0x204E: // WM_REFLECT_NOTIFY
            //        if (!this.HandleNotify(ref m))
            //            return;
            //        break;
            //}
            this.window.DefWndProc(ref msg);
        }

        internal class MyToolTipNativeWindow : NativeWindow
        {
            public MyToolTipNativeWindow(MyToolTip control)
            {
                this.control = control;
            }

            protected override void WndProc(ref Message m)
            {
                if (this.control != null) {
                    this.control.WndProc(ref m);
                }
            }

            private MyToolTip control;
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -