2012-06-21 2 views
4

WinForms에서 사용자 지정 AutoCompleteTextBox 컨트롤을 만들려고합니다. 기본 텍스트 상자에서 제공하는 자동 완성 기능은 (string).Contains이 아닌 (string).StartsWith이라는 결과 만 제공합니다.마우스 클릭을 수신하는 동안 양식이 포커스를 훔치지 않도록하려면 어떻게해야합니까?

에 도킹 된 ListBox의 자동 완성 검색 결과가 표시됩니다. 전체를 통해 WndProc 방법을 재정 의하여 I 초점을 얻고에서 Form을 방지 할 수 있습니다, 그리고

protected override bool ShowWithoutActivation 
{ 
    get { return true; } 
} 

: 나는 통해 사용하여 처음에 초점을 훔치는에서 Form을 방지 할 수 있습니다

protected override void WndProc(ref Message m) 
{ 
    base.WndProc(ref m); 
    switch (m.Msg) 
    { 
     case WM_MOUSEACTIVATE: 
      m.Result = (IntPtr) MA_NOACTIVATEANDEAT; 
      break; 

     default: 
      break; 
    } 

나는이의 작업을 수행 할 때 Form에 포함 된 ListBox 이벤트는 MouseMoved 이벤트를 수신하지만 MouseClicked 이벤트는 수신하지 않습니다. 단지 MA_NOACTIVATEListBox 마우스 이벤트를 통과 할 것이 아니라, 다음 ListBox에 클릭이 Form에서 초점을 훔치는하게됩니다 MA_NOACTIVATEANDEAT을 Chaning

ListBox가에있는 -에 통과하는 '부동'는 ListBox가에 Form을 .

내가 여전히 ListBoxMouseClick 이벤트를 가져 오는 동안 Form '기본'에서 초점을 steeling에서 '부동' Form을 방지 할 수있는 방법이 있습니까?

+0

더 난 당신이 단순히 클릭이 목록 상자에서 수신 한 후 기본 폼에 다시 초점을 넣어 강제 것입니다 ... 또는 목록 상자 항목을 결정하기 위해 마우스 이동 이벤트를 사용하여 생각 끝났어. HitTest (IIRC)는 ListBoxItem을 제공합니다. – IAbstract

+0

@lAbstract 포커스를 뒤로 이동하는 문제는 다음 번에 부동 양식을 표시 할 때 기본 폼이 부동 양식 앞에 표시되는 것입니다. 그런 다음 플로팅 폼에서 BringToFront를 호출하면 포커스가 주어져 다시 메인 폼에서 훔쳐옵니다. – Anthony

+0

... 아, 이해 : 그렇다면 메인 폼에서 마우스 움직임을 모니터링 할 수 있다면 메인 폼에서'HitTestInfo'를 얻을 수 있습니까? 그렇게 할 수 있다면 실제로 플로팅 폼에서 선택한 항목을받을 수 있습니다. 내 생각 엔. ;) – IAbstract

답변

0

부동 양식을 Usercontrol으로 변환하십시오. - ListBox를 당겨 & Click 이벤트에 연결하여 Focus 시나리오를 시뮬레이션하십시오. MainForm에서

using System.Text; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 

namespace WindowsFormsApplication3 
{ 
    public partial class InactiveForm : UserControl 
    { 
     private const int WS_EX_TOOLWINDOW = 0x00000080; 
     private const int WS_EX_NOACTIVATE = 0x08000000; 
     private const int WS_EX_TOPMOST = 0x00000008; 


     [DllImport("user32")] 
     public static extern int SetParent 
     (IntPtr hWndChild, IntPtr hWndNewParent); 

     [DllImport("user32")] 
     public static extern int ShowWindow 
     (IntPtr hWnd, int nCmdShow); 


     protected override CreateParams CreateParams 
     { 
      get 
      { 

       CreateParams p = base.CreateParams; 
       p.ExStyle |= (WS_EX_NOACTIVATE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST); 
       p.Parent = IntPtr.Zero; 
       return p; 
      } 
     } 

     public InactiveForm() 
     { 
      InitializeComponent(); 
     } 

     public new void Show() 
     { 
      if (this.Handle == IntPtr.Zero) base.CreateControl(); 

      SetParent(base.Handle, IntPtr.Zero); 
      ShowWindow(base.Handle, 1); 
     } 


     private void OnListBoxClicked(object sender, EventArgs e) 
     { 
      MessageBox.Show("Clicked List Box on floating control"); 

     } 
    } 
} 

코드 (A 버튼과 클릭 핸들러 부착 된) : -

이 목록 상자에 떠있는 컨트롤을 호출합니다. 당신이 떠있는 형태로 UserControl을 (국경 양식)를 표시 할 때

namespace WindowsFormsApplication3 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      InactiveForm f = new InactiveForm(); 
      f.Show(); 
     } 
    } 
} 

, 당신은 it wont receive focus even if you clicked (selected) any of its children 있음을 알 수 있습니다. 이 경우 하위 컨트롤은 UserControl의 ListBox입니다.

herehere을 참조하십시오. Angshuman 아가 왈으로 이전 대답 addtion에서

0

: 당신은 양식을 부동으로 UserControl을 쇼 당신의 UserControl을 몇 가지 코드를 수정할 때 기본 폼이 비활성화되지 않습니다하려면 다음 제작 한

private Control _mControl; 

[DllImport("user32.dll")] 
static extern IntPtr SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam); 

public new void Show(Control c) 
{ 
    if (c == null) throw new ArgumentNullException(); 
    _mControl = c; 
    if (this.Handle == IntPtr.Zero) base.CreateControl(); 
    SetParent(base.Handle, IntPtr.Zero); 
    ShowWindow(base.Handle, 1); 
} 

protected override void WndProc(ref Message m) 
{ 
    if (m.Msg == 0x86) //WM_NCACTIVATE 
    { 
     if (m.WParam != IntPtr.Zero) //activate 
     { 
      SendMessage(_mControl.Handle, 0x86, (IntPtr)1, IntPtr.Zero); 
     } 
     this.DefWndProc(ref m); 
     return; 
    } 
    base.WndProc(ref m); 
} 
0

뭔가 비슷하지만 내 솔루션은 lAbstract가 제안한 것과 유사합니다. floatin 폼에는 사용자 지정 TextBox (이 경우 AutoCompleteTextBox 컨트롤)가 구독하는 DoReturnFocus 이벤트가 있으며 포커스를 다시 자체적으로 설정합니다. 플로팅 폼 앞에 기본 폼이 나타나지 않게하려면 메인 폼을 소유자 플로팅 폼으로 설정합니다. 소유 폼은 소유자 폼 뒤에 표시되지 않습니다.Form.Owner Property

관련 문제