2011-01-05 1 views
1

점프 ...</p> <p>내가 notepad.exe를 다음에 뭔가를 입력 실행 후 메인 창을 찾을 C#에서 난 창 내 메인 프로그램에서 처리 찾을 방법의 또 다른 응용 프로그램의 자막

를 읽을 수 없습니다 (0x111111) ++ SPY를 사용하여 처리하고

[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] 

internal static extern int GetWindowText(IntPtr hWnd, [Out] StringBuilder lpString, int nMaxCount); 
. 
. 
. 
GetWindowText((IntPtr)(0x111111), str, 1024); 

이 코드는 잘 작동하고 나에게 메인 윈도우의 캡션을 반환합니다.

: :하지만 notepad.exe의 하위 항목 캡션을 찾기 위해 동일한 작업을 수행하면 str이 아무 것도 설정되지 않습니다. 스파이 ++는 그 아이의 캡션이 가치 있다고 말해 줬어.

+2

파일 메뉴 옵션에서 상태 표시 줄 또는 그 사이의 모든 항목까지 다양합니다. –

+0

나는 텍스트 영역에 뭔가를 썼다. 그런 다음 spy ++를 사용하여 캡션의 텍스트가있는 핸들을 찾은 다음 해당 코드에서 해당 핸들을 사용하십시오. –

+1

당신은 핸들 ('hWnd')이 항상 같지 않다는 것을 알고 있습니까? 응용 프로그램에서 값을 하드 코딩하면 쓸모가 없습니다. –

답변

3

할 수있는 "가장 올바른"방법 :

public static string GetWindowText(IntPtr hwnd) 
{ 
    if (hwnd == IntPtr.Zero) 
     throw new ArgumentNullException("hwnd"); 
    int length = SendMessageGetTextLength(hwnd, WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero); 
    if (length > 0 && length < int.MaxValue) 
    { 
     length++; // room for EOS terminator 
     StringBuilder sb = new StringBuilder(length); 
     SendMessageGetText(hwnd, WM_GETTEXT, (IntPtr)sb.Capacity, sb); 
     return sb.ToString(); 
    } 
    return String.Empty; 
} 

const int WM_GETTEXT = 0x000D; 
const int WM_GETTEXTLENGTH = 0x000E; 

[DllImport("User32.dll", EntryPoint = "SendMessage")] 
extern static int SendMessageGetTextLength(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam); 
[DllImport("User32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)] 
extern static IntPtr SendMessageGetText(IntPtr hWnd, int msg, IntPtr wParam, [Out] StringBuilder lParam); 
[DllImport("User32.dll", CharSet = CharSet.Auto)] 
extern static IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, [In] string lpClassName, [In] string lpWindowName); 

[In]의 사용 및 [Out] 속성에 마샬링 중에 불필요한 복사를 제거하십시오.

p/invoke 메소드를 외부 세계 (공개되지 않음)에 노출 시켜서는 안됩니다.

+0

내 텍스트 상자의 최신 변경 사항을 찾는 방법에 대한 힌트를 제공해 주시겠습니까? 내가 성장하는 텍스트 박스가 있는데, 나는이 텍스트 박스의 이벤트 목록이나 이와 비슷한 것을 연결할 수 있습니까? –

+0

외부 프로세스가 모니터 할 수있는 시스템 EDIT 제어에 변경 통보가 없습니다. 폴링 할 수도 있고 글로벌 훅을 작성하여 그러한 이벤트를 구현할 수도 있습니다. 그 후크는 CBT_CALLWNDPROCRET이됩니다. 이를 위해서는 네이티브 DLL (예 : C/C++)을 작성해야하며, 메모장처럼 32 비트와 64 비트 모두 연결되는 프로세스가 복잡하면 복잡합니다. – Tergiver

4

GetWindowText function documentation 명확하게 "GetWindowText 다른 응용 프로그램에서 컨트롤의 텍스트를 검색 할 수 없습니다 ... 다른 프로세스에서 컨트롤의 텍스트를 검색하려면 GetWindowText 호출하는 대신 직접 WM_GETTEXT 메시지를 보냅니다."

다음과 같은 코드를 사용하여 컨트롤의 텍스트 검색 할 수 있습니다

이 될 것이라고

[DllImport("user32.dll", EntryPoint = "SendMessage")] 
public static extern IntPtr SendMessageGetText(IntPtr hWnd, uint msg, UIntPtr wParam, StringBuilder lParam); 

const uint WM_GETTEXT = 13; 
const int bufferSize = 1000; // adjust as necessary 
StringBuilder sb = new StringBuilder(bufferSize); 
SendMessageGetText(hWnd, WM_GETTEXT, new UIntPtr(bufferSize), sb); 
string controlText = sb.ToString(); 
+1

wParam 인수는 IntPtr입니다. 반환 값 역시이 경우별로 중요하지 않습니다. –

+0

@ 한스 감사합니다; 문서화 된 유형 LRESULT (LONG_PTR), UINT 및 WPARAM (UINT_PTR)과 일치하도록 서명을 수정했습니다. –

+0

감사합니다. 작동합니다. 읽으려면 텍스트의 길이를 어떻게 찾을 수 있습니까? 아니면 텍스트의 꼬리를 읽을 수 있습니까? –