EnumDesktopWindows 컬렉션에 대한 변경 사항을 폴링하는 C# 프로그램이 있습니다. 사용자가 창을 닫거나 열면 폴링 루틴이이를 감지하고 업데이트 된 사용 가능한 창 목록을 다른 .Net 창 양식 프로젝트로 보냅니다. 그러나 폴링 방식이 마음에 들지 않습니다. 변경에 대한 응답이 비동기 적으로 완료되도록 EnumDesktopWindows를 변경하면 이벤트가 트리거되는 것을 선호합니다.데스크톱 윈도우 컬렉션이 변경되면 비동기 델파이로 위장됩니까?
제가 생각할 수있는 가장 좋은 점은 아래에서 보는 것입니다. 나는 Scott C의 제안을 콘솔 창에서 실행하려고 시도했지만 작동하지 않았다.
현재 Windows Form이로드 될 때 CreateWnd = 3이 캡처됩니다 (이것은 Windows 양식 응용 프로그램입니다). 그러나 전역 적으로 캡처하지는 않습니다. 현재 실행중인 실행 파일의 창 이벤트 만 캡처합니다. 독수리 눈을 가진 사람이라면이 코드를 전 세계적으로 캡처하는 방법을 알아낼 수 있습니다.
사용해보기; 먼저 윈도우 폼 응용 프로그램 프로젝트를 만들고 Form1.cs에 다음 코드를 추가
using System;
using System.Windows.Forms;
namespace Utilities
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
var gwh = new GlobalWindowHook();
gwh.WindowCreated += onWindowCreated;
}
private void onWindowCreated()
{
lstLog.Items.Add("window creation event detected.");
}
}
}
이 GlobalWindowHook 이름이 같은 프로젝트에서 클래스 파일을 만듭니다 (당신은 제대로 컴파일 lstLog라는 이름의 양식에 목록 상자를 추가해야합니다) .cs 및 복사 붙여 넣기 다음 :
using System;
using System.Runtime.InteropServices;
namespace Utilities
{
internal class GlobalWindowHook
{
private delegate IntPtr HookProc(int code, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
public enum HookType
{
WH_JOURNALRECORD = 0,
WH_JOURNALPLAYBACK = 1,
WH_KEYBOARD = 2,
WH_GETMESSAGE = 3,
WH_CALLWNDPROC = 4,
WH_CBT = 5,
WH_SYSMSGFILTER = 6,
WH_MOUSE = 7,
WH_HARDWARE = 8,
WH_DEBUG = 9,
WH_SHELL = 10,
WH_FOREGROUNDIDLE = 11,
WH_CALLWNDPROCRET = 12,
WH_KEYBOARD_LL = 13,
WH_MOUSE_LL = 14
}
public enum HCBT
{
MoveSize = 0,
MinMax = 1,
QueueSync = 2,
CreateWnd = 3,
DestroyWnd = 4,
Activate = 5,
ClickSkipped = 6,
KeySkipped = 7,
SysCommand = 8,
SetFocus = 9
}
private IntPtr hhook = IntPtr.Zero;
public GlobalWindowHook()
{
hook();
}
~GlobalWindowHook()
{
unhook();
}
public void hook()
{
IntPtr hInstance = LoadLibrary("User32");
hhook = SetWindowsHookEx(HookType.WH_CBT, hookProc, hInstance, 0);
}
public void unhook()
{
UnhookWindowsHookEx(hhook);
}
public IntPtr hookProc(int code, IntPtr wParam, IntPtr lParam)
{
if (code != (int) HCBT.CreateWnd && code != (int) HCBT.DestroyWnd)
return CallNextHookEx(IntPtr.Zero, code, wParam, lParam);
//Do whatever with the created or destroyed window.
return CallNextHookEx(IntPtr.Zero, code, wParam, lParam);
}
[DllImport("user32.dll")]
private static extern IntPtr SetWindowsHookEx(HookType code, HookProc func, IntPtr hInstance, int threadId);
[DllImport("user32.dll")]
private static extern bool UnhookWindowsHookEx(IntPtr hInstance);
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Auto)]
private static extern IntPtr LoadLibrary(string fileName);
}
}
위의 단계를 수행 한 후 Windows 양식 프로젝트를 실행하십시오. 생성 된 하나의 창, 즉 방금 실행 한 창이 발견됩니다.
에 정의 된 유형을 사용
내가 사용이 작업을 수행 할 수 있다고 생각'SetWindowsHookEx()'은'WH_CBT' 후크 타입. – cdhowie
http://msdn.microsoft.com/en-us/library/windows/desktop/dd373640%28v=vs.85%29.aspx –
방금 질문을 수정하여 지금까지 최선의 시도로 업데이트했습니다 (감사합니다. 당신 스콧). 나는 아직도 대답을 추구하고있다. – sapbucket