vb.net 调用windows传真和扫描

前言

windows传真和扫描 程序 是WFS.exe,文件路径是 "c:\windows\system32\WFS.exe",然而我尝试在此用代码来启动,换了三种方法都提示说找不到文件,而我用运行命令却能够打来,估计是可能要设置某些权限的问题。时间问题没细捣。

程序大体如此,上下各三个文本框,中间一个按键。

模块代码:

Imports System.Text   ''当变量为 StringBuilder类型时必须引用

Module FindWinAndSenNews
    ''参考网址: https://www.cnblogs.com/del/category/122464.html

    ''查找窗体和发送信息

    ''查找窗体句柄使用API,上一个是取得主程序窗口句柄,下一个是子窗体。
    Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer
    ''lpClassName As String :窗口的类名
    ''l lpWindowNameAs String :窗口的标题
    ''本函数的返回值:H返回窗口的句柄; 失败则返回 0
    ''例:  GW_SaveAs_hwnd = FindWindow(vbNullString, "Save Sound As")    '检索主窗体句柄

    '根据主程序检索子窗口句柄
    Public Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Integer, ByVal hWnd2 As Integer, ByVal lpsz1 As String, ByVal lpsz2 As String) As Integer
    ''hWnd1 As Integer : 要查找子窗口的父窗口句柄,如果是 0, 则函数以桌面窗口为父窗口, 查找桌面窗口的所有子窗口;如果是 HWND_MESSAGE, 函数仅查找所有消息窗口;
    ''hWnd2 As Integer : 子窗口句柄,如果是 0, 查找从 父窗口 的第一个子窗口开始;
    ''lpsz1 As String  : 子窗口的类名
    ''lpsz2 As String  : 可以是 vbNullString
    ''本函数的返回值:H返回窗口的句柄; 失败则返回 0
    ''例:   subClassName = FindWindowEx(GW_SaveAs_hwnd, 0, "DUIViewWndClassName", vbNullString)  

    '’返回与指定窗口有特定关系(如Z序或所有者)的窗口句柄,函数原型是HWND GetWindow(HWND hWnd, UINT nCmd)。
    ''设置窗体全屏、设置和取消窗体始终点亮、增加窗体常亮的特性、设置窗体背景模糊等
    ''相 GetWindow 相关的有:GetTopWindow和GetNextWindow
    Public Declare Function GetWindow Lib "user32" (ByVal hwnd As Int32, ByVal wCmd As Int32) As Int32

    ''获得指定窗口的可视状态,即显示或者隐藏。
    Public Declare Function IsWindowVisible Lib "user32" (ByVal hwnd As Int32) As Int32

    ''获取窗口标题长度
    Public Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd As Int32) As Int32

    ''由主程序窗口句柄取得主程序标题名
    Public Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Int32, ByVal lpString As StringBuilder, ByVal cch As Int32) As Int32

    ''由主程序窗口句柄取得主程序类名
    Public Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Int32, ByVal lpClassName As StringBuilder, ByVal nMaxCount As Int32) As Int32

    ''休眠,发送按键信息时用到,中止零点几秒
    Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Int32)

    ''发送信息用
    Public Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Int32, ByVal wMsg As Int32, ByVal wParam As Int32, ByVal lParam As Int32) As Int32
    Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Int32, ByVal wMsg As Int32, ByVal wParam As Int32, ByVal lParam As String) As Int32

    ''发送按键
    Public Declare Function MapVirtualKey Lib "user32" Alias "MapVirtualKeyA" (ByVal wCode As Int32, ByVal wMapType As Int32) As Int32
    Public Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Int32) As Int32
    Public Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Int32, ByVal dwExtraInfo As Int32)
    Public Const VK_Menu = &H12    ''MENU 键 = &H12
    Public Const WM_KEYDOWN = &H100             '按下一个键
    Public Const WM_KEYUP = &H101            '释放一个键
    Public Const WM_SYSKEYDOWN = &H104        '当用户按住ALT键同时按下其它键时提交此消息给拥有焦点的窗口 
    Public Const WM_SYSKEYUP = &H105            '当用户释放一个键同时ALT 键还按着时提交此消息给拥有焦点的窗口
    Public Const KEYEVENTF_KEYUP = &H2
    Public Const VK_F = &H46
    Public Const VK_Right = &H27
    Public Const VK_S = &H53
    Public Const VK_CONTROL = &H11   ''CTRL 键


    ''其他相关但少用到  :
    ''GetActiveWindow 只是获取当前程序中(严格地说是线程中)被激活的窗口;
    ''GetForegroundWindow 是获取当前系统中被激活的窗口.

    ''自定义变量
    Public My_Main_hWnd As Integer        '要查找的程序主窗口句柄

    Public Sub FileMainWindows(ByVal MyTittle As String, ByVal txtBox1 As TextBox, ByVal txtBox2 As TextBox, ByVal txtBox3 As TextBox)
        ''查找主程序窗体句柄、标题和类名
        ''在这里只用到一个FindWindow函数
        Dim title As New StringBuilder(256)
        Dim ClassName As New StringBuilder(256)

        '根据主窗体的标题名和窗体类别查找主窗体,并返回主窗体的句柄数
        My_Main_hWnd = FindWindow(vbNullString, MyTittle)  ''取得主程序窗口句柄,不知道主窗体的类名
        GetWindowText(My_Main_hWnd, title, 256)  ''由主程序窗口句柄取得主程序标题名
        txtBox1.Text = "主程序标题名:" & title.ToString
        GetClassName(My_Main_hWnd, ClassName, 256)  ''由主程序窗口句柄取得主程序类名
        txtBox2.Text = "主程序类名:" & ClassName.ToString
        txtBox3.Text = "主程序窗口句柄:" & Hex(My_Main_hWnd)  ''主程序窗口句柄

    End Sub

    Function MakeKeyLparam(ByVal VirtualKey As Int32, ByVal flag As Int32) As Int32
        Dim s As String
        Dim Firstbyte As String    'lparam参数的24-31位
        If flag = WM_KEYDOWN Then '如果是按下键
            Firstbyte = "00"
        Else
            Firstbyte = "C0"       '如果是释放键
        End If
        Dim Scancode As Int32
        '获得键的扫描码
        Scancode = MapVirtualKey(VirtualKey, 0)
        Dim Secondbyte As String   'lparam参数的16-23位,即虚拟键扫描码
        Secondbyte = Right("00" & Hex(Scancode), 2)
        s = Firstbyte & Secondbyte & "0001"  '0001为lparam参数的0-15位,即发送次数和其它扩展信息
        MakeKeyLparam = Val("&H" & s)
    End Function

    Function SendAltPlusKey(hwnd, vkey)  ''发送Alt+其他键命令
        keybd_event(VK_Menu, MapVirtualKey(VK_Menu, 0), 0, 0) '前台按下ALT键
        Sleep(100)
        'PostMessage(hwnd, WM_SYSKEYDOWN, vkey, MakeKeyLparam(vkey, WM_SYSKEYDOWN))''不起作用
        ''MsgBox(MakeKeyLparam(vkey, WM_SYSKEYDOWN))   ''运行结果为小数,不知何解
        PostMessage(hwnd, WM_SYSKEYDOWN, vkey, 1 << 29) ''当值为1时表示ALT键被按下,是需要效果,把29位设置为1
        Sleep(100)
        ''PostMessage(hwnd, WM_SYSKEYUP, vkey, MakeKeyLparam(vkey, WM_SYSKEYUP))''上面不起作用这句也没用
        PostMessage(hwnd, WM_SYSKEYUP, vkey, 1 << 29)

        Sleep(100)
        keybd_event(VK_Menu, MapVirtualKey(VK_Menu, 0), KEYEVENTF_KEYUP, 0) '前台释放ALT键
    End Function

    Function SendCtrlPlusKey(hwnd, vkey)  ''发送Ctrl+其他键命令
        keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), 0, 0) '前台按下Ctrl键
        Sleep(100)
        PostMessage(hwnd, WM_KEYDOWN, vkey, MakeKeyLparam(vkey, WM_KEYDOWN))
        ''MsgBox(MakeKeyLparam(vkey, WM_KEYDOWN))  ''运行结果为整数
        Sleep((200))
        PostMessage(hwnd, WM_KEYUP, vkey, MakeKeyLparam(vkey, WM_KEYUP))
        Sleep(100)
        keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), KEYEVENTF_KEYUP, 0) '前台释放Ctrl键
    End Function

    Function sendKey(hwnd, vkey)  ''发送单个按键(字母、数字等)
        PostMessage(hwnd, WM_KEYDOWN, vkey, MakeKeyLparam(vkey, WM_KEYDOWN))
        Sleep(100)
        PostMessage(hwnd, WM_KEYUP, vkey, MakeKeyLparam(vkey, WM_KEYUP))
    End Function

End Module
 

窗体代码:

Imports System.Text   ''当变量为 StringBuilder类型时必须引用
Imports System.Diagnostics
Public Class Form1


    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        ''查找主程序窗体的      名、      类、     句柄,并传给三个文本框
        Call FileMainWindows("Windows 传真和扫描", TextBox1, TextBox2, TextBox3)

        'My_Main_hWnd = FindWindow(vbNullString, "Windows 传真和扫描")  ''检查该程序是否已经在运行
        If My_Main_hWnd = 0 Then   ''确保只能运行一个窗体
            MsgBox("扫描程序没有运行。")
            Exit Sub
        End If

        ''发送ALT+F命令打开文件列表
        SetForegroundWindow(My_Main_hWnd)
        SendAltPlusKey(My_Main_hWnd, VK_F)
        Sleep(100)
        sendKey(My_Main_hWnd, VK_Right)
        Sleep(100)
        SendCtrlPlusKey(My_Main_hWnd, VK_S)

        Call subScanner()  ''向下一级窗体发送命令
    End Sub

    Private Sub subScanner()
        ''弱出的子窗体
        Dim subClassName As Integer
        Dim title As New StringBuilder(256)
        '扫描(& S)
        Call FileMainWindows("新扫描", TextBox4, TextBox5, TextBox6)

        subClassName = FindWindowEx(My_Main_hWnd, 0, vbNullString, "扫描(&S)")      '检索子窗口句柄
        SendCtrlPlusKey(subClassName, VK_S)

    End Sub


End Class

运行效果:

因为我没连接扫描机,所以下三行文本框没有结果。

补充:

另外,我本打算是发送命令到ToolBar栏中点击“新扫描”,然而ToolBar栏的找不到“新扫描”的句柄,可能要使用到枚举来查找或其他什么的,时间有限没有去实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值