C++ Windows Credential Provider Progress Screen

C++ Windows Credential Provider Progress Screen



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 screen is displayed with a Cancel button when credential provider is working. I have attached a screenshot of it. I have managed to show the error screen with an Ok button using the following code:


*pcpgsr = CPGSR_NO_CREDENTIAL_NOT_FINISHED;
SHStrDupW(L"Authentication Failed", ppwszOptionalStatusText);
*pcpsiOptionalStatusIcon = CPSI_ERROR;



Now I need to show this progress screen with a cancel button. Any advice how can it be achieved? Also, how to handle the event that fires when this button is pressed?This screen should be displayed when credential provider is working




3 Answers
3



As I understand your scenario you want to do something in background presenting to the user "wait screen".



You must run a separate thread for background work and change the layout of your credential tile to leave visible only one text element with "Wait..." content and no submit button.



Once your background thread complete its work you may reveal submit button and let user to continue to logon.



For example, have a look at embedded Smartcard Credential Porvider and its behaviour on insertion and removal of the card.


Smartcard Credential Porvider





Yes you understood it right. Yes I have currently implemented it like you suggested (I have hidden all other elements and just shown the text 'Please wait...'). But in this approach, there is no cancel button. Like, for example, if a background thread is running and a user wants to cancel and go back to change authentication method (assuming different authentication methods are available), how will he do that? He would have to wait for the process to complete or timeout. So I need to include a cancel button.
– js.hrt
Aug 22 at 13:35





Though, we can handle this via SetDeselected() method as well but I need to take the approach that is shown in screenshot (with a cancel button)
– js.hrt
Aug 22 at 13:35





Have to try using CPFT_COMMAND_LINK element(s).
– Alexander
Aug 22 at 13:53



CPFT_COMMAND_LINK





in my knowledge CPFT_COMMAND_LINK is a hyperlink. Can it be shown as a button?
– js.hrt
Aug 26 at 9:47





@js.hrt No, hyperlink is a link-style control (underscored text), but it is clickable!
– Alexander
Aug 26 at 20:40



@js.hrt Per your request.


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<GUI>
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 Please post your code, I'll help you.
– valeca
Sep 3 at 5:22



@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<GUI>
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





Thanks. Can you give an example of how you are showing the dialog?
– js.hrt
Aug 26 at 9:49





I am trying your code but getting a lot of errors. I am new to c++ so facing difficulties identifying the issues. Can you please tell which files to include and how to make this sample working?
– js.hrt
Sep 2 at 13:00



Thanks for contributing an answer to Stack Overflow!



But avoid



To learn more, see our tips on writing great answers.



Some of your past answers have not been well-received, and you're in danger of being blocked from answering.



Please pay close attention to the following guidance:



But avoid



To learn more, see our tips on writing great answers.



Required, but never shown



Required, but never shown






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

ャフサォクコ ケウ,コ,ワ メ,ロスョノ゙,クネ,フムカヤヲニ,エコ゚ツ ウイオン゙ケワサネォキモュキォウイノンコチ゚メヌナイゥフュ,カヒウネェ ネ,ホノケ,ムュキ ッボーミュハ,チ ツス ィ メウイマヤ,゙ウチ ヅ ロ,ォジヌェ ャヌット ェ,マャ,チナエヒネソキツテ トホヲヲミーァ

How do I collapse sections of code in Visual Studio Code for Windows?