Compartir a través de


Código de ejemplo para usar una búsqueda de VLV

En los ejemplos de código siguientes se usan búsquedas de VLV para obtener resultados de búsqueda.

  • GetVLVItemCount
  • GetVLVItemText
  • GetVLVItemsByString

Funciones de la utilidad

En este tema se usan los ejemplos de código siguientes.

/***************************************************************************

    CopyContextID()

***************************************************************************/

BOOL CopyContextID(LPBYTE pContextID, 
                   DWORD dwContextIDLength, 
                   LPBYTE* ppContextIDOut)
{
    
    /*
    Ensure that the context ID buffer is large enough and copy the context ID 
    into it. Reallocation of the buffer is not required if the same size is 
    required.
    */
    if(*ppContextIDOut && (LocalSize(*ppContextIDOut) != dwContextIDLength))
    {
        FreeContextID(ppContextIDOut);
        *ppContextIDOut = NULL;
    }

    // If the buffer does not exist, allocate it.
    if(!*ppContextIDOut)
    {
        *ppContextIDOut = (LPBYTE)LocalAlloc(LPTR, dwContextIDLength);
    }

    // Copy the memory.
    if(*ppContextIDOut)
    {
        CopyMemory(*ppContextIDOut, pContextID, dwContextIDLength);
    }

    return (NULL != *ppContextIDOut);
}

/***************************************************************************

    FreeContextID()

***************************************************************************/

void FreeContextID(LPBYTE* ppContextID)
{
        LocalFree(*ppContextID);
        *ppContextID = NULL;
}

/**************************************************************************

   WideCharToLocal()
   
**************************************************************************/

int WideCharToLocal(LPTSTR pLocal, LPCWSTR pWide, DWORD dwChars)
{
    if(!pLocal || !pWide)
    {
        return 0;
    }

    *pLocal = 0;

#ifdef UNICODE
    wcsncpy_s(pLocal, pWide, dwChars);
#else
    WideCharToMultiByte( CP_ACP, 
                        0, 
                        pWide, 
                        -1, 
                        pLocal, 
                        dwChars, 
                        NULL, 
                        NULL);
#endif

    return lstrlen(pLocal);
}

Función de ejemplo GetVLVItemCount

En el ejemplo de código siguiente se muestra cómo usar una búsqueda de VLV para obtener una estimación del número de elementos resultantes de la búsqueda.

/***************************************************************************

    GetVLVItemCount()

***************************************************************************/

HRESULT GetVLVItemCount(IDirectorySearch *pSearch, 
                        LPCWSTR pwszSearchFilter, 
                        LPCWSTR pwszAttribute,
                        DWORD *pdwCount,
                        LPBYTE* ppContextID)
{
    HRESULT hr;

    if(!pSearch || !pdwCount)
    {
        return E_INVALIDARG;
    }

    *pdwCount = 0;

    // Initialize the ADS_VLV structure.
    ADS_VLV vlvPref;
    ZeroMemory(&vlvPref, sizeof(vlvPref));

    // Using these values will retrieve the approximate number of items returned by the search.
    vlvPref.dwOffset = 0;
    vlvPref.dwContentCount = 0;
    vlvPref.dwContextIDLength = 0;

    // Set the VLV search preference.
    ADS_SEARCHPREF_INFO SearchPrefs[2];
    SearchPrefs[0].dwSearchPref = ADS_SEARCHPREF_VLV;
    SearchPrefs[0].vValue.dwType = ADSTYPE_PROV_SPECIFIC;
    SearchPrefs[0].vValue.ProviderSpecific.dwLength = sizeof(ADS_VLV);
    SearchPrefs[0].vValue.ProviderSpecific.lpValue = (LPBYTE)&vlvPref;

    /*
    Have the server perform the sorting. This option must be explicitly added 
    when using VLV searching.
    */
    ADS_SORTKEY sortKey;
    sortKey.pszAttrType = (LPWSTR)pwszAttribute;
    sortKey.pszReserved = NULL;
    sortKey.fReverseorder = 0;

    SearchPrefs[1].dwSearchPref = ADS_SEARCHPREF_SORT_ON;
    SearchPrefs[1].vValue.dwType = ADSTYPE_PROV_SPECIFIC;
    SearchPrefs[1].vValue.ProviderSpecific.dwLength = sizeof(ADS_SORTKEY);
    SearchPrefs[1].vValue.ProviderSpecific.lpValue = (LPBYTE)&sortKey;

    // Set the search preferences.
    hr = pSearch->SetSearchPreference(SearchPrefs, sizeof(SearchPrefs)/sizeof(SearchPrefs[0]));
    if(S_OK != hr)
    {
        return hr;
    }

    // Execute the search.
    ADS_SEARCH_HANDLE hSearchHandle;
    LPWSTR rgAttributes[1];
    rgAttributes[0] = (LPWSTR)pwszAttribute;
    hr = pSearch->ExecuteSearch((LPWSTR)pwszSearchFilter, 
        rgAttributes, 
        sizeof(rgAttributes)/sizeof(rgAttributes[0]), 
        &hSearchHandle);
    if(S_OK != hr)
    {
        return hr;
    }

    // Get the first result row.
    hr = pSearch->GetFirstRow(hSearchHandle);
    if(S_OK != hr)
    {
        return hr;
    }

    // Get the VLV response data.
    ADS_SEARCH_COLUMN column;
    hr = pSearch->GetColumn(hSearchHandle, ADS_VLV_RESPONSE, &column);
    if(S_OK != hr)
    {
        return hr;
    }

    ADS_VLV *pVlv = (ADS_VLV*)column.pADsValues->ProviderSpecific.lpValue;
    *pdwCount = pVlv->dwContentCount;

    /*
    Allocate or reallocate the buffer if required and copy the context ID 
    to the buffer.
    */
    CopyContextID(pVlv->lpContextID, pVlv->dwContextIDLength, ppContextID);

    // Release the column.
    pSearch->FreeColumn(&column);

    // Close the search handle.
    pSearch->CloseSearchHandle(hSearchHandle);

    return hr;
}

Función de ejemplo GetVLVItemText

En el ejemplo de código siguiente se muestra cómo usar una búsqueda VLV para obtener el texto de un solo elemento basado en un índice.

/***************************************************************************

    GetVLVItemText()

***************************************************************************/

HRESULT GetVLVItemText(IDirectorySearch *pSearch, 
                       LPCWSTR pwszSearchFilter, 
                       LPCWSTR pwszAttribute,
                       DWORD dwIndex,
                       LPTSTR pszADsPath,
                       DWORD dwChars,
                       LPBYTE* ppContextID)
{
    HRESULT hr;

    if(!pSearch)
    {
        return E_INVALIDARG;
    }

    // Initialize the ADS_VLV structure.
    ADS_VLV vlvPref;
    ZeroMemory(&vlvPref, sizeof(vlvPref));

    // This index is one-based, but the index passed is zero-based.
    vlvPref.dwOffset = dwIndex + 1;
    vlvPref.dwBeforeCount = 0;
    vlvPref.dwAfterCount = 0;
    vlvPref.dwContentCount = 0;
    if(*ppContextID)
    {
        vlvPref.lpContextID = *ppContextID;
        vlvPref.dwContextIDLength = (DWORD)LocalSize(*ppContextID);
    }

    // Set the VLV search preference.
    ADS_SEARCHPREF_INFO SearchPrefs[2];
    SearchPrefs[0].dwSearchPref = ADS_SEARCHPREF_VLV;
    SearchPrefs[0].vValue.dwType = ADSTYPE_PROV_SPECIFIC;
    SearchPrefs[0].vValue.ProviderSpecific.dwLength = sizeof(ADS_VLV);
    SearchPrefs[0].vValue.ProviderSpecific.lpValue = (LPBYTE)&vlvPref;

    /*
    Instruct the server to perform the sort. This option must be explicitly added 
    when using a VLV search.
    */
    ADS_SORTKEY sortKey;
    sortKey.pszAttrType = (LPWSTR)pwszAttribute;
    sortKey.pszReserved = NULL;
    sortKey.fReverseorder = 0;

    SearchPrefs[1].dwSearchPref = ADS_SEARCHPREF_SORT_ON;
    SearchPrefs[1].vValue.dwType = ADSTYPE_PROV_SPECIFIC;
    SearchPrefs[1].vValue.ProviderSpecific.dwLength = sizeof(ADS_SORTKEY);
    SearchPrefs[1].vValue.ProviderSpecific.lpValue = (LPBYTE)&sortKey;

    // Set the search preferences.
    hr = pSearch->SetSearchPreference(SearchPrefs, sizeof(SearchPrefs)/sizeof(SearchPrefs[0]));
    if(S_OK != hr)
    {
        return hr;
    }

    // Execute the search.
    ADS_SEARCH_HANDLE hSearchHandle;
    LPWSTR rgAttributes[1];
    rgAttributes[0] = (LPWSTR)pwszAttribute;
    hr = pSearch->ExecuteSearch((LPWSTR)pwszSearchFilter, 
        rgAttributes, 
        sizeof(rgAttributes)/sizeof(rgAttributes[0]), 
        &hSearchHandle);
    if(S_OK != hr)
    {
        return hr;
    }

    // Get the first result row.
    hr = pSearch->GetFirstRow(hSearchHandle);
    if(S_OK == hr)
    {
        ADS_SEARCH_COLUMN column;

        // Get the ADsPath.
        hr = pSearch->GetColumn(hSearchHandle, (LPWSTR)pwszAttribute, &column);
        if(SUCCEEDED(hr))
        {
            WideCharToLocal(pszADsPath, column.pADsValues->CaseIgnoreString, dwChars);
            pSearch->FreeColumn(&column);
        }
    
        // Get the VLV response data.
        hr = pSearch->GetColumn(hSearchHandle, ADS_VLV_RESPONSE, &column);
        if(SUCCEEDED(hr))
        {
            ADS_VLV *pVlv = (ADS_VLV*)column.pADsValues->ProviderSpecific.lpValue;
        
            /*
            Allocate or reallocate the buffer if required and copy the context ID 
            to the buffer.
            */
            CopyContextID(pVlv->lpContextID, pVlv->dwContextIDLength, ppContextID);

            pSearch->FreeColumn(&column);
        }

    }

    // Close the search handle.
    pSearch->CloseSearchHandle(hSearchHandle);

    return hr;
}

Función de ejemplo GetVLVItemsByString

En el ejemplo de código siguiente se muestra cómo usar una búsqueda de VLV para obtener el texto de un número especificado de elementos en función de una cadena. En este ejemplo se agregarán las ordenaciones recuperadas a un cuadro de lista.

/***************************************************************************

    GetVLVItemsByString()

***************************************************************************/

HRESULT GetVLVItemsByString(HWND hwndListbox,
                            IDirectorySearch *pSearch, 
                            LPCWSTR pwszSearchFilter, 
                            DWORD dwNumToRetrieve,
                            LPCWSTR pwszAttribute,
                            LPCWSTR pwszFilter,
                            LPBYTE* ppContextID)
{
    HRESULT hr;

    if(!pSearch || (0 == dwNumToRetrieve))
    {
        return E_INVALIDARG;
    }

    // Clear the list box.
    SendMessage(hwndListbox, LB_RESETCONTENT, 0, 0);

    // Initialize the ADS_VLV structure.
    ADS_VLV vlvPref;
    ZeroMemory(&vlvPref, sizeof(vlvPref));

    vlvPref.pszTarget = (LPWSTR)pwszFilter;
    vlvPref.dwBeforeCount = 0;
    vlvPref.dwAfterCount = dwNumToRetrieve - 1;
    vlvPref.dwContentCount = 0;

    // Set the VLV search preference.
    ADS_SEARCHPREF_INFO SearchPrefs[2];
    SearchPrefs[0].dwSearchPref = ADS_SEARCHPREF_VLV;
    SearchPrefs[0].vValue.dwType = ADSTYPE_PROV_SPECIFIC;
    SearchPrefs[0].vValue.ProviderSpecific.dwLength = sizeof(ADS_VLV);
    SearchPrefs[0].vValue.ProviderSpecific.lpValue = (LPBYTE)&vlvPref;

    /*
    Instruct the server to perform the sort. This option must be explicitly added 
    when using VLV search.
    */
    ADS_SORTKEY sortKey;
    sortKey.pszAttrType = (LPWSTR)pwszAttribute;
    sortKey.pszReserved = NULL;
    sortKey.fReverseorder = 0;

    SearchPrefs[1].dwSearchPref = ADS_SEARCHPREF_SORT_ON;
    SearchPrefs[1].vValue.dwType = ADSTYPE_PROV_SPECIFIC;
    SearchPrefs[1].vValue.ProviderSpecific.dwLength = sizeof(ADS_SORTKEY);
    SearchPrefs[1].vValue.ProviderSpecific.lpValue = (LPBYTE)&sortKey;

    // Set the search preferences.
    hr = pSearch->SetSearchPreference(SearchPrefs, sizeof(SearchPrefs)/sizeof(SearchPrefs[0]));
    if(S_OK != hr)
    {
        return hr;
    }

    // Execute the search.
    ADS_SEARCH_HANDLE hSearchHandle;
    hr = pSearch->ExecuteSearch((LPWSTR)pwszSearchFilter, 
        NULL, 
        -1, 
        &hSearchHandle);
    if(S_OK != hr)
    {
        return hr;
    }

    ADS_SEARCH_COLUMN column;

    // Get the first result row.
    hr = pSearch->GetFirstRow(hSearchHandle);
    while(S_OK == hr)
    {
        // Get the data.
        hr = pSearch->GetColumn(hSearchHandle, (LPWSTR)pwszAttribute, &column);
        if(SUCCEEDED(hr))
        {
            TCHAR szItemText[MAX_PATH];
            WideCharToLocal(szItemText, column.pADsValues->CaseIgnoreString, MAX_PATH);
            SendMessage(hwndListbox, LB_ADDSTRING, 0, (LPARAM)szItemText);

            pSearch->FreeColumn(&column);
        }
    
        // Get the next row.
        hr = pSearch->GetNextRow(hSearchHandle);
    }

    // Get the VLV response data.
    hr = pSearch->GetColumn(hSearchHandle, ADS_VLV_RESPONSE, &column);
    if(S_OK != hr)
    {
        return hr;
    }

    ADS_VLV *pVlv = (ADS_VLV*)column.pADsValues->ProviderSpecific.lpValue;

    /*
    Allocate or reallocate the buffer if required and copy the context ID 
    to the buffer.
    */
    CopyContextID(pVlv->lpContextID, pVlv->dwContextIDLength, ppContextID);

    // Release the column.
    pSearch->FreeColumn(&column);

    // Close the search handle.
    pSearch->CloseSearchHandle(hSearchHandle);

    return hr;
}