zoukankan      html  css  js  c++  java
  • CFileViewer(文件浏览器)

     1 #pragma once
     2 #include <afxwin.h>
     3 #include <afxtempl.h>
     4 
     5 class CFileViewer : public CWnd
     6 {
     7     DECLARE_MESSAGE_MAP()
     8     DECLARE_DYNAMIC(CFileViewer)
     9 public:
    10     struct FileItem
    11     {
    12         int type;        //0为File 1为 directory
    13         CString name;    //
    14         CString path;    //代表当前D:Download的路径,不包括名称
    15         HICON hIcon;
    16     };
    17     CFileViewer();
    18     ~CFileViewer();
    19     /**
    20      * 创建一个控件使其初始化
    21      * @param pParent 父窗口对象指针
    22      * @param dwStyle 控件样式
    23      * @param rect 控件区域
    24      * @param nId 控件的ID
    25      */
    26     void Create(CWnd* parent, DWORD style, RECT rect, UINT nId);
    27     LPCTSTR GetClassName() {
    28         return _T("CFileViewer");
    29     }
    30     LPCTSTR GetWindowName() {
    31         return _T("CFileViewer");
    32     }
    33     /**
    34      * 列举指定目录的文件
    35      * @param dir 要列举的文件目录
    36      */
    37     void ListFile(CString dir);
    38     virtual void SetDefaultVisualStyle();
    39 private:
    40     void AddFileViewer(FileItem* item)
    41     {
    42         m_arrItem.Add(item);
    43     }
    44     HICON GetFileIcon(SHFILEINFO strFileIcon, const CString& path);
    45     /**
    46      * 控件改变大小的时候会触发
    47      * @param nType 是垂直还是水平大小
    48      * @param cx x方向的偏移
    49      * @param cy y方向的偏移
    50      */
    51     afx_msg void OnSize(UINT nType, int cx, int cy);
    52     /**
    53      * 重新绘制的时候触发
    54      */
    55     afx_msg void OnPaint();
    56     afx_msg void OnVScroll(UINT, UINT, CScrollBar*);
    57     afx_msg BOOL OnMouseWheel(UINT, short, CPoint);
    58     afx_msg BOOL OnEraseBkgnd(CDC* pDC);
    59 
    60     void RegisterCtrl();
    61     void DrawItem(const FileItem* item, CDC* pDC);
    62     void DrawText(CDC* pDC, CRect cr, CString str);
    63     void GetPosition(CPoint& p);
    64     void GetLayoutInfo();
    65     static LRESULT WndProc(HWND, UINT, WPARAM, LPARAM);
    66 protected:
    67     CArray<FileItem*> m_arrItem;
    68     int curX;    ///< 每个item获取完位置后的X偏移
    69     int curY;    ///< 每个item获取完位置后的Y偏移
    70     CSize itemSize;        ///< 每个item的大小
    71     CRect m_ctrlPadding;    ///< ctrl的内间距
    72     CRect m_itemPadding;    ///< item的内间距
    73     CRect m_itemMargin;        ///< item之间的间距
    74     CScrollBar m_scVertical;    ///< 垂直滚动条
    75     int m_nVertScrollPos;///< 垂直滚动的位置
    76     int m_nRow;        ///< item画出来需要多少行
    77     int m_nCol;        ///< item画出来需要多少列
    78     bool m_bNeedGetLayout;    ///< 是否需要重新计算布局 如果为true则需要 
    79     bool m_bFileMode; ///<  是否是文件模式 ,如果为否则为文件夹模式 
    80 };
    #include "pch.h"
    #include "CFileViewer.h"
    #include <Gdiplus.h>
    
    IMPLEMENT_DYNAMIC(CFileViewer, CWnd)
    BEGIN_MESSAGE_MAP(CFileViewer, CWnd)
        ON_WM_PAINT()
        ON_WM_ERASEBKGND()
        ON_WM_SIZE()
        ON_WM_VSCROLL()
        ON_WM_MOUSEWHEEL()
    END_MESSAGE_MAP()
    
    
    CFileViewer::CFileViewer()
    {
        WNDCLASS windowclass;
        HINSTANCE hInst = AfxGetInstanceHandle();
        if (!::GetClassInfo(hInst, this->GetClassName(), &windowclass))
        {
            RegisterCtrl();
        }
        m_bNeedGetLayout = false;
    }
    
    CFileViewer::~CFileViewer()
    {
        for (int i = 0; i < m_arrItem.GetSize(); i++)
        {
            delete m_arrItem[i];
        }
    }
    
    void CFileViewer::Create(CWnd* pParent, DWORD dwStyle, RECT rect, UINT nId)
    {
        WNDCLASS windowclass;
        HINSTANCE hInst = AfxGetInstanceHandle();
    
        if (!::GetClassInfo(hInst, this->GetClassName(), &windowclass))
        {
            RegisterCtrl();
        }
        CWnd::Create(GetClassName(), GetWindowName(), dwStyle, rect, pParent, nId);
        SetDefaultVisualStyle();
        rect.left = rect.right - 10;
        m_scVertical.Create(WS_CHILD | WS_CLIPCHILDREN | SBS_VERT, rect, this, AFX_IDW_VSCROLL_FIRST);
        m_scVertical.EnableScrollBar(ESB_ENABLE_BOTH);
        m_scVertical.SetScrollRange(0, 100, TRUE);
    }
    void CFileViewer::GetPosition(CPoint& p)
    {
        //p点作为右上角的点
        //默许从左到右排序,然后依次换行
        CRect rectClient;
        GetClientRect(&rectClient);
        if (curX == 0)
            curX += m_ctrlPadding.left;
        else
            curX += m_itemMargin.right + itemSize.cx + m_itemMargin.left;
        if (curY == 0)
            curY += m_ctrlPadding.top;
    
        if (curX >= rectClient.Width() - m_ctrlPadding.right)
        {
            //超过范围 开始下一行
            curX = m_ctrlPadding.left;
            curY += m_itemMargin.bottom + m_itemMargin.top + itemSize.cy;
        }
        p.SetPoint(curX, curY);
    }
    
    void CFileViewer::GetLayoutInfo()
    {
        if (m_bNeedGetLayout) return;
        CRect rectClient;
        GetClientRect(&rectClient);
        int size = m_arrItem.GetSize();
        //计算col列row行
    
        m_nCol = (rectClient.Width() - m_ctrlPadding.left - m_ctrlPadding.right) / (itemSize.cx + m_itemMargin.left + m_itemMargin.top);
        m_nRow = size / m_nCol + 1;
        double dbTotalHeight = m_nRow * (itemSize.cy + m_itemMargin.top + m_itemMargin.bottom)
            + m_ctrlPadding.top + m_ctrlPadding.bottom;
        float range = dbTotalHeight / (double)rectClient.Height() * 100.0;
        if (range > 100)
        {
            m_scVertical.ShowScrollBar();
            //set range
            m_scVertical.SetScrollRange(0, range);
        }
        m_bNeedGetLayout = true;
    }
    
    void CFileViewer::OnSize(UINT nType, int cx, int cy)
    {
        //Invalidate();
    }
    
    
    void CFileViewer::ListFile(CString srcFile)
    {
        m_arrItem.RemoveAll();
        //HICON hIcon = GetFileIcon(sfile, srcFile);
        //逐个列举文件夹内所有txt文件
        CString strFileName, strFileTemp, strSuffixTemp;
        CFileFind findFile;
        if (srcFile.Right(1) != '\')
            srcFile = srcFile += '\';
        else
        {
            srcFile.Right(1) = '\';
            srcFile = srcFile;
        }
    
        strFileTemp = srcFile + _T("*.*");
        int nIsFind = findFile.FindFile(strFileTemp);          //执行文件搜索
    
        while (nIsFind)
        {
            nIsFind = findFile.FindNextFile();          //查找下一个文件
            if (findFile.IsDirectory())           //若为目录,结束本次循环
                continue;
            strFileName = findFile.GetFileName();         //获取文件名称,包括后缀
            FileItem* fitem = new FileItem();
            SHFILEINFO sfile{ 0 };
            fitem->hIcon = GetFileIcon(sfile, srcFile + strFileName);
            fitem->name = strFileName;
            fitem->path = srcFile;
            //if (strFileName == ".." || strFileName == ".")
            //    continue;
            //strSuffixTemp = strFileName.Mid(strFileName.GetLength() - 3, 3);
            strFileName = srcFile + strFileName;
            AddFileViewer(fitem);
            //对文件进行后续处理
            Invalidate();
        }
    }
    
    HICON CFileViewer::GetFileIcon(SHFILEINFO stFileInfo, const CString& path)
    {
        // 同时将 ENM_CHANGE 标志“或”运算到掩码中。
        ::SHGetFileInfo(path, 0, &stFileInfo, sizeof(stFileInfo), SHGFI_ICON);
        return stFileInfo.hIcon;
    }
    
    void CFileViewer::OnPaint()
    {
        CClientDC client(this);
    
        //CDC& client = *GetDC();
    
        PAINTSTRUCT ps;
        this->BeginPaint(&ps);
        CRect rectClient;
        GetClientRect(&rectClient);
        //bufferMemBitmap.CreateCompatibleBitmap(&client, rectClient.Width(), rectClient.Height());
    
        //计算滚动
        int size = m_arrItem.GetSize();
        ////计算col列row行
        //int nCol = (rectClient.Width() - m_ctrlPadding.left - m_ctrlPadding.right) / (itemSize.cx + m_itemMargin.left + m_itemMargin.top);
        //int nRow = size / nCol + 1;
        //double dbTotalHeight = nRow * (itemSize.cy + m_itemMargin.top + m_itemMargin.bottom)
        //    + m_ctrlPadding.top + m_ctrlPadding.bottom;
        //float range = dbTotalHeight /(double) rectClient.Height() * 100.0;
        ////set range
        //m_scVertical.SetScrollRange(0,range);
        //重新计算布局,
        curX = 0;
        curY = 0;
        for (int i = 0; i < size; i++)
        {
            FileItem* fi = m_arrItem.GetAt(i);
            DrawItem(fi, &client);
        }
    
        /*client.BitBlt(rectClient.left, rectClient.top, rectClient.Width(), rectClient.Height(),
            &memDC, 0, 0, SRCCOPY);*/
            //bufferMemBitmap.DeleteObject();
            //memDC.DeleteDC();
        EndPaint(&ps);
    
        ::SwapBuffers(client.GetSafeHdc());
        /*LPITEMIDLIST pidl = NULL;
        int hr = SHGetFolderLocation(NULL, CSIDL_BITBUCKET, NULL, 0, &pidl);*/
        //SHFILEINFO    shfi = { 0 }; //文件信息结构变量用于存放函数调用的结果
        ////memset(&shfi, 0, sizeof(shfi));
        //DWORD dwError = GetLastError();
        //SHGetFileInfo(_T("E:\"), 0, &shfi, sizeof(SHFILEINFO), SHGFI_LARGEICON);
        ////SHGetFileInfo((LPCTSTR)pidl, -1, &shfi, sizeof(SHFILEINFO), SHGFI_ATTRIBUTES | SHGFI_TYPENAME);
        //dwError = GetLastError();
        //HICON hIcon = shfi.hIcon;
        //client.DrawIcon(200, 20, hIcon);
    }
    
    void CFileViewer::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* scroll)
    {
        int TempPos = m_scVertical.GetScrollPos();
        //SCROLLINFO si;
        //GetScrollInfo(SB_HORZ, &si, SIF_ALL);
        //m_ImgVScrollPos = si.nPos;
        //dbHScroll = si.nPos;
        m_nVertScrollPos = nPos;
        GetLayoutInfo();
        //switch (nSBCode)
        //{
        //case SB_THUMBPOSITION://拖动滑块
        //    m_scVertical.SetScrollPos(nPos);
        //    break;
        //case SB_TOP://点击左边的箭头
        //    if (TempPos > 1)
        //    {
        //        TempPos--;
        //    }
        //    m_scVertical.SetScrollPos(TempPos);
        //    break;
        //case SB_BOTTOM://点击右边的箭头
        //    if (TempPos < 100)
        //    {
        //        TempPos++;
        //    }
        //    m_scVertical.SetScrollPos(TempPos);
        //    break;
        //}
        //m_scVertical.Invalidate();
        Invalidate(TRUE);
    
    }
    
    BOOL CFileViewer::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
    {
        if (m_nVertScrollPos < 0)
        {
            m_nVertScrollPos = 0;
            return TRUE;
        }
        m_nVertScrollPos -= zDelta / 100.0;
        INT min, max;
        m_scVertical.GetScrollRange(&min, &max);
        m_scVertical.SetScrollPos(m_nVertScrollPos);
        GetLayoutInfo();
        CRect rectClient;
        GetWindowRect(&rectClient);
        rectClient.right -= 60;
        //InvalidateRect(&rectClient);
        Invalidate();
        //    m_scVertical.Invalidate();
        return TRUE;
    }
    
    BOOL CFileViewer::OnEraseBkgnd(CDC* pDC)
    {
        CRect rect;
        GetClientRect(&rect);
        //rect.right -= 60;
        pDC->FillSolidRect(&rect, RGB(255, 255, 255));
        //pDC->FillSolidRect(0, 0, 320, 240, RGB(255,255,255));
        return TRUE;
    }
    
    void CFileViewer::SetDefaultVisualStyle()
    {
        itemSize.SetSize(100, 80);
        m_itemPadding = { 1,1,1,1 };    //item内部
        m_itemMargin = { 2,2,2,2 };    //margin间距
        m_ctrlPadding = { 2,2,2,2 };    //控件内部padding
        //m_arrItem.SetSize(3);
    }
    void CFileViewer::RegisterCtrl()
    {
        WNDCLASS w;
        memset(&w, 0, sizeof(WNDCLASS));   // start with NULL defaults
        w.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
        w.lpszClassName = GetClassName();
        w.hCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
        w.hIcon = NULL;//GetIcon(FALSE);
        w.hInstance = AfxGetInstanceHandle();
        w.lpszMenuName = NULL;//_T("Menu");
        w.cbClsExtra = w.cbWndExtra = 0;
        w.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);//::GetSysColor(COLOR_WINDOW);
        w.lpfnWndProc = (WNDPROC)AfxWndProc; //::DefWindowProc;//(WNDPROC)CGridCtrl::GridCtrlProc;
        if (!AfxRegisterClass(&w))
        {
            AfxThrowResourceException();
            return;
        }
    }
    void CFileViewer::DrawItem(const FileItem* item, CDC* pDC)
    {
        CPoint p;
        GetPosition(p);
        p.y -= m_nVertScrollPos;
    
        //p.Offset(itemSize.cx / 2, itemSize.cy / 2);
        //pDC->Ellipse(p.x, p.y, p.x + itemSize.cx, p.y + itemSize.cy);
        pDC->Rectangle(p.x, p.y, p.x + itemSize.cx, p.y + itemSize.cy);
        CRect rect{ p.x, p.y, p.x + itemSize.cx, p.y + itemSize.cy };
        CBrush brush(RGB(125, 125, 125));
        pDC->FillRect(&rect, &brush);
        pDC->DrawIcon(p.x + 40, p.y + 10, item->hIcon);
        rect.DeflateRect(10, 50, 10, 10);
        //pDC->TextOut(p.x, p.y, item->name);
        //pDC->DrawText(item->name, rect,  ES_MULTILINE|  DT_TOP);
        DrawText(pDC, rect, item->name);
    
    
    }
    
    void CFileViewer::DrawText(CDC* pDC, CRect cr, CString text)
    {
        CSize size;
        GetTextExtentPoint(pDC->GetSafeHdc(), text, text.GetLength(), &size);
        //BOOL B = this->SetCaretPos(nStartX, nStartY);
        int cx = cr.left;
        int cy = cr.top;
        CString cstr;
        for (int i = 0; i < text.GetLength(); i++)
        {
            cstr = text.GetAt(i);
            GetTextExtentPoint(pDC->GetSafeHdc(), cstr, 1, &size);
            //cr.SetRect(0, 0, size.cx, size.cy);
    
            if (cx >= cr.right)
            {
                cx = cr.left;
                cy += size.cy;
            }
            //cr.MoveToX(size.cx);
            //pDC->DrawText(cstr, &cr, DT_CENTER);
            pDC->TextOut(cx, cy, cstr);
            cx += size.cx;
        }
    
    }
    
    LRESULT CFileViewer::WndProc(HWND hWnd, UINT msgType, WPARAM wParam, LPARAM lParam)
    {
        return AfxWndProc(hWnd, msgType, wParam, lParam);
    }
  • 相关阅读:
    Image Processing and Analysis_8_Edge Detection:Finding Edges and Lines in Images by Canny——1983
    2019年C题 视觉情报信息分析
    Image Processing and Analysis_8_Edge Detection:Theory of Edge Detection ——1980
    Computer Vision_2_Active Shape Models:Active Shape Models-Their Training and Application——1995
    Computer Vision_1_Active Appearance Models:Active Appearance Models——2001
    Computer Vision_1_Active Appearance Models :Active Appearance Models——1998
    这群程序员疯了!他们想成为IT界最会带货的男人
    阿里云视频云正式支持AV1编码格式 为视频编码服务降本提效
    Knative Serverless 之道:如何 0 运维、低成本实现应用托管?
    千呼万唤始出来——DataV私有部署功能
  • 原文地址:https://www.cnblogs.com/yang131/p/14372442.html
Copyright © 2011-2022 走看看