2009-12-02 6 views
5

패널에 20 개의 그림 상자를 동적으로 추가했으며 마우스 휠을 사용할 때 패널 스크롤을보고 싶습니다. 이를 구현하기 위해 패널 컨트롤에서 autoscroll을 true로 설정하려고했습니다. 여기에 코드가 있습니다. 를 들어 내가 정수 = 1 ~ 20 : 그림 상자 컨트롤이 동적으로 추가 된 패널의 마우스 휠 스크롤?

 Dim b As New PictureBox() 
     b.Image = Nothing 
     b.BorderStyle = BorderStyle.FixedSingle 
     b.Text = i.ToString() 
     b.Size = New Size(60, 40) 
     b.Location = New Point(0, (i * b.Height) - b.Height) 
     b.Parent = Panel1 
     Panel1.Controls.Add(b) 
    Next 

내가 단추 컨트롤과 같은 일을했고 그냥 잘 작동합니다. 대한 내가 정수 = 1 내지 100 :

 Dim b As New Button() 

     b.Text = i.ToString() 
     b.Size = New Size(60, 40) 
     b.Location = New Point(0, (i * b.Height) - b.Height) 
     b.Parent = Panel1 
     Panel1.Controls.Add(b) 
    Next 

그것은 "버튼을"제어를 위해 작동하지만,하지 "PictureBox를"또는 "라벨"컨트롤? '마우스 휠'을 사용하여 스크롤 효과를 구현하려면 어떻게해야합니까?

답변

6

마우스 휠이나 컨트롤에 포커스가있을 때 패널이 스크롤됩니다. 실행중인 문제는 클릭 할 때 PictureBox와 패널 모두 포커스를받지 못한다는 것입니다. 패널에서 select()으로 전화하면 마우스 휠이 다시 작동하는 것을 볼 수 있습니다.

마우스 커서가 Control.MouseEnter 이벤트 처리하여, 그것을 입력 할 때마다 한 가지 가능한 솔루션은 패널을 선택하는 것입니다 : 창에

void panel1_MouseEnter(object sender, EventArgs e) 
{ 
    panel1.select(); 
} 
3

"cwick"입니다 확실히 바로, 윈도우 게시합니다 WM_MOUSWHEEL 알림 그 초점이 있습니다. 포커스를 얻을 수 있기 때문에 패널에 단추를 넣을 때 작동합니다. 그 다음에 일어나는 일은 Windows가 부모 컨트롤을 찾고 메시지를 가져 오는 것입니다. 버튼은 상관하지 않습니다. 부모 패널입니다. 행복하게 스크롤하고 메시지를 소비합니다.

자식 컨트롤의 포커스를 변경할 수있는 기능을 가진 의사 결정 이외의 다른 방법 (이 경우 재정의하고 SetStyle (ControlStyles.Selectable)을 호출해야 함) 이외에이 메시지가 처리되는 방식을 변경할 수 있습니다. 많은 상용 응용 프로그램은 몇 개의 창만 있기 때문에 이러한 문제 (브라우저, Office 응용 프로그램)가없는 것처럼 보입니다. WF 앱은 대개 각 컨트롤마다 하나씩 많습니다. 메시지를 집중된 컨트롤로 보내기 전에 먼저 메시지를 처리하여 메시지를 처리하십시오. IMessageFilter 인터페이스는 이것을 허용합니다.

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

namespace WindowsApplication1 { 
    public partial class Form1 : Form, IMessageFilter { 
    public Form1() { 
     InitializeComponent(); 
     Application.AddMessageFilter(this); 
    } 

    public bool PreFilterMessage(ref Message m) { 
     if (m.Msg == 0x20a) { 
     // WM_MOUSEWHEEL, find the control at screen position m.LParam 
     Point pos = new Point(m.LParam.ToInt32()); 
     IntPtr hWnd = WindowFromPoint(pos); 
     if (hWnd != IntPtr.Zero && hWnd != m.HWnd && Control.FromHandle(hWnd) != null) { 
      SendMessage(hWnd, m.Msg, m.WParam, m.LParam); 
      return true; 
     } 
     } 
     return false; 
    } 

    // P/Invoke declarations 
    [DllImport("user32.dll")] 
    private static extern IntPtr WindowFromPoint(Point pt); 
    [DllImport("user32.dll")] 
    private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp); 
    } 
} 

이 코드는 앱에서 어떤 창 활성화되어 있음을주의 :이 샘플 코드는 마우스 아래의 컨트롤 대신 포커스가 컨트롤을 스크롤합니다. 시도해보고 사용자가 혼동하지 않도록 확인하십시오.

관련 문제