Страница: 1 |
Страница: 1 |
Вопрос: хук на закрытие
Добавлено: 08.03.08 00:03
Автор вопроса: Skywalker | Web-сайт:
Возможно ли поставить хук на WM_CLOSE любого произвольного чужого окна и получить координаты и размер окна? Покажите пжл пример, если возможно.
Ответы
Всего ответов: 3
Номер ответа: 1
Автор ответа:
Skywalker
ICQ: 300-70-6пятьЪ
Вопросов: 62
Ответов: 545
Web-сайт:
Профиль | | #1
Добавлено: 08.03.08 22:44
вот нашел на C#
namespace Hook
{
public delegate void OnForegroundWindowChangedDelegate(IntPtr hWnd);
public delegate void OnWindowMinimizeStartDelegate(IntPtr hWnd);
public delegate void OnWindowMinimizeEndDelegate(IntPtr hWnd);
public delegate void OnWindowDestroyDelegate(IntPtr hWnd);
public sealed class Hooks
{
#region Windows API
private enum SystemEvents : uint
{
EVENT_SYSTEM_DESTROY = 0x8001,
EVENT_SYSTEM_MINIMIZESTART = 0x0016,
EVENT_SYSTEM_MINIMIZEEND = 0x0017,
EVENT_SYSTEM_FOREGROUND = 0x0003
}
private const uint WINEVENT_OUTOFCONTEXT = 0x0000;
private delegate void WinEventDelegate(
IntPtr hWinEventHook,
uint eventType,
IntPtr hWnd,
int idObject,
int idChild,
uint dwEventThread,
uint dwmsEventTime);
[llImport("User32.dll", SetLastError = true)]
private static extern IntPtr SetWinEventHook(
uint eventMin,
uint eventMax,
IntPtr hmodWinEventProc,
WinEventDelegate lpfnWinEventProc,
uint idProcess,
uint idThread,
uint dwFlags);
[llImport("user32.dll"]
private static extern bool UnhookWinEvent(
IntPtr hWinEventHook
#endregion
private WinEventDelegate dEvent;
private IntPtr pHook;
public OnForegroundWindowChangedDelegate OnForegroundWindowChanged;
public OnWindowMinimizeStartDelegate OnWindowMinimizeStart;
public OnWindowMinimizeEndDelegate OnWindowMinimizeEnd;
public OnWindowDestroyDelegate OnWindowDestroy;
public Hooks()
{
dEvent = this.WinEvent;
pHook = SetWinEventHook(
 uint)SystemEvents.EVENT_SYSTEM_DESTROY,
 uint)SystemEvents.EVENT_SYSTEM_DESTROY,
IntPtr.Zero,
dEvent,
0,
0,
WINEVENT_OUTOFCONTEXT
if (IntPtr.Zero.Equals(pHook)) throw new Win32Exception();
GC.KeepAlive(dEvent);
}
private void WinEvent(IntPtr hWinEventHook, uint eventType, IntPtr hWnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{
switch (eventType)
{
case (uint)SystemEvents.EVENT_SYSTEM_DESTROY:
if (OnWindowDestroy != null) OnWindowDestroy(hWnd);
break;
//extend here when required
}
}
}
~Hooks()
{
if (!IntPtr.Zero.Equals(pHook)) UnhookWinEvent(pHook);
pHook = IntPtr.Zero;
dEvent = null;
OnWindowDestroy = null;
}
}
}
private void Form1_Load(object sender, EventArgs e)
{
Hook.Hooks hook = new Hook.Hooks();
hook.OnWindowDestroy += new Hook.OnWindowDestroyDelegate(window_destroyed);
}
private void window_destroyed(IntPtr hWnd)
{
//Код
}
Чуток добавил:
private void WinEvent(IntPtr hWinEventHook, uint eventType, IntPtr hWnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{
if (idObject == 0)
{
if (idChild!=0)
{
UnhookWinEvent((IntPtr)(Convert.ToInt32(hWnd)+idObject+idChild));
}
switch (eventType)
{
case (uint)SystemEvents.EVENT_SYSTEM_DESTROY:
if (OnWindowDestroy != null) OnWindowDestroy(hWnd);
break;
//extend here when required
}
}
}
То есть ищем только окна (idObject == 0) и для всех чайлдов снимаем хук, нам ведь нужно только окно.
private void window_destroyed(IntPtr hWnd)
{
textBox1.Text += string.Concat(hWnd.ToString(), " "
}
Но все равно выводится что-то лишнее. То есть открыл меню пуск, повозюкал по нему мышкой, уже в текстбокс написалась пара хендлов. (Но ведь никакие окно при этом не закрывались). Кликнул Мой компьютер, еще написалось (ну тут допускаю, что якобы для пуска дестрой вызвался). И потом, когда щелкнул закрыть Мой компьютер написалось штук 15 хэндлов, хотя поидее раз я снял хук с чайлдов должен был быть только 1. Что не так, помогите?
Номер ответа: 2
Автор ответа:
Skywalker
ICQ: 300-70-6пятьЪ
Вопросов: 62
Ответов: 545
Web-сайт:
Профиль | | #2
Добавлено: 08.03.08 23:42
вот еще забацал, чтобы рисовался прямоугольник, чтобы понять чтоже там дестроица, но в структуре Rect всегда одни нули... почему?)
namespace DrawToScreenTestApp
{
#region UnmanagedMethods
public class UnmanagedMethods
{
[llImport("user32.dll"]
public static extern IntPtr GetDC(IntPtr hwnd);
[llImport("user32.dll",EntryPoint="ReleaseDC"]
public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr dc);
[llImport("user32.dll", EntryPoint = "GetDesktopWindow"]
public static extern IntPtr GetDesktopWindow();
}
#endregion
#region DrawToScreen
public class DrawToScreen
{
public void PaintRectangleToScreen(int x, int y, int w, int h)
{
IntPtr deskDC = UnmanagedMethods.GetDC(IntPtr.Zero);
Graphics g = Graphics.FromHdc(deskDC);
Random rand = new Random();
g.FillRectangle(new SolidBrush(Color.FromArgb(100, 0, 0, 0)), x, y, w, h);
//g.EndContainer(cont);
g.Dispose();
UnmanagedMethods.ReleaseDC(UnmanagedMethods.GetDesktopWindow(), deskDC);
}
}
#endregion
}
private void window_destroyed(IntPtr hWnd)
{
RECT rect = new RECT();
GetWindowRect(hWnd,ref rect);
 rawToScreenTestApp.DrawToScreen draw = new DrawToScreenTestApp.DrawToScreen();
draw.PaintRectangleToScreen(rect.left,rect.top,rect.right-rect.left,rect.bottom-rect.top);
textBox1.Text += string.Concat(hWnd.ToString(), " "
}
Номер ответа: 3
Автор ответа:
Администратор
ICQ: 278109632
Вопросов: 42
Ответов: 3949
Web-сайт:
Профиль | | #3
Добавлено: 09.03.08 11:54
Ну так окна-то уже нет, оно дестройнулось, вот он тебе нули и выдает