Sto provando a intercettare i clic del mouse da un altro programma. Sto facendo un plugin per il programma, che si sovrappone a un modulo trasparente sul programma e mostra informazioni aggiuntive. Quando clicco sulla parte trasparente del modulo posso fare clic su cose nel programma main
. Non voglio che ciò accada (almeno non ogni volta - ci sono alcune parti in cui è consentito fare clic e alcune parti in cui non lo sei, ma questo non è il problema).Intercetta il clic del mouse da un altro programma
Il modo in cui sto facendo questo ora è utilizzando WH_MOUSE_LL
, questo sta funzionando bene e posso mantenere il clic del mouse da ottenere al programma restituendo un valore diverso da zero (http://msdn.microsoft.com/en-gb/library/windows/desktop/ms644988(v=vs.85).aspx).
Il problema è che questo rende il mio programma principale in ritardo, non ho bisogno di ricevere notifiche per tutti i movimenti del mouse, voglio solo ricevere una notifica se l'utente ha effettivamente cliccato qualcosa. C'è un modo in cui posso limitare il WH_MOUSE_LL
in modo che si attivi solo sui clic del mouse? (Il ritardo è non a causa di calcoli nel metodo MouseHookProc
- è attualmente facendo nulla tranne che per la chiamata: CallNextHookEx(hHook, nCode, wParam, lParam)
.)
Ho cercato di risolvere questo problema utilizzando un hook globale (http://www.codeproject.com/Articles/18638/Using-Window-Messages-to-Implement-Global-System-H) che si aggancia il WM_MOUSEACTIVATE
Messaggio. L'idea era di collegare il WH_MOUSE_LL
solo quando ho ricevuto una notifica WM_MOUSEACTIVATE
. Sfortunatamente la notifica del clic WH_MOUSE_LL
viene inviata prima del WM_MOUSEACTIVATE
quindi non funziona.
EDIT:
@Nanda ecco il codice proc:
public int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam)
{
return WindowUtility.CallNextHookEx(hHook, nCode, wParam, lParam);
}
Come si può vedere che non sto facendo molto con esso atm, ma ritardi già ...
@Cody Grey ho fatto un piccolo test per la gestione dei messaggi Modulo:
public class Form1 : Form
{
private TrackBar m_Trackbar;
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
public Form1()
{
m_Trackbar = new System.Windows.Forms.TrackBar();
m_Trackbar.LargeChange = 1;
m_Trackbar.Location = new System.Drawing.Point(5, 10);
m_Trackbar.Maximum = 100;
m_Trackbar.Size = new System.Drawing.Size(280, 40);
m_Trackbar.Value = 100;
this.Controls.Add(m_Trackbar);
m_Trackbar.Scroll += new System.EventHandler(this.m_TrackbarScroll);
}
private void m_TrackbarScroll(object sender, System.EventArgs e)
{
this.Opacity = ((Convert.ToDouble(m_Trackbar.Value))/100);
}
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case 0x201: //WM_LBUTTONDOWN
Console.WriteLine("MouseButton Down!");
//I could copy the Message over to the MainProgram with this right?
//SendMessage(MainProgramHwnd, m.Msg, m.WParam, m.LParam);
//This will also only work on an opacity higher than 0.
break;
}
base.WndProc(ref m);
}
}
Quando hai detto: "restituisci che è trasparente e lascia che sia indirizzato alla finestra sottostante"? Posso farlo usando SendMessage e fondamentalmente copiando il messaggio che ricevo nel mio metodo WndProc?
Per rendere le cose più complicate sto utilizzando anche questo modulo http://www.codeproject.com/Articles/1822/Per-Pixel-Alpha-Blend-in-C. A mio parere questo mi consente di disegnare bitmap sul modulo che sono Anti Aliasing sullo sfondo. Con questa forma non sembra esserci modo di impostare l'opacità, poiché è sempre trasparente. C'è un modo migliore per disegnare bitmap su un modulo?
Potrebbe essere che il tuo hook proc sta eseguendo troppe operazioni anche prima di verificare se il tipo di evento e il salvataggio su evento irrilevante. Porta il tuo hook proc a un solo richiamo CallNextHook (...) e aggiungi make incremental change. – nanda
Perché il modulo di overlay non può ricevere solo tutti gli eventi del mouse che si verificano e filtrarli in modo appropriato? Se deve elaborarne uno, elaborarlo. In caso contrario, restituire che è trasparente e lasciarlo indirizzare alla finestra sottostante? Gli hook globali sono quasi sempre la soluzione sbagliata (anche se il suggerimento di nanda è buono se devi usarne uno). –
Grazie ad entrambi per i vostri commenti, ho modificato la mia prima domanda con un po 'di codice e alcune informazioni aggiuntive. @Nanda Non sono esattamente sicuro di cosa intendi, sto attualmente restituendo solo CallNextHookEx ma questo è già in ritardo (ho aggiunto il mio codice proc al mio primo post). – VincentC