Esempio n. 1
0
        /// <summary>
        /// The CallbackProc. Called by the shell to inform of key property page events.
        /// </summary>
        /// <param name="hWnd">The h WND.</param>
        /// <param name="uMsg">The u MSG.</param>
        /// <param name="ppsp">The PPSP.</param>
        /// <returns></returns>
        private uint CallbackProc(IntPtr hWnd, PSPCB uMsg, ref PROPSHEETPAGE ppsp)
        {
            switch (uMsg)
            {
            case PSPCB.PSPCB_ADDREF:

                //  Increment the reference count.
                referenceCount++;

                break;

            case PSPCB.PSPCB_RELEASE:

                //  Decrement the reference count.
                referenceCount--;

                //  If we're down to zero references, cleanup.
                if (referenceCount == 0)
                {
                    Cleanup();
                }

                break;

            case PSPCB.PSPCB_CREATE:

                //  Allow the sheet to be created.
                return(1);
            }
            return(0);
        }
        /// <summary>
        /// The CallbackProc. Called by the shell to inform of key property page events.
        /// </summary>
        /// <param name="hWnd">The h WND.</param>
        /// <param name="uMsg">The u MSG.</param>
        /// <param name="ppsp">The PPSP.</param>
        /// <returns></returns>
        private uint CallbackProc(IntPtr hWnd, PSPCB uMsg, ref PROPSHEETPAGE ppsp)
        {
            switch (uMsg)
            {
            case PSPCB.PSPCB_ADDREF:

                break;

            case PSPCB.PSPCB_RELEASE:

                break;

            case PSPCB.PSPCB_CREATE:

                //  Allow the sheet to be created.
                return(1);
            }
            return(0);
        }
Esempio n. 3
0
        /// <summary>
        /// The CallbackProc. Called by the shell to inform of key property page events.
        /// </summary>
        /// <param name="hWnd">The h WND.</param>
        /// <param name="uMsg">The u MSG.</param>
        /// <param name="ppsp">The PPSP.</param>
        /// <returns></returns>
        private uint CallbackProc(IntPtr hWnd, PSPCB uMsg, ref PROPSHEETPAGE ppsp)
        {
            //  Important: The docs at: https://docs.microsoft.com/en-us/windows/desktop/shell/how-to-register-and-implement-a-property-sheet-handler-for-a-file-type
            //  Imply we *must* set PSP_USEPARENTREF and give access to the parent reference count, to avoid the server being
            //  unloaded while the property sheet is still visible. It is damn near impossible to do this as
            //  the IUnknown of the IShellPropSheetExt is managed by the runtime. Instead, when the internal
            //  reference count increases, we will manually increment the COM server ref count, then release
            //  it when our property sheet tells us we are done. This *appears* to have resolved the lifetime
            //  issues. The theory is that we are using the lifecycle hooks below to manage our IShellPropSheetExt
            //  server ref count and ensure that the shell will not unload it while the property sheet is in use.

            switch (uMsg)
            {
            case PSPCB.PSPCB_ADDREF:
            {
                //  Increment the internal reference count.
                Log($"Add Internal Ref {referenceCount} -> {referenceCount + 1}");
                referenceCount++;

                //  At this point, increment the IPropSheetShellExt interface reference count, so that the
                //  shell doesn't try and release the server before we are done.
                var pUnk     = Marshal.GetIUnknownForObject(Parent); // i.e. IShellPropSheetExt
                var newCount = Marshal.AddRef(pUnk);
                Log($"IShellPropSheetExt: Add Ref {newCount - 1} -> {newCount}");

                break;
            }

            case PSPCB.PSPCB_RELEASE:
            {
                Log($"Release Internal Ref {referenceCount} -> {referenceCount - 1}");

                //  Decrement the internal reference count.
                referenceCount--;

                //  If we're down to zero references, cleanup.
                if (referenceCount == 0)
                {
                    //  The Target is a child of the host window handle, and that is child of the sheet.
                    //  So these windows will be destroyed as part of the normal lifecycle. It's important
                    //  we *don't* destroy them here or they could be destroyed twice. This is the place
                    //  however to free up other resources which might be used by the page.
                    try
                    {
                        Target?.OnRelease();
                    }
                    catch (Exception exception)
                    {
                        LogError("An exception occured releasing the property page", exception);
                    }
                }

                //  Balance out the AddRef all from PSPCB_ADDREF by releasing now.
                var pUnk     = Marshal.GetIUnknownForObject(Parent); // i.e. IShellPropSheetExt
                var newCount = Marshal.Release(pUnk);
                Log($"IShellPropSheetExt: Release {newCount + 1} -> {newCount}");

                break;
            }

            case PSPCB.PSPCB_CREATE:

                Log($"Create Callback");

                //  Allow the sheet to be created.
                return(1);
            }
            return(0);
        }
Esempio n. 4
0
        /// <summary>
        /// The CallbackProc. Called by the shell to inform of key property page events.
        /// </summary>
        /// <param name="hWnd">The h WND.</param>
        /// <param name="uMsg">The u MSG.</param>
        /// <param name="ppsp">The PPSP.</param>
        /// <returns></returns>
        private uint CallbackProc(IntPtr hWnd, PSPCB uMsg, ref PROPSHEETPAGE ppsp)
        {
            switch (uMsg)
            {
                case PSPCB.PSPCB_ADDREF:

                    //  Increment the reference count.
                    referenceCount++;

                    break;

                case PSPCB.PSPCB_RELEASE:

                    //  Decrement the reference count.
                    referenceCount--;

                    //  If we're down to zero references, cleanup.
                    if (referenceCount == 0)
                        Cleanup();

                    break;

                case PSPCB.PSPCB_CREATE:

                    //  Allow the sheet to be created.
                    return 1;
            }
            return 0;
        }
        /// <summary>
        /// The CallbackProc. Called by the shell to inform of key property page events.
        /// </summary>
        /// <param name="hWnd">The h WND.</param>
        /// <param name="uMsg">The u MSG.</param>
        /// <param name="ppsp">The PPSP.</param>
        /// <returns></returns>
        private uint CallbackProc(IntPtr hWnd, PSPCB uMsg, ref PROPSHEETPAGE ppsp)
        {
            switch (uMsg)
            {
                case PSPCB.PSPCB_ADDREF:

                    break;

                case PSPCB.PSPCB_RELEASE:

                    break;

                case PSPCB.PSPCB_CREATE:

                    //  Allow the sheet to be created.
                    return 1;
            }
            return 0;
        }