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

📄 multiselecttreeview.cpp

📁 FreeAMP(MP3播放)程序源代码-用来研究MP3解码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*____________________________________________________________________________

        FreeAmp - The Free MP3 Player

        Portions Copyright (C) 1999 EMusic.com

        This program is free software; you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        the Free Software Foundation; either version 2 of the License, or
        (at your option) any later version.

        This program is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.

        You should have received a copy of the GNU General Public License
        along with this program; if not, write to the Free Software
        Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

        $Id: MultiSelectTreeView.cpp,v 1.25 2000/09/27 12:16:40 elrod Exp $
____________________________________________________________________________*/

#include <windows.h>
#include <windowsx.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <direct.h>

#include "config.h"
#include "utility.h"
#include "resource.h"
#include "Win32MusicBrowser.h"
#include "DropSource.h"
#include "DropObject.h"
#include "eventdata.h"

#define IsCtrlDown()  (GetKeyState(VK_CONTROL) < 0)
#define IsShiftDown()  (GetKeyState(VK_SHIFT) < 0)

static HTREEITEM g_editItem = NULL;


static BOOL TreeView_SetTree(HWND hwnd, TV_ITEM* root)
{
    BOOL result = FALSE;
    HTREEITEM childItem; 
    TV_ITEM tv_item = *root;

    do
    {
        result = TreeView_SetItem(hwnd, &tv_item);

        childItem = TreeView_GetChild(hwnd, tv_item.hItem);

        if(result && childItem)
        {
            TV_ITEM child_tv_item = tv_item;

            child_tv_item.hItem = childItem;
            result = TreeView_SetTree(hwnd, &child_tv_item);
        }

    }while(result && (tv_item.hItem = TreeView_GetNextSibling(hwnd, tv_item.hItem)));
    
    return result;
}

static BOOL TreeView_SetBranch(HWND hwnd, TV_ITEM* root)
{
    BOOL result = FALSE;
    TV_ITEM tv_item = *root;

    result = TreeView_SetItem(hwnd, &tv_item);

    tv_item.hItem = TreeView_GetChild(hwnd, tv_item.hItem);

    if(result && tv_item.hItem)
    {
        TreeView_SetTree(hwnd, &tv_item);
    }
    
    return result;
}

static
LRESULT WINAPI 
EditLabelWndProc(HWND hwnd, 
                 UINT msg, 
                 WPARAM wParam, 
                 LPARAM lParam)
{
    WNDPROC lpOldProc = (WNDPROC)GetProp(hwnd, "oldproc" );
    BOOL isPlaylist = (BOOL)GetProp(hwnd, "playlist" );

    switch(msg)
	{
		case WM_DESTROY:   
		{
			//  Put back old window proc and
			SetWindowLong( hwnd, GWL_WNDPROC, (DWORD)lpOldProc );

			// remove window property
			RemoveProp( hwnd, "oldproc" ); 
            RemoveProp( hwnd, "playlist" ); 

			break;
        }

        case WM_GETDLGCODE:
        {
            return DLGC_WANTALLKEYS;
        }

        case WM_CHAR:
        {
            if(wParam == VK_ESCAPE)
            {
                SendMessage(GetParent(hwnd), TVM_ENDEDITLABELNOW, TRUE, 0); 
                return 1;
            }
            else if(wParam == VK_RETURN)
            {
                SendMessage(GetParent(hwnd), TVM_ENDEDITLABELNOW, FALSE, 0); 
                return 1;
            }

            if( isPlaylist &&
               (wParam == '\\'  ||
                wParam == '/'   ||
                wParam == ':'   ||
                wParam == '*'   ||
                wParam == '?'   ||
                wParam == '\"'  ||
                wParam == '<'   ||
                wParam == '>'   ||
                wParam == '|' ) )
            {
                return 1;
            }

            break;
        }


    }

    return CallWindowProc(lpOldProc, hwnd, msg, wParam, lParam );
}

void MusicBrowserUI::EditItemLabel(HWND hwnd, HTREEITEM item)
{
    if (item == NULL)
        return;

    g_editItem = item;

    bool isPlaylist = false;
    TV_ITEM tv_item;

    tv_item.hItem = item;
    tv_item.mask = TVIF_PARAM;

    TreeView_GetItem(hwnd, &tv_item);

    TreeData* treedata = (TreeData*)tv_item.lParam;

    if(treedata)
    {
        isPlaylist = treedata->IsPlaylist();

        if(treedata->IsTrack())
        {
            TV_ITEM tv_item;

            tv_item.mask = TVIF_HANDLE | TVIF_TEXT;
            tv_item.hItem = item;
            tv_item.pszText = (char*)treedata->m_pTrack->GetMetaData().Title().c_str();
            tv_item.cchTextMax = strlen(tv_item.pszText);

            TreeView_SetItem(hwnd, &tv_item);        
        }
    }

    SetFocus(hwnd);

    HWND hwndEdit = TreeView_EditLabel(hwnd, item);

    if(hwndEdit)
    {
        /*RECT rect;

        GetWindowRect(hwndEdit, &rect);

        MapWindowPoints(NULL, hwnd, (LPPOINT)&rect, 2);

        MoveWindow(hwndEdit, rect.left, rect.top, (rect.right - rect.left)/2,
            rect.bottom - rect.top, TRUE);*/

        SetProp(hwndEdit, 
                "oldproc",
                (HANDLE)GetWindowLong(hwndEdit, GWL_WNDPROC));

        SetProp(hwndEdit, 
                "playlist",
                (HANDLE)isPlaylist);

        // Subclass the window so we can filter characters
        SetWindowLong(hwndEdit, 
			          GWL_WNDPROC, 
                      (DWORD)::EditLabelWndProc);
    }
}

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

    //if(msg == 0x110c)
    //    return 0;

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

LRESULT MusicBrowserUI::TreeViewWndProc(HWND hwnd, 
                                        UINT msg, 
                                        WPARAM wParam, 
                                        LPARAM lParam)
{
    WNDPROC lpOldProc = (WNDPROC)GetProp(hwnd, "oldproc" );
    static bool dragging = false;
    static RECT dragRect;
    static HTREEITEM dragItem = NULL;
    static bool selectedOnMouseDown = false;

    //return CallWindowProc(lpOldProc, hwnd, msg, wParam, lParam );

	switch(msg)
	{
		case WM_DESTROY:   
		{
			//  Put back old window proc and
			SetWindowLong( hwnd, GWL_WNDPROC, (DWORD)lpOldProc );

			// remove window property
			RemoveProp( hwnd, "oldproc" ); 
            RemoveProp( hwnd, "this" ); 

			break;
        }

        case WM_MOUSEMOVE:
        {
            if(dragging)
            {
                if(wParam & MK_LBUTTON)
                {
                    POINT dragPt;

                    dragPt.x = LOWORD(lParam);
                    dragPt.y = HIWORD(lParam);

                    if( !PtInRect(&dragRect, dragPt) )
                    {
                        SetCapture(NULL);
                        dragging = false;

                        NM_TREEVIEW nm_treeview;

                        memset(&nm_treeview, 0x00, sizeof(NM_TREEVIEW));
                        
                        nm_treeview.hdr.code = TVN_BEGINDRAG;
                        nm_treeview.hdr.hwndFrom = hwnd;
                        nm_treeview.hdr.idFrom = GetWindowLong(hwnd, GWL_ID);

                        nm_treeview.itemNew.hItem = dragItem;
                        nm_treeview.itemNew.mask = TVIF_STATE|TVIF_PARAM;
                        nm_treeview.itemNew.stateMask = TVIS_BOLD|TVIS_CUT|TVIS_DROPHILITED|TVIS_EXPANDED|TVIS_SELECTED|TVIS_EXPANDEDONCE;
                        
                        TreeView_GetItem(hwnd, &nm_treeview.itemNew);

                        nm_treeview.ptDrag.x = LOWORD(lParam);
                        nm_treeview.ptDrag.y = HIWORD(lParam);

                        SendMessage(GetParent(hwnd), 
                                    WM_NOTIFY, 
                                    (WPARAM)nm_treeview.hdr.idFrom,
                                    (LPARAM)&nm_treeview);

                        return TRUE;
                    }
                }
            }

            break;
        }

        case WM_RBUTTONDOWN:
        {
            SetFocus(hwnd);

            HTREEITEM item;
            TV_HITTESTINFO hti;

            hti.pt.x = LOWORD(lParam);
            hti.pt.y = HIWORD(lParam);

            item = TreeView_HitTest(hwnd, &hti);  

            if(item && (hti.flags & TVHT_ONITEM))
            {
                HTREEITEM focusItem = TreeView_GetSelection(hwnd);
                TV_ITEM tv_item;

                tv_item.hItem = focusItem;
                tv_item.mask = TVIF_STATE;
                tv_item.stateMask = TVIS_SELECTED;

                TreeView_GetItem(hwnd, &tv_item);

                bool wasFocusSelected = (tv_item.state & TVIS_SELECTED) != 0;

                tv_item.hItem = item;
                tv_item.mask = TVIF_STATE;
                tv_item.stateMask = TVIS_SELECTED;

                TreeView_GetItem(hwnd, &tv_item);

                bool wasFocus = item == focusItem;
                bool wasSelected = (tv_item.state & TVIS_SELECTED) != 0;

                if(!wasSelected)
                {
                    // need to iterate all the items and 
                    // make sure they aren't selected
                    HTREEITEM rootItem = TreeView_GetRoot(hwnd);

                    if(rootItem)
                    {
                        do
                        {
                            tv_item.hItem = rootItem;
                            tv_item.mask = TVIF_STATE;
                            tv_item.stateMask = TVIS_SELECTED;
                            tv_item.state = 0;

                            TreeView_SetBranch(hwnd, &tv_item);
                        
                        }while(rootItem = TreeView_GetNextSibling(hwnd, rootItem));
                    }

                    // need to set this back cause windows won't
                    // set it if it is already the focus item and
                    // we just deselected it
                    if(wasSelected && wasFocus)
                    {
                        tv_item.hItem = focusItem;
                        tv_item.mask = TVIF_STATE;
                        tv_item.stateMask = TVIS_SELECTED;
                        tv_item.state = TVIS_SELECTED;

                        TreeView_SetItem(hwnd, &tv_item);
                    }
                }

                TreeView_Select(hwnd, item, TVGN_CARET);

                if(!wasFocus && wasFocusSelected && wasSelected)
                {
                    tv_item.hItem = focusItem;
                    tv_item.mask = TVIF_STATE;
                    tv_item.stateMask = TVIS_SELECTED;
                    tv_item.state = TVIS_SELECTED;

                    TreeView_SetItem(hwnd, &tv_item);
                }
            }

            //return TRUE;

            break;
        }

        case WM_RBUTTONUP:
        {
            break;
        }

        case WM_LBUTTONDBLCLK:
        {
            TV_ITEM tv_item;
            TV_HITTESTINFO tv_htinfo;

            KillTimer(hwnd, 1);

            //GetCursorPos(&tv_htinfo.pt);
            //ScreenToClient(m_hMusicView, &tv_htinfo.pt);
            tv_htinfo.pt.x =  LOWORD(lParam);
            tv_htinfo.pt.y =  HIWORD(lParam);


            if(TreeView_HitTest(m_hMusicView, &tv_htinfo) && 
			   (tv_htinfo.flags & TVHT_ONITEM))
            {
                tv_item.hItem = TreeView_GetSelection(m_hMusicView); 
                tv_item.mask = TVIF_PARAM | TVIF_HANDLE;
                tv_item.lParam = 0;

                TreeView_GetItem(m_hMusicView, &tv_item);

                TreeData* treedata = (TreeData*)tv_item.lParam;

                bool playNow;

                m_context->prefs->GetPrefBoolean(kPlayImmediatelyPref, &playNow);

⌨️ 快捷键说明

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