2009-04-05 11 views
9

Chcę wysłać dane wejściowe z klawiatury do okna w innym procesie, bez wywoływania tego okna na pierwszy plan. Mogę użyć PostMessage do sfałszowania WM_KEYDOWN i WM_KEYUP; wszystko, co muszę wiedzieć, to który uchwyt okna powinien otrzymać dane wejściowe z klawiatury - to jest coś takiego jak GetFocus, ale dla innej, nieaktywnej aplikacji.Wywołanie GetGUIThreadInfo przez P/Invoke

Interfejs API GetGUIThreadInfo wygląda obiecująco - zwraca inną hwndFocus dla innej aplikacji. Ale nie miałem szczęścia, aby uruchomić go z C# na moim 64-bitowym systemie operacyjnym. Skopiowałem (a następnie jeszcze poprawiłem) deklaracje z pinvoke.net, ale wszystko, co kiedykolwiek otrzymałem, to ogólny kod błędu (więcej szczegółów poniżej).

Ustawiam cbSize przed wywołaniem GetGUIThreadInfo, więc uniknąłem najbardziej oczywistego potencjalnego problemu.

Używam 64-bitowego systemu Vista, więc nie wiem, czy problem polega na tym, że nie używam poprawnie interfejsu API, czy też działa on inaczej w wersji 64-bitowej - jeszcze nie znalazłem próbka kodu, która mówi, że działa poprawnie w Win64.

Oto przykładowy kod. Używam GetWindowThreadProcessId as recommended, więc nie sądzę, problem ma do czynienia z mieszaniem identyfikatory wątku nićmi uchwyty:

[StructLayout(LayoutKind.Sequential)] 
internal struct Rect 
{ 
    public int Left; 
    public int Top; 
    public int Right; 
    public int Bottom; 
} 

[StructLayout(LayoutKind.Sequential)] 
internal class GuiThreadInfo 
{ 
    public int cbSize; 
    public uint flags; 
    public IntPtr hwndActive; 
    public IntPtr hwndFocus; 
    public IntPtr hwndCapture; 
    public IntPtr hwndMenuOwner; 
    public IntPtr hwndMoveSize; 
    public IntPtr hwndCaret; 
    public Rect rcCaret; 
} 

[DllImport("user32.dll")] 
internal static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId); 
[DllImport("user32.dll", SetLastError = true)] 
internal static extern bool GetGUIThreadInfo(uint idThread, ref GuiThreadInfo lpgui); 

IntPtr GetFocusedHandleFromProcessWithWindow(IntPtr window) 
{ 
    var threadId = GetWindowThreadProcessId(window, IntPtr.Zero); 
    var info = new GuiThreadInfo(); 
    info.cbSize = Marshal.SizeOf(info); 
    if (!GetGUIThreadInfo(threadId, ref info)) 
     throw new Win32Exception(); 
    return info.hwndFocus; 
} 

window jest prawidłowy uchwyt okna; GetWindowThreadProcessId zwraca niezerowy uchwyt wątku. Jednak wywołanie GetGUIThreadInfo zawsze zwraca false, a komunikat o wyjątku jest zawsze "Parametr jest niepoprawny".

Tylko w przypadku problemem było to, że GetGUIThreadInfo jakoś nie ma wersji 64-bitowej, Próbuję zmienić wszystkie 8-bajtowych IntPtr S w GuiThreadInfo deklaracja do 4-bajtowy int s, ale nadal mam ten sam błąd.

Czy ktoś ma działającą próbkę C# z GetGUIThreadInfo na Win64? Lub czy istnieje inny sposób na znalezienie tego, w jaki sposób ukierunkowana rączka okna potomnego znajdowałaby się w innej aplikacji, bez aktywowania tej aplikacji?

Odpowiedz

4

Nie przyglądałem się temu zbyt uważnie, ale jedno wyskakuje. W swoim wywołaniu GetGUIThreadInfo przekazujesz strukturę GUIThreadInfo przez ref, ale zdefiniowałeś ją jako klasę, więc wysyłasz referencję przez ref, czyli wskaźnik do wskaźnika. Zmień GUIThreadInfo na struct lub usuń ref na parametrze i dodaj atrybuty [In, Out].

+1

Ouch. Masz rację - nie mogę uwierzyć, że to przegapiłem. Punkt etykiety: naprawiono natychmiastowy problem, ale pojawił się kolejny problem; więc mój cel końcowy "zdobyć ukierunkowaną obsługę w innym procesie" jest nadal otwarty. Czy mogę edytować to pytanie, lub zaakceptować tę odpowiedź, a następnie napisać nowe pytanie? –

+0

W tym przypadku, pytanie brzmi tak naprawdę o pInvoking GetGUIThreadInfo, więc prawdopodobnie powinieneś zagłosować jako pomocne i oznaczyć je jako odpowiedź. Możesz również edytować tytuł, aby dokładniej opisać to pytanie. Następnie dodaj nowe pytanie o bardziej ogólnym problemie, w tym o tym, co ... –

+0

... Twoim podstawowym wymaganiem jest i co próbujesz do tej pory. Ogólnie rzecz biorąc, należy edytować pytanie, aby dodać informacje lub jasność, aby nie zmieniać tego, co jest zadawane. –

Powiązane problemy