// Populate a list of all the child windows of a given parent
        // (Uses the Win32 API's EnumChildWindows() function)
        private static List <IntPtr> listChildWindows(IntPtr p)
        {
            List <IntPtr> lstChildWindows = new List <IntPtr>();
            GCHandle      gchChildWindows = GCHandle.Alloc(lstChildWindows);

            try
            {
                WindowsInterop.EnumChildWindows(p,
                                                new EnumerateWindowDelegate(WindowsInterop.enumWindowsCallback),
                                                GCHandle.ToIntPtr(gchChildWindows));
            }
            finally
            {
                if (gchChildWindows.IsAllocated)
                {
                    gchChildWindows.Free();
                }
            }

            return(lstChildWindows);
        }
        // Hook proceedure called by the OS when a message has been processed by the target Window
        private static Int32 WH_CALLWNDPROCRET_PROC(Int32 iCode, IntPtr pWParam, IntPtr pLParam)
        {
            if (iCode < 0)
            {
                return(CallNextHookEx(WindowsInterop._pWH_CALLWNDPROCRET, iCode, pWParam, pLParam));
            }

            CWPRETSTRUCT cwp = (CWPRETSTRUCT)
                               Marshal.PtrToStructure(pLParam, typeof(CWPRETSTRUCT));

            if (cwp.message == WM_INITDIALOG)
            {
                // A dialog was initialised, find out what sort it was via it's Caption text
                Int32         iLength = GetWindowTextLength(cwp.hwnd);
                StringBuilder sb      = new StringBuilder(iLength + 1);

                GetWindowText(cwp.hwnd, sb, sb.Capacity);
                if (StringConstants.DialogCaptionSecurityAlert.Equals(sb.ToString(),
                                                                      StringComparison.InvariantCultureIgnoreCase))
                {
                    // A "Security Alert" dialog was initialised, now need
                    //
                    // a)   To know what type it is - e.g. is it an SSL related one or a switching b/w
                    //      secure/non-secure modes etc one - and,
                    //
                    // b)   A handle to the 'Yes' button so a user-click can be simulated on it
                    //
                    Boolean blnIsSslDialog = true; // assumed true for now
                    IntPtr  pYesButtonHwnd = IntPtr.Zero;

                    // Check out further properties of the dialog
                    foreach (IntPtr pChildOfDialog in WindowsInterop.listChildWindows(cwp.hwnd))
                    {
                        // Go through all of the child controls on the dialog and see what they reveal via their text
                        iLength = GetWindowTextLength(pChildOfDialog);
                        if (iLength > 0)
                        {
                            StringBuilder sbProbe = new StringBuilder(iLength + 1);
                            GetWindowText(pChildOfDialog, sbProbe, sbProbe.Capacity);

                            if (StringConstants.DialogTextSecureToNonSecureWarning.Equals(sbProbe.ToString(),
                                                                                          StringComparison.InvariantCultureIgnoreCase) ||
                                StringConstants.DialogTextNonSecureToSecureWarning.Equals(sbProbe.ToString(),
                                                                                          StringComparison.InvariantCultureIgnoreCase))
                            {
                                // Ok, the text says something about toggling secure/non-secure or vice-versa so,
                                blnIsSslDialog = false;
                            }

                            if (StringConstants.ButtonTextYes.Equals(sbProbe.ToString(), StringComparison.InvariantCultureIgnoreCase))
                            {
                                // Hey, this one says 'Yes', so cache a pointer to it
                                pYesButtonHwnd = pChildOfDialog;

                                // NB: Could also confim it is a button we're pointing at, at this point, and
                                // not a label or something by using the Win32 API's GetClassName() function (see below for e.g.),
                                // but in this case it is already known that a button is the only thing saying 'Yes'
                                // on this particular dialog
                            }
                        }
                    }

                    // Ok, some sort of "Security Alert" dialog was initialised, fire a message
                    // to anyone who's listening i.e. In this case, ask the event receiver if
                    // they want to ignore it
                    if (SecurityAlertDialogWillBeShown != null)
                    {
                        if (SecurityAlertDialogWillBeShown(blnIsSslDialog) && pYesButtonHwnd != IntPtr.Zero)
                        {
                            // Alert the dialog's message-pump that the 'Yes' button was 'Pressed'
                            Int32 ctrlId = GetDlgCtrlID(pYesButtonHwnd);
                            SendMessage(cwp.hwnd, WM_COMMAND, new IntPtr(ctrlId), pYesButtonHwnd);

                            // Block any further processing of the WM_INITDIALOG message by anyone else
                            // This is important: by doing this, the dialog never shows up on the screen
                            return(1);
                        }
                    }
                }
                else if (sb.ToString().StartsWith(StringConstants.DialogCaptionConnectTo))
                {
                    // 'Connect to ...' style dialog shown

                    IntPtr pComboHwnd    = IntPtr.Zero;
                    IntPtr pEditHwnd     = IntPtr.Zero;
                    IntPtr pOkButtonHwnd = IntPtr.Zero;

                    foreach (IntPtr pChildOfDialog in WindowsInterop.listChildWindows(cwp.hwnd))
                    {
                        // Go through all of the child controls on the dialog and see what they reveal via their type/text
                        StringBuilder sbProbe = new StringBuilder(255);
                        if (GetClassName(pChildOfDialog, sbProbe, sbProbe.Capacity) != 0 &&
                            !String.IsNullOrEmpty(sbProbe.ToString()))
                        {
                            if (sbProbe.ToString().Equals("SysCredential"))
                            {
                                // This control is actually a set of controls called a "SysCredential"
                                // (as determined via Spy++), so cache it's child controls that are of
                                // type "ComboBoxEx32" and "Edit"
                                foreach (IntPtr pChildOfSysCredential in WindowsInterop.listChildWindows(pChildOfDialog))
                                {
                                    StringBuilder sbProbe2 = new StringBuilder(255);
                                    if (GetClassName(pChildOfSysCredential, sbProbe2, sbProbe2.Capacity) != 0 &&
                                        !String.IsNullOrEmpty(sbProbe2.ToString()))
                                    {
                                        if (StringConstants.WindowTypeCombo.Equals(sbProbe2.ToString(),
                                                                                   StringComparison.InvariantCultureIgnoreCase))
                                        {
                                            // Hey, here's the Combo
                                            pComboHwnd = pChildOfSysCredential;
                                        }

                                        if (StringConstants.WindowTypeEdit.Equals(sbProbe2.ToString(),
                                                                                  StringComparison.InvariantCultureIgnoreCase))
                                        {
                                            // Hey, here's *an* Edit box.
                                            //
                                            // This will happen several times as there is an Edit box at the bottom of
                                            // the "ComboBoxEx" heirarchy as well, but luckily the last one encountered
                                            // is actually the required one
                                            pEditHwnd = pChildOfSysCredential;
                                        }
                                    }
                                }
                            }

                            if (StringConstants.WindowTypeButton.Equals(sbProbe.ToString(),
                                                                        StringComparison.InvariantCultureIgnoreCase))
                            {
                                // This control is a Button, does it have text, if so what does it say
                                iLength = GetWindowTextLength(pChildOfDialog);
                                if (iLength > 0)
                                {
                                    StringBuilder sbText = new StringBuilder(iLength + 1);
                                    GetWindowText(pChildOfDialog, sbText, sbText.Capacity);
                                    if (StringConstants.ButtonTextOk.Equals(sbText.ToString(),
                                                                            StringComparison.InvariantCultureIgnoreCase))
                                    {
                                        // Hey, this one says 'OK', so cache a pointer to it
                                        pOkButtonHwnd = pChildOfDialog;
                                    }
                                }
                            }
                        }
                    }

                    // Ok, a "Connect to" dialog was initialiased, fire a message to anyone who's interested
                    // i.e. Ask the event receiver if they want to automate the dialog by providing
                    // a username and password with which to populate the dialog
                    if (ConnectToDialogWillBeShown != null)
                    {
                        String sUsername = null;
                        String sPassword = null;

                        if (ConnectToDialogWillBeShown(ref sUsername, ref sPassword) &&
                            sUsername != null && sPassword != null && pOkButtonHwnd != IntPtr.Zero &&
                            pComboHwnd != IntPtr.Zero && pEditHwnd != IntPtr.Zero)
                        {
                            // Yep, they do

                            // Put the username and password into the boxes
                            SetWindowText(pComboHwnd, sUsername);
                            SetWindowText(pEditHwnd, sPassword);

                            // Alert the dialog's message-pump that the 'OK' button was 'Pressed'
                            Int32 ctrlId = GetDlgCtrlID(pOkButtonHwnd);
                            SendMessage(cwp.hwnd, WM_COMMAND, new IntPtr(ctrlId), pOkButtonHwnd);

                            // Block further processing of the WM_INITDIALOG message by anyone else
                            // This is important: by doing this, the dialog never shows up on the screen
                            return(1);
                        }
                    }
                }
            }

            // Call the next hook in the chain
            return(CallNextHookEx(WindowsInterop._pWH_CALLWNDPROCRET, iCode, pWParam, pLParam));
        }