none
Наклон колесика мыши для горизонтальной прокрутки RRS feed

  • Вопрос

  • Всем доброго время суток столкнулся с такой проблемой. Нужно создать программу которая позволяет горизонтальную прокрутку объекта колесиком мыши. используется проект WindowsForms. на форму добавляются элеметы panel, pictureBox, label. Свойства формы (Text: Horiz Tilt Wheel Demo; AutoScroll: True).  Свойства panel(AutoScroll: True; Dock:Top; TabIndex:2).    Свойства pictureBox(SizeMode:AutoSize). Свойства label (Text:H delta: 0; AutoSize:True).

    Добавляются 2 класса:

    Класс Win32Messages:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace HorizTiltWheelDemo
    {
      abstract class Win32Messages
      {
        //Константа из winuser.h
        public const int WM_MOUSEWHEEL = 0x020a;
    
        //Константы из winuser.h <pre lang="x-c#">using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace HorizTiltWheelDemo
    {
      class Win32Constants
      {
        //Константы из winuser.h (Platform SDK)
        public const int MK_LBUTTON = 0x0001;
        public const int MK_RBUTTON = 0x0002;
        public const int MK_SHIFT = 0x0004;
        public const int MK_CONTROL = 0x0008;
        public const int MK_MBUTTON = 0x0010;
        public const int MK_XBUTTON1 = 0x0020;
        public const int MK_XBUTTON2 = 0x0040;
    
        public const int WHEEL_DELTA = 120;
    
        //(требуется ОС Vista или Server 2008 и выше!)
    
        public const int SPI_GETWHEELSCROLLCHARS = 0x006C;
      }
    }
    

    Класс Win32Contacts:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace HorizTiltWheelDemo
    {
      class Win32Constants
      {
        //Константы из winuser.h (Platform SDK)
    
        public const int MK_LBUTTON = 0x0001;
        public const int MK_RBUTTON = 0x0002;
        public const int MK_SHIFT = 0x0004;
        public const int MK_CONTROL = 0x0008;
        public const int MK_MBUTTON = 0x0010;
        public const int MK_XBUTTON1 = 0x0020;
        public const int MK_XBUTTON2 = 0x0040;
    
        public const int WHEEL_DELTA = 120;
    
        //(требуется ОС Vista или Server 2008 и выше!)
       public const int SPI_GETWHEELSCROLLCHARS = 0x006C;
      }
    }
    

    Главная форма, включающая в себя панель, определенную выше:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    
    
    namespace HorizTiltWheelDemo
    {
      public partial class Form1 : Form
      {
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
    
        public Form1()
        {
          InitializeComponent();
    
          panel1.MouseHWheel += new EventHandler<MouseEventArgs>(panel1_MouseHWheel);
        }
    
        void panel1_MouseHWheel(object sender, MouseEventArgs e)
        {
          label1.Text = string.Format("H Delta: {0}", e.Delta);
        }
    
        protected override void WndProc(ref Message m)
        {
        //Все сообщения от колесика мыши отправляются панели
          switch (m.Msg)
          {
            case Win32Messages.WM_MOUSEWHEEL:
            case Win32Messages.WM_MOUSEHWHEEL:
              SendMessage(panel1.Handle, m.Msg, m.WParam, m.LParam);
              m.Result = IntPtr.Zero;
              break;
          }
          base.WndProc(ref m);
        }
      }
    }
    
    
    И вот собственно вопрос к какому элементу отнести TiltAwarePanel: Class, ComponentClass, InstallerClass, Windows Service?

    TiltAwarePanel:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    using System.Drawing;
    
    namespace HorizTiltWheelDemo
    {
      class TiltAwarePanel : Panel
      {
        
        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool SystemParametersInfo(uint uiAction, uint uiParam, ref uint pvParam, uint fWinIni);
    
        private int _wheelHPos = 0;
        private readonly uint HScrollChars = 1;
       
        private const int CharacterWidth = 8;
    
        public event EventHandler<MouseEventArgs> MouseHWheel;
    
        public TiltAwarePanel()
        {
          (!SystemParametersInfo(Win32Constants.SPI_GETWHEELSCROLLCHARS, 0, ref HScrollChars, 0))
          {
            throw new InvalidOperationException("Unsupported on this platform");
          }
    
        }
    
        protected void OnMouseHWheel(MouseEventArgs e)
        {
          //we have to accumulate the value
          _wheelHPos += e.Delta;
          //this method
          while (_wheelHPos >= Win32Constants.WHEEL_DELTA)
          {
            ScrollHorizontal((int)HScrollChars * CharacterWidth);
            _wheelHPos -= Win32Constants.WHEEL_DELTA;
          }
    
          while (_wheelHPos <= -Win32Constants.WHEEL_DELTA)
          {
            ScrollHorizontal(-(int)HScrollChars * CharacterWidth);
            _wheelHPos += Win32Constants.WHEEL_DELTA;
          }
    
          if (MouseHWheel != null)
          {
            MouseHWheel(this, e);
          }
    
          Refresh();
        }
    
        private void ScrollHorizontal(int delta)
        {
          AutoScrollPosition =
            new Point(
              -AutoScrollPosition.X + delta,
              -AutoScrollPosition.Y);
        }
    
        protected override void WndProc(ref Message m)
        {
          if (m.HWnd == this.Handle)
          {
            switch (m.Msg)
            {
              case Win32Messages.WM_MOUSEHWHEEL:
                OnMouseHWheel(CreateMouseEventArgs(m.WParam, m.LParam));
                //0 to indicate we handled it
                m.Result = (IntPtr)0;
                return;
              default:
                break;
            }
          }
          base.WndProc(ref m);
        }
    
        protected override void OnMouseWheel(MouseEventArgs e)
        {
          base.OnMouseWheel(e);
          return;
        }
    
        private MouseEventArgs CreateMouseEventArgs(IntPtr wParam, IntPtr lParam)
        {
          int buttonFlags = LOWORD(wParam);
          MouseButtons buttons = MouseButtons.None;
          buttons |= ((buttonFlags & Win32Constants.MK_LBUTTON) != 0) ? MouseButtons.Left : 0;
          buttons |= ((buttonFlags & Win32Constants.MK_RBUTTON) != 0) ? MouseButtons.Right : 0;
          buttons |= ((buttonFlags & Win32Constants.MK_MBUTTON) != 0) ? MouseButtons.Middle : 0;
          buttons |= ((buttonFlags & Win32Constants.MK_XBUTTON1) != 0) ? MouseButtons.XButton1 : 0;
          buttons |= ((buttonFlags & Win32Constants.MK_XBUTTON2) != 0) ? MouseButtons.XButton2 : 0;
    
          int delta = (Int16)HIWORD(wParam);
          int x = LOWORD(lParam);
          int y = HIWORD(lParam);
    
          return new MouseEventArgs(buttons, 0, x, y, delta);
        }
    
        private static Int32 HIWORD(IntPtr ptr)
        {
          Int32 val32 = ptr.ToInt32();
          return ((val32 >> 16) & 0xFFFF);
        }
    
        private static Int32 LOWORD(IntPtr ptr)
        {
          Int32 val32 = ptr.ToInt32();
          return (val32 & 0xFFFF);
        }
      }
    }
    
    

    Я перепробовал все 4, но при компиляции возникает одна и та же ошибка:

    Error    1    'System.Windows.Forms.Panel' does not contain a definition for 'MouseHWheel' and no extension method 'MouseHWheel' accepting a first argument of type 'System.Windows.Forms.Panel' could be found (are you missing a using directive or an assembly reference?)    C:\Users\Администратор\Documents\Visual Studio 2010\Projects\C#\HorizTiltWheelDemo\HorizTiltWheelDemo\Form1.cs    23    20    HorizTiltWheelDemo
    Помогите пожалуйста у же 2-ые сутки бьюсь. За ранее огромное спасибо.

     

    22 февраля 2011 г. 10:40

Ответы

Все ответы

  • Перейдите в класс Form1, установите курсор на строку

    InitializeComponent();

    нажмите правую кнопку мыши на надписи "InitializeComponent", выберите пункт "Go To Definition". В появившейся вкладке найдите строку

    private Panel panel1;

    или аналогичную ей, замените "Panel" в этой строке на "HorizTiltWheelDemo.TiltAwarePanel", попробуйте скомпилировать приложение, сообщите о результатах в этой теме.

    22 февраля 2011 г. 10:48
  • Алексей Митев я перешел

    в класс Form1, установите курсор на строку
    InitializeComponent();

    нажал правую кнопку мыши на надписи "InitializeComponent", выбрал пункт "Go To Definition". В появившейся вкладке найдите строку

    private System.Windows.Forms.HorizTiltWheelDemo.Panel panel1;
    

    Заменил ее на:

    private System.Windows.Forms.HorizTiltWheelDemo.TiltAwarePanel panel1;
    

    и

    this.panel1 = new System.Windows.Forms.Panel();
    

    на

    this.panel1 = new System.Windows.Forms.HorizTiltWheelDemo.TiltAwarePanel();
    
    Скомпилировал форма вообще исчезла и появились ошибки, что panel1 не описана. В чем ошибка????

    22 февраля 2011 г. 11:30
  • Да, забыл, что в строке создания тоже нужно изменить тип.

    В данный момент нужно заменить в этом же файле System.Windows.Forms.HorizTiltWheelDemo.TiltAwarePanel на HorizTiltWheelDemo.TiltAwarePanel.

    22 февраля 2011 г. 11:47
  • К какому элементу отнести TiltAwarePanel?
    22 февраля 2011 г. 12:43
  • По большому счету — неважно. Можете выбрать обычный класс.
    22 февраля 2011 г. 12:48
  • Когда я нажимаю правую кнопку мыши на надписи "InitializeComponent", выбраю пункт "Go To Definition". Я автоматически перехожу в Form1.Designers.cs делаю выше указанные изменения:

    namespace HorizTiltWheelDemo
    {
      partial class Form1
      {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;
    
        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
          if (disposing && (components != null))
          {
            components.Dispose();
          }
          base.Dispose(disposing);
        }
    
        #region Windows Form Designer generated code
    
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
          this.label1 = new System.Windows.Forms.Label();
          this.panel1 = new HorizTiltWheelDemo.TiltAwarePanel();
          this.pictureBox1 = new System.Windows.Forms.PictureBox();
          this.panel1.SuspendLayout();
          ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
          this.SuspendLayout();
          // 
          // label1
          // 
          this.label1.AutoSize = true;
          this.label1.Location = new System.Drawing.Point(13, 225);
          this.label1.Name = "label1";
          this.label1.Size = new System.Drawing.Size(53, 13);
          this.label1.TabIndex = 3;
          this.label1.Text = "H delta: 0";
          // 
          // panel1
          // 
          this.panel1.AutoScroll = true;
          this.panel1.Controls.Add(this.pictureBox1);
          this.panel1.Dock = System.Windows.Forms.DockStyle.Top;
          this.panel1.Location = new System.Drawing.Point(0, 0);
          this.panel1.Name = "panel1";
          this.panel1.Size = new System.Drawing.Size(284, 218);
          this.panel1.TabIndex = 2;
          // 
          // pictureBox1
          // 
          this.pictureBox1.Image = global::HorizTiltWheelDemo.Properties.Resources.TestImage;
          this.pictureBox1.Location = new System.Drawing.Point(-700, -550);
          this.pictureBox1.Name = "pictureBox1";
          this.pictureBox1.Size = new System.Drawing.Size(1600, 1200);
          this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
          this.pictureBox1.TabIndex = 2;
          this.pictureBox1.TabStop = false;
          // 
          // Form1
          // 
          this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
          this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
          this.AutoScroll = true;
          this.ClientSize = new System.Drawing.Size(284, 264);
          this.Controls.Add(this.label1);
          this.Controls.Add(this.panel1);
          this.Name = "Form1";
          this.Text = "Horizontal Tilt Wheel Demo";
          this.panel1.ResumeLayout(false);
          this.panel1.PerformLayout();
          ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
          this.ResumeLayout(false);
          this.PerformLayout();
    
        }
    
        #endregion
    
        private TiltAwarePanel panel1;
        private System.Windows.Forms.PictureBox pictureBox1;
        private System.Windows.Forms.Label label1;
    
    
      }
    }
    
    
    
    Компилирую у меня вместо формы выскакивает ошибка почему помогите пожалуйста уже 3-и сутки бьюсь за ранее огромное спасибо.

    23 февраля 2011 г. 11:15
  • Я вряд ли догадаюсь, какая именно у Вас возникает ошибка, без ее текстового описания. Более того, когда я начал пробовать повторить Вашу ситуацию, я обнаружил, что код класса Win32Messages в Вашем первом сообщении вставлен неверно (по всей видимости, случайно). Поэтому я нашел в интернете исходные тексты этого проекта, скопировал их в новый проект на своем компьютере, затем исправил исходный текст метода InitializeComponent и не встретил каких-либо проблем — проект скомпилировался без единой ошибки. Получившийся результат выложил сюда , Вы можете сравнить его с Вашим.
    23 февраля 2011 г. 14:43
  • Пример взят из "C#4.0 на примерах" Бен Ватсон.

     

    23 февраля 2011 г. 16:09
  • Тогда, тем более, Вы можете скачать все исходные тексты примеров книги с сайта издательства .
    • Помечено в качестве ответа Abolmasov Dmitry 24 февраля 2011 г. 7:41
    24 февраля 2011 г. 5:24
  • Я их скачал, но в каждой главе состоящей из проектов, после компиляции и запуска на выполнение запускается только один. Поэтому приходится создать каждый проект отдельно, чтобы увидеть как он работает.
    24 февраля 2011 г. 9:03
  • Вы можете нажать на проект в окне Solution Explorer правой кнопкой мыши и выбрать пункт меню "Set as startup project". Таким обрзом можно выбирать, какой проект будет запускаться при запуске всего решения.
    24 февраля 2011 г. 9:20
  • По чему при запуске нет картинки выскакивает пустая форма хотя в свойствах pictureBox Image я выбирал рисунок?????
    25 февраля 2011 г. 13:47