【问题标题】:Can I create a CommandLink that works the same as the submit button?我可以创建一个与提交按钮一样工作的 CommandLink 吗?
【发布时间】:2018-12-07 00:13:19
【问题描述】:

请理解我缺乏写作技巧。

我正在测试制作自定义凭据提供程序。 我想创建一个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;
             // ...
         }
     }
 }

【问题讨论】:

    标签: c++ windows credential-providers


    【解决方案1】:

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

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

    第一个参数是指向事件接口ICredentialProviderEvents的指针,它只有一个方法:CredentialsChanged。 您的任务是从用户(登录名/密码)那里获取凭据,将它们存储在您的内部结构中并调用此方法。 在下一回合,您的提供者将被调用此方法:

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

    您的任务是在pdwDefaultpbAutoLogonWithDefault 参数中返回正确的值(我的建议是0TRUE)。 比实现ICredentialProviderCredential 接口的类将立即为GetSerialization 方法调用。

    您可以在此处返回已存储的凭据。

    【讨论】:

    • 您的友好解释对我帮助很大。
    【解决方案2】:

    这里是新手,

    对于不理解@Alexander 解释的人(比如前几天的我),推荐阅读Sample Harware Event Credential Provider。您需要不是从ICredentialProviderICredentialProviderCredential 继承的第三类。这是一个独立的类,与它们都没有关系。我使用这个类来调用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的自定义类中将凭据(我使用用户名和密码)保存为变量(字符串)
    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. 调用调用ICredentialProviderCredentialsChanged函数的第三类函数
    HRESULT CGuardianCredential::CommandLinkClicked(DWORD dwFieldID)
    {
        . . . 
    
        _commandWindow->callOnChange();
    }
    

    然后在 commandWindow 的类中

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

    那么你就有了

    【讨论】:

      猜你喜欢
      • 2017-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-25
      • 2015-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多