热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

请教下GetOpenFileNameW文件多选的问题

因为需要用COMMONDIALG选择一些UNICODE编码的文件名用GetOpenFileNameW选择单个文件可以正确获取到文件名包括为什么多选的话,只能返回一个目录呢,谢谢。
因为需要用COMMONDIALG选择一些UNICODE编码的文件名
用GetOpenFileNameW 选择单个文件可以正确获取到文件名包括
为什么多选的话,只能返回一个目录呢,谢谢。

5 个解决方案

#1


http://msdn.microsoft.com/en-us/library/windows/desktop/ms646839(v=vs.85).aspx

#2


唉,给你写一个凑合着用吧。标准点的封装(比如说按comdlg32.ocx或.net的windowsforms中的风格尽量写完整)就不是一时半会能弄出来的了。
调用:
Private Sub Command1_Click()
    TestVBGetOpenFileName
End Sub
Private Sub TestVBGetOpenFileName()
    Dim bResult As Boolean, sFilename As String
    bResult = VBGetOpenFileName(sFilename, "打开文件", True, True)
    If (bResult) Then
        'MsgBox Join(Split(sFilename, vbNullChar), vbCrLf)  '内置的MsgBox不支持ansi
        MessageBox Me.hWnd, Join(Split(sFilename, vbNullChar), vbCrLf), Me.Caption, vbOKOnly
    End If
    
End Sub


封装的模块:
Option Explicit
Private Declare Function GetOpenFileName Lib "comdlg32.dll" Alias "GetOpenFileNameW" (pOpenfilename As OPENFILENAME) As Long
Private Declare Function MessageBoxW Lib "user32" (ByVal hWnd As Long, ByVal lpText As Long, _
    ByVal lpCaption As Long, ByVal wType As Long) As Long
Private Const MAX_PATH = 4096
Private Const MAX_FILE = 260

  Private Type OPENFILENAME
    lStructSize As Long
    hwndOwner As Long
    hInstance As Long
    lpstrFilter As Long
    lpstrCustomFilter As String
    nMaxCustFilter As Long
    nFilterIndex As Long
    lpstrFile As Long
    nMaxFile As Long
    lpstrFileTitle As Long
    nMaxFileTitle As Long
    lpstrInitialDir As Long
    lpstrTitle As Long
    flags As Long
    nFileOffset As Integer
    nFileExtension As Integer
    lpstrDefExt As Long
    lCustData As Long
    lpfnHook As Long
    lpTemplateName As String
End Type
Public Enum EOpenFile
    OFN_READONLY = &H1
    OFN_OVERWRITEPROMPT = &H2
    OFN_HIDEREADONLY = &H4
    OFN_NOCHANGEDIR = &H8
    OFN_SHOWHELP = &H10
    OFN_ENABLEHOOK = &H20
    OFN_ENABLETEMPLATE = &H40
    OFN_ENABLETEMPLATEHANDLE = &H80
    OFN_NOVALIDATE = &H100
    OFN_ALLOWMULTISELECT = &H200
    OFN_EXTENSIONDIFFERENT = &H400
    OFN_PATHMUSTEXIST = &H800
    OFN_FILEMUSTEXIST = &H1000
    OFN_CREATEPROMPT = &H2000
    OFN_SHAREAWARE = &H4000
    OFN_NOREADONLYRETURN = &H8000
    OFN_NOTESTFILECREATE = &H10000
    OFN_NONETWORKBUTTON = &H20000
    OFN_NOLONGNAMES = &H40000
    OFN_EXPLORER = &H80000  '它使用类似资源管理器的打开一个文件的对话框模板。
    OFN_NODEREFERENCELINKS = &H100000
    OFN_LONGNAMES = &H200000
End Enum
' Common dialog errors

Private Declare Function CommDlgExtendedError Lib "COMDLG32" () As Long

Public Enum EDialogError
    CDERR_DIALOGFAILURE = &HFFFF

    CDERR_GENERALCODES = &H0
    CDERR_STRUCTSIZE = &H1
    CDERR_INITIALIZATION = &H2
    CDERR_NOTEMPLATE = &H3
    CDERR_NOHINSTANCE = &H4
    CDERR_LOADSTRFAILURE = &H5
    CDERR_FINDRESFAILURE = &H6
    CDERR_LOADRESFAILURE = &H7
    CDERR_LOCKRESFAILURE = &H8
    CDERR_MEMALLOCFAILURE = &H9
    CDERR_MEMLOCKFAILURE = &HA
    CDERR_NOHOOK = &HB
    CDERR_REGISTERMSGFAIL = &HC

    PDERR_PRINTERCODES = &H1000
    PDERR_SETUPFAILURE = &H1001
    PDERR_PARSEFAILURE = &H1002
    PDERR_RETDEFFAILURE = &H1003
    PDERR_LOADDRVFAILURE = &H1004
    PDERR_GETDEVMODEFAIL = &H1005
    PDERR_INITFAILURE = &H1006
    PDERR_NODEVICES = &H1007
    PDERR_NODEFAULTPRN = &H1008
    PDERR_DNDMMISMATCH = &H1009
    PDERR_CREATEICFAILURE = &H100A
    PDERR_PRINTERNOTFOUND = &H100B
    PDERR_DEFAULTDIFFERENT = &H100C

    CFERR_CHOOSEFONTCODES = &H2000
    CFERR_NOFONTS = &H2001
    CFERR_MAXLESSTHANMIN = &H2002

    FNERR_FILENAMECODES = &H3000
    FNERR_SUBCLASSFAILURE = &H3001
    FNERR_INVALIDFILENAME = &H3002
    FNERR_BUFFERTOOSMALL = &H3003

    CCERR_CHOOSECOLORCODES = &H5000
End Enum
Private Declare Function MoveFile Lib "kernel32" Alias "MoveFileW" (lpExistingFileName As Any, ByVal lpNewFileName As Long) As Long
Private Declare Function lstrlen Lib "kernel32" Alias "lstrlenW" (ByVal lpString As Long) As Long
Function VBGetOpenFileName(Filename As String, _
                           Optional FileTitle As String, _
                           Optional FileMustExist As Boolean = True, _
                           Optional MultiSelect As Boolean = False, _
                           Optional ReadOnly As Boolean = False, _
                           Optional HideReadOnly As Boolean = False, _
                           Optional Filter As String = "All (*.*)| *.*", _
                           Optional FilterIndex As Long = 1, _
                           Optional InitDir As String, _
                           Optional DlgTitle As String, _
                           Optional DefaultExt As String, _
                           Optional Owner As Long = -1, _
                           Optional flags As Long = 0) As Boolean

    Dim opfile As OPENFILENAME, s As String, afFlags As Long, lApiReturn As Long, lExtendedError As Long
    
    lApiReturn = 0
    lExtendedError = 0

With opfile
    .lStructSize = Len(opfile)
    
    ' Add in specific flags and strip out non-VB flags
    
    .flags = (-FileMustExist * OFN_FILEMUSTEXIST) Or _
            (-MultiSelect * OFN_ALLOWMULTISELECT) Or _
             (-ReadOnly * OFN_READONLY) Or _
             (OFN_EXPLORER) Or _
             (-HideReadOnly * OFN_HIDEREADONLY) Or _
             (flags And CLng(Not (OFN_ENABLEHOOK Or _
                                  OFN_ENABLETEMPLATE)))
    ' Owner can take handle of owning window
    If Owner <> -1 Then .hwndOwner = Owner
    ' InitDir can take initial directory string
    .lpstrInitialDir = StrPtr(InitDir)
    ' DefaultExt can take default extension
    .lpstrDefExt = StrPtr(DefaultExt)
    ' DlgTitle can take dialog box title
    .lpstrTitle = StrPtr(DlgTitle)
    
    ' To make Windows-style filter, replace | and : with nulls
    Dim ch As String, i As Integer
    For i = 1 To Len(Filter)
        ch = Mid$(Filter, i, 1)
        If ch = "|" Or ch = ":" Then
            s = s & vbNullChar
        Else
            s = s & ch
        End If
    Next
    ' Put double null at end
    s = s & vbNullChar & vbNullChar
    .lpstrFilter = StrPtr(s)
    .nFilterIndex = FilterIndex

    ' Pad file and file title buffers to maximum path
    Filename = Filename & String$(MAX_PATH - Len(Filename), 32)
    .lpstrFile = StrPtr(Filename)
    .nMaxFile = MAX_PATH
    s = FileTitle & String$(MAX_FILE - Len(FileTitle), 0)
    .lpstrFileTitle = StrPtr(s)
    .nMaxFileTitle = MAX_FILE
    ' All other fields set to zero
    
    lApiReturn = GetOpenFileName(opfile)
    Select Case lApiReturn
    Case 1
        ' Success
        VBGetOpenFileName = True
        Filename = Str2ZeroToStr(Filename)
        'FileTitle = StrZToStr(.lpstrFileTitle)
        flags = .flags
        ' Return the filter index
        FilterIndex = .nFilterIndex
        ' Look up the filter the user selected and return that
        'Filter = FilterLookup(.lpstrFilter, FilterIndex)
        If (.flags And OFN_READONLY) Then ReadOnly = True
    Case 0
        ' Cancelled
        VBGetOpenFileName = False
        Filename = ""
        FileTitle = ""
        flags = 0
        FilterIndex = -1
        Filter = ""
    Case Else
        ' Extended error
        lExtendedError = CommDlgExtendedError()
        VBGetOpenFileName = False
        Filename = ""
        FileTitle = ""
        flags = 0
        FilterIndex = -1
        Filter = ""
    End Select
End With
End Function

Public Function StrZToStr(s As String) As String
    StrZToStr = Left$(s, lstrlen(StrPtr(s)))
End Function
'---------------------------------------------------------------------------------------
' 过程名    : Str2ZeroToStr
' 时间      : 2013/7/26
' 作者      : 杨过.网狐.cn(csdn bcrun)
' 功能      : 将有效值部分以2个连续空格结束的字符串的有效部分提取出来
' 输入输出  :
' 说明      :
' 备注      : 星辰设计室VB一群:283362041,星辰学园BASIC辅导群:289219875
'---------------------------------------------------------------------------------------

Public Function Str2ZeroToStr(s As String) As String
    Str2ZeroToStr = s
    Dim iPos As Long
    iPos = InStr(1, Str2ZeroToStr, vbNullChar & vbNullChar)
    If (iPos > 0) Then
        Str2ZeroToStr = Left$(Str2ZeroToStr, iPos - 1)
    End If
    
End Function

Private Function FilterLookup(ByVal sFilters As String, ByVal iCur As Long) As String
    Dim iStart As Long, iEnd As Long, s As String
    iStart = 1
    If sFilters = "" Then Exit Function
    Do
        ' Cut out both parts marked by null character
        iEnd = InStr(iStart, sFilters, vbNullChar)
        If iEnd = 0 Then Exit Function
        iEnd = InStr(iEnd + 1, sFilters, vbNullChar)
        If iEnd Then
            s = Mid$(sFilters, iStart, iEnd - iStart)
        Else
            s = Mid$(sFilters, iStart)
        End If
        iStart = iEnd + 1
        If iCur = 1 Then
            FilterLookup = s
            Exit Function
        End If
        iCur = iCur - 1
    Loop While iCur
End Function

Public Function MessageBox(ByVal hWnd As Long, ByVal lpText As String, _
    ByVal lpCaption As String, ByVal wType As Long) As Long
    MessageBox = MessageBoxW(hWnd, StrPtr(lpText), StrPtr(lpCaption), wType)
End Function

#3


通常我都是用CommonDialog控件,怎么你这个不能用这个控件吗?

#4


汗,包括CommonDialog控件在内的很多activex控件都不支持UNICODE的,不信你用这样的字符做文件名打开试试:㐁떡 

#5


感谢了,bcrun,可以用,我再仔细看看

推荐阅读
  • 开机自启动的几种方式
    0x01快速自启动目录快速启动目录自启动方式源于Windows中的一个目录,这个目录一般叫启动或者Startup。位于该目录下的PE文件会在开机后进行自启动 ... [详细]
  • [转]doc,ppt,xls文件格式转PDF格式http:blog.csdn.netlee353086articledetails7920355确实好用。需要注意的是#import ... [详细]
  • 本文详细解析了使用C++实现的键盘输入记录程序的源代码,该程序在Windows应用程序开发中具有很高的实用价值。键盘记录功能不仅在远程控制软件中广泛应用,还为开发者提供了强大的调试和监控工具。通过具体实例,本文深入探讨了C++键盘记录程序的设计与实现,适合需要相关技术的开发者参考。 ... [详细]
  • 如果应用程序经常播放密集、急促而又短暂的音效(如游戏音效)那么使用MediaPlayer显得有些不太适合了。因为MediaPlayer存在如下缺点:1)延时时间较长,且资源占用率高 ... [详细]
  • VB.net 进程通信中FindWindow、FindWindowEX、SendMessage函数的理解
    目录一、代码背景二、主要工具三、函数解析1、FindWindow:2、FindWindowEx:3、SendMessage: ... [详细]
  • 本文介绍了如何在 Vue 3 组合 API 中正确设置 setup() 函数的 TypeScript 类型,以避免隐式 any 类型的问题。 ... [详细]
  • WinMain 函数详解及示例
    本文详细介绍了 WinMain 函数的参数及其用途,并提供了一个具体的示例代码来解析 WinMain 函数的实现。 ... [详细]
  • 网站访问全流程解析
    本文详细介绍了从用户在浏览器中输入一个域名(如www.yy.com)到页面完全展示的整个过程,包括DNS解析、TCP连接、请求响应等多个步骤。 ... [详细]
  • window下的python安装插件,Go语言社区,Golang程序员人脉社 ... [详细]
  • 在Delphi7下要制作系统托盘,只能制作一个比较简单的系统托盘,因为ShellAPI文件定义的TNotifyIconData结构体是比较早的版本。定义如下:1234 ... [详细]
  • php更新数据库字段的函数是,php更新数据库字段的函数是 ... [详细]
  • XAMPP 遇到 404 错误:无法找到请求的对象
    在使用 XAMPP 时遇到 404 错误,表示请求的对象未找到。通过详细分析发现,该问题可能由以下原因引起:1. `httpd-vhosts.conf` 文件中的配置路径错误;2. `public` 目录下缺少 `.htaccess` 文件。建议检查并修正这些配置,以确保服务器能够正确识别和访问所需的文件路径。 ... [详细]
  • 本文探讨了资源访问的学习路径与方法,旨在帮助学习者更高效地获取和利用各类资源。通过分析不同资源的特点和应用场景,提出了多种实用的学习策略和技术手段,为学习者提供了系统的指导和建议。 ... [详细]
  • 2018年9月21日,Destoon官方发布了安全更新,修复了一个由用户“索马里的海贼”报告的前端GETShell漏洞。该漏洞存在于20180827版本的某CMS中,攻击者可以通过构造特定的HTTP请求,利用该漏洞在服务器上执行任意代码,从而获得对系统的控制权。此次更新建议所有用户尽快升级至最新版本,以确保系统的安全性。 ... [详细]
  • 在进行网络编程时,准确获取本地主机的IP地址是一项基本但重要的任务。Winsock作为20世纪90年代初由Microsoft与多家公司共同制定的Windows平台网络编程接口,为开发者提供了一套高效且易用的工具。通过Winsock,开发者可以轻松实现网络通信功能,并准确获取本地主机的IP地址,从而确保应用程序在网络环境中的稳定运行。此外,了解Winsock的工作原理及其API函数的使用方法,有助于提高开发效率和代码质量。 ... [详细]
author-avatar
话说的爱
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有