'panel'에 해당되는 글 1건

  1. 2011.02.09 C# Panel에서 스크롤을 마우스 휠로 움직이기 2
C#2011. 2. 9. 11:45


#. panel에서 AutoScroll을 true로 설정할 경우 스크롤 표현이 가능합니다. 하지만 이 스크롤은 마우스 휠로 컨트롤이 안되는데요. 다음 클래스를 추가하면 마우스 휠로 컨트롤할 수 있습니다.

#. 추가할 클래스 - ScrollPanelMessageFilter 클래스를 프로젝트에 추가합니다.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace MouseWheel
{
    /// <summary>
    /// panel에 표시된 스크롤을 마우스 휠로 움직일 수 있도록 하는 클래스
    /// </summary>
    public class ScrollPanelMessageFilter : IMessageFilter
    {
        int WM_MOUSEWHEEL = 0x20A;
        Panel panel;
        bool panelHasFocus = false;
        [DllImport("user32.dll")]
        static extern bool GetCursorPos(ref Point lpPoint);
        [DllImport("User32.dll")]
        static extern Int32 SendMessage(int hWnd, int Msg, int wParam, int lParam);

        public ScrollPanelMessageFilter(Panel panel)
        {
            this.panel = panel;
            //Go through each control on the panel and add an event handler.
            //We need to know if a control on the panel has focus to prevent sending
            //the scroll message a second time
            AddFocusEvent(panel);
        }

        private void AddFocusEvent(Control parentControl)
        {
            foreach (Control control in parentControl.Controls)
            {
                if (control.Controls.Count == 0)
                {
                    control.GotFocus += new EventHandler(control_GotFocus);
                    control.LostFocus += new EventHandler(control_LostFocus);
                }
                else
                {
                    AddFocusEvent(control);
                }
            }
        }

        void control_LostFocus(object sender, EventArgs e)
        {
            panelHasFocus = false;
        }

        void control_GotFocus(object sender, EventArgs e)
        {
            panelHasFocus = true;
        }


        #region IMessageFilter Members
        public bool PreFilterMessage(ref Message m)
        {
            //filter out all other messages except than mousewheel
            //also only proceed with processing if the panel is focusable,
            //no controls on the panel have focus
            //and the vertical scroll bar is visible

            if (m.Msg == WM_MOUSEWHEEL && panel.CanFocus && !panelHasFocus && panel.VerticalScroll.Visible)
            {
                //is mouse cordinates over the panel display rectangle?
                Rectangle rect = panel.RectangleToScreen(panel.ClientRectangle);
                Point cursorPoint = new Point();
                GetCursorPos(ref cursorPoint);

                if ((cursorPoint.X > rect.X && cursorPoint.X < rect.X + rect.Width) &&
                    (cursorPoint.Y > rect.Y && cursorPoint.Y < rect.Y + rect.Height))
                {
                    //send the mouse wheel message to the panel.
                    SendMessage((int)panel.Handle, m.Msg, (Int32)m.WParam, (Int32)m.LParam);
                    return true;
                }
            }

            return false;
        }
        #endregion

    }
}

#. 사용법.
 - Form 의 Activated, Deactivate 이벤트에서 아래와 같이 구현 하여 줍니다.

    public partial class Form1 : Form
    {
        private ScrollPanelMessageFilter filter;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Activated(object sender, EventArgs e)
        {
            filter = new ScrollPanelMessageFilter(panel);
            Application.AddMessageFilter(filter);
        }

        private void Form1_Deactivate(object sender, EventArgs e)
        {
            Application.AddMessageFilter(filter);
        }
    }


네이년 블로그를 뒤져서 찾았습니다.

Posted by 쿵캉켕