2011-11-25 92 views
3

我試圖以編程方式在「另存爲」對話框中更改編輯控件的文本。第一部分很簡單 - 獲取「另存爲」窗口的句柄。但找到編輯控件的?不那麼容易。在另一個窗口中設置編輯控件的文本

無論如何,這是我到目前爲止的代碼。有人能告訴我我要去哪裏嗎?

[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, "..."); 
} 

在此先感謝!

+0

會發生什麼?它是否會拋出異常?您可以發佈您正在使用的user32.dll函數的簽名嗎? – svick

+0

沒有任何例外或任何事情,編輯只是返回'0'。 ..並編輯以添加我的簽名 – mattsven

回答

0

我結束了使用the Autoit DLL提供的功能,因爲它簡單和高效。

但是另一種解決方案(和本機C#)是Md。Rashim Uddin的。

6

Yes.it真是一個複雜的一個。我花了1周時間才讓它工作,當時我被分配到工作。我已經給你下面的代碼部分的任何方式。通過該代碼,您可以將文本設置爲保存/打開對話框的編輯控件。不僅限於這些任務,你可以做任何你想要的窗口,

看看pls。

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 
    } 
+0

工作很好,你的文章真的幫助我解決問題很多問題。一個細節 - 當我在編輯窗口中設置文本時,在點擊對話保存按鈕之後,原始值被使用,並且我的新值被忽略,任何想法還需要設置以使對話使用新值? – Vojtiik

+0

ABC.FileSystemBrowser.CustomView.CommonEnum.RTBW_FLAGS從哪裏引用? –

3

只需使用自動化界面即可。這就是它的目的。這是一個單線。 (一長列,但還是一條線。)

這是說在根「開始,找到第一個後代的名字是"Save As",然後找到第一個後代的名字是"File name:"並且是編輯控件,然後將值設置爲"Booga"

+0

哇,整潔。謝謝,我會研究這個。 – mattsven

相關問題