Перетаскивание как Шпион Winspector

Я задавался вопросом, мог ли кто-либо дать понимание о том, как реализовать селектор окна в Шпионе Winspector. В основном я хотел бы обеспечить панель, что я мог мышь вниз на, перетащить к другому окну процессов (или sub окну) и получить что-то как HWND из нее. Идеально, я сделал бы это в C#, но если это только возможно путем обертывания API C, затем я могу просто сделать это в C++.

Я бездельничал с событием DragDrop и вызовом DoDragDrop на мыши вниз в C#, но не был действительно уверен, могло ли это дать мне, что я хочу. Будет легче просто получить глобальный X/Y на месте продажи мыши и найти самое верхнее окно в том местоположении? Существует ли API, который делает это автоволшебно для меня данный x, y параметры?

Править: Просто обнаруженный WindowFromPoint для последнего вопроса

5
задан NG. 21 February 2010 в 19:38
поделиться

6 ответов

Обычно вы не получаете сообщения мыши, когда мышь не находится над вашим окном. Но это необходимо для выполнения операций перетаскивания. Итак, Windows предоставляет механизм, называемый захватом мыши. Чтобы предотвратить злоупотребление захватом мыши, вы можете захватить мышь только при нажатии кнопки. После захвата вы будете получать сообщения о перемещении мыши независимо от того, где находится мышь на экране, до тех пор, пока вы не отпустите захват или когда Windows не увидит соответствующее сообщение о нажатии кнопки.

Код C ++ для этого выглядит примерно так

 case WM_LBUTTONDOWN:
     { 
     SetCapture(hwnd);
     }
     break;

 case WM_MOUSEMOVE:
     if (GetCapture() == hwnd)
        {
        POINT pt = {GET_MOUSE_X(lParam), GET_MOUSE_Y(lParam));
        ClientToScreen(hwnd, &pt);
        HWND hwndAtPoint = WindowFromPoint(pt);
        // Show info for hwndAtPoint....
        }
     break;

  case WM_LBUTTONUP:
     if (GetCapture() == hwnd)
        {
        ReleaseCapture();
        }
     break;

  case WM_CANCELMODE:
     // this is a request from Windows that leave my modal state
     if (GetCapture() == hwnd)
        ReleaseCapture(hwnd);
     break;

  case WM_CAPTURECHANGED:
     // notification that I lost capture (I released it or it was taken from me)
     break;      

Функция GetAncestor может быть полезна для перехода от окна в точке к окну верхнего уровня, которому она принадлежит. GetWindow можно использовать для обхода дерева окон.

В.NET у класса Control есть свойство Capture, которое делает то же самое, см. http://msdn.microsoft.com/en-us/library/system.windows.forms.control.capture.aspx

5
ответ дан 14 December 2019 в 04:36
поделиться

Вам нужно сначала подумать о том, как вы собираетесь рисовать прямоугольник вокруг окна, который влияет на остальную часть вашего кода. Самый простой способ сделать это - использовать форму, для которой для параметра TransparencyKey установлено значение BackColor, а для FormBorderStyle - значение None. Нарисуйте прямоугольник в событии Paint того же размера, что и ClientRectangle формы, который дает вам видимый прямоугольник со всем остальным прозрачным. Задайте для формы свойства Location и Size в соответствии с найденным окном.

Теперь поиск окна с позиции мыши. Вы не можете использовать WindowFromPoint (), он не учитывает отключенные окна. Вам нужно будет использовать EnumWindows (). В обратном вызове вызовите GetWindowRect () и проверьте, находится ли мышь внутри прямоугольника. Обязательно игнорируйте окно рисования прямоугольника.

Когда вы найдете совпадение, теперь вызовите GetWindow () несколько раз с GW_HWNDPREV, чтобы найти окна, которые перекрывают найденное вами окно. Продолжайте проверять прямоугольник и игнорируйте прямоугольное окно.

В конечном итоге вы получите окно верхнего уровня, в котором находится курсор мыши. Теперь используйте ChildWindowFromPoint (), чтобы проверить, находится ли мышь в дочернем окне, если таковое имеется. При необходимости создайте прямоугольную форму чертежа и задайте ей такой же размер и расположение, как и у найденного окна.

Вызовите этот код из события MouseMove, скажем, PictureBox, который отображает графику "бычий глаз". Установите для свойства Capture значение true в событии MouseDown.

Закройте метод Close () формы рисования прямоугольника в событии MouseUp.

2
ответ дан 14 December 2019 в 04:36
поделиться

Но что именно является O (log n)

Что это означает точно, так это "поскольку n стремится к бесконечности , время стремится к a * log (n) , где a является постоянным масштабным коэффициентом".

Или на самом деле, это не совсем означает, что; скорее всего, это означает что-то вроде " время , деленное на a * log (n) , стремится к 1 ".

"Стремится к" имеет обычное математическое значение из "анализа": например, что "если выбрать любую произвольно малую ненулевую константу k , то я могу найти соответствующее значение X такое, что (время/( a * log (n))) - 1) меньше k для всех значений n больше X "


. но эти другие компоненты бледнеют в сторону незначительности для больших значений n, и a * log (n) является доминирующим членом для больших n.

Обратите внимание, что если уравнение было, например,...

время (n) = a + b log (n) + c n + d n n

... тогда это будет O (n в квадрате), потому что, независимо от того, какие значения констант a, b, c и ненулевые d, член d * n * n всегда будет доминировать над другими для любого достаточно большого значения n.

Вот что означает обозначение бита O: это означает "какой порядок доминирующего члена для любого достаточно большого n".

-121--1744362-

Мне не удалось воспроизвести вашу проблему в Google Chrome 4,0, IE8 или Firefox 3,5 с помощью этого кода. Метка и переключатель остались на одной линии.

Попробуйте поместить их оба в тег < p > или установите переключатель в положение "Включено", как это предлагал The Elite Gentleman.

-121--2045486-

Просто. Вы просто устанавливаете захват мыши на мышь вниз, так что вы получаете все сообщения мыши, даже если они находятся за пределами вашего собственного окна. Затем при наведении мыши используйте WindowStartPoint.

Я не знаком с .NET, но с Win32 API вы используете SetCapture для настройки захвата мыши.

0
ответ дан 14 December 2019 в 04:36
поделиться

Вы могли бы посмотреть исходный текст на C++ для Winspy++, другой программы инспектора окон, похожей на Winspector Spy. Однако я не знаю ни одной подобной программы на C# с открытым исходным кодом.

0
ответ дан 14 December 2019 в 04:36
поделиться

Поскольку вы отметили это с помощью C #, я могу добавить пару ссылок для этой работы, которую вы пытаетесь выполнить, и, надеюсь, предоставлю вам необходимые понимание того, как этого добиться:

Все вышеперечисленные статьи находятся на CodeProject.

Надеюсь, это поможет, С уважением, Том.

1
ответ дан 14 December 2019 в 04:36
поделиться

Импорт: с использованием System.Runtime.InteropServices;

Мое предложение, когда мышь находится в вашей форме, обрабатывайте движение мыши / mouse up события (чтобы захватить мышь за пределами вашей формы с помощью ловушки Windows, посмотрите здесь: http://support.microsoft.com/kb/318804 ), и когда кнопка мыши отпущена, получить позицию мыши на экране и получить окно за курсором, используя ссылку, которую вы предоставили, например:

[DllImport("user32.dll")]
public static extern IntPtr WindowFromPoint(Point lpPoint);
[DllImport("user32.dll")]
public static extern bool GetCursorPos(out Point lpPoint);
public static IntPtr GetWindowUnderCursor()
{
   Point ptCursor = new Point();
   if (!(PInvoke.GetCursorPos(out ptCursor)))
       return IntPtr.Zero;
   return WindowFromPoint(ptCursor);
}

Теперь у вас есть дескриптор окна, оттуда возможности безграничны.

ПРИМЕЧАНИЕ. Ссылка выше (обработчик Windows) будет работать только в том случае, если указатель мыши опущен на вашу форму, а обработчик завершится, когда мышь будет поднята

0
ответ дан 14 December 2019 в 04:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: