Установка текста элемента управления редактирования в другом окне - PullRequest
3 голосов
/ 25 ноября 2011

Я пытаюсь программно изменить текст элемента управления для редактирования в диалоге «Сохранить как». Первая часть была простой - получить дескриптор окна «Сохранить как». Но найти элемент управления редактирования? Не так просто.

Во всяком случае, это код, который я дошел до сих пор. Может кто-нибудь сказать мне, где я иду не так?

[DllImport("user32.dll")]
public static extern Int32 SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, String lParam);

[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

[DllImport("user32.dll")]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

IntPtr dialog = FindWindow(null, "Save As");
if (dialog.ToInt32() != 0)
{
    IntPtr edit = FindWindowEx(dialog, IntPtr.Zero, "Edit", "");
    SendMessage(edit, 0x000C /* WM_SETTEXT */, IntPtr.Zero, "...");
}

Заранее спасибо!

Ответы [ 4 ]

7 голосов
/ 25 ноября 2011

Да. Это действительно сложный вопрос. Мне потребовалась 1 неделя, чтобы сделать его работоспособным, когда мне поручили работать с этим. В любом случае, я дал вам часть кода ниже. С помощью этого кода вы можете установить текст для элемента управления Edit диалогового окна Save / Open. Не ограничиваясь только этими задачами, с этим вы можете делать все что угодно с этим окном,

Посмотрите пожалуйста.

  public delegate int CallbackToFindChildWindow(int hWnd, int lParam);


    private void AccessEditControlOfDialog()
    {
        IntPtr winHandle = IntPtr.Zero;
        winHandle = GetActiveWindow();

        const int NumberOfChars = 256;
        string dialogCaption = string.Empty;
        StringBuilder buff = new StringBuilder(NumberOfChars);

        ////Getting the caption of window..eg.  Open/Save/Save as
        if (GetWindowText((int)winHandle, buff, NumberOfChars) > 0)
        {
            dialogCaption = buff.ToString();
        }

        ////Getting the ClassName of the Dialog Window handle
        StringBuilder winClassName = new StringBuilder();
        int numChars = GetClassName((IntPtr)winHandle, winClassName, winClassName.Capacity);

        int targetControlWinHandle;

        CallbackToFindChildWindow myCallBack = new CallbackToFindChildWindow(this.EnumChildGetValue);

        ////Find the window handle by using its caption
        targetControlWinHandle = FindWindow(null, dialogCaption);

        if (targetControlWinHandle == 0)
        {
            Logger.Error("No handle value is found in the Common Doalog");
        }
        else
        {
            EnumChildWindows(targetControlWinHandle, myCallBack, 0);
        }

    }

    private int EnumChildGetValue(int handleWnd, int param)
    {
        StringBuilder controlWinClassName = new StringBuilder();

        ////Getting the ClassName of the Control Window handle
        int numChars = GetClassName((IntPtr)handleWnd, controlWinClassName, controlWinClassName.Capacity);

        if (controlWinClassName != null)
        {
            string text = "hi";

            ////For Normal Common Dialog box, the class name of Edit box is "Edit" which is for office 2007 "RichEdit20W"
            if ((!string.Equals(controlWinClassName.ToString().Trim(), ""))
                && (controlWinClassName.ToString().Equals("Edit") || controlWinClassName.ToString().Equals("RichEdit20W")))
            {
                if (controlWinClassName.ToString().Equals("Edit"))
                {

                    //// Set Text to the Edit box                  
                    SendMessage(handleWnd, WM_SETTEXT, text.Length, text);
                }
                else if (controlWinClassName.ToString().ToLower().Equals("richedit20w"))
                {
                    SendMessage(handleWnd, WM_SETTEXT, 1, "");

                    ////Set the path to the RichEdit20W Which is specially for office 2007 and winxp                                                    
                    this.SetRichEditText((IntPtr)handleWnd, text);
                }
            }
        }
    }



    private void SetRichEditText(IntPtr handleWnd, string text)
    {
        try
        {
            const uint WM_USER = 0x0400;

            SETTEXTEX setextex = new SETTEXTEX();
            setextex.codepage = 1200;
            setextex.flags = RTBW_FLAGS.RTBW_SELECTION;
            IntPtr ptr = System.Runtime.InteropServices.Marshal.AllocCoTaskMem(System.Runtime.InteropServices.Marshal.SizeOf(setextex.GetType()));
            System.Runtime.InteropServices.Marshal.StructureToPtr(setextex, ptr, true);
            IntPtr stringPtr = System.Runtime.InteropServices.Marshal.StringToBSTR(text);
            int result = SendMessage((int)handleWnd, (int)WM_USER + 97, ptr.ToInt32(), text);
            System.Runtime.InteropServices.Marshal.FreeCoTaskMem(ptr);
            System.Runtime.InteropServices.Marshal.FreeBSTR(stringPtr);
        }
        catch (Exception oEx)
        {
            Logger.Exception(oEx, "SetRichEditText");
            throw;
        }
    }

    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

    [DllImport("User32.dll")]
    public static extern Int32 SendMessage(int hWnd, int Msg, int wParam, string lParam);

    [DllImport("User32.dll")]
    public static extern Int32 SendMessage(int hWnd, int Msg, int wParam, string lParam);

    [DllImport("User32.dll")]
    public static extern Int32 FindWindow(String lpClassName, String lpWindowName);

    [DllImport("User32.dll")]
    public static extern Boolean EnumChildWindows(int hWndParent, Delegate lpEnumFunc, int lParam);

    [DllImport("user32.dll")]
    public static extern IntPtr GetActiveWindow();

    [DllImport("User32.dll")]
    public static extern Int32 GetWindowText(int hWnd, StringBuilder s, int nMaxCount);

    [DllImport("User32.dll")]
    public static extern Int32 SendMessage(int hWnd, int Msg, int wParam, string lParam);

    [DllImport("User32.dll")]
    public static extern Int32 SendMessage(int hWnd, int Msg, int wParam, string lParam);

    public const Int32 WM_SETTEXT = 0x000C;

    [StructLayout(LayoutKind.Sequential)]
    public struct SETTEXTEX
    {
        public ABC.FileSystemBrowser.CustomView.CommonEnum.RTBW_FLAGS flags;
        public long codepage;
    }
    public enum RTBW_FLAGS
    {
        RTBW_DEFAULT = 0,
        RTBW_KEEPUNDO = 1,
        RTBW_SELECTION = 2
    }
3 голосов
/ 11 апреля 2012

Просто используйте интерфейс автоматизации.Вот для чего это.И это однострочник.(Длинная строка, но все еще одна строка.)

using System.Windows.Automation;

    (AutomationElement.RootElement
        .FindFirst(TreeScope.Descendants,
                   new PropertyCondition(AutomationElement.NameProperty, "Save As"))
        .FindFirst(TreeScope.Descendants,
                   new AndCondition(
                       new PropertyCondition(AutomationElement.NameProperty,
                                             "File name:"),
                       new PropertyCondition(AutomationElement.ControlTypeProperty,
                                             ControlType.Edit)))
        .GetCurrentPattern(ValuePattern.Pattern) as ValuePattern).SetValue("Booga");

Это говорит: «Начиная с корня, найдите первого потомка с именем "Save As", затем найдите первого потомка с именем "File name:"и который является элементом редактирования, затем установите значение "Booga".

1 голос
/ 25 ноября 2011

Если это диалоговое окно «Сохранить», которое вы создали сами из C #, вы можете просто использовать API для установки определенных частей диалогового окна сохранения файла (например, заголовок, допустимые расширения), это делает то, что вам нужно?

http://msdn.microsoft.com/en-us/library/system.windows.forms.savefiledialog.aspx

0 голосов
/ 10 апреля 2012

В итоге я использовал функциональность, предоставленную Autoit DLL , для простоты и эффективности.

Но альтернативным решением (и нативным C #) является Md. Rashim Uddin's.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...