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);
}

CFileViewer(文件浏览器)的更多相关文章

  1. 下载apk文件浏览器会直接打开并显示乱码的问题

    今天同事反映他的apk文件在自己的老项目中下载有问题:下载apk文件浏览器会直接打开并显示乱码,在别的项目中就没有问题. 后分析response的content-type发现,老项目的类型是text/ ...

  2. Win 10 文件浏览器无法打开

    今天遇到个很奇怪的问题,文件浏览器File Explorer无法正常显示,点击打开后任务栏上已经显示打开了,但是屏幕上却看不到任何窗口,开始以为机子中了恶意的木马,然后就疯狂的查毒,然而并没有解决问题 ...

  3. Mac下DIY文件浏览器

    2015-07-14 15:07:53 Mac下的finder不能浏览Linux文件目录, 一些优秀的资源管理器是收费的..... 于是想到了既然Mac的本质是类Unix, 而在windows下查看L ...

  4. 比nerdtree更好的文件浏览器:vimfiler

    通过:VimFilerExplorer来打开一个文件浏览器 h:收起 t:展开 -:close 回车:进入或展开 空格:收起

  5. 【转】显示Ubuntu文件浏览器的地址栏--不错

    原文网址:http://www.blogbus.com/anythingok-logs/144447448.html Ubuntu默认使用nautilus作为其可视化的文件浏览器,其默认值不显示地址栏 ...

  6. 【Java】 实现一个简单文件浏览器(1)

    学习Java的Swing的时候写的一个超简单文件浏览器 效果如图: 项目结构: 这里面主要用了两个控件,JTree和JTable 下面先说下左侧的文件树如何实现: 首先是FileTree类,继承于JT ...

  7. SharePoint 2013 解惑 无法打开文件浏览器

    你有时候会看到这东西谈出来,当你想像管理文件一样,管理SharePoint上资源的时候 意思是说,不能打开文件浏览器,请加入你的站点到信任站点,这个有两个问题,一个是IE设置,一个是WebClient ...

  8. 跟我一起使用electron搭建一个文件浏览器应用吧(二)

    这个文件浏览器应用可以具备以下两种功能噢- This file browser application can have the following two functions. 一:用户浏览文件夹和 ...

  9. 安卓工作室 文件浏览器 android studio File browser

    安卓工作室 文件浏览器 android studio  File browser 作者:韩梦飞沙 Author:han_meng_fei_sha 邮箱:313134555@qq.com E-mail: ...

  10. winform利用ImageList控件和ListView控件组合制作图片文件浏览器

    winform利用ImageList控件和ListView控件组合制作图片文件浏览器,见图,比较简单,实现LISTVIEW显示文件夹图片功能. 1.选择文件夹功能代码: folderBrowserDi ...

随机推荐

  1. MindSponge分子动力学模拟——多路径分子模拟(2024.05)

    技术背景 在前面的MindSponge教程系列博客中,我们已经介绍过MindSponge分子动力学模拟框架的基础功能使用方法,例如MindSponge的安装与使用.定义分子系统.计算单点能和迭代器等等 ...

  2. RHEL7.9安装Podman4.1.1并部署Redis集群

    原文链接:RHEL7.9安装Podman4.1.1并部署Redis集群-语雀 环境 操作系统 cat /etc/redhat-release Red Hat Enterprise Linux Serv ...

  3. 领域驱动设计(Domain-Driven Design,简称DDD)【简介 个人学习笔记】

    找到了第 1 篇资料:领域驱动设计详解:是什么.为什么.怎么做? - 知乎 找到了第 2 篇资料:领域驱动架构(DDD)建模中的模型到底是什么? - 知乎 找到了第 3 篇资料:一文看懂DDD 领域驱 ...

  4. Typora编写博客并发布

    (1)工具安装:下载博主xhznl开发的的工具,并按照说明进行正确的配置. EasyBlogImageForTypora使用说明:https://www.cnblogs.com/xhznl/p/132 ...

  5. 箭头函数 函数中的this指向

      // 箭头函数         // 在匿名函数中,使用 => 箭头来替换 关键词 function          // 箭头定义下 () 和 {} 之间         // 等于在使 ...

  6. 2023CSP-S游记

    2023 CSP-S 游记 赛前 上午去花卉市场看了半天花,算是放松放松,主要是为了晚上给干妈过50岁生日. 还以为是 2 点开始,1 点 40 多就到了,然后去买了杯奶茶,然后进场. 结果我是第一考 ...

  7. WIN8 WIN10 WIN11离线安装 .NET 3.5

    WIN8 WIN10 WIN11离线安装 .NET 3.5 以WIN10为例: 1.双击WIN10 ISO 镜像,看挂载的是哪个盘符.我这边是E:. 2.使用 WIN + X 快捷键,打开 Windo ...

  8. Ubuntu安装VMware tools后不起作用

    复制和立即适应客户机不起作用. 解决: 1)不需要卸载 2)命令行执行sudo apt-get install open-vm-tools-desktop 3)可能会提示apt-get update或 ...

  9. 加入域 " " 时出现了以下错误

    加入域 " " 时出现了以下错误: 因为文件共享不安全,所以你不能连接到文件共享.此共享需要过时的 SMB1 协议,而此协议是不安全的,可能会使你的系统遭受攻击. 你的系统需要 S ...

  10. OpenWrt安装配置Tailscale

    什么是tailscale? Tailscale就是基于Wireguard的一个联网工具,无需公网地址,通过去中心化,实现各个节点之间点对点的连接.配置简单友好,支持的各类平台和客户端. 相比较其他组网 ...