' open dialog
'  创建并显示打开的通用对话框，允许用户选择一个或多个文件。
'用 AfxOpenFileDialog 代替，具有现代风格
'nFilename = AfxOpenFileDialog(hWndForm, "打开图像文件", nFilename,pp , _
'                         "图像文件(*.bmp;*.jpg;*.jpeg;*.gif;*.png)|*.bmp;*.jpg;*.jpeg;*.gif;*.png", "bmp")
'默认文件夹最后不能带 \ 字符
'   hWnd:       （如果有） 的父窗口的句柄 
'   Caption:      标题将显示为对话框的标题。
'   FileSpec:     要显示的默认文件名。此参数还返回所选的文件，当用户关闭该对话框。
'   InitialDir:  对话框中将显示初始目录。如果此值为 null，则使用当前目录。
'   Filter:      .要在对话框中显示的文件的筛选器： 说明。这是一个分隔的字符串，将在"文件类型"组合框中产生可用的选项。
'   DefExtension: 默认文件扩展名适用于文件名，如果用户不提供一个。
'   Flags:          Win32 帮助下"OpenFileName"文件中所述的一个或多个值的组合。
'                 E.g.: %OFN_ALLOWMULTISELECT Or %OFN_FILEMUSTEXIST Or %OFN_NOCHANGEDIR 
'   CenterFlag:   TRUE  对中心对话框上的桌面屏幕。
'返回： 如果用户指定的文件名，然后单击确定按钮返回值为非零。如果取消对话框中为零。
'       参数包含将返回选定文件的名称。如果选择了多个文件然后 将会用 $Nul （Chr(0)) 分隔列表。用户可以使用 Parse$  函数来提取单个文件名称。
'                 OFN_ALLOWMULTISELECT	指定文件名列表框允许多选。
'                 OFN_CREATEPROMPT	如果用户指定了一个不存在的文件，这个标记使用对话框能提示用户是否新建这个文件。
'                 OFN_ENABLEHOOK	        激活在lpfnHook成员中指定的钩子函数。
'                 OFN_ENABLETEMPLATE	当用户打开一个文件夹时，引起对话框发送CDN_INCLUDEITEM通知消息到你的OFNHookProc程序。
'                 OFN_ENABLETEMPLATEHANDLE  指出hInstance成员能识别的包含预载对话框模板的数据块。如果这个标记被指定的，系统忽略lpTemplateName。	
'                 OFN_EXPLORER	          指出任何打开或另存为对话框使用新的Explorer风格的用户化模块。
'                 OFN_EXTENSIONDIFFERENT  指定用户输入的一个文件的扩展名与lpstrDefExt指定的扩展名不同。	
'                 OFN_FILEMUSTEXIST       指定用户仅可以在文件名登录字段中输入已存在的文件的名字。	
'                 OFN_HIDEREADONLY	  隐藏只读复选框
'                 OFN_LONGNAMES	          对于旧风格对话框，这个标记引起对话框使用长文件名。
'                 OFN_NOCHANGEDIR         如果当搜索文件时用户改变了目录的时候，恢复当前目录到它的初始值。	
'                 OFN_NODEREFERENCELINKS  引导对话框为选择的快捷方式（.LNK）文件返回路径和文件名。	
'                 OFN_NOLONGNAMES	  对于旧风格对话框，这个标识引起对话框去使用短文件名（8.3格式）。
'                 OFN_NONETWORKBUTTON	  隐藏和显示风格按钮。
'                 OFN_NOREADONLYRETURN	 指定返回的文件不带有只读复选框，不是在写保护的目录中。
'                 OFN_NOTESTFILECREATE	 指定文件不是在对话框关闭前建立的。
'                 OFN_NOVALIDATE	
'                 OFN_OVERWRITEPROMPT	 如果选择的文件已经存在，使用另存为对话框产生一个消息框。用户必须确认是否覆盖这个文件。
'                 OFN_PATHMUSTEXIST	 指定用户仅能输入的路径和文件名。
'                 OFN_READONLY	          当对话框建立时，显示被选择的只读复选框。
'                 OFN_SHAREAWARE          指出如果调用OpenFile函数因为网络共享冲突而失败，这个错误被忽略并且对话框返回选择的文件名。	
'                 OFN_SHOWHELP	          使对话框显示帮助按钮。
Function FF_OpenFileDialog(ByVal HWnd as HWnd, ByRef sCaption as String, ByRef FileSpec as String, ByRef InitialDir as String, ByRef Filter As String, ByRef DefExtension As String, ByVal Flags As UInteger, ByVal CenterFlag As Integer) As Integer
   
   Dim sFile As String
   Dim Ofn As OPENFILENAMEA  'OFNA
   Dim zFileTitle As ZString * MAX_PATH
   Dim zInitialDir As ZString * MAX_PATH
   Dim zTitle As ZString * MAX_PATH
   Dim zDefExt As ZString * 10
   Dim hHook As Integer
   
   Filter = FF_Replace(Filter, "|", Chr(0))
   
   If Len(InitialDir) = 0 Then InitialDir = Curdir
   
   Filter = Filter & Chr(0)
   zInitialDir = InitialDir & Chr(0)
   
   sFile = String(16383, 0)  '<- PLENTY OF ROOM FOR MULTIPLE FILES
   Mid(sFile, 1) = FileSpec
   
   zDefExt = DefExtension & Chr(0)
   zTitle = sCaption & Chr(0)
   
   ofn.lStructSize = SizeOf(OPENFILENAME)
   ofn.hWndOwner = HWnd
   ofn.lpstrFilter = StrPtr(Filter)
   ofn.nFilterIndex = 1
   ofn.lpstrFile = StrPtr(sFile)
   ofn.nMaxFile = Len(sFile)
   ofn.lpstrFileTitle = VarPtr(zFileTitle)
   ofn.nMaxFileTitle = Sizeof(zFileTitle)
   ofn.lpstrInitialDir = Varptr(zInitialDir)
   'ofn.FlagsEx           = 0
   If Len(zTitle) Then
      ofn.lpstrTitle = Varptr(zTitle)
   End If
   
   'If needed, hook the Common dialog so it centers on the screen
   If CenterFlag Then
      If Flags = 0 Then
         Flags = OFN_EXPLORER Or OFN_ENABLESIZING
      End If
      Flags = Flags Or OFN_ENABLEHOOK
      ofn.lpfnHook = Cast(LPOFNHOOKPROC, @FF_CenterOpenFileDialog)
   End If
   
   ofn.Flags = Flags
   ofn.lpstrDefExt = Varptr(zDefExt)
   
   Function = GetOpenFileNameA(ByVal Varptr(ofn))
   
   Filespec = RTrim(sFile, chr(0))  ' return the filename(s)
   
End Function
' Help function for FF_OpenFileDialog that will center the dialog on the screen.
Function FF_CenterOpenFileDialog(ByVal HWnd as HWnd, ByVal wMsg as UInteger, ByVal wParam as WPARAM, ByVal lParam as LPARAM) as Long
   
   Dim pNMHDR as NMHDR Ptr
   Dim rc1 as Rect
   Dim rc2 as Rect
   
   If wMsg = WM_NOTIFY Then
      pNMHDR = Cast(Any Ptr, lParam)
      
      If pNMHDR->Code = CDN_INITDONE Then
         GetWindowRect GetDesktopWindow, VarPtr(rc1)
         GetWindowRect GetParent(HWnd), VarPtr(rc2)
         SetWindowPos GetParent(HWnd), HWND_TOPMOST, (rc1.Left + rc1.Right - rc2.Right + rc2.Left) / 2, _
            (rc1.Top + rc1.Bottom - rc2.Bottom + rc2.Top) / 2, 0, 0, SWP_NOSIZE Or SWP_NOACTIVATE
         
         Function = True : Exit Function
      End If
      
   End If
   
End Function
