當一個不同的C#應用程序(表單)即將關閉時,我想在我的C#應用程序中收到一個事件。C#訂閱FormClosing
我該如何做到這一點?這可以用Reflections完成嗎?
編輯:詳細說明
我意識到我原來的問題是不是很具體。 我會嘗試更詳細地描述我的目標。
所以我有3個應用程序。讓我們將它們命名爲容器,Placer和ToPlace。 我發展Contaner和砂礦在C#中,普萊瑟是一個DLL,而集裝箱是一個WinForm。我無法訪問ToPlace的源代碼。在容器我有一個自定義控件,我把它放在主窗口ToPlace與SetParent從Placer調用。目標是在關閉應用程序之前恢復父窗口,或者過濾掉髮送到主窗口的WM_DESTROY消息(或其他消息)。最終的目標不是破壞ToPlace的主窗口,當Container退出。
我試圖覆蓋Container中的自定義控件的WndProc,但不會通過父窗口發送到子窗口的消息。
我也嘗試在Container應用程序上安裝消息過濾器,但這也不是成功的。
我在寫這個問題之前的最後一次嘗試是SetWindowsHookEx,但是在成功安裝了鉤子之後,鉤子程序從不會被調用。也許是因爲我在某處讀過,鉤子函數必須位於win32 dll中,而不是託管函數中。接下來的嘗試將是使用SetWinEventHook,我讀過關於它更容易從C#中獲得它的工作。
我和SetWindowsHookEx嘗試的代碼如下,也許有人是誰在C#互操作更有經驗,看到一個錯誤,可以得到它的工作:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace AppMonitor
{
public class AppMonitor
{
private const int WH_GETMESSAGE = 3;
private const int HC_ACTION = 0;
private const int PM_NOREMOVE = 0x0000;
private const int PM_REMOVE = 0x0001;
private const int WM_QUIT = 0x0012;
[DllImport("user32.dll")]
private static extern int SetWindowsHookEx(int idHook, GetMsgProcDelegate lpfn, int hMod, int dwThreadId);
[DllImport("user32.dll")]
private static extern bool UnhookWindowsHookEx(int hhk);
[DllImport("user32.dll")]
private unsafe static extern int CallNextHookEx(int hhk, int nCode, int wParam, void* lParam);
[DllImport("user32.dll")]
private static extern int GetWindowThreadProcessId(int hWnd, out int lpdwProcessId);
[DllImport("kernel32.dll")]
private static extern int GetLastError();
private struct Msg {
public int hwnd;
public int message;
public int wParam;
public int lParam;
public int time;
public int pt;
};
[DllImport("kernel32.dll")]
public static extern int LoadLibrary(string dllToLoad);
public AppMonitor()
{
}
private int hHook;
private int hMod;
public event EventHandler AppClosing;
private unsafe delegate int GetMsgProcDelegate(int code, int wParam, void* lParam);
private unsafe GetMsgProcDelegate m_dlgt;
private unsafe int GetMsgProc(int code, int wParam, void* lParam)
{
if (code != HC_ACTION || wParam != PM_REMOVE)
return CallNextHookEx(this.hHook, code, wParam, lParam);
Msg* msg = (Msg*)lParam;
//if (msg.message == WM_QUIT)
// OnAppClosing(new EventArgs());
return CallNextHookEx(this.hHook, code, wParam, lParam);
}
protected virtual void OnAppClosing(EventArgs e)
{
EventHandler h = AppClosing;
if (h != null)
{
h(this, e);
}
}
public unsafe bool setHook(int hWnd)
{
hMod = LoadLibrary("AppMonitor.dll"); //this dll
int procId = 0;
int threadId = GetWindowThreadProcessId(hWnd, out procId);
if (threadId == 0)
throw new System.Exception("Invalid thread Id");
m_dlgt = GetMsgProc;
this.hHook = SetWindowsHookEx(WH_GETMESSAGE, m_dlgt, hMod, threadId);
if (this.hHook == 0)
throw new System.Exception("Hook not successfull! Error code: " + GetLastError());
return this.hHook != 0;
}
public bool unSetHook()
{
bool result = false;
if (hHook != 0)
result = UnhookWindowsHookEx(hHook);
return result;
}
}
}
在同一臺計算機上的進程? – jglouie
使用[消息鉤子](http://stackoverflow.com/questions/9665579/setting-up-hook-on-windows-messages)並查找WM_CLOSE消息,或設置一個計時器來輪詢其他窗口是否處理離開舉辦活動。 –
是的,這些進程在同一臺機器上。 – kozolika