⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpi_playlist.c

📁 VC++视频开发实例集锦(包括“远程视频监控”"语音识别系统"等13个经典例子)
💻 C
📖 第 1 页 / 共 5 页
字号:
    wp_SortFN pfnSort;
    CP_CHECKOBJECT(pPlaylist);

    // Skip if list is empty
    if(pPlaylist->m_hFirst == NULL)
        return;

    // Decide sort function
    {
        switch(enElement)
        {
        case piseTrackStackPos:
            pfnSort = cpl_sort_TrackStackPos;
            break;
        case piseTrackName:
            pfnSort = cpl_sort_TrackName;
            break;
        case piseArtist:
            pfnSort = cpl_sort_Artist;
            break;
        case piseAlbum:
            pfnSort = cpl_sort_Album;
            break;
        case piseYear:
            pfnSort = cpl_sort_Year;
            break;
        case piseTrackNum:
            pfnSort = cpl_sort_TrackNum;
            break;
        case piseGenre:
            pfnSort = cpl_sort_Genre;
            break;
        case piseComment:
            pfnSort = cpl_sort_Comment;
            break;
        case piseFilename:
            pfnSort = cpl_sort_Filename;
            break;
        case pisePath:
            pfnSort = cpl_sort_Path;
            break;
        case piseLength:
            pfnSort = cpl_sort_Length;
            break;
        default:
            CP_FAIL(UnknownSortOrder);
        }
    }

    // Count items
    {
        CP_HPLAYLISTITEM hCursor;
        iNumItems = 0;
        for(hCursor = pPlaylist->m_hFirst; hCursor; hCursor = CPLI_Next(hCursor))
            iNumItems++;
    }

    // Build flat array
    {
        CP_HPLAYLISTITEM hCursor;
        int iItemIDX;
        pFlatArray = (CPs_PlaylistItem**)malloc(sizeof(CPs_PlaylistItem*) * iNumItems);

        iItemIDX = 0;
        for(hCursor = pPlaylist->m_hFirst; hCursor; hCursor = CPLI_Next(hCursor), iItemIDX++)
            pFlatArray[iItemIDX] = CPLII_DECODEHANDLE(hCursor);
    }

    // Qsort it
    qsort(pFlatArray, iNumItems, sizeof(CPs_PlaylistItem*), pfnSort);

    // Relink list
    {
        int iFirstItem, iTermItem, iInc;
        CP_HPLAYLISTITEM* phCursor_Referrer = &(pPlaylist->m_hFirst);
        CP_HPLAYLISTITEM hCursor_Prev = NULL;
        CP_HPLAYLISTITEM hLastAssignment = NULL;
        int iItemIDX;

        // Work out how to traverse the flat array
        if(bDesc == FALSE)
        {
            iFirstItem = 0;
            iTermItem = iNumItems;
            iInc = 1;
        }
        else
        {
            iFirstItem = iNumItems-1;
            iTermItem = -1;
            iInc = -1;
        }

        // Traverse the array
        for(iItemIDX = iFirstItem; iItemIDX != iTermItem; iItemIDX+=iInc)
        {
            *phCursor_Referrer = pFlatArray[iItemIDX];
            pFlatArray[iItemIDX]->m_hPrev = hCursor_Prev;

            phCursor_Referrer = &(CPLII_DECODEHANDLE(*phCursor_Referrer)->m_hNext);
            hCursor_Prev = pFlatArray[iItemIDX];
            hLastAssignment = hCursor_Prev;
        }
        pPlaylist->m_hLast = hLastAssignment;
        CPLII_DECODEHANDLE(pPlaylist->m_hLast)->m_hNext = NULL;
    }

    free(pFlatArray);
    CPL_cb_SetWindowToReflectList();
}
//
//
//
void CPL_InsertItemBefore(CP_HPLAYLIST hPlaylist, CP_HPLAYLISTITEM hItem_Anchor, CP_HPLAYLISTITEM hItem_ToMove)
{
    CPs_Playlist* pPlaylist = (CPs_Playlist*)hPlaylist;
    CPs_PlaylistItem* pAnchor = CPLII_DECODEHANDLE(hItem_Anchor);
    CP_CHECKOBJECT(pPlaylist);

    CPL_UnlinkItem(hPlaylist, hItem_ToMove);
    if(pAnchor->m_hPrev)
    {
        CPLII_DECODEHANDLE(pAnchor->m_hPrev)->m_hNext = hItem_ToMove;
        CPLII_DECODEHANDLE(hItem_ToMove)->m_hPrev = pAnchor->m_hPrev;
    }
    else
    {
        pPlaylist->m_hFirst = hItem_ToMove;
        CPLII_DECODEHANDLE(hItem_ToMove)->m_hPrev = NULL;
    }

    pAnchor->m_hPrev = hItem_ToMove;
    CPLII_DECODEHANDLE(hItem_ToMove)->m_hNext = hItem_Anchor;
}
//
//
//
void CPL_InsertItemAfter(CP_HPLAYLIST hPlaylist, CP_HPLAYLISTITEM hItem_Anchor, CP_HPLAYLISTITEM hItem_ToMove)
{
    CPs_Playlist* pPlaylist = (CPs_Playlist*)hPlaylist;
    CPs_PlaylistItem* pAnchor = CPLII_DECODEHANDLE(hItem_Anchor);
    CP_CHECKOBJECT(pPlaylist);

    CPL_UnlinkItem(hPlaylist, hItem_ToMove);
    if(pAnchor->m_hNext)
    {
        CPLII_DECODEHANDLE(pAnchor->m_hNext)->m_hPrev = hItem_ToMove;
        CPLII_DECODEHANDLE(hItem_ToMove)->m_hNext = pAnchor->m_hNext;
    }
    else
    {
        pPlaylist->m_hLast = hItem_ToMove;
        CPLII_DECODEHANDLE(hItem_ToMove)->m_hNext = NULL;
    }

    pAnchor->m_hNext = hItem_ToMove;
    CPLII_DECODEHANDLE(hItem_ToMove)->m_hPrev = hItem_Anchor;
}
//
//
//
void SortLList(CPs_FilenameLLItem* pFirst)
{
    char** ppStrings;
    int iNumStrings;
    int iStringIDX;
    CPs_FilenameLLItem* pCursor;

    if(!pFirst)
        return;

    // Count the number of strings in the list
    iNumStrings = 0;
    for(pCursor = pFirst; pCursor; pCursor = (CPs_FilenameLLItem*)pCursor->m_pNextItem)
        iNumStrings++;

    // Allocate string buffer and assign strings to it
    ppStrings = (char**)malloc(sizeof(char*) * iNumStrings);
    iStringIDX = 0;
    for(pCursor = pFirst; pCursor; pCursor = (CPs_FilenameLLItem*)pCursor->m_pNextItem)
    {
        ppStrings[iStringIDX] = pCursor->m_pcFilename;
        iStringIDX++;
    }

    // Sort filelist
    qsort(ppStrings, iNumStrings, sizeof(char*), exp_CompareStrings);

    // Assign list to the now sorted string list
    iStringIDX = 0;
    for(pCursor = pFirst; pCursor; pCursor = (CPs_FilenameLLItem*)pCursor->m_pNextItem)
    {
        pCursor->m_pcFilename = ppStrings[iStringIDX];
        iStringIDX++;
    }

    free(ppStrings);
}
//
//
//
void CPL_AddDirectory_Recurse(CP_HPLAYLIST hPlaylist, const char *pDir)
{
    CPs_Playlist* pPlaylist = (CPs_Playlist*)hPlaylist;
    CPs_FilenameLLItem* m_pFirstFile = NULL;
    CPs_FilenameLLItem* m_pFirstDir = NULL;
    CPs_FilenameLLItem* pCursor;
    CPs_FilenameLLItem* pNextItem;
    char cFullPath[MAX_PATH];
    char cWildCard[MAX_PATH];
    const int iDirStrLen = strlen(pDir);
    WIN32_FIND_DATA finddata;
    HANDLE hFileFind;
    CP_CHECKOBJECT(pPlaylist);

    // Build a full path to the directory
    strcpy(cFullPath, pDir);
    if(cFullPath[iDirStrLen-1] == '\\' && iDirStrLen > 1)
        cFullPath[iDirStrLen-1] = '\0';

    // Check that this is a correct path
    if(cFullPath[0] == '\0' || path_is_directory(cFullPath) == FALSE)
    {
        MessageBox(NULL, "Not a valid directory.", cFullPath, MB_ICONERROR);
        return;
    }

    //Scan directory building a list of filenames
    if(strcmp(cFullPath, "\\") == 0)
        strcpy(cWildCard, "\\*.*");
    else
    {
        strcpy(cWildCard, cFullPath);
        strcat(cWildCard, "\\*.*");
    }

    strcat(cFullPath, "\\");
    hFileFind = FindFirstFile(cWildCard, &finddata);
    if(hFileFind == INVALID_HANDLE_VALUE)
    {
        MessageBox(NULL, "Could not perform scan", cFullPath, MB_ICONERROR);
        return;
    }

    do
    {
        char pcFullPath[MAX_PATH];

        // Skip dots
        if(finddata.cFileName[0] == '.')
            continue;

        strcpy(pcFullPath, cFullPath);
        strcat(pcFullPath, finddata.cFileName);

        // Add to linked list
        if(finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
        {
            // Add to dirs list
            CPs_FilenameLLItem* pNewItem = (CPs_FilenameLLItem*)malloc(sizeof(CPs_FilenameLLItem));
            pNewItem->m_pNextItem = m_pFirstDir;
            STR_AllocSetString(&pNewItem->m_pcFilename, pcFullPath, FALSE);
            m_pFirstDir = pNewItem;
        }
        else
        {
            // Add to files list
            CPs_FilenameLLItem* pNewItem = (CPs_FilenameLLItem*)malloc(sizeof(CPs_FilenameLLItem));
            pNewItem->m_pNextItem = m_pFirstFile;
            STR_AllocSetString(&pNewItem->m_pcFilename, pcFullPath, FALSE);
            m_pFirstFile = pNewItem;
        }

    } while(FindNextFile(hFileFind, &finddata) != 0);

    FindClose(hFileFind);

    SortLList(m_pFirstDir);
    SortLList(m_pFirstFile);

    // Add files first - then directories
    for(pCursor = m_pFirstFile; pCursor; pCursor = (CPs_FilenameLLItem*)pCursor->m_pNextItem)
        CPL_AddFile(globals.m_hPlaylist, pCursor->m_pcFilename);
    for(pCursor = m_pFirstDir; pCursor; pCursor = (CPs_FilenameLLItem*)pCursor->m_pNextItem)
        CPL_AddDirectory_Recurse(hPlaylist, pCursor->m_pcFilename);

    // Cleanup
    for(pCursor = m_pFirstFile; pCursor; pCursor = pNextItem)
    {
        pNextItem = (CPs_FilenameLLItem*)pCursor->m_pNextItem;
        free(pCursor->m_pcFilename);
        free(pCursor);
    }
    for(pCursor = m_pFirstDir; pCursor; pCursor = pNextItem)
    {
        pNextItem = (CPs_FilenameLLItem*)pCursor->m_pNextItem;
        free(pCursor->m_pcFilename);
        free(pCursor);
    }
}
//
//
//
void CPL_AddDroppedFiles(CP_HPLAYLIST hPlaylist, HDROP hDrop)
{
    CPs_Playlist* pPlaylist = (CPs_Playlist*)hPlaylist;
    int iNumFiles, iFileIDX;
    char** ppFiles;

    CP_CHECKOBJECT(pPlaylist);

    // Read all the files into an array of strings
    iNumFiles = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0);
    ppFiles = (char**)malloc(iNumFiles * sizeof(char*));
    for(iFileIDX = 0; iFileIDX < iNumFiles; iFileIDX++)
    {
        const int iBufferSize = DragQueryFile(hDrop, iFileIDX, NULL, 0)+1;
        ppFiles[iFileIDX] = (char*)malloc(iBufferSize * sizeof(char));
        DragQueryFile(hDrop, iFileIDX, ppFiles[iFileIDX], iBufferSize);
    }
    DragFinish(hDrop);

    // Sort filelist
    qsort(ppFiles, iNumFiles, sizeof(char*), exp_CompareStrings);

    // Add to playlist
    CLV_BeginBatch(globals.m_hPlaylistViewControl);
    for(iFileIDX = 0; iFileIDX < iNumFiles; iFileIDX++)
    {
        if(path_is_directory(ppFiles[iFileIDX]) == TRUE)
        {
            CPL_AddDirectory_Recurse(globals.m_hPlaylist, ppFiles[iFileIDX]);
            strcpy(options.last_used_directory, ppFiles[iFileIDX]);
        }
        else
            CPL_AddFile(globals.m_hPlaylist, ppFiles[iFileIDX]);
    }
    CLV_EndBatch(globals.m_hPlaylistViewControl);

    // Free string array
    for(iFileIDX = 0; iFileIDX < iNumFiles; iFileIDX++)
        free(ppFiles[iFileIDX]);
    free(ppFiles);

    // Shuffle playlist
    if(options.shuffle_play)
        PostThreadMessage(pPlaylist->m_dwWorkerThreadID, CPPLWT_SYNCSHUFFLE, 0, 0);
}
//
//
//
void CPL_Stack_Append(CP_HPLAYLIST hPlaylist, CP_HPLAYLISTITEM hItem)
{
    CPs_Playlist* pPlaylist = (CPs_Playlist*)hPlaylist;
    int iItemNumber;
    CP_CHECKOBJECT(pPlaylist);

    // Ensure buffer is big enough
    if( (pPlaylist->m_iTrackStackSize+1) >= pPlaylist->m_iTrackStackBufferSize)
    {
        pPlaylist->m_iTrackStackBufferSize += CPC_TRACKSTACK_BUFFER_QUANTISATION;
        pPlaylist->m_pTrackStack = realloc(pPlaylist->m_pTrackStack, pPlaylist->m_iTrackStackBufferSize * sizeof(CP_HPLAYLISTITEM));
    }

    // Ensure cursor is rational
    if(pPlaylist->m_iTrackStackCursor > pPlaylist->m_iTrackStackSize)
        pPlaylist->m_iTrackStackCursor = pPlaylist->m_iTrackStackSize;

    // Add item
    pPlaylist->m_pTrackStack[pPlaylist->m_iTrackStackSize] = hItem;
    pPlaylist->m_iTrackStackSize++;

    // Number item
    iItemNumber = (pPlaylist->m_iTrackStackSize-1) - pPlaylist->m_iTrackStackCursor;
    CPLI_SetTrackStackPos(hItem, iItemNumber);
    CPL_cb_TrackStackChanged();
}
//
//
//
void CPL_Stack_Renumber(CP_HPLAYLIST hPlaylist)
{
    CPs_Playlist* pPlaylist = (CPs_Playlist*)hPlaylist;
    unsigned int iStackIDX;
    CP_CHECKOBJECT(pPlaylist);

    for(iStackIDX = 0; iStackIDX < pPlaylist->m_iTrackStackSize; iStackIDX++)
        CPLI_SetTrackStackPos(pPlaylist->m_pTrackStack[iStackIDX], iStackIDX - pPlaylist->m_iTrackStackCursor);

    CPL_cb_TrackStackChanged();
}
//
//
//
void CPL_Stack_Remove(CP_HPLAYLIST hPlaylist, CP_HPLAYLISTITEM hItem)
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -