如何从第三方DLL监听表单的“ Form.Shown”和“ Window.Closing”?

时间:2019-06-10 16:58:59

标签: c# winforms events

我的C#应用​​程序调用第3方DLL。此DLL可能会或可能不会显示窗口(窗体)。我希望在显示该窗口时注册一个回调/通知/事件,并在关闭窗口时(通过X或“关闭”按钮)注册一个回调/通知/事件。如果我能说出引起该操作的按钮的名称,则是有好处的(即:如果他们按下“关闭”或“ X”,而他们按下“购买”,我会做些不同的事情)

我无权访问此DLL的源代码,并且标头未指定格式。

我什至需要吗?

如果您想知道,它是为PaddleSDK

2 个答案:

答案 0 :(得分:0)

使用 SetWinEventHook

互联网上 种愚蠢的方式 来做到这一点,但这是正确的方式。轮询不好(是吗?)。

如果您在StackOverflow上搜索 SetWinEventHook 并查找c#命中,则会发现很多示例可供使用。

答案 1 :(得分:0)

好吧,这似乎可行:(感谢大家的提示!)

    private int[]           i_checkoutWindID;

    private void    RegisterEventListener()
    {
        Automation.AddAutomationEventHandler(
            WindowPattern.WindowOpenedEvent,
            AutomationElement.RootElement,
            TreeScope.Children,
            (sender, e) => 
        {
            AutomationElement       element = sender as AutomationElement;
            string                  automationID = element.Current.AutomationId;

            if (automationID != kLicenseWindowAutomationID) return;

            i_checkoutWindID = element.GetRuntimeId();

            AutomationElement licenseButton = element.FindFirst(
                TreeScope.Descendants,
                new PropertyCondition(AutomationElement.AutomationIdProperty, kLicenseButtonAutomationID));

            if (licenseButton != null) {
                IntPtr      hwnd = new IntPtr(licenseButton.Current.NativeWindowHandle);
                Control     buttonRef = Control.FromHandle(hwnd);

                HideButton_Safe(buttonRef);
            }
        });

        Automation.AddAutomationEventHandler(
            WindowPattern.WindowClosedEvent,
            AutomationElement.RootElement,
            TreeScope.Subtree,
            (sender, e) => 
        {
            WindowClosedEventArgs       args = e as WindowClosedEventArgs;

            if (Automation.Compare(args.GetRuntimeId(), i_checkoutWindID)) {
                Array.Clear(i_checkoutWindID, 0, i_checkoutWindID.Length);
                <do your "window closed" callback here>;
            }
        });
    }

    private void HideButton_Safe(Control buttonRef)
    {
        if (buttonRef.InvokeRequired) {
            var d = new SafeCallDelegate_ButtonHide(HideButton_Safe);
            buttonRef.Invoke(d, new object[] { buttonRef });
        } else {
            buttonRef.Hide();
        }
    }