2011-07-27 13 views
9

trzeba wykryć, kiedy użytkownik naciśnie Ctrl + V (niezależnie od ostrości oknie - moja aplikacja może zostać zminimalizowany), ale nie musi zatrzymać rzeczywistą operację wklejania .Wykrywanie Ctrl + V z RegisterHotKey ale nie przechwytując ją

Próbowałem kilka rzeczy: (ja z powodzeniem wiązanie z klawiszy z RegisterHotKey)

mam:

protected override void WndProc(ref Message m) 
{ 
    if (m.Msg == 0x312) 
    hotKey(); 
    base.WndProc(ref m); 
} 

i próbowałem następujące:

void hotKey() 
{ 
    SendKeys.SendWait("^v"); //just puts 'v' instead of clipboard contents 
} 

i

void hotKey() 
{ 
    SendKeys.SendWait(ClipBoard.GetText()); 
    /* This works, but since Ctrl is still down, it triggers 
    * all the shortcut keys for the app, e.g. if the keyboard 
    * contains 's' then instead of putting 's' in the app, it 
    * calls Ctrl+S which makes the app think the user wants 
    * to save. 
    */ 
} 

Obecnie jedynym działającym rozwiązaniem, które mam, jest powiązanie z czymś innym, np. Ctrl + B, a następnie zadzwoń pod numer SendKeys.SendWait("^v");, jednak nie jest to idealne rozwiązanie.

Idealnym rozwiązaniem byłoby, gdyby moje okno nie przechwyciło klawisza po prostu zareagowało.

+1

Czy możesz wyjaśnić swoje pytanie? Mam problem ze zrozumieniem Twojego zamiaru. Wspomniałeś, że chcesz zatrzymać samą operację wklejania, ale dlaczego próbujesz ponownie wysłać Ctrl + V w swojej pierwszej implementacji skrótu(). Czy mam rację, zakładając, że chcesz przechwycić obejmujące cały system operacje wklejania i zapisać wartości schowka w swojej aplikacji? –

+0

Nie, napisałem "Nie mogę * zatrzymać rzeczywistej operacji wklejania". Chcę wykryć systemowe operacje wklejania i później zastąpić zawartość schowka, aby użytkownik mógł wielokrotnie naciskać Ctrl + V i za każdym razem, gdy następny element został wklejony. Program ma na celu przyspieszenie (i zapobieganie błędom) osoby wprowadzającej dane. – Ozzah

+0

Ok. Źle to przeczytałem. Możesz użyć do tego hooków Windows. Zobacz moją odpowiedź poniżej. –

Odpowiedz

12

Możesz to zrobić, wykorzystując haki przy pomocy SetWindowsHookEx().

HHOOK WINAPI SetWindowsHookEx(
    __in int idHook, 
    __in HOOKPROC lpfn, 
    __in HINSTANCE hMod, 
    __in DWORD dwThreadId 
); 

Zasadniczo można skonfigurować haka klawiatury niskiego poziomu:

_hookHandle = SetWindowsHookEx(
    WH_KEYBOARD_LL, 
    KbHookProc,     // Your keyboard handler 
    (IntPtr)0, 
    0);       // Set up system-wide hook. 

uchwycić systemowych zdarzenia klawiatury. Ale pozwala także przekazywać te zdarzenia na klawiaturę do innych aplikacji. Dla konkretnego przypadku można zdefiniować KbHookProc jak:

private static int KbHookProc(int nCode, IntPtr wParam, IntPtr lParam) 
{ 
    if (nCode >= 0) // This means we can intercept the event. 
    { 
     var hookStruct = (KbLLHookStruct)Marshal.PtrToStructure(
       lParam, 
       typeof(KbLLHookStruct)); 

     // Quick check if Ctrl key is down. 
     // See GetKeyState() doco for more info about the flags. 
     bool ctrlDown = 
       GetKeyState(VK_LCONTROL) != 0 || 
       GetKeyState(VK_RCONTROL) != 0; 

     if (ctrlDown && hookStruct.vkCode == 0x56) // Ctrl+V 
     { 
      // Replace this with your custom action. 
      Clipboard.SetText("Hi"); 
     } 
    } 

    // Pass to other keyboard handlers. Makes the Ctrl+V pass through. 
    return CallNextHookEx(_hookHandle, nCode, wParam, lParam); 
} 

mam zakodowane app szybki i brudny WinForm to zilustrować. Pełna lista kodów znajduje się pod adresem http://pastebin.com/uCSvqwb4.

+0

Próbowałem przekonwertować to, aby działało jako aplikacja konsolowa, a to po prostu nie zadziała. Wytnij i wklej do aplikacji WinForm, i działa dobrze ... Jakieś pomysły, dlaczego? – codeputer

+1

Myślę, że mam to wymyślone - ServiceWindowsHookEx wymaga pętli wiadomości w wątku, który wykonuje kod - upewnij się, że nie ma pętli wiadomości! – codeputer

Powiązane problemy