我可以创建一个与提交按钮一样工作的 CommandLink 吗?

Can I create a CommandLink that works the same as the submit button?

文笔不足请大家谅解

我正在测试制作自定义凭证提供程序。 我想创建一个 CommandLink 与提交按钮做同样的事情。 我想通过 CommandLink 与提交按钮分开登录。 目前,只有自定义凭证提供程序通过 providerFilter::Filter(CREDENTIAL_PROVIDER_USAGE_SCENARIO cpus, DWORD dwFlags, GUID* rgclsidProviders, BOOL* rgbAllow, DWORD cProviders) 公开。 点击[anathor longon按钮]登录。

这是我的示例代码:

 HRESULT CSampleCredential::CommandLinkClicked(DWORD dwFieldID)
 {
     HRESULT hr = S_OK;
     DWORD dwResult = 0;

     if (dwFieldID < ARRAYSIZE(_rgCredProvFieldDescriptors) &&
         (CPFT_COMMAND_LINK == _rgCredProvFieldDescriptors[dwFieldID].cpft))
     {
         HWND hwndOwner = nullptr;
         switch (dwFieldID)
         {
         case SFI_ANATHOR_SUBMIT_LINK:
             dwResult = function_foo();
             if(dwResult == 1) { 
                  Call GetSerialization()...?
                  Run the logon.
             }
             break;
             // ...
         }
     }
 }

因为您正在编写凭据提供程序,所以您已经在实现 ICredentialProvider 接口及其 Advise 方法:

    virtual HRESULT STDMETHODCALLTYPE Advise( 
        /* [annotation][in] */ 
        _In_  ICredentialProviderEvents *pcpe,
        /* [annotation][in] */ 
        _In_  UINT_PTR upAdviseContext) = 0;

第一个参数是指向事件接口 ICredentialProviderEvents 的指针,它只有一个方法:CredentialsChanged。 您的任务是从用户 (login/password) 获取凭据,将其存储在您的内部并调用此方法。 在下一轮,您的提供者将调用此方法:

    virtual HRESULT STDMETHODCALLTYPE GetCredentialCount( 
        /* [annotation][out] */ 
        _Out_  DWORD *pdwCount,
        /* [annotation][out] */ 
        _Out_  DWORD *pdwDefault,
        /* [annotation][out] */ 
        _Out_  BOOL *pbAutoLogonWithDefault) = 0;

你的任务是 return pdwDefaultpbAutoLogonWithDefault 参数中的正确值(我的建议是 0TRUE)。 比你的 class 实现 ICredentialProviderCredential 接口将立即调用 GetSerialization 方法。

在这里您可以return已经存储的凭据。

这里是新手,

对于不明白@Alexander 解释的人(比如我几天前),我建议阅读Sample Harware Event Credential Provider。您需要不是从 ICredentialProviderICredentialProviderCredential 继承的第三个 class。这是一个独立的 class ,与他们两个都没有关系。我用这个 class 来调用 CredentialsChanged 函数。

所以,TL;DR 这就是我实现它的方式:

  1. ICredentialProviderGetCredentialCount 函数中创建条件,如下所示
HRESULT CSampleCredentialProvider::GetCredentialCount(
    DWORD* pdwCount,
    DWORD* pdwDefault,
    BOOL* pbAutoLogonWithDefault
)
{   
    //SavedCredentialInfo is just a simple Bool variable
    if (_pCredential->SavedCredentialInfo == true)
    {
        *pdwCount = 1;
        *pdwDefault = 0;
        *pbAutoLogonWithDefault = TRUE;
    }else{
        *pdwCount = 1;
        *pdwDefault = 0;
        *pbAutoLogonWithDefault = FALSE;
    }

    return S_OK;

}
  1. 将凭据(我使用用户名和密码)保存为继承 ICredentialProviderCredential
  2. 的自定义 class 中的变量(字符串)
HRESULT CGuardianCredential::CommandLinkClicked(DWORD dwFieldID)
{
    if (dwFieldID < ARRAYSIZE(_rgCredProvFieldDescriptors) &&
        (CPFT_COMMAND_LINK == _rgCredProvFieldDescriptors[dwFieldID].cpft)) {
       
        this._username = "Ramon";
        this._domain = "DESKTOP-937SDJ";
        this._password = "MyPassword";
    }

    . . .
}
  1. 调用第 3 个 class 函数调用 ICredentialProviderCredentialsChanged 函数
HRESULT CGuardianCredential::CommandLinkClicked(DWORD dwFieldID)
{
    . . . 

    _commandWindow->callOnChange();
}

然后在commandWindow的class

里面
BOOL CCommandWindow::callOnChange()
{
    _pProvider->OnConnectStatusChanged();
    return true;
}

那你就有了