2013-11-16 4 views
2

Как я могу разрешить пользователю выбирать элемент управления из любого окна? Может быть что-то вроде inspect.exe или WinySpy ++ (см. Снимок экрана).Позволяет пользователю выбирать управление/окно из другого процесса

enter image description here

EDIT: Под «выберите элемент управления» Я имею в виду, как я могу получить ручку управления под курсором мыши, так что я могу после этого сделать что-то с ним (например, нарисовать рамку вокруг него, получить его позиции и имени). Я знаю, что мне нужно использовать WinAPI, просто не знаю, с чего начать (как получить дескриптор элемента управления под указателем мыши).

+0

Что вы имеете в виду * "выберите элемент управления" *? Установить фокус на это? Вызывать связанную команду? Что-то еще? – IInspectable

+0

Он проверяет сообщения ОС. Для этого вам нужно проверить API Windows. – SJuan76

+0

Я обновил вопрос, извините за то, что не объяснил это с самого начала. – xx77aBs

ответ

8

Вот кое-что, чтобы начать с: (это очень грубо и требует больше работы!)

  1. В пустую форму, добавить PictureBox и четыре этикетки.
  2. Измените BorderStyle в PictureBox на FixedSingle.
  3. Добавить using System.Runtime.InteropServices; вверху код с другим using заявления.
  4. Подключите события MouseDown(), MouseMove и MouseUp() к PictureBox к следующим методам.
  5. Выполнить это и перетащить PictureBox вокруг экрана ...

Very Rough Spy++ Example

Код:

public partial class Form1 : Form 
{ 

    [StructLayout(LayoutKind.Sequential)] 
    public struct RECT 
    { 
     public int Left; 
     public int Top; 
     public int Right; 
     public int Bottom; 
    } 

    public const int WM_GETTEXT = 0xD; 
    public const int WM_GETTEXTLENGTH = 0x000E; 

    [DllImport("user32.dll")] 
    public static extern IntPtr WindowFromPoint(Point point); 

    [DllImport("user32.dll", CharSet = CharSet.Auto)] 
    public static extern int GetClassName(IntPtr handle, StringBuilder ClassName, int MaxCount); 

    [DllImport("user32.dll")] 
    public static extern int SendMessage(IntPtr handle, int msg, int Param1, int Param2); 

    [DllImport("user32.dll")] 
    public static extern int SendMessage(IntPtr handle, int msg, int Param, System.Text.StringBuilder text); 

    [DllImport("user32.dll")] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    public static extern bool GetWindowRect(IntPtr handle, out RECT Rect); 

    public class WindowInfo 
    { 
     public IntPtr Handle; 
     public string ClassName; 
     public string Text; 
     public Rectangle Rect; 

     public WindowInfo(IntPtr Handle) 
     { 
      this.Handle = Handle; 
      this.ClassName = GetWindowClassName(Handle); 
      this.Text = GetWindowText(Handle); 
      this.Rect = GetWindowRectangle(Handle); 
     } 
    } 

    WindowInfo LastWindow = null; 
    WindowInfo CurWindow; 

    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void pictureBox1_MouseDown(object sender, MouseEventArgs e) 
    { 
     if (e.Button == System.Windows.Forms.MouseButtons.Left) 
     { 
      pictureBox1.Cursor = Cursors.Cross; 
     } 
    } 

    private void pictureBox1_MouseMove(object sender, MouseEventArgs e) 
    { 
     if (e.Button == System.Windows.Forms.MouseButtons.Left) 
     { 
      Point pt = Cursor.Position; 
      this.Text = "Mouse Position: " + pt.ToString(); 
      this.CurWindow = new WindowInfo(WindowFromPoint(pt)); 

      label1.Text = "Handle: " + this.CurWindow.Handle.ToString("X"); 
      label2.Text = "Class: " + this.CurWindow.ClassName; 
      label3.Text = "Text: " + this.CurWindow.Text; 
      label4.Text = "Rectangle: " + this.CurWindow.Rect.ToString(); 

      if (this.LastWindow == null) 
      { 
       ControlPaint.DrawReversibleFrame(this.CurWindow.Rect, Color.Black, FrameStyle.Thick); 
      } 
      else if (!this.CurWindow.Handle.Equals(this.LastWindow.Handle)) 
      { 
       ControlPaint.DrawReversibleFrame(this.LastWindow.Rect, Color.Black, FrameStyle.Thick); 
       ControlPaint.DrawReversibleFrame(this.CurWindow.Rect, Color.Black, FrameStyle.Thick);     
      } 

      this.LastWindow = this.CurWindow; 
     } 
    } 

    private void pictureBox1_MouseUp(object sender, MouseEventArgs e) 
    { 
     if (e.Button == System.Windows.Forms.MouseButtons.Left) 
     { 
      pictureBox1.Cursor = Cursors.Default; 
      if (this.LastWindow != null) 
      { 
       ControlPaint.DrawReversibleFrame(this.LastWindow.Rect, Color.Black, FrameStyle.Thick); 

       // ... do something with "this.LastWindow" ... 

      } 
     } 
    } 

    public static string GetWindowClassName(IntPtr handle) 
    { 
     StringBuilder buffer = new StringBuilder(128); 
     GetClassName(handle, buffer, buffer.Capacity); 
     return buffer.ToString(); 
    } 

    public static string GetWindowText(IntPtr handle) 
    { 
     StringBuilder buffer = new StringBuilder(SendMessage(handle, WM_GETTEXTLENGTH,0,0) + 1); 
     SendMessage(handle, WM_GETTEXT, buffer.Capacity, buffer); 
     return buffer.ToString(); 
    } 

    public static Rectangle GetWindowRectangle(IntPtr handle) 
    { 
     RECT rect = new RECT(); 
     GetWindowRect(handle, out rect); 
     return new Rectangle(rect.Left, rect.Top, (rect.Right - rect.Left) + 1, (rect.Bottom - rect.Top) + 1); 
    } 

} 
+0

Спасибо. спас мой день – kakopappa

2

Используйте функцию GetCursorPos, чтобы получить текущую позицию курсора.

Используйте WindowFromPoint, чтобы получить окно, содержащее указанную точку.

Что касается рисунка прямоугольника, посмотрите на source code of WinSpy++.

+1

Другие полезные вызовы API: GetWindowText, GetClassName, GetWindowLongA, GetWindowRect ... проверьте pinvoke.net для объявлений. – HypnoToad

Смежные вопросы