Win32: IProgressDialog will not disappear until you mouse over it

拥有回忆 提交于 2019-12-04 15:01:51

To really hide the dialog, I've added the following to my C++ wrapper class:

void CProgressDlg::Stop()
{
    if ((m_isVisible)&&(m_bValid))
    {
        HWND hDlgWnd = NULL;
        //Sometimes the progress dialog sticks around after stopping it,
        //until the mouse pointer is moved over it or some other triggers.
        //This process finds the hwnd of the progress dialog and hides it
        //immediately.
        IOleWindow *pOleWindow;
        HRESULT hr=m_pIDlg->QueryInterface(IID_IOleWindow,(LPVOID *)&pOleWindow);
        if(SUCCEEDED(hr))
        {
            hr=pOleWindow->GetWindow(&hDlgWnd);
            if(FAILED(hr))
            {
                hDlgWnd = NULL;
            }
            pOleWindow->Release();
        }
        m_pIDlg->StopProgressDialog();
        if (hDlgWnd)
            ShowWindow(hDlgWnd, SW_HIDE);

        m_isVisible = false;
        m_pIDlg->Release();
        m_bValid = false;
    }
}

This is in C++, but you should be able to adapt this to C# without much problems.

Check the return value of the StopProgressDialog Method, maybe that will give you more information about what is going on:

HRESULT StopProgressDialog(VOID);

Returns S_OK if successful, or an error value otherwise.

The full P/Invoke signature is available, but here's the condensed version for easy reading:

[ComImport]
[Guid("EBBC7C04-315E-11d2-B62F-006097DF5BD4")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IProgressDialog
{
    void StartProgressDialog(IntPtr hwndParent,
    [MarshalAs(UnmanagedType.IUnknown)]    object punkEnableModless, //IUnknown
        PROGDLG dwFlags,  //DWORD
        IntPtr pvResevered //LPCVOID
        );
    void StopProgressDialog();
    void SetTitle(
        [MarshalAs(UnmanagedType.LPWStr)] string pwzTitle //LPCWSTR
        );
    void SetAnimation(
        IntPtr hInstAnimation, //HINSTANCE
        ushort idAnimation //UINT
        );
    [PreserveSig]
    [return: MarshalAs(UnmanagedType.Bool)]
    bool HasUserCancelled();
    void SetProgress(
        uint dwCompleted, //DWORD
        uint dwTotal //DWORD
        );
    void SetProgress64(
        ulong ullCompleted, //ULONGLONG
        ulong ullTotal //ULONGLONG
        );
    void SetLine(
        uint dwLineNum, //DWORD
        [MarshalAs(UnmanagedType.LPWStr)] string pwzString, //LPCWSTR
        [MarshalAs(UnmanagedType.VariantBool)] bool fCompactPath, //BOOL
        IntPtr pvResevered //LPCVOID
        );
    void SetCancelMsg(
        [MarshalAs(UnmanagedType.LPWStr)] string pwzCancelMsg,
        object pvResevered
        );
    void Timer(PDTIMER dwTimerAction, object pvResevered);
}

Note: That almost all of the methods follow proper COM rules for their signatures. Except HasUserCancelled. It is does not follow the rules for the signature of a method in a COM class. All methods are supposed to return an HRESULT, and return values are supposed to be in an out retval paramater. HasUserCancelled actually returns a Boolean value.

Note: That almost all these worlds are yours. Except Europa. Attempt no landing there.

Note: That almost all your base are belong to us. Except WhatYouSay. Main light turn on.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!