自動で[プリンターのプロパティ]を呼び出し、[ノズルチェックパターン印刷]を実施するプログラムをVBで制作したいと思います。
途中、FindWindow関数実施時、2番目の引数(ウィンドウ名)の値が実施するたびに勝手に減っていきます。
ましてByVal参照なのに勝手に引数の値が変わる理由がわからず、アドバイスをお願いいたします。
ちなみに、プログラムを実行すると[プリンターのプロパティ]ウィンドウまでは出ます。
手動でのマウス操作は正常にタブ操作、ボタン操作できます。
●ソースコード(Form1.vb):Form1にはButton1のみ配置
VB.net
1Public Class Form1 2 3 Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" _ 4 (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer 5 6 Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" _ 7 (ByVal hwndParent As Integer, ByVal hwndChildAfter As Integer, _ 8 ByVal lpszClass As String, ByVal lpszWindow As String) As Integer 9 10 11 'SendMessage用 12 Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" _ 13 (ByVal hWnd As Integer, ByVal MSG As Integer, _ 14 ByVal wParam As Integer, ByVal lParam As Integer) As Integer 15 16 17 Public Const BM_CLICK = &HF5 18 Public Const CB_SETCURSEL = &H14E& 19 20 Public Const WM_LBUTTONDOWN = &H201 21 Public Const WM_LBUTTONUP = &H202 22 23 Const MK_LBUTTON = &H1 24 25 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 26 Dim Printer_Name As String = "【ダミー】Canon Inkjet MP630 series" 27 28 'Processオブジェクトを作成 29 Dim p As New System.Diagnostics.Process() 30 31 'ComSpec(cmd.exe)のパスを取得して、FileNameプロパティに指定 32 p.StartInfo.FileName = System.Environment.GetEnvironmentVariable("ComSpec") 33 34 'ウィンドウを表示しないようにする 35 p.StartInfo.CreateNoWindow = True 36 'コマンドラインを指定("/c"は実行後閉じるために必要) 37 p.StartInfo.Arguments = "/c start rundll32 printui.dll, PrintUIEntry /e /n """ & Printer_Name & """" 38 39 '起動 40 p.Start() 41 42 'プロセス終了まで待機する 43 'WaitForExitはReadToEndの後である必要がある 44 '(親プロセス、子プロセスでブロック防止のため) 45 p.WaitForExit() 46 p.Close() 47 48 49 Dim hwnd1 As Integer 50 51 'Text: 【ダミー】Canon Inkjet MP630 series 印刷設定 52 hwnd1 = FW("#32770", Printer_Name & " 印刷設定") 53 Call FWex(hwnd1, 0, "SysTabControl32", "") 54 55 'とりあえずここまで、この後、タブ切り替え、ボタン操作にてノズルチェックパターン印刷を実施 56 57 End Sub 58 59 Private Function FW(ByVal Class_Name As String, ByVal Window_Name As String) 60 Dim hwnd As Integer = 0 61 Do Until hwnd > 0 62 Debug.Print("Window_Name:" & Window_Name) '←●今回のImmidiate Window出力 63 hwnd = FindWindow(Class_Name, Window_Name) 64 System.Threading.Thread.Sleep(200) '念のため0.2秒停止 65 My.Application.DoEvents() '描画フリーズ防止 66 Loop 67 FW = hwnd 68 Debug.Print(Window_Name & ":" & hwnd) 69 End Function 70 71 Private Function FWex(ByVal hwnd1 As Integer, ByVal Arg As Integer, ByVal Class_Name As String, ByVal Obj_Name As String) 72 Dim hwnd2 As Integer = 0 73 Do Until hwnd2 > 0 74 hwnd2 = FindWindowEx(hwnd1, 0, Class_Name, Obj_Name) 75 System.Threading.Thread.Sleep(200) '念のため0.2秒停止 76 My.Application.DoEvents() '描画フリーズ防止 77 Loop 78 FWex = hwnd2 79 Debug.Print(Obj_Name & "、" & Class_Name & ":" & hwnd2) 80 End Function 81 82End Class
●Immediate Window の出力
#######
Window_Name:【ダミー】Canon Inkjet MP630 series 印刷設定
Window_Name:【ダミー】Canon Inkjet MP630 series
Window_Name:【ダミー】Canon Inkjet MP630 s
Window_Name:【ダミー】Canon Inkjet MP
Window_Name:【ダミー】Canon Inkj
Window_Name:【ダミー】Canon
Window_Name:【ダミー】
Window_Name:【ダ・
Window_Name:【・
Window_Name:【
Window_Name:・
Window_Name:・
Window_Name:・
Window_Name:・
#######
ちなみに、FindWindow
の処理をFunction内ではなく、Private Sub Button1_Click
のまま実施すると、引数の値は変化せず、正常に該当hwndがヒットして処理が進みます。
VB.net
1 'hwnd1 = FW("#32770", Printer_Name & " 印刷設定") 2 Do Until hwnd1 > 0 3 Debug.Print("Window_Name:" & Printer_Name & " 印刷設定") 4 hwnd1 = FindWindow("#32770", Printer_Name & " 印刷設定") 5 System.Threading.Thread.Sleep(200) '念のため0.2秒停止 6 My.Application.DoEvents() '描画フリーズ防止 7 Loop
開発環境:
OS:Windows10x86 1703
Visual Studio 2013

回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/07/25 05:55