Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - .NET

Страница: 1 |

 

  Вопрос: хук на закрытие Добавлено: 08.03.08 00:03  

Автор вопроса:  Skywalker | Web-сайт: iSkywalker.ru | ICQ: 300-70-6пятьЪ 
Возможно ли поставить хук на WM_CLOSE любого произвольного чужого окна и получить координаты и размер окна? Покажите пжл пример, если возможно.

Ответить

  Ответы Всего ответов: 3  

Номер ответа: 1
Автор ответа:
 Skywalker



ICQ: 300-70-6пятьЪ 

Вопросов: 62
Ответов: 545
 Web-сайт: iSkywalker.ru
 Профиль | | #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);

        [;DllImport("User32.dll", SetLastError = true)]
        private static extern IntPtr SetWinEventHook(
            uint eventMin,
            uint eventMax,
            IntPtr hmodWinEventProc,
            WinEventDelegate lpfnWinEventProc,
            uint idProcess,
            uint idThread,
            uint dwFlags);

        [;DllImport("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-сайт: iSkywalker.ru
 Профиль | | #2
Добавлено: 08.03.08 23:42
вот еще забацал, чтобы рисовался прямоугольник, чтобы понять чтоже там дестроица, но в структуре Rect всегда одни нули... почему?)


namespace DrawToScreenTestApp
{

    #region UnmanagedMethods
    public class UnmanagedMethods
    {

        [;DllImport("user32.dll";)]
        public static extern IntPtr GetDC(IntPtr hwnd);

        [;DllImport("user32.dll",EntryPoint="ReleaseDC";)]
        public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr dc);

        [;DllImport("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);
            ;DrawToScreenTestApp.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-сайт: domkratt.com
 Профиль | | #3
Добавлено: 09.03.08 11:54
Ну так окна-то уже нет, оно дестройнулось, вот он тебе нули и выдает =)

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам