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

📄 playlistview.cpp

📁 一个简单漂亮的C++编写的mp3播放器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
                              LVIS_SELECTED|LVIS_FOCUSED);

        ListView_RedrawItems(m_hPlaylistView, 0, ListView_GetItemCount(m_hPlaylistView) - 1);

        //HMENU menu = GetSubMenu(GetMenu(m_hWnd), 1);

        //EnableMenuItem(menu, ID_EDIT_UNDO_ACTION, (m_oPlm->CanUndo() ? MF_ENABLED : MF_GRAYED));
        //EnableMenuItem(menu, ID_EDIT_REDO_ACTION, (m_oPlm->CanRedo() ? MF_ENABLED : MF_GRAYED));
    }
}

void MusicBrowserUI::PlaylistListItemRemoved(const PlaylistItem* item, 
                                             uint32 oldIndex)
{
    // item has already been deleted when we get this 
    // msg so don't access it. only use it for comparison

    if(oldIndex != kInvalidIndex)
    {
        LV_ITEM lv_item;
        
        lv_item.mask = LVIF_PARAM|LVIF_STATE;
        lv_item.iItem = oldIndex;
        lv_item.iSubItem = 0;
        lv_item.lParam = 0;
        lv_item.stateMask = LVIS_SELECTED|LVIS_FOCUSED;

        ListView_GetItem(m_hPlaylistView, &lv_item);
        
        ListView_DeleteItem(m_hPlaylistView, oldIndex);

        if(oldIndex >= ListView_GetItemCount(m_hPlaylistView))
            oldIndex = ListView_GetItemCount(m_hPlaylistView) - 1;

        if(lv_item.state & LVIS_SELECTED)
        {
            ListView_SetItemState(m_hPlaylistView, oldIndex, LVIS_SELECTED, LVIS_SELECTED);
        }

        if(lv_item.state & LVIS_FOCUSED)
        {
            ListView_SetItemState(m_hPlaylistView, oldIndex, LVIS_FOCUSED, LVIS_FOCUSED);
        }

        ListView_RedrawItems(m_hPlaylistView, oldIndex, ListView_GetItemCount(m_hPlaylistView) - 1);

        SetFocus(m_hPlaylistView);
        m_bListChanged = true;
        UpdateTotalTime();
        UpdateButtonMenuStates();

        //HMENU menu = GetSubMenu(GetMenu(m_hWnd), 1);

        //EnableMenuItem(menu, ID_EDIT_UNDO_ACTION, (m_oPlm->CanUndo() ? MF_ENABLED : MF_GRAYED));
        //EnableMenuItem(menu, ID_EDIT_REDO_ACTION, (m_oPlm->CanRedo() ? MF_ENABLED : MF_GRAYED));
    }
}

void MusicBrowserUI::PlaylistListSorted(void)
{
    ListView_RedrawItems(m_hPlaylistView, 0, ListView_GetItemCount(m_hPlaylistView) - 1);
    m_bListChanged = true;
    UpdateButtonMenuStates();

    //HMENU menu = GetSubMenu(GetMenu(m_hWnd), 1);

    //EnableMenuItem(menu, ID_EDIT_UNDO_ACTION, (m_oPlm->CanUndo() ? MF_ENABLED : MF_GRAYED));
    //EnableMenuItem(menu, ID_EDIT_REDO_ACTION, (m_oPlm->CanRedo() ? MF_ENABLED : MF_GRAYED));
}

void MusicBrowserUI::PlaylistListItemUpdated(const PlaylistItem* item)
{
    uint32        index = m_oPlm->IndexOf(item);
    HWND          hwnd = GetDlgItem(m_hWnd, IDC_PLAYLISTBOX);

    if(index != kInvalidIndex)
    {
        ListView_RedrawItems(hwnd, index, index);

        //HMENU menu = GetSubMenu(GetMenu(m_hWnd), 1);

        //EnableMenuItem(menu, ID_EDIT_UNDO_ACTION, (m_oPlm->CanUndo() ? MF_ENABLED : MF_GRAYED));
        //EnableMenuItem(menu, ID_EDIT_REDO_ACTION, (m_oPlm->CanRedo() ? MF_ENABLED : MF_GRAYED));
    }
}

void MusicBrowserUI::PlaylistListItemAdded(const PlaylistItem* item)
{
    LV_ITEM       lv_item;
    uint32        index = m_oPlm->IndexOf(item);

    if(index != kInvalidIndex)
    {
        if(m_hPlaylistView)
        {
            lv_item.mask = 0;
            lv_item.iSubItem = 0;
            lv_item.iItem = 0;

            if(!ListView_GetItemCount(m_hPlaylistView) && 
               !m_pParent && 
               !m_autoPlayHack)
                m_context->target->AcceptEvent(new Event(CMD_Play));

            ListView_InsertItem(m_hPlaylistView, &lv_item);

            // this skips change notification
            // for initial loading of list for
            // editing. a hack pretty much but
            // i can't think of a better way
            if(m_initialCount)
                m_initialCount--;
            else
            {
                m_bListChanged = true;
                UpdateButtonMenuStates();
            }

            UpdateTotalTime();
        }
        else
        {
            m_itemsAddedBeforeWeWereCreated++;
        }

        //HMENU menu = GetSubMenu(GetMenu(m_hWnd), 1);

        //EnableMenuItem(menu, ID_EDIT_UNDO_ACTION, (m_oPlm->CanUndo() ? MF_ENABLED : MF_GRAYED));
        //EnableMenuItem(menu, ID_EDIT_REDO_ACTION, (m_oPlm->CanRedo() ? MF_ENABLED : MF_GRAYED));
    }
}

void MusicBrowserUI::PlaylistListItemsAdded(const vector<PlaylistItem*>* items)
{
    uint32 count = ListView_GetItemCount(m_hPlaylistView);

    if(m_oPlm->CountItems() != count)
    {
        uint32 newSize = ListView_GetItemCount(m_hPlaylistView);
        newSize += items->size();
        ListView_SetItemCount(m_hPlaylistView, newSize);
    }

    if(m_hPlaylistView)
    {
        LV_ITEM lv_item;

        lv_item.mask = 0;
        lv_item.iSubItem = 0;
        lv_item.iItem = 0;

        if(!count && 
           !m_pParent && 
           !m_autoPlayHack)
            m_context->target->AcceptEvent(new Event(CMD_Play));

        count = items->size();

        for(uint32 i = 0; i < count; i++)
            ListView_InsertItem(m_hPlaylistView, &lv_item);

        // this skips change notification
        // for initial loading of list for
        // editing. a hack pretty much but
        // i can't think of a better way
        if(m_initialCount)
            m_initialCount--;
        else
        {
            m_bListChanged = true;
            UpdateButtonMenuStates();
        }

        UpdateTotalTime();
    }
    else
    {
        m_itemsAddedBeforeWeWereCreated += items->size();
    }


}

void MusicBrowserUI::GetSelectedPlaylistItems(vector<PlaylistItem*>* items)
{
    uint32 selected = ListView_GetSelectedCount(m_hPlaylistView);
    uint32 count = ListView_GetItemCount(m_hPlaylistView);
    uint32 index = 0;
    uint32 found = 0;

    for(index = 0, found = 0; found < selected && index < count; index++)
    {
        uint32 state = ListView_GetItemState(m_hPlaylistView, 
                                             index, 
                                             LVIS_SELECTED);
        if(state & LVIS_SELECTED)
        {
            PlaylistItem* item = m_oPlm->ItemAt(index);

            items->push_back(item);
            found++;
        }
    }
}

void MusicBrowserUI::LVBeginDrag(HWND hwnd, NM_LISTVIEW* nmlv)
{
    vector<string>* urls = new vector<string>;
    vector<PlaylistItem*> items;

    m_playlistDropTarget->TargetIsSource(true);

    GetSelectedPlaylistItems(&items);

    vector<PlaylistItem*>::iterator i;

    for(i = items.begin(); i != items.end(); i++)
    {
        urls->push_back((*i)->URL().c_str());
    }

    HIMAGELIST himl;
    RECT rcItem;
    POINT hotspot;
    
    himl = ListView_CreateDragImage(hwnd, nmlv->iItem, &hotspot);

    ListView_GetItemRect(hwnd, nmlv->iItem, &rcItem, LVIR_ICON); 

    hotspot.x = 0;
    hotspot.y = (rcItem.bottom - rcItem.top)/2;

    DataObject* data = new DataObject(CFSTR_FREEAMP_PLAYLISTITEM, urls);
    DropSource* src = new DropSource(hwnd, himl, hotspot, nmlv->ptAction);
    DWORD dwEffect = 0;

    DoDragDrop(data, 
               src, 
               DROPEFFECT_COPY|DROPEFFECT_SCROLL|DROPEFFECT_MOVE, 
               &dwEffect); 

    if(dwEffect == DROPEFFECT_MOVE)
    {
        vector<PlaylistItem*>::iterator i;

        for(i = items.begin(); i != items.end(); i++)
        {
            m_oPlm->RemoveItem(*i);         
        }
    }

    /*if(dwEffect != DROPEFFECT_NONE)
    {
        for(index = 0, found = 0; found < selected && index < count; index++)
        {
            uint32 state = ListView_GetItemState(hwnd, 
                                                 index, 
                                                 LVIS_SELECTED);
            if(state & LVIS_SELECTED)
            {
                ListView_SetItemState(hwnd, index, 0, LVIS_SELECTED);
                found++;
            }
        }
    }

    if(dwEffect == DROPEFFECT_MOVE)
    {
        vector<PlaylistItem*>::iterator i;

        for(i = list.begin(); i != list.end(); i++)
        {
            m_oPlm->RemoveItem(*i);         
        }
    }*/

    data->Release();
    src->Release();

    m_playlistDropTarget->TargetIsSource(false);
}

void MusicBrowserUI::UpdateTotalTime()
{
    uint32 count = ListView_GetItemCount(m_hPlaylistView);
    uint32 index = 0;
    uint32 total = 0;
    bool approximate = false;

    for(index = 0; index < count; index++)
    {
        PlaylistItem* item = m_oPlm->ItemAt(index);

        if(item)
        {
            uint32 time = item->GetMetaData().Time();

            if(!time)
                approximate = true;

            total += time;
        }
    }   

    char buf[32] = "~";
    char* time = buf;

    // this will place a twiddle in front of the time
    // if any of the times are zero and thus assumed 
    // to be unknown...
    if(approximate)
        time++;

    uint32 hours = total / 3600;
    uint32 minutes = total / 60 - hours * 60;
    uint32 seconds = total - minutes * 60 - hours * 3600;

    if(hours)
        sprintf(time, "%d:%02d:%02d", hours, minutes, seconds);
    else
        sprintf(time, "%d:%02d", minutes, seconds);

    SendMessage(m_hStatus, SB_SETTEXT, 1, (LPARAM) time);
}

LRESULT WINAPI 
ListViewWndProc(HWND hwnd, 
                UINT msg, 
                WPARAM wParam, 
                LPARAM lParam)
{
    MusicBrowserUI* ui = (MusicBrowserUI*)GetProp(hwnd, "this" );

    return ui->ListViewWndProc(hwnd, msg, wParam, lParam);
}

void MusicBrowserUI::ResizeHeader(HWND hwnd, uint32 column)
{
    if(ListView_GetItemCount(hwnd))
    {
        PlaylistItem* item = NULL;
        uint32 textLength = 0;
        int32 columnWidth = ListView_GetColumnWidth(hwnd,column);
        uint32 i = 0;
        string text;
        HDC hdc = GetDC(hwnd);

        while(item = m_oPlm->ItemAt(i++))
        {
            MetaData metadata = item->GetMetaData();
       
            switch(column)
            {
                case 1:
                    text = metadata.Title();
                    break;

                case 2:
                    text = metadata.Artist();
                    break;

                case 3:
                    text = metadata.Album();
                    break;

                case 4:
                {
                    char buf[16];

                    if(metadata.Time() != 0)
                    {
                        int32 seconds = metadata.Time();
                        int32 hours = seconds / 3600;
		                int32 minutes = seconds / 60 - hours * 60;
                        seconds = seconds - minutes * 60 - hours * 3600;

                        if(hours)
                            sprintf(buf, "%d:%02d:%02d", hours, minutes, seconds);
                        else
                            sprintf(buf, "%d:%02d", minutes, seconds);

                        text = buf;
                    }
                    else    
                        text = "Unknown";

                    break;
                }

                default:
                    return;
                    break;
            }

            SIZE size;

            GetTextExtentPoint32(hdc, text.c_str(), text.size(), &size); 

            if(size.cx > textLength)
                textLength = size.cx;
        }

        ReleaseDC(hwnd, hdc);

        textLength += 3;

        if(column < 4)
        {
            int32 nextColumnWidth = ListView_GetColumnWidth(hwnd,column + 1);

            ListView_SetColumnWidth(hwnd,column, textLength);

            int32 delta = columnWidth - textLength;

            nextColumnWidth += delta;

            ListView_SetColumnWidth(hwnd,column + 1, nextColumnWidth);
        }
        else
        {
            int32 nextColumnWidth = ListView_GetColumnWidth(hwnd,column - 1);

            ListView_SetColumnWidth(hwnd,column, textLength);

            int32 delta = columnWidth - textLength;

            nextColumnWidth += delta;

            ListView_SetColumnWidth(hwnd,column - 1, nextColumnWidth);
        }
    }
}

LRESULT MusicBrowserUI::ListViewWndProc(HWND hwnd, 
                                        UINT msg, 
                                        WPARAM wParam, 
                                        LPARAM lParam)
{
    WNDPROC lpOldProc = (WNDPROC)GetProp( hwnd, "oldproc" );
    bool filesAreURLs = false;

	switch(msg)
	{
		case WM_DESTROY:   

⌨️ 快捷键说明

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