SigningProgress.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / TrustUi / MS / Internal / documents / SigningProgress.cs / 1 / SigningProgress.cs

                            //---------------------------------------------------------------------------- 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// 
// Description: 
//    ProgressDialog invokes a progress notification dialog that runs on
//    its own thread, with its own message pump.  It is used to notify 
//    users when a long, blocking operation on XPSViewer's main thread is
//    running (and blocking).
//
// History: 
// 05/20/05 - [....] created
// 02/13/06 - [....] updated 
// 
//---------------------------------------------------------------------------
using System; 
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Security; 
using System.Security.Permissions; // For Friend Access and elevations
using System.Threading; 
using System.Windows.Forms; 
using System.Windows.TrustUI;
using MS.Internal.Documents.Application; 

namespace MS.Internal.Documents
{
    internal sealed partial class ProgressDialog : DialogBaseForm 
    {
        #region Constructors 
        //----------------------------------------------------- 
        //
        //  Constructors 
        //
        //-----------------------------------------------------

        ///  
        /// Private Constructor
        ///  
        /// Critical - We want to ensure that no instances of this object 
        ///            are created on the main UI thread; see comments on
        ///            CloseThreadedImpl() for more information. 
        /// 
        /// 
        [SecurityCritical]
        private ProgressDialog(string title, string message) 
        {
            _label.Text = message; 
            Text = title; 
        }
 
        #endregion Constructors

        #region Internal Methods
 
        /// 
        /// Creates an instance of the ProgressDialog in a new thread, returning a 
        /// ProgressDialogReference wrapper which will eventually contain a valid 
        /// reference to the dialog (when the dialog is actually instantiated.)
        ///  
        /// The title to appear in the Titlebar of the dialog
        /// The message to appear in the dialog
        /// 
        public static ProgressDialogReference CreateThreaded(string title, string message) 
        {
            ProgressDialogReference reference = 
                new ProgressDialogReference(title, message); 

            // Spin up a new thread 
            Thread dialogThread = new Thread(
                new ParameterizedThreadStart(ProgressDialogThreadProc));

            // Start it, passing in our reference 
            dialogThread.Start(reference);
 
            // Return the reference -- the Form inside will eventually point to 
            // the dialog created in ProgressDialogThreadProc.
            return reference; 
        }

        /// 
        /// Closes an instance of a ProgressDialog on its thread. 
        /// 
        ///  
        ///  
        public static void CloseThreaded(ProgressDialog dialog)
        { 
            dialog.Invoke(new MethodInvoker(dialog.CloseThreadedImpl));
        }

        #endregion Internal Methods 

        #region Private Methods 
 
        /// 
        /// Creates a new ProgressDialog on its own thread, with its own 
        /// message pump.
        /// 
        /// Critical - Asserts for permissions to create a top-level dialog
        /// 
        /// TreatAsSafe - The window is a safe (WinForms) dialog which exposes no
        ///               critical information. 
        ///  
        /// 
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        private static void ProgressDialogThreadProc(object state)
        {
            ProgressDialogReference reference = state as ProgressDialogReference; 
            Invariant.Assert(reference != null);
 
            (new UIPermission(UIPermissionWindow.AllWindows)).Assert(); //Blessed 
            try
            { 
                reference.Form = new ProgressDialog(reference.Title, reference.Message);
            }
            finally
            { 
                UIPermission.RevertAssert();
            } 
 
            //Spawn a new message pump for this dialog
            System.Windows.Forms.Application.Run(); 
        }

        /// 
        /// Invokes the ProgressDialog (calls ShowDialog on it) when the Timer is elapsed. 
        /// We do this so that the dialog only appears after the blocking operation
        /// we're showing status for takes a certain amount of time.  (Prevents UI flicker 
        /// in cases where the action doesn't take very long) 
        /// 
        /// Critical - Shows a top-level dialog 
        ///
        /// TreatAsSafe - The window is a safe (WinForms) dialog which exposes no
        ///               critical information.
        ///  
        /// 
        ///  
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        private void OnTimerTick(object sender, EventArgs e) 
        {
            // Disable the timer so this will only occur once
            _timer.Enabled = false;
            ShowDialog(null); 
        }
 
        ///  
        /// Closes the dialog on its own thread.
        ///  
        ///   Critical - Asserts for UnmanagedCode permissions in order to shut down
        ///              the dialog's message pump and thread.
        ///   TreatAsSafe - Uses the permissions to invoke ExitThread on the dialog
        ///                 to cause it to close.  Since ProgressDialogs can only be 
        ///                 instantiated on their own thread using CreateThreaded()
        ///                 (constructor is private and critical), ExitThread can only 
        ///                 affect the ProgressDialog instance if abused, and not other 
        ///                 threads (which could be catastrophic.)
        ///  
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        private void CloseThreadedImpl()
        { 
            (new SecurityPermission(SecurityPermissionFlag.UnmanagedCode)).Assert(); //Blessed
            try 
            { 
                System.Windows.Forms.Application.ExitThread();
            } 
            finally
            {
                SecurityPermission.RevertAssert();
            } 
        }
 
        #endregion Private Methods 

        ///  
        /// ProgressDialogReference exists to allow passing a reference to a ProgressDialog
        /// created on a new thread back to the main UI thread, and to ensure that the main
        /// thread blocks until the ProgressDialog is ready before using it.
        /// 
        /// This is a mitigation for an unfortunate design limitation because we have to block
        /// on a UI thread and show a dialog on a non-blocking thread, instead of the other 
        /// way around. 
        /// 
        internal class ProgressDialogReference 
        {

            /// 
            /// Constructor 
            /// 
            ///  
            ///  
            public ProgressDialogReference(string title, string message)
            { 
                _title = title;
                _message = message;
                _isReady = new ManualResetEvent(false);
            } 

            ///  
            /// The title of the dialog being shown 
            /// 
            public String Title 
            {
                get { return _title; }
            }
 
            /// 
            /// The message in the dialog being shown 
            ///  
            public String Message
            { 
                get { return _message; }
            }

            public ProgressDialog Form 
            {
                get 
                { 
                    // Wait until the form has been set and instantiated...
                    _isReady.WaitOne(); 
                    return _form;
                }

                set 
                {
                    _form = value; 
                    // Our form is running on a separate thread, setup an event handler 
                    // so that we're notified when it is loaded.
                    _form.Load += new EventHandler(FormLoaded); 
                }
            }

            ///  
            /// Handler for the form.Loaded event used to set the ready state.
            ///  
            ///  
            /// 
            private void FormLoaded(object sender, EventArgs e) 
            {
                // Since the form has successfully loaded then update the ready state.
                _isReady.Set();
            } 

            private ManualResetEvent _isReady; 
            private ProgressDialog _form; 

            private string _title; 
            private string _message;
        }

 
        //The amount to wait (in msec) before actually invoking the dialog.
        private const int _timerInterval = 500; 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK