如何实现VB中打开图像文件时的预览功能

    技术2022-05-11  118

    关键字:VB 预览

           前一阵有人在VB专家门诊中提出一个问题,如何在VB中实现打开图像文件的预览,虽然给出了300分的高分,回答着却寥寥无几。我在参照了DELPHI的源代码后在VB中实现了其部分图像预览功能,在中文WINDOWS98 SE下测试通过。

          从MSDN中可以知道调用文件打开通用对话框需调用API 函数GetOpenFileName,原形如下:

        BOOL GetOpenFileName( LPOPENFILENAME lpofn );// lpofn 为初始化数据结构的地址

          其参数lpofn指向类型为OPENFILENAME变量的地址,Windows已经为我们实现自定义的文件打开对话框留了接口。为了实现这个自定义的对话框,重点设置OPENFILENAME中的如下几个参数:

    Flags OFN_ENABLEHOOK   使由lpfnHook成员指定的钩子函数有效
     OFN_ENABLETEMPLATE 表示由lpTemplateName指定一个对话框模板资源,这个资源存在于由hInstance指定的模块中
    OFN_EXPLORER 如果指定了上述两个标志则必须指定这标志
    lpfnHook指向钩子函数的地址
    lpTemplateName对话框模板资源的字符串名,而不是ID

        就是说你要在你的程序中包含一个对话框模板,Windows将以这个模板为基础显示通用对话框。从很多资料上都可以知道如果要在自定义的对话框中显示通用对话框,在您的对话框资源中必须包含一个Static,它的ID是stc32,十进制值为1119,这个Static也就是显示原来通用对话框的地方。当然他对对话框也有一些要求,这里就不废话了,自己看MSDN吧。

          我们在一个可以制作对话框资源的环境(我用的是VC)中制作出这个对话框,并将它存为res文件。从这里开始我们进入VB IDE中,把这个资源文件加入到你的VB应用程序中,假设它的名字是“DLGOPENTEMP”。

          接下来我们在VB工程中加入一个FORM,假设它的名字是FrmPreview,将它的BorderStyle 设定为None。并将一个PictureBox或者Image加入到窗体中,名字就叫做Picture1吧,我们就将在它里边显示预览的内容。下边呢也就是最关键的一步,编写Hook。

          在工程中加入一个Module,名字无所谓啦。假设我们的钩子叫wndProc,定义如下:

    Public Function wndProc(ByVal hDlg As Long, ByVal uiMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long    On Error GoTo lblExit    Select Case uiMsg        Case WM_NOTIFY            CopyMemory NMHeader, ByVal lParam, Len(NMHeader)            Select Case NMHeader.code                Case CDN_INITDONE                    GetWindowRect GetDlgItem(hDlg, 1119), staticRect                    MapWindowPoints 0, hDlg, staticRect, 2                    SetParent FrmPreview.hwnd, hDlg                    FrmPreview.Visible = True                    FrmPreview.Move (staticRect.Right - staticRect.Left + 10) * Screen.TwipsPerPixelX, 5 * Screen.TwipsPerPixelX                    FrmPreview.Refresh                    wndProc = 0                Case CDN_SELCHANGE                    FrmPreview.LoadPic GetFilesName(hDlg)                    wndProc = 0            End Select        Case WM_DESTROY            FrmPreview.Visible = False            SetParent FrmPreview.hwnd, 0            Unload FrmPreview        Case Else    End Select    Exit FunctionlblExit:End Function

        在FrmPreview 中增加一个方法LoadPic,此方法将用户选中的可识别的图像文件显示在FrmPreview中的Picture1中,如何显示看您自己了。在得到CDN_SELCHANGE时,调用GetFilesName得到此时用户选中的文件,代码如下:

    Private Function GetFilesName(hWindow As Long) As String    Dim hParent As Long    Dim lRetValue As Long    Dim theFileName(1024) As Byte    For i = 0 To UBound(theFileName)        theFileName(i) = 0    Next    hParent = GetParent(hWindow)    lRetValue = SendMessage(hParent, CDM_GETFILEPATH, 1024, theFileName(0))    GetFilesName = StrConv(theFileName, vbUnicode)End Function

        调用GetOpenFileName API的方法如下:

    Public Function ShowOpenFileDlg(hParent As Long) As Long    On Error GoTo lblExit    Static strFilter As String    strFilter = "All Pictures" & Chr(0) & "*.bmp;*.dib;*.jpg;*.gif;*.wmf;*.emf;*.ico;*.cur" & Chr(0) & _    "Bitmap (*.bmp;*.dib)" & Chr(0) & "*.bmp;*.dib" & Chr(0) & _    "JPEG (*.jpg)" & Chr(0) & "*.jpg" & Chr(0) & _    "GIF (*.gif)" & Chr(0) & "*.gif" & Chr(0) & _    "Metafile (*.wmf;*.emf)" & Chr(0) & "*.wmf;*.emf" & Chr(0) & _    "Icons (*.ico;*.cur)" & Chr(0) & "*.ico;*.cur" & Chr(0) & _    "All files (*.*)" & Chr(0) & "*.*" & Chr(0) & Chr(0)    FrmPreview.Hide    pointer = GetProcAddr(AddressOf wndProc)    Dim MyID As Long    With openfile        .lStructSize = Len(openfile)        .hwndOwner = hParent        .hInstance = App.hInstance        .lpstrFilter = strFilter        .lpstrCustomFilter = ""        .nMaxCustFilter = 0         .nFilterIndex = 0        .lpstrFile = filesname        .nMaxFile = 1023        .lpstrFileTitle = ""        .nMaxFileTitle = 0        .lpstrInitialDir = ""        .lpstrTitle = ""        .flags = OFN_ENABLEHOOK + OFN_HIDEREADONLY + OFN_ENABLETEMPLATE + OFN_EXPLORER        .nFileOffset = 0        .nFileExtension = 0        .lpstrDefExt = ""        .lCustData = 0        .lpfnHook = pointer        .lpTemplateName = "DLGOPENTEMP"    End With    ShowOpenFileDlg = GetOpenFileName(openfile)lblExit:End Function

        文件就放在filesname里,它必须预先分配好空间。Soryy,又说废话了。

        这些代码没有经过严格的测试,只是实现了简单的功能,肯定存在很多BUG,如果哪位兄弟姐妹发现了或者给DEBUG了,别忘了给我妹一份。我的Email地址是wjxcn@263.net。


    最新回复(0)