Question

i want to build an app that work in the background, and will capture all click events on the minimize button, of all opened forms / windows that actually running. (not only in my current app)

it will be some sort of hook to add minimize handler to all of other windows.

how to setup this kind of hook ? ( please provide some code example in csharp with marsheling )

To better understand the idea : this procedure already exists in program called TrayIt that handle Ctrl+Click on the Minimize button, and send programs to system tray .

EDIT:

i have found that SetWindowsHookEx cannot set a global hook with c# due to limitation in manged code (see the msdn documentation )

but may WinEventProc with EVENT_OBJECT_STATECHANGE should do the work

Était-ce utile?

La solution

finely i have found solution for this hook , this is not the best solution that i can get but it do the work

i have mixed window_state_change in SetWinEventHook

and component to track Control Key in Gma.UserActivityMonitor

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Windows;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Security.Permissions;
using Gma.UserActivityMonitor;

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

        public const uint WINEVENT_OUTOFCONTEXT = 0;
        public const uint EVENT_OBJECT_STATECHANGE = 0x800A;
        [DllImport("user32.dll")]
        public static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr hmodWinEventProc, WinEventDelegate lpfnWinEventProc, uint idProcess, uint idThread, uint dwFlags);
        [DllImport("user32.dll")]
        public static extern bool UnhookWinEvent(IntPtr hWinEventHook);

        public delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime);

        public static bool ControlDown = false;
        public static IntPtr hhook;
        static WinEventDelegate procDelegate = new WinEventDelegate(WinEventProc);

        private void load(object sender, System.EventArgs e) {
            hhook = SetWinEventHook(EVENT_OBJECT_STATECHANGE, EVENT_OBJECT_STATECHANGE, IntPtr.Zero, procDelegate, 0, 0, winapi.WINEVENT_OUTOFCONTEXT);
            HookManager.KeyDown += HookManager_KeyDown;
            HookManager.KeyUp += HookManager_KeyUp;
        }
        private void closing(object sender, System.Windows.Forms.FormClosingEventArgs e) {
            UnhookWinEvent(hhook);

            HookManager.KeyDown -= HookManager_KeyDown;
            HookManager.KeyUp -= HookManager_KeyUp;
        }
        private void HookManager_KeyUp(object sender, KeyEventArgs e) {
            if (e.KeyCode == Keys.LControlKey) { ControlDown = false; }
        }
        private void HookManager_KeyDown(object sender, KeyEventArgs e) {
            if (e.KeyCode == Keys.LControlKey) { ControlDown = true; }
        }

        static void WinEventProc(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime) {
            if (idObject == -2 && idChild == 2) {
                if (ControlDown) {

                    // HookWindow(hwnd);
                    .....
                }

            }
        }
    }
}

if you like you can setup a simple hook with RegisterHotKey

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top