我正在开发自定义凭据提供程序,并且必须显示带有取消按钮的进度屏幕。我已经在某些凭证提供程序和pgina插件中看到,当凭证提供程序正在工作时,屏幕上会显示一个带有“取消”按钮的屏幕。我已经附上了它的截图。我设法使用以下代码通过“确定”按钮显示错误屏幕:
*pcpgsr = CPGSR_NO_CREDENTIAL_NOT_FINISHED;
SHStrDupW(L"Authentication Failed", ppwszOptionalStatusText);
*pcpsiOptionalStatusIcon = CPSI_ERROR;
答案 0 :(得分:1)
据我所知,您想在后台向用户“等待屏幕”展示一些内容。
您必须运行一个单独的线程来进行后台工作,并更改凭据磁贴的布局,以使可见的一个文本元素仅具有“等待...”内容,并且没有提交按钮。
一旦您的后台线程完成其工作,您可以显示“提交”按钮,并让用户继续登录。
例如,看看嵌入式Smartcard Credential Porvider
及其在插入和取出卡时的行为。
答案 1 :(得分:1)
@ js.hrt您可以将主线程作为对话框运行,而后台线程则可以运行。取消按钮将是对话框中的控件,允许将其取消。如果您需要更多信息,请告诉我,我可以提供一些详细信息,因为这是我们的方法。
@ js.hrt简要地说,您需要两个类:对话框和线程。 创建对话框时,它将创建一个线程,该线程将运行所需的线程,并显示“取消”按钮。单击它将终止您的线程。下面的一些代码。希望对您有所帮助。
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;
};
然后,为您的用户界面创建类,类似于此
#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;
};
用于对话的资源可能是这样的:
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如果您不介意发布代码,则将其运行。 无法直接评论您的留言,因为我受网站的限制 要求
答案 2 :(得分:0)
@ js.hrt根据您的请求。
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;
}; 然后,为您的UI编写类,类似于此
#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;
}; 对话框的资源可能是这样的:
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
答案 3 :(得分:0)
我假设您正在寻找IConnectableCredentialProviderCredential::Connect()
。
您需要实现IConnectableCredentialProviderCredential
接口,并将逻辑放入Connect()
函数中。按下“提交”按钮后立即调用。
Connect()
函数将为您提供IQueryContinueWithStatus
界面。在此界面中,您需要定期调用QueryContinue()
函数,以处理“取消”按钮或某些系统事件。