Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >显示文件和文件夹的关联图标和说明

显示文件和文件夹的关联图标和说明

作者头像
加菲猫的VFP
发布于 2023-08-21 09:26:49
发布于 2023-08-21 09:26:49
19700
代码可运行
举报
文章被收录于专栏:加菲猫的VFP加菲猫的VFP
运行总次数:0
代码可运行
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
PUBLIC oForm As Explorer
oForm = CREATEOBJECT("Explorer")
oForm.Visible=.T.
* end of main

DEFINE CLASS Explorer As Form
#DEFINE LVM_FIRST 0x1000
#DEFINE LVM_GETIMAGELIST (LVM_FIRST + 2)
#DEFINE LVM_SETIMAGELIST (LVM_FIRST + 3)
#DEFINE LVM_SETITEM (LVM_FIRST + 6)
#DEFINE LVIF_IMAGE 0x0002

#DEFINE LVSIL_SMALL 1
#DEFINE LVS_SHAREIMAGELISTS 0x0040
#DEFINE GWL_STYLE -16
#DEFINE MAX_PATH 260

#DEFINE SHGFI_SYSICONINDEX 0x000004000
#DEFINE SHGFI_SMALLICON 0x000000001
#DEFINE SHGFI_ICON 0x000000100
#DEFINE SHGFI_TYPENAME 0x000000400
#DEFINE SHGFI_USEFILEATTRIBUTES 0x000000010

#DEFINE FILE_ATTRIBUTE_NORMAL 0x00000080
#DEFINE FILE_ATTRIBUTE_DIRECTORY 0x00000010

  Width=560
  Height=370
  MaxButton=.F.
  BorderStyle=2
  AutoCenter=.T.
  Caption="File Explorer"
  ShowWindow=2

  ADD OBJECT lst As TListViewFiles WITH;
  Left=5, Top=35, Width=550, Height=310

  ADD OBJECT Label1 As Label WITH Autosize=.T.,;
  BackStyle=0, Left=7, Top=7, Caption="Address:"
  
  ADD OBJECT txtFolder As TextBox WITH;
  Left=64, Top=5, Width=466,;
  ControlSource="THIS.Parent.lst.defaultpath"

  ADD OBJECT cmdFolder As CommandButton WITH;
  Left=530, Top=4, Width=24, Height=24, Caption=".."

PROCEDURE Init
  = BINDEVENT(THIS.cmdFolder, "Click", THIS, "GetFolder")
  THIS.lst.populatelist

PROCEDURE GotFocus
  THIS.lst.SwitchToSystemList

PROCEDURE GetFolder
  LOCAL cStoredPath, cPath
  cStoredPath = SYS(5) + SYS(2003)
  cPath = GETDIR(THIS.lst.defaultpath,;
    "Folders:", "Select Folder")
  SET DEFAULT TO (m.cStoredPath)
  IF NOT EMPTY(m.cPath)
    THIS.lst.defaultpath = LOWER(m.cPath)
    THIS.Refresh
  ENDIF

ENDDEFINE

DEFINE CLASS TListViewFiles As OleControl
  OleClass="MSComctlLib.ListViewCtrl"
  defaultpath=JUSTPATH(_vfp.ServerName)

PROCEDURE Init
  THIS.declare
  WITH THIS
    .View=3
    .LabelEdit=1
    .AddColumnHeader("Name", 200)
    .AddColumnHeader("Size", 80)
    .AddColumnHeader("Type", 110)
    .AddColumnHeader("Date Modified", 130)
    
    LOCAL oMsgFont As SystemMessageFont
    oMsgFont=CREATEOBJECT("SystemMessageFont")
    .Font.Name=oMsgFont.lfFaceName &&"Segoe UI"
    .Font.Size=oMsgFont.GetFontSize()  &&9
  ENDWITH

PROCEDURE defaultpath_ASSIGN(cPath As String)
  cPath=LOWER(ALLTRIM(JUSTPATH(m.cPath)))
  IF RIGHT(m.cPath,1)="\" AND LEN(m.cPath) > 3
    cPath=SUBSTR(m.cPath,1,LEN(m.cPath)-1)
  ENDIF
  THIS.defaultpath=m.cPath
  THIS.PopulateList

PROCEDURE ColumnClick
LPARAMETERS columnheader
  THIS.PopulateList

PROCEDURE AddColumnHeader(cCaption, nWidth)
  WITH THIS.ColumnHeaders.Add()
    .Text=cCaption
    .Width=nWidth
  ENDWITH

PROCEDURE SwitchToSystemList
  LOCAL nWStyle, hSysImageList, nResult, cBuffer

  * check if the list is already assigned
  IF SendMessage(THIS.HWND, LVM_GETIMAGELIST,;
    LVSIL_SMALL, 0) <> 0
    RETURN
  ENDIF

  WITH THIS
    nWStyle = GetWindowLong(.HWND, GWL_STYLE)
    nWStyle = BITOR(m.nWStyle, LVS_SHAREIMAGELISTS)
    SetWindowLong(.HWND, GWL_STYLE, nWStyle)

    cBuffer = REPLICATE(CHR(0), 1024)
    hSysImageList = SHGetFileInfo("", FILE_ATTRIBUTE_NORMAL,;
      @cBuffer, LEN(cBuffer),;
      BITOR(SHGFI_SYSICONINDEX, SHGFI_SMALLICON,;
        SHGFI_ICON, SHGFI_TYPENAME,;
        SHGFI_USEFILEATTRIBUTES))

    = SendMessage(.HWND, LVM_SETIMAGELIST, LVSIL_SMALL, 0)
    = INKEY(0.1)
    = SendMessage(.HWND, LVM_SETIMAGELIST, LVSIL_SMALL, hSysImageList)

  ENDWITH

PROCEDURE PopulateList
* scans current directory and populates the ListView
  THIS.ListItems.Clear
  
  LOCAL nCount, nIndex

  nCount = ADIR(arrListOfFiles,;
    THIS.defaultpath + "\*.*", "D", 1)

  FOR nIndex=1 TO nCount
    IF arrListOfFiles[nIndex, 1] = "."
      LOOP
    ENDIF
    IF DIRECTORY(THIS.defaultpath + "\" +;
      arrListOfFiles[nIndex, 1])
      THIS.AddLstItem(@arrListOfFiles, nIndex, .T.)
    ENDIF
  NEXT

  nCount = ADIR(arrListOfFiles,;
    THIS.defaultpath + "\*.*", "A", 1)

  FOR nIndex=1 TO nCount
    IF NOT DIRECTORY(THIS.defaultpath + "\" +;
      arrListOfFiles[nIndex, 1])
      THIS.AddLstItem(@arrListOfFiles, nIndex, .F.)
    ENDIF
  NEXT
  RELEASE arrListOfFiles

PROCEDURE AddLstItem(arr, nIndex, lDirectory)
* adds new ListItem to the ListView control
  LOCAL cFilename, nTypeIndex, cFiletype, oItem

  cFilename = arr[nIndex, 1]
  nTypeIndex=0
  cFiletype=""
  
  THIS.GetFileTypeInfo(THIS.defaultpath+"\"+m.cFilename,;
    @nTypeIndex, @cFiletype,;
    IIF(lDirectory, FILE_ATTRIBUTE_DIRECTORY,;
      FILE_ATTRIBUTE_NORMAL))
  
  oItem = THIS.ListItems.Add(,,cFilename)
  THIS.SetIcon(oItem.Index, m.nTypeIndex)

  WITH oItem
    IF NOT lDirectory
      .Subitems(1) = THIS.FormatFilesize(arr[nIndex, 2])
    ENDIF
    .Subitems(2) = m.cFiletype
    .Subitems(3) = THIS.FormatDT(arr[nIndex, 3], arr[nIndex, 4])
  ENDWITH

PROCEDURE SetIcon(nItemIndex, nImageIndex)
* sets the icon for the specified ListItem
    LOCAL cItemBuffer  && LVITEM structure

    cItemBuffer = num2dword(LVIF_IMAGE) +;
      num2dword(nItemIndex-1) + num2dword(0) + num2dword(0) +;
      num2dword(0) + num2dword(0) + num2dword(0) +;
      num2dword(nImageIndex) + num2dword(0)

    = SendMessageS(THIS.hWnd , LVM_SETITEM, 0, @cItemBuffer)

FUNCTION FormatDT(dDate, cTime) As String
  LOCAL cResult
  cResult = DTOC(dDate) + " " + cTime
RETURN m.cResult

FUNCTION FormatFilesize(nSize) As String
  LOCAL cBuffer
  cBuffer = REPLICATE(CHR(0), 128)
  = StrFormatByteSizeA(m.nSize, @cBuffer, LEN(m.cBuffer))
RETURN STRTRAN(m.cBuffer, CHR(0), "")

PROCEDURE GetFileTypeInfo(cFilename, nTypeIndex,;
  cFileType, nFileAttr)
* obtains the icon and description associated
* with the specified file type
  LOCAL nBufsize, cBuffer, nFlags, hIcon, nTypeIndex

  nBufsize=0x200
  cBuffer = REPLICATE(CHR(0), nBufsize)

  nFlags = BITOR(SHGFI_SYSICONINDEX,;
    SHGFI_SMALLICON, SHGFI_ICON, SHGFI_TYPENAME,;
    SHGFI_USEFILEATTRIBUTES)

  = SHGetFileInfo(m.cFilename, m.nFileAttr,;
    @cBuffer, nBufsize, nFlags)
  
  hIcon = buf2dword(SUBSTR(cBuffer, 1, 4))
  nTypeIndex = buf2dword(SUBSTR(cBuffer,5, 4))
  cFileType = STRTRAN(SUBSTR(m.cBuffer,13+MAX_PATH), CHR(0),"")

  IF hIcon <> 0
    = DestroyIcon(hIcon)
  ENDIF

PROCEDURE declare
  DECLARE INTEGER DestroyIcon IN user32 INTEGER hIcon

  DECLARE STRING StrFormatByteSizeA IN Shlwapi;
    INTEGER dw, STRING @pszBuf, INTEGER cchBuf

  DECLARE INTEGER SHGetFileInfo IN shell32;
    STRING pszPath, LONG dwFileAttributes,;
    STRING @psfi, LONG cbFileInfo, LONG uFlags

  DECLARE INTEGER SendMessage IN user32;
    INTEGER hWindow, INTEGER Msg,;
    INTEGER wParam, INTEGER lParam

  DECLARE INTEGER SendMessage IN user32 AS SendMessageS;
    INTEGER hWindow, INTEGER Msg,;
    INTEGER wParam, STRING @lParam

  DECLARE INTEGER SetWindowLong IN user32;
    INTEGER hWindow, INTEGER nIndex, INTEGER dwNewLong

  DECLARE INTEGER GetWindowLong IN user32;
    INTEGER hWindow, INTEGER nIndex

  DECLARE INTEGER GetWindowDC IN user32 INTEGER hWindow

  DECLARE INTEGER SystemParametersInfo IN user32;
    INTEGER uiAction, INTEGER uiParam,;
    STRING @pvParam, INTEGER fWinIni

  DECLARE INTEGER GetDeviceCaps IN gdi32;
    INTEGER hdc, INTEGER nIndex

  DECLARE INTEGER ReleaseDC IN user32;
    INTEGER hWindow, INTEGER hDC

ENDDEFINE

DEFINE CLASS SystemMessageFont As Custom
#DEFINE SPI_GETNONCLIENTMETRICS 0x0029
#DEFINE NONCLIENTMETRICS_SIZE 0x0154
#DEFINE LOGFONT_SIZE 0x003c
#DEFINE LOGPIXELSY 0x005a
  lfHeight=12
  lfFaceName="Arial"

PROCEDURE Init
  LOCAL cNonClientMetrics, cBuffer
  cNonClientMetrics=num2dword(NONCLIENTMETRICS_SIZE)
  cNonClientMetrics=PADR(cNonClientMetrics,;
    NONCLIENTMETRICS_SIZE, CHR(0))

  IF SystemParametersInfo(SPI_GETNONCLIENTMETRICS,;
    NONCLIENTMETRICS_SIZE, @cNonClientMetrics, 0) <> 0
    cBuffer=SUBSTR(cNonClientMetrics, 281, LOGFONT_SIZE)
    WITH THIS
      .lfHeight=buf2dword(SUBSTR(cBuffer,1,4))
      .lfFaceName=STRTRAN(SUBSTR(cBuffer,29,32), CHR(0),"")
    ENDWITH
  ENDIF

FUNCTION GetFontSize() As Number
  LOCAL hWindow, hDC, nPxPerInchY
  hWindow=_screen.HWnd
  hDC=GetWindowDC(hWindow)
  nPxPerInchY = GetDeviceCaps(hDC, LOGPIXELSY)
  ReleaseDC(hWindow, hDC)
RETURN ROUND((ABS(THIS.lfHeight) * 72) / nPxPerInchY, 0)

ENDDEFINE

FUNCTION buf2dword(lcBuffer)
RETURN Asc(SUBSTR(lcBuffer, 1,1)) + ;
  BitLShift(Asc(SUBSTR(lcBuffer, 2,1)),  8) +;
  BitLShift(Asc(SUBSTR(lcBuffer, 3,1)), 16) +;
  BitLShift(Asc(SUBSTR(lcBuffer, 4,1)), 24)

FUNCTION num2dword(lnValue)
#DEFINE m0 256
#DEFINE m1 65536
#DEFINE m2 16777216
  IF lnValue < 0
    lnValue = 0x100000000 + lnValue
  ENDIF
  LOCAL b0, b1, b2, b3
  b3 = Int(lnValue/m2)
  b2 = Int((lnValue - b3*m2)/m1)
  b1 = Int((lnValue - b3*m2 - b2*m1)/m0)
  b0 = Mod(lnValue, m0)
RETURN Chr(b0)+Chr(b1)+Chr(b2)+Chr(b3)  

每种文件类型的关联图标和说明存储在注册表中。

例如,若要获取 DBF 文件的这些关联,第一步是找到“HKEY_CLASSES_ROOT.dbf”注册表项。此项的默认值为“Visual.FoxPro.Table”。这意味着“HKEY_CLASSES_ROOT\Visual.FoxPro.Table”键必须位于下一个。

后者具有默认值“Microsoft Visual FoxPro Table”,这是操作系统坚持DBF文件类型的实际描述。

此项的“DefaultIcon”子项的值为“C:\Program Files\Microsoft Visual FoxPro 9\vfp9.exe,-103”。这意味着组图标 #103 资源存在于 VFP9 可执行文件中。

此资源包含操作系统在需要时用于表示视觉 FoxPro DBF 文件的几个图标;例如,在资源管理器窗口中显示文件列表时。

资源查看器显示此资源以及存储在 VFP9 可执行文件中的其他资源。

以类似的方式,任何其他文件类型(读取“文件扩展名”)都可以追溯到图标+描述对。

没有单一的规则,寻找关联的方法即使不是混乱,也是棘手的。走这条路需要相当广泛的编码。幸运的是,MS费心在SHGetFileInfo API调用中隐藏了该过程的复杂性。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-06-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 加菲猫的VFP 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
vfp创建垂直标签控件,效果还是不错的
加菲猫的VFP
2023/08/21
2630
vfp创建垂直标签控件,效果还是不错的
把表单放大看看,好玩的不只一点点
加菲猫的VFP
2023/08/21
1420
把表单放大看看,好玩的不只一点点
表单水平文字滚动,效果还有阴影
加菲猫的VFP
2023/08/21
2100
表单水平文字滚动,效果还有阴影
WIN32API使用“选择颜色”函数
加菲猫的VFP
2023/08/21
2650
WIN32API使用“选择颜色”函数
VFP打开系统“页面设置”对话框以指定打印页面的属性
加菲猫的VFP
2023/08/21
2620
VFP打开系统“页面设置”对话框以指定打印页面的属性
如何查找正在等待打印的打印机的打印任务
加菲猫的VFP
2023/08/21
2230
如何查找正在等待打印的打印机的打印任务
vfp使用win32 API 函数加密和解密文件
加菲猫的VFP
2023/08/21
3980
vfp使用win32 API 函数加密和解密文件
VFP生成随机加密密钥
加菲猫的VFP
2023/08/21
2200
VFP生成随机加密密钥
VFP多线程读取串口
因为我要发送的指令很多,所以当时用方案二同步去读取,结果很卡。方法一倒没有试过,但COM口只支持16个。
加菲猫的VFP
2023/08/21
3340
VFP多线程读取串口
【读书笔记】Windows程序设计5
与从BeginPaint函数返回的设备句柄不同,从GetDC返回的设备句柄中的裁剪区域是整个客户区,而不仅仅
zhang_derek
2022/12/21
2.5K0
【Win32】初识Win32编程
编译链接过程:将代码转换为机器语言,将生成的res文件和obj文件加上使用的库链接到一起,整合出一个exe文件,这是用编译器所感受不到的。
半生瓜的blog
2023/05/13
2.2K0
【Win32】初识Win32编程
C++日志系统如何设计
笔者在写作本章节的时候,并不敢把此章节的标题叫做《高性能日志系统的设计》,之所以不敢加上“高性能”三个字的原因是,第一,我的对于日志系统设计知识和经验都来自于学习和工作经验,我并不是原创者,只是知识的搬运工;第二,目前有许多优秀的、被广泛使用的开源的日志系统,他们给了我很多启发,不敢在此班门弄斧。不管怎样,笔者还是想写一些自己关于对日志系统的理解和经验,让我们开始吧。
范蠡
2018/12/12
2.6K0
C++日志系统如何设计
prg版的VFPENCRYPTION.FLL
作者试图使用 prg 重新实现 VFPENCRYPTION.FLL 以便于平替该 FLL。按照作者说明,还是有一些问题。仅供学习。
firstxinjie
2024/12/06
640
prg版的VFPENCRYPTION.FLL
VC编程常见问题解答收集贴
1.使用ModifyStyleEx改变了控件风格无效 答:修改之后,重绘一次,如果还不行的话,再试试看调用SetWindowPos(0,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_DRAWFRAME);
全栈程序员站长
2022/09/09
1.7K0
问题随记 —— 无法打开包括文件: “dirent.h”: No such file or directory
问题描述 CMake 时出现 以下问题 fatal error C1083: 无法打开包括文件: “dirent.h”: No such file or directory 解决方法 ① 创建 dirent.h 并将该头文件,复制下面代码并保存。 /* * Dirent interface for Microsoft Visual Studio * * Copyright (C) 1998-2019 Toni Ronkko * This file is part of dirent. Dire
繁依Fanyi
2023/05/07
1.9K0
问题随记 —— 无法打开包括文件: “dirent.h”: No such file or directory
简单的TCP客户端发包工具[通俗易懂]
链接:https://pan.baidu.com/s/1MzNUzwd7WwBat6vNMcu6Ow 密码:ibuv
全栈程序员站长
2022/10/04
3.7K0
简单的TCP客户端发包工具[通俗易懂]
From CVE-2017-0263 To Windows Menu Management Component
CVE-2017-0263 is a UAF vulnerability in Menu Management Component in win32k kernel module of Windows operating system, which was reported to be used to attack with an EPS vulnerability to interfere the French election. This article will simply analyze the CVE-2017-0263 part of the attacking sample in order to come up with the operation principle and basic exploiting idea of this vulnerability, and make a brief investigation into the Menu Management Component of Windows Window Manager Subsystem. The analyzing environment is Windows 7 x86 SP1 basic virtual machine.
稻草小刀
2022/12/12
4060
From CVE-2017-0263 To Windows Menu Management Component
API钩取
继续学习《逆向工程核心原理》,本篇笔记是第四部分:API钩取,主要介绍了调试钩取、DLL注入实现IAT钩取、API代码修改钩取和全局API钩取等内容
红客突击队
2022/09/29
8960
API钩取
游戏编程之三 DirectX SDK简介
Microsoft DirectX提供了一套非常优秀的应用程序接口,包含了设计高性能、实时应用程序的源代码。DirectX技术将帮助您建构下一代的电脑游戏和多媒体应用程序。它的内容包括了DirectDraw、DirectSound、DirectPlay、Direct3D和DirectInput等部分,它们分别主要应用在图形程序、声音程序等方面。
用户9184480
2024/12/17
1920
内网中关于MS-SAMR协议的利用
我们虽然拿到了修改/重置密码的权限,但我们又不想直接修改目标用户的密码,因为这样用户在登录时就会发现自己的密码被修改,此时有两种情况:
红队蓝军
2024/05/17
2640
内网中关于MS-SAMR协议的利用
相关推荐
vfp创建垂直标签控件,效果还是不错的
更多 >
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文