#. 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);
}
}
출처 : http://irontooth.tistory.com/181
'C#' 카테고리의 다른 글
[C#] CellSet ==> DataSet 변환 (0) | 2016.04.06 |
---|---|
[C#] – Windows 환경에 따른 Control Layout 불일치 (0) | 2016.01.05 |
[C#][WCF] 이유없이 Communacation Exception / end point / 끝점이없습니다. 오류나올때 확인사항 (0) | 2015.08.21 |
[c#] delegate 델리게이트 파라미터 매개변수 선언 (0) | 2015.06.08 |
[C#] Access DB 에 대한 32bit/64bit OLE DB Provider 관련 오류 excel import (2) | 2014.12.18 |