:
뿐만 아니라, 대신 Alt + Tab 키를 보내는, 다음과 같이 사용할 수 있습니다. SendMessage를 사용하려면 먼저 메모장의 텍스트 영역에 대한 유효한 창 핸들이 필요합니다. 이 방법은 다양한 방법으로 수행 할 수 있지만 단순한 하위 조회 기능을 사용하는 것을 선호합니다. 자식 창 조회에 지금
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Text;
//pinvoke
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
[return:MarshalAs(UnmanagedType.Bool)]
private static extern bool GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
[DllImport("user32.dll")]
private static extern int GetWindowTextLength(IntPtr hWnd);
[DllImport("user32.dll")]
[return:MarshalAs(UnmanagedType.Bool)]
private static extern bool EnumChildWindows(IntPtr hParent, delChildWndProc callback, IntPtr lpParam);
//delegate callback for EnumChildWindows:
[return:MarshalAs(UnmanagedType.Bool)]
private delegate bool delChildWndProc(IntPtr hWnd, IntPtr lParam);
:
는 다음과 같은 네임 스페이스 수입의 PInvoke 선언이 필요합니다. 기본적으로 FindWindowEx와 비슷하게 작동하지만, 필자는 직접 작성하고 싶다.
private static List<IntPtr> FindAllWindows(IntPtr hParent, string className, int maxdepth = 0)
{
var lookup = new WindowLookup(className, maxdepth);
var gcAlloc = GCHandle.Alloc(lookup);
try
{
LookupChildProc(hParent, GCHandle.ToIntPtr(gcAlloc));
}
finally
{
if (gcAlloc.IsAllocated)
gcAlloc.Free();
}
return lookup.MatchedChildren;
}
private static bool LookupChildProc(IntPtr hChild, IntPtr lParam)
{
var handle = GCHandle.FromIntPtr(lParam);
WindowLookup lookup = null;
if (handle.IsAllocated && (lookup = handle.Target as WindowLookup) != null)
{
if (lookup.Depth < lookup.MaxDepth || lookup.MaxDepth == 0)
{
lookup.Depth++;
var builder = new StringBuilder(256);
if (GetClassName(hChild, builder, builder.Capacity) && builder.ToString().ToLower() == lookup.LookupName.ToLower())
lookup.MatchedChildren.Add(hChild);
EnumChildWindows(hChild, LookupChildProc, lParam);
}
}
return true;
}
당신도 이러한 기능의 구현에 대해 걱정할 필요가 없습니다 : 다음과 같은 기능이 모든 일을 다음
private class WindowLookup
{
public string LookupName { get; private set; }
public List<IntPtr> MatchedChildren { get; private set; }
public int Depth { get; set; }
public int MaxDepth { get; set; }
public WindowLookup(string lookup, int maxdepth)
{
this.MatchedChildren = new List<IntPtr>();
this.LookupName = lookup;
this.MaxDepth = maxdepth;
if (this.MaxDepth > 0)
this.MaxDepth++; //account for the depth past the parent control.
this.Depth = 0;
}
}
그리고 :이 호출 사이의 정보를 설명하기 위해 다음과 같은 래퍼 클래스를 사용하여 많이, 그들은 그대로 일할 것입니다. 중요한 점은 이러한 함수를 사용하면 notepad
의 Edit
창 (사용자가 입력하는 텍스트 영역)에 대한 핸들을 매우 쉽게 찾을 수 있다는 것입니다. 내가 코드를 왼쪽 이제
var notepads = Process.GetProcessesByName("notepad");
if (notepads.Length > 0)
{
foreach(var notepad in notepads) //iterate through all the running notepad processes. Of course, you can filter this by processId or whatever.
{
foreach(var edit in FindAllWindows(notepad.MainWindowHandle, "Edit"))
{
//next part of the code will go here, read on.
}
}
}
는 시간에 실행하는 각 메모장 프로세스의 "편집"창을 통해 루프의 중간에 있었다. 이제는 유효한 윈도우 핸들을 가지고 있으므로 SendMessage를 사용하여 보낼 수 있습니다. 특히, 텍스트 추가.(내가 코멘트를 넣어 경우)
지금
private static void AppendWindowText(IntPtr hWnd, string text)
{
if (hWnd != IntPtr.Zero)
{
//for your reference, 0x0E (WM_GETTEXTLENGTH), 0xB1 (EM_SETSEL), 0xC2 (EM_REPLACESEL)
int len = SendMessage(hWnd, 0x000E, IntPtr.Zero, IntPtr.Zero).ToInt32();
var unmanaged = Marshal.StringToHGlobalAuto(text);
SendMessage(hWnd, 0x00B1, new IntPtr(len), new IntPtr(len));
SendMessage(hWnd, 0x00C2, IntPtr.Zero, unmanaged);
Marshal.FreeHGlobal(unmanaged);
}
}
우리는 우리의 AppendWindowText 기능을 가지고, 위의 중첩 루프에서에 함수 호출을 추가 할 수 있습니다 : 나는 원격 제어에 텍스트를 추가 처리하기 위해 다음과 같은 기능을 썼다 :
AppendWindowText(edit, "Some text here");
그리고 거기에 있습니다. 이것은 약간의 말투적 인 반응이지만, 결국이 방법은 SendKeys를 사용하고 창에 집중하는 것보다 훨씬 더 안정적입니다. 자신의 응용 프로그램에 집중할 필요가 없습니다.
질문이 있으시면 언제든지 말씀해 주시면 최대한 대답하겠습니다.
건배,
J
편집 : 일부 참조 :
SendMessage function (MSDN)이
EnumChildWindows function (MSDN)
Appending text using SendMessage
우, 감사합니다. 나는 그 기회를 줄거야! – MattM
흠, 이제 alt-tab은 가지 않습니다. 나는 alt-tab을 그냥 "보내기"로 유지하려고 시도했다. 그것이 왜 그렇게 작동하지 않는지 어떤 생각? – MattM
alt-tab에 대해 SendKeys를 사용하는지 잘 모르겠습니다. 다른 앱으로 전환 할 수있는 기본 제공 방법이 없습니다. FindWindow + SetForegroundWindow 네이티브 호출을 사용합니다. – Blorgbeard