Handle IntPtr for Main WPF window is zero

Viewed 967

I have recently been trying to develop a simple WPF application in C#, and I need to be able to get the HwndSource of a window so I can add an event handler. Everytime I run the code, I get stopped on handleSource = HwndSource.FromHwnd(handle); and I get the error System.ArgumentException: 'Hwnd of zero is not valid.'. From my understanding, this happens when the window is not fully initialized or there is no window, or it is being destructed. If I have learned correctly, than I have no idea how this is happening.
I have not found anyone else with the same problem from googling, and my code is below.

public partial class MainWindow:Window {

        SimConnect simConnect;
        bool connectedToSim = false;

        /// Window handle
        IntPtr handle;
        HwndSource handleSource;

        const int WM_USER_SIMCONNECT = 0x0402;

        /// <summary>
        /// Constructor and starting for the window
        /// </summary>
        public MainWindow() {
            InitializeComponent();

            handle = new WindowInteropHelper(this).Handle; // Get handle of main WPF Window
            handleSource = HwndSource.FromHwnd(handle); // Get source of handle in order to add event handlers to it
            handleSource.AddHook(HandleSimConnectEvents);

            Thread pollThread = new Thread(PollThread);
        }

        ~MainWindow() {
            if (handleSource != null) {
                handleSource.RemoveHook(HandleSimConnectEvents);
            }
        }

        private IntPtr HandleSimConnectEvents(IntPtr hWnd, int message, IntPtr wParam, IntPtr lParam, ref bool isHandled) {
            isHandled = false;

            switch (message) {
                case WM_USER_SIMCONNECT: {
                        if (simConnect != null) {
                            simConnect.ReceiveMessage();
                            isHandled = true;
                        }
                    }
                    break;

                default:
                    break;
            }

            return IntPtr.Zero;
        }
    }

Any help would be appreciated, Thanks!

2 Answers

You will likely want to make use of EnsureHandle at that point in the window lifecycle (i.e. construction). The call is light and you won't need to wait for the form to show and have a dependency on an event to get access to the handle (if that suits your workflow)

WindowInteropHelper.EnsureHandle Method

Creates the HWND of the window if the HWND has not been created yet.

Remarks

Use the EnsureHandle method when you want to separate window handle (HWND) creation from the actual showing of the managed Window...

If the native window has not yet been created, this method creates the native window, sets the Handle property, and returns the HWND. If the native window has been created already, the handle of the existing native window is returned.

Move the code from the constructor of the class to the first invocation of the Shown event as explained in this question: Window shown event in WPF?

The window handle is guaranteed to be there once the window is shown. And you usually don't want to enforce the window handle to be created as early as in the constructor as suggested by Michael Randall's suggestion to use EnsureHandle.

Related