Example #1
0
        internal void NativeShow()
        {
            // Applies config struct and other settings, then
            // calls main Win32 function
            if (settings == null)
            {
                throw new InvalidOperationException("An error has occurred in dialog configuration.");
            }

            // Do a last-minute parse of the various dialog control lists, only
            // allocate the memory at the last minute
            MarshalDialogControlStructs(settings);

            // Make the call and show the dialog.
            // NOTE: this call is BLOCKING, though the thread WILL re-enter via the DialogProc
            try
            {
                showState = NativeDialogShowState.Showing;

                // Here is the way we would use "vanilla" PInvoke to call TaskDialogIndirect;
                // but if we did so here, we'd be at the mercy of the CLR's native DLL cache -
                // see below for more details.
                // HRESULT hresult = UnsafeNativeMethods.TaskDialogIndirect(
                //    nativeDialogConfig,
                //    out selectedButtonID,
                //    out selectedRadioButtonID,
                //    out checkBoxChecked);

                // Instead, we load comctl and bind to TaskDialogIndirect
                // We do it this way so we can rigidly control which version of comctl32
                // we get loaded, as the CLR's PInvoke mechanism maintains a DLL cache that is
                // NOT invalidated when the OS activation context is changed such that different
                // DLL versions are needed
                // TEST: Try to get the activation context goo working
                //DllVersionManager.CreateCorrectActivationContext();

                // TEST: Currently no worky, as the activation context isn't getting pushed properly
                IntPtr tdi = DllVersionManager.GetNativeFunctionPointer(
                    ExternDll.ComCtl32, "TaskDialogIndirect");

                // TEST: temporarily using the full path to v6 comctl32
                //IntPtr tdi = DllVersionManager.GetFunctionPointer(
                //    ExternDll.FullPathComCtl32, "TaskDialogIndirect");
                //DllVersionManager.ResetActivationContext();
                SafeNativeMethods.TDIDelegate taskDialogFunctionPointer = (SafeNativeMethods.TDIDelegate)
                                                                          Marshal.GetDelegateForFunctionPointer(tdi, typeof(SafeNativeMethods.TDIDelegate));

                // Invoke TaskDialogIndirect!
                HRESULT hresult = taskDialogFunctionPointer(
                    nativeDialogConfig,
                    out selectedButtonID,
                    out selectedRadioButtonID,
                    out checkBoxChecked);
                if (ErrorHelper.Failed(hresult))
                {
                    string msg;
                    switch (hresult)
                    {
                    case HRESULT.E_INVALIDARG:
                        msg = "Invalid arguments to Win32 call";
                        break;

                    case HRESULT.E_OUTOFMEMORY:
                        msg = "Dialog contents too complex";
                        break;

                    default:
                        msg = "An unexpected internal error occurred in the Win32 call: " + hresult;
                        break;
                    }
                    throw new Win32Exception(msg);
                }
            }
            finally
            {
                showState = NativeDialogShowState.Closed;
            }
        }
Example #2
0
        internal void NativeShow()
        {
            // Applies config struct and other settings, then
            // calls main Win32 function.
            if (settings == null)
            {
                throw new InvalidOperationException(
                          "An error has occurred in dialog configuration.");
            }

            // Do a last-minute parse of the various dialog control lists,
            // and only allocate the memory at the last minute.

            MarshalDialogControlStructs();
            // Make the call and show the dialog.
            // NOTE: this call is BLOCKING, though the thread
            // WILL re-enter via the DialogProc.
            try
            {
                showState = NativeDialogShowState.Showing;

                // Here is the way we would use "vanilla" PInvoke to call TaskDialogIndirect;
                // but if we did so here, we'd be at the mercy of the CLR's native DLL cache -
                // see below for more details.
                // HRESULT hresult = NativeMethods.TaskDialogIndirect(
                //    nativeDialogConfig,
                //    out selectedButtonID,
                //    out selectedRadioButtonID,
                //    out checkBoxChecked);

                // Instead, we load comctl and bind to TaskDialogIndirect
                // We do it this way so we can rigidly control
                // which version of comctl32 is loaded,
                // The CLR's PInvoke mechanism maintains a DLL cache that is
                // NOT invalidated when the OS activation context is changed
                // such that different DLL versions are needed.


                IntPtr tdi = DllVersionManager.GetNativeFunctionPointer(
                    ExternDll.ComCtl32, "TaskDialogIndirect");

                NativeMethods.TDIDelegate taskDialogFunctionPointer =
                    (NativeMethods.TDIDelegate)
                    Marshal.GetDelegateForFunctionPointer(
                        tdi,
                        typeof(NativeMethods.TDIDelegate)
                        );

                // Invoke TaskDialogIndirect.
                HRESULT hresult = taskDialogFunctionPointer(
                    nativeDialogConfig,
                    out selectedButtonID,
                    out selectedRadioButtonID,
                    out checkBoxChecked);
                if (ErrorHelper.Failed(hresult))
                {
                    string msg;
                    switch (hresult)
                    {
                    case HRESULT.E_INVALIDARG:
                        msg = "Invalid arguments to Win32 call.";
                        break;

                    case HRESULT.E_OUTOFMEMORY:
                        msg = "Dialog contents too complex.";
                        break;

                    default:
                        msg = String.Format(

                            "An unexpected internal error occurred in the Win32 call:{0:x}",
                            hresult);
                        break;
                    }
                    Exception e = Marshal.GetExceptionForHR((int)hresult);
                    throw new Win32Exception(msg, e);
                }
            }
            finally
            {
                showState = NativeDialogShowState.Closed;
            }
        }