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

关键字: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 Function
lblExit:
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
    点赞
  • 1
    收藏
  • 打赏
    打赏
  • 0
    评论
VB相册(缩略图预览程序) VB小型相册,实际上是一个图片浏览程序,打开显示缩略图,鼠标点击显示大图片,并可接着浏览下去,程序相关说明:   函数功能: 该函数将指定位图位拷贝到缓冲区里?   函数原型:LONG GetBitmapBits(HBITMAP hbmp, LONG cbBuffer, LPVOID lpvBits);   参数:   hbmp:指向感兴趣位图句柄?   cbBuffer:指定要从位图拷贝到缓冲区字节数?   lpvBits:指向接收位图位数据缓冲区指针?这些位是按字节类型存储在数组?   返回值:如果该函数执行成功,那么返回值就是拷贝到缓冲区字节数;如果该函数执行失败,那么返回值为0。   Declare Function GetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal nwCount As Long, lpBits As Any) As Long      函数功能:该函数将位图颜色数据位设置成指定值?   函数原型:LONG SetBitmapBits(HBITMAP hmbp, DWORD cBytes, CONST VOID (lpBits);   参数:   hbmp:指向要设置位图句柄?   cBytes:指定参数lpBits指向数组字节数?   lpBits:指向字节类型数组指针?该数组包含了指定位图颜色数据?   返回值:如果该函数执行成功,则返回值就是在设置位图位使用字节数;如果失败,则返回值为0。      函数功能:该函数得到指定图形对象信息,根据图形对象,函数把填满或结构,或表项(用于逻辑调色板)数目放入一个指定缓冲区。   函数原型:int GetObject(HGDIOBJ hgdiobj, int cbBuffer, LPVOID lpvObject);   参数:   hgdiobj:指向感兴趣图形对象句柄,它可以是这样一个句柄:一个逻辑位图、一个刷子、一种字体、一个调色板、笔或通过调用CreateDIBsection函数创建与设备无关位图。   cbBuffer:指定将要写到缓冲区信息字节数目?‘lpvObject:指向一个缓冲区指针,该缓冲区将要检索指定图形对象信息。      函数功能描述:将一块内存数据从一个位置复制到另一个位置   函数原型:VOID CopyMemory(PVOID Destination,CONST VOID *Source,DWORD Length);   参数:   Destination:要复制内存块地址?   Source:要复制内存块源地址?   Length:指定要复制内存块大小,单位为字节   返回值:该函数为VOID型,没有返回值。
Option Explicit Global Const mm = 567 Global Const cm = 567 Global Const NM_PP_Ofs = 0 '36 Global Const Gray = &HC0C0C0 Global Scala As Single Global Const ANTEPRIMA = 0 Global Const STAMPANTE = 1 Global Const NONESCLUSIVO = 0 Global Const ESCLUSIVO = 1 Global LocPerc As String Global Const LocName = "_$$_TEMP.TMP" Global Ofs As Single Global Const SistemaCoordinate = 0 Global NM_AnnullaStampa As Boolean Global TempDemoMode As Boolean Sub SistemaBarra(sP As Integer, eP As Integer, aP As Integer) ' PrnPRN.sBar > max bar ' PrnPRN.aBar > actual value ' ' sP = start page ' eP = end page ' aP = actual page Static Stp As Single Stp = PrnPrn.tBar.Width / ((eP - sP) + 1) PrnPrn.pBar.Width = Stp * aP End Sub Function TempFileExists(MyFilename As String) As Boolean Dim TempAttr As Double TempFileExists = True On Error GoTo MyErrorFileExist TempAttr = FileLen(MyFilename) GoTo MyExitFileExist MyErrorFileExist: TempFileExists = False Resume MyExitFileExist MyExitFileExist: On Error GoTo 0 End Function Sub ContaPagine() PrnPrv.MousePointer = vbHourglass Static NumPag As Integer NumPag = 0 Static A As String, B As String PrnPrv.ePag.Clear Open LocPerc + LocName For Append As #27: Close #27 '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Open LocPerc + LocName For Input As #27 While Not EOF(27) Line Input #27, A If A = "#startpage" Then NumPag = NumPag + 1 ElseIf A = "#endpage" Then PrnPrv.ePag.AddItem Format(NumPag) End If Wend Close #27 If PrnPrv.ePag.ListCount > 0 Then PrnPrv.ePag.ListIndex = 0 Else PrnPrv.MousePointer = vbDefault MsgBox "No pages to print!", vbInformation, "Preview non available" Unload PrnPrv End If PrnPrv.MousePointer = vbDefault End Sub Sub SistemaStatusBar()

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论

打赏作者

老碧鹅

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值