C++ Windows Credential Provider Progress Screen

后端 未结 4 1810
误落风尘
误落风尘 2021-01-15 09:03

I am developing a custom credential provider and I have to show a progress screen with a cancel button. I have seen in some credentials providers and pgina plugins that a sc

4条回答
  •  悲哀的现实
    2021-01-15 09:43

    @js.hrt You can run your main thread as dialog, while your background thread does the job. The cancel button would be the control in the dialog, allowing to cancel it. If you need more info, let me know, I can provide some details, as this is the way we do it.

    @js.hrt Briefly, you need two classes: dialog and thread. When you create a dialog, it will create a thread, which will run what you need, and show cancel button. Clicking on it will terminate your thread. Some code below. Hope it helps.

    class Thread  {
        public:
            Thread(GUI* object);
            virtual ~Thread();
            bool start( bool )   {
            ::CreateThread( NULL, 0, threadRun, lpParameter, dwCreationFlags, 
                 &m_dwThreadId );
            }
            static DWORD WINAPI threadRun( void* lpVoid )   {
                DWORD dwReturn( 0 );
                dwReturn = m_object->yourProcessToRun();
                return dwReturn;
             }
        protected:
            GUI* m_object;
            Runnable* m_lpRunnable;
    };
    

    Then, class for your UI, similar to this

    #include "atlwin.h"
    
    class GUI: public CDialogImpl  {
       public:
          enum { IDD = IDD_FOR_YOUR_DIALOG  };
          GUI();
         ~GUI();
          BEGIN_MSG_MAP(GUI)
              MESSAGE_HANDLER(WM_INITDIALOG,OnInitDialog)
              COMMAND_ID_HANDLER(ID_CANCEL,OnCancel)
              MESSAGE_HANDLER(WM_TIMER,OnTimer)
              MESSAGE_HANDLER(WM_DESTROY,OnDestroy)
          END_MSG_MAP()
          LRESULT OnInitDialog(UINT,WPARAM,LPARAM, BOOL&) {
              myThread = new Thread(this);
              m_nTimerID = SetTimer(1,3000,NULL);
              myThread->start();
          }
          LRESULT OnCancel(WORD,WORD,HWND,BOOL& )  {
              if(NULL != myThread)  {
                 DWORD exitCode = 0;
                 myThread->getExitCode(exitCode);
                 if(exitCode == STILL_ACTIVE)
                     myThread->terminate();
                 delete myThread;
                  myThread = NULL;
               }
               EndDialog(IDCANCEL);
               return true;
          }        
          LRESULT OnTimer(UINT,WPARAM wParam,LPARAM,BOOL&)  {
              if(wParam != m_nTimerID)
                  return FALSE;
              m_timerticks++;
              return FALSE;
          }
          LRESULT OnDestroy(UINT,WPARAM,LPARAM,BOOL&)  {
              KillTimer(m_nTimerID);
              return FALSE;
          }
          virtual int yourProcessToRun() {};
          void onFinishProgress(int retCode = IDOK) {
              if (retCode != IDCANCEL)  {
                  delete myThread;
                  myThread = NULL;
                  KillTimer(m_nTimerID);
                  EndDialog(retCode);
               }
           }
    
          private:
              Thread* myThread;
               UINT    m_nTimerID;
               UINT    m_timerticks;
     };
    

    The resource for dialog could be like this:

    IDD_FOR_YOUR_DIALOG DIALOGEX 0, 0, 309, 80
           STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP 
           | WS_CAPTION
    CAPTION "Whatever"
    FONT 8, "MS Shell Dlg", 400, 0, 0x0
    BEGIN
        PUSHBUTTON      "Cancel",ID_CANCEL,113,50,84,14
        CTEXT           "Static",IDC_FOR_SOMETHING,7,7,295,20
    END
    

    @js.hrt If you don't mind to post your code, I'll make it run. Can't comment to your's message directly, as I limit by site requirements

提交回复
热议问题