SendMessage WM_SETTEXT字符串更改

时间:2016-05-09 15:52:20

标签: winapi sendmessage

我正在自动执行一些任务,我需要将一个字符串发送到"编辑"使用' SendMessage'在另存为对话框中的框一切正常,除非按下" Save"按钮(还有' SendMessage'以及正确传递给编辑框的字符串更改为以前存在的字符串...有什么想法吗?

2 个答案:

答案 0 :(得分:-1)

最后,我设法用一些keybd_events设置带有UI自动化的编辑框。 仅使用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 :(得分:-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);
}