私はいくつかのタスクを自動化しています。「SendMessage」を使用して名前を付けて保存ダイアログボックスの「編集」ボックスに文字列を送信する必要があります。 "Save"ボタン( "SendMessage"と同様)を押すと、編集ボックスに正しく渡された文字列が以前にそこにあった文字列に変わる以外は、すべて正常に動作します。SendMessage WM_SETTEXT文字列の変更
-1
A
答えて
-1
最後に、いくつかのkeybd_eventsを使ってUI Automationで編集ボックスを設定することができました。 UIオートメーションのSetValueメソッドのみを使用できませんでした。最初に定義済みのパスを削除し、Ctrl + Aを押して送信したパスを選択しなければなりませんでした。ここにコードがあります。
Do
Ret = FindWindow(vbNullString, "Save As")
If Ret <> 0 Then
ChildRet = FindWindowEx(Ret, 0, "DUIViewWndClassName", vbNullString)
ChildRet = FindWindowEx(ChildRet, 0, "DirectUIHWND", vbNullString)
ChildRet = FindWindowEx(ChildRet, 0, "FloatNotifySink", vbNullString)
ChildRet = FindWindowEx(ChildRet, 0, "ComboBox", vbNullString)
ChildRet = FindWindowEx(ChildRet, 0, "Edit", vbNullString)
If ChildRet <> 0 Then
Thread.Sleep(3000)
keybd_event(VK_DELETE, MapVirtualKey(VK_DELETE, 0), 0, 0)
Thread.Sleep(100)
keybd_event(VK_DELETE, MapVirtualKey(VK_DELETE, 0), 2, 0)
elementEdit = AutomationElement.FromHandle(ChildRet)
elementEditTextBox = elementEdit.GetCurrentPattern(ValuePattern.Pattern)
elementEdit.SetFocus()
elementEditTextBox.SetValue(pathToSave)
keybd_event(VK_LCONTROL, MapVirtualKey(VK_LCONTROL, 0), 0, 0)
keybd_event(VK_KEY_A, MapVirtualKey(VK_KEY_A, 0), 0, 0)
Thread.Sleep(100)
keybd_event(VK_KEY_A, MapVirtualKey(VK_KEY_A, 0), 2, 0)
keybd_event(VK_LCONTROL, MapVirtualKey(VK_LCONTROL, 0), 2, 0)
Thread.Sleep(1000)
SaveAsWindowElements = AutomationElement.FromHandle(Ret).FindAll(TreeScope.Children, Condition.TrueCondition)
For Each element In SaveAsWindowElements
If element.Current.Name = "Save" Then
elementSaveButton = element.GetCurrentPattern(InvokePattern.Pattern)
elementSaveButton.Invoke()
End If
Next
End If
Else
Thread.Sleep(1000)
End If
Loop
-1
私は同じ問題を持っていたと私は私の完全なコードの下に、編集コンポーネントにキーストロークをシミュレートすることで解決:
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
static extern bool SetFocus(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = false)]
public static extern IntPtr GetDlgItem(IntPtr hDlg, int nIDDlgItem);
[DllImport("USER32.DLL")]
public static extern bool PostMessage(IntPtr hWnd, uint msg, uint wParam, uint lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern IntPtr SendMessage(HandleRef hWnd, uint Msg, IntPtr wParam, string lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
public const Int32 VK_SPACE = 0x20;
public const Int32 BM_CLICK = 0x00F5;
public const uint WM_SETTEXT = 0x000C;
enum KEYBOARD_MSG : uint
{
WM_KEYDOWN = 0x100,
WM_KEYUP = 0x101
}
public static async void SaveFileName(string text)
{
IntPtr exportWindow = GetForegroundWindow();
IntPtr comboHandle = GetDlgItem(exportWindow, 13006); //check this control ID is correct
IntPtr editHandle = GetDlgItem(comboHandle, 1001); //check this control ID is correct
SetControlText(comboHandle, 1001, text); //check this control ID is correct
SetFocus(editHandle);
//need to simulate a keystroke or the path won't come throught
PostMessage(editHandle, (uint)KEYBOARD_MSG.WM_KEYDOWN, VK_SPACE, 0);
ClickControl(exportWindow, "&Save");
}
/// <summary>
/// Sets the text value of a control using Win32API
/// </summary>
/// <param name="windowHandle">Handle of the windows the control belongs to</param>
/// <param name="controlId">ID of the control, to get it use WinSpy and convert the value fron Hex to Decimal</param>
/// <param name="text">String to be set</param>
private static void SetControlText(IntPtr windowHandle, int controlId, string text)
{
IntPtr iptrHWndControl = GetDlgItem(windowHandle, controlId);
HandleRef hrefHWndTarget = new HandleRef(null, iptrHWndControl);
SendMessage(hrefHWndTarget, WM_SETTEXT, IntPtr.Zero, text);
}
/// <summary>
/// Clicks a button using Win32API
/// </summary>
/// <param name="windowHandle">Handle of the windows the control belongs to</param>
/// <param name="buttonText">Label of the button, to get it correctly use WinSpy</param>
private static void ClickControl(IntPtr windowHandle, string buttonText)
{
IntPtr export = FindWindowEx(windowHandle, IntPtr.Zero, null, buttonText);
SendMessage(export, BM_CLICK, IntPtr.Zero, IntPtr.Zero);
}
は、UIオートメーションを使用する方が良いと思いませんか? –
ターゲットアプリケーションがバグです。おそらく、キーボードメッセージのみに応答して入力を処理/検証します。標準のEDITコントロールは正しいテキストを表示しますが、アプリケーションは変更を認識しません(マウスを使用してEDITコントロールにテキストを貼り付けると同じ問題が発生する可能性があります)。これはあなた自身がバグのコードを書くべきではありません。メッセージを送信して偽の入力を停止します。適切なツール、[UI Automation](https://msdn.microsoft.com/en-us/library/windows/desktop/ee684009.aspx)を使用してください。 – IInspectable
@IInspectableターゲットアプリケーションが標準の名前を付けて保存ダイアログ( 'GetSaveFileName()'または 'IFileSaveDialog')を使用している場合、キーボード入力に応答してファイル名の処理/検証を行うダイアログは適用されませんどのようにそれがそこにあったかにかかわらず、編集コントロール内のファイル名に関係なく、アプリに。 –