C++ 凭证提供者';SetComboBoxSelectedValue';不使用附加字段调用

C++ 凭证提供者';SetComboBoxSelectedValue';不使用附加字段调用,c++,winapi,combobox,credential-providers,C++,Winapi,Combobox,Credential Providers,我正在从VistaCredentialProviderSamples运行SampleWrapExistingCredentialProvider,在CSampleCredential.cpp文件中有一个名为“SetComboxSelectedValue”的函数。当用户更改组合框中的选定项并存储选定项索引时,将调用此函数。但是,当我在运行时使用AppendFieldComboBoxItem函数在组合框中追加项时,如果选择了追加项,则不调用此函数。因此,我无法获取附加字段的选定项索引 我试图显示一个

我正在从VistaCredentialProviderSamples运行SampleWrapExistingCredentialProvider,在CSampleCredential.cpp文件中有一个名为“SetComboxSelectedValue”的函数。当用户更改组合框中的选定项并存储选定项索引时,将调用此函数。但是,当我在运行时使用AppendFieldComboBoxItem函数在组合框中追加项时,如果选择了追加项,则不调用此函数。因此,我无法获取附加字段的选定项索引

我试图显示一个messagebox,以查看何时调用此函数。仅当用户选择了其中一个默认组合框项时,才会调用此函数,而当选择了附加项时,不会调用此函数

// Called when the user changes the selected item in the combobox. We'll check to see if 
// it's for us or the wrapped credential, and then handle or route it as appropriate.
HRESULT CSampleCredential::SetComboBoxSelectedValue(
DWORD dwFieldID,
DWORD dwSelectedItem
)
{
    HRESULT hr = E_UNEXPECTED;

// Make sure we have a wrapped credential.
if (_pWrappedCredential != NULL)
{
    // If this field belongs to the wrapped credential, hand it off.
    if (_IsFieldInWrappedCredential(dwFieldID))
    {
        hr = _pWrappedCredential->SetComboBoxSelectedValue(dwFieldID, dwSelectedItem);
    }
    // Otherwise determine if we need to handle it.
    else
    {
        FIELD_STATE_PAIR *pfsp = _LookupLocalFieldStatePair(dwFieldID);
        if ((pfsp != NULL) && (dwSelectedItem < ARRAYSIZE(s_rgDatabases)))
        {
            _dwComboIndex = dwSelectedItem;

            HWND hwndOwner = nullptr;
            if (_pCredProvCredentialEvents)
            {
                _pCredProvCredentialEvents->OnCreatingWindow(&hwndOwner);
            }
            TCHAR msg[100];
            StringCbPrintf(msg, 100, TEXT("%d"), _dwComboIndex);
            MessageBox(hwndOwner, msg, TEXT("Combobox selected ID"), MB_OK | MB_ICONERROR);

            hr = S_OK;
        }
        else
        {
            hr = E_INVALIDARG;
        }
    }
}

return hr;
}
//当用户更改组合框中的选定项时调用。我们会检查一下
//它是为我们或包装好的凭证,然后根据需要处理或传送它。
HRESULT CSampleCredential::SetComboBoxSelectedValue(
德沃德·德菲尔德,
德沃德
)
{
HRESULT hr=E_意外;
//确保我们有包装好的凭证。
如果(_pwrapedCredential!=NULL)
{
//如果此字段属于已包装凭证,请将其移交。
if(_IsFieldInWrappedCredential(dwFieldID))
{
hr=\u pRappedCredential->SetComboxSelectedValue(dwFieldID,dwSelectedItem);
}
//否则,请确定我们是否需要处理它。
其他的
{
字段\状态\对*pfsp=\查找本地字段状态对(dwFieldID);
if((pfsp!=NULL)&(dwSelectedItemOnCreatingWindow(&hwndOwner);
}
TCHAR msg[100];
StringCbPrintf(msg,100,文本(“%d”),_-dwComboIndex);
消息框(HwnOwner,msg,TEXT(“组合框选定ID”),MB_OK | MB_ICONERROR);
hr=S_OK;
}
其他的
{
hr=E_INVALIDARG;
}
}
}
返回人力资源;
}

我还需要检测附加字段的组合框选定项索引。如果您对如何检测附加的组合框项目的索引有任何帮助,我们将不胜感激。

新的组合框项目将始终附加到列表的末尾

跟踪外观顺序是您的责任,您可以维护列表的内部“副本”以跟踪更改

因为您使用的是
SampleWrapeExistingCredentialProvider
,所以您可以创建一个代理类来跟踪从包装的提供程序内部到登录UI的调用

更新

我刚刚查看了提供商的日志

我在
GetSerialization
方法中填充组合框列表

在用对
AppendFieldComboBoxItem
的几个调用填充列表后,我手动调用
setFieldComboxSelectedItem
,将第三个参数设置为
0
,以确保选择了第一个项目

// Called when the user changes the selected item in the combobox. We'll check to see if 
// it's for us or the wrapped credential, and then handle or route it as appropriate.
HRESULT CSampleCredential::SetComboBoxSelectedValue(
DWORD dwFieldID,
DWORD dwSelectedItem
)
{
    HRESULT hr = E_UNEXPECTED;

// Make sure we have a wrapped credential.
if (_pWrappedCredential != NULL)
{
    // If this field belongs to the wrapped credential, hand it off.
    if (_IsFieldInWrappedCredential(dwFieldID))
    {
        hr = _pWrappedCredential->SetComboBoxSelectedValue(dwFieldID, dwSelectedItem);
    }
    // Otherwise determine if we need to handle it.
    else
    {
        FIELD_STATE_PAIR *pfsp = _LookupLocalFieldStatePair(dwFieldID);
        if ((pfsp != NULL) && (dwSelectedItem < ARRAYSIZE(s_rgDatabases)))
        {
            _dwComboIndex = dwSelectedItem;

            HWND hwndOwner = nullptr;
            if (_pCredProvCredentialEvents)
            {
                _pCredProvCredentialEvents->OnCreatingWindow(&hwndOwner);
            }
            TCHAR msg[100];
            StringCbPrintf(msg, 100, TEXT("%d"), _dwComboIndex);
            MessageBox(hwndOwner, msg, TEXT("Combobox selected ID"), MB_OK | MB_ICONERROR);

            hr = S_OK;
        }
        else
        {
            hr = E_INVALIDARG;
        }
    }
}

return hr;
}
然后我将
pcpgsr
设置为
CPGSR\u NO\u CREDENTIAL\u NOT\u FINISHED


当控件退出
GetSerialization
方法时,登录UI立即使用
SetComboBoxSelectedValue
和value
0
将我回调

新的组合框项目将始终附加到列表的末尾

跟踪外观顺序是您的责任,您可以维护列表的内部“副本”以跟踪更改

因为您使用的是
SampleWrapeExistingCredentialProvider
,所以您可以创建一个代理类来跟踪从包装的提供程序内部到登录UI的调用

更新

我刚刚查看了提供商的日志

我在
GetSerialization
方法中填充组合框列表

在用对
AppendFieldComboBoxItem
的几个调用填充列表后,我手动调用
setFieldComboxSelectedItem
,将第三个参数设置为
0
,以确保选择了第一个项目

// Called when the user changes the selected item in the combobox. We'll check to see if 
// it's for us or the wrapped credential, and then handle or route it as appropriate.
HRESULT CSampleCredential::SetComboBoxSelectedValue(
DWORD dwFieldID,
DWORD dwSelectedItem
)
{
    HRESULT hr = E_UNEXPECTED;

// Make sure we have a wrapped credential.
if (_pWrappedCredential != NULL)
{
    // If this field belongs to the wrapped credential, hand it off.
    if (_IsFieldInWrappedCredential(dwFieldID))
    {
        hr = _pWrappedCredential->SetComboBoxSelectedValue(dwFieldID, dwSelectedItem);
    }
    // Otherwise determine if we need to handle it.
    else
    {
        FIELD_STATE_PAIR *pfsp = _LookupLocalFieldStatePair(dwFieldID);
        if ((pfsp != NULL) && (dwSelectedItem < ARRAYSIZE(s_rgDatabases)))
        {
            _dwComboIndex = dwSelectedItem;

            HWND hwndOwner = nullptr;
            if (_pCredProvCredentialEvents)
            {
                _pCredProvCredentialEvents->OnCreatingWindow(&hwndOwner);
            }
            TCHAR msg[100];
            StringCbPrintf(msg, 100, TEXT("%d"), _dwComboIndex);
            MessageBox(hwndOwner, msg, TEXT("Combobox selected ID"), MB_OK | MB_ICONERROR);

            hr = S_OK;
        }
        else
        {
            hr = E_INVALIDARG;
        }
    }
}

return hr;
}
然后我将
pcpgsr
设置为
CPGSR\u NO\u CREDENTIAL\u NOT\u FINISHED


当控件退出
GetSerialization
方法时,登录UI立即使用
SetComboBoxSelectedValue
和value
0
将我回调

假设我维护列表的内部副本,但是如何检测在运行时选择了哪个项目?选择附加项时将触发哪个功能?因为选择附加项时未激发SetComboBoxSelectedValue。对于其他项目,它将被触发,并且我能够检测到所选项目。默认情况下,列表中有两个项目,其他项目在初始化凭据提供程序时,在API调用后动态追加。现在,我的问题是,当用户在从combobox中选择一个项目后单击submit按钮时,我无法获取用户选择的项目。在我的情况下,我的凭证提供者凭证被调用是关于combobox选择更改的。我会检查日志文件的…谢谢,非常感谢好的。。我通过一种变通方法实现了我的目标:我使用了删除方法而不是追加方法。我在初始化时静态地包含列表中的所有项目,然后在运行时动态地删除用户不需要的项目。在这种情况下,如果用户需要所有项目,我不会删除任何项目并能够获取所有项目的索引。例如,我维护列表的内部副本,但如何检测在运行时选择了哪个项目?选择附加项时将触发哪个功能?因为选择附加项时未激发SetComboBoxSelectedValue。对于其他人来说,它会被触发,我能够检测到选中的项目