是否可以捕获全局鼠标事件
Is it possible to catch global mouse events
我有一个包含一些按钮的简单框架。我的目标是,在单击 GetMousePosition 按钮 后,获取第一个鼠标单击位置。我尝试捕获鼠标点击,即使我在 运行 应用程序之外点击也是如此。
这是 Windows 上的桌面应用程序 运行。我尝试了一些wxwidgets提供的鼠标事件,但是无法处理下一个点击事件。我试图用下面的代码找到解决方案,但如果有一些不同的解决方案,我可以把那个代码扔进垃圾桶。
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_BUTTON(BUTTON_GetPos, MyFrame::OnButtonClick)
EVT_MOUSE_EVENTS(MyFrame::OnMouseEvent)
EVT_MOUSE_CAPTURE_LOST(MyFrame::OnMouseCaptureLost)
END_EVENT_TABLE()
//some more code
void MyFrame::OnButtonClick(wxCommandEvent & WXUNUSED(event))
{
//Start Capturing for next mouse left-click
if (!HasCapture())
CaptureMouse();
}
void MyFrame::OnMouseEvent(wxMouseEvent &event)
{
if (event.LeftDown()) {
//GetMousePosition
if (HasCapture())
ReleaseMouse();
}
}
void MyFrame::OnMouseCaptureLost(wxMouseCaptureLostEvent& WXUNUSED(event))
{
}
我希望获得鼠标位置,在按下按钮后的第一次左键单击。
您发布的代码看起来应该可以工作。如果有问题,它可能在您省略的代码中。无论如何,这是一个显示您想要的行为的小示例应用程序。此示例的基础逻辑与您发布的代码相同,只是此示例使用动态绑定而不是事件表。
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
// for all others, include the necessary headers (this file is usually all you
// need because it includes almost all "standard" wxWidgets headers)
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
class MyFrame : public wxFrame
{
public:
MyFrame(wxWindow* parent);
protected:
void OnButtonClick(wxCommandEvent& event);
void OnMouseCapLost(wxMouseCaptureLostEvent& event);
void OnLeftDown(wxMouseEvent&);
void CleanUp();
private:
wxTextCtrl* m_textCtrl;
};
class MyApp : public wxApp
{
public:
virtual bool OnInit() wxOVERRIDE;
};
MyFrame::MyFrame(wxWindow* parent)
:wxFrame(parent, wxID_ANY, "Demo", wxDefaultPosition, wxDefaultSize,
wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL)
{
wxPanel* panel = new wxPanel(this, wxID_ANY );
wxButton* button = new wxButton(panel, wxID_ANY, "Click Me");
m_textCtrl = new wxTextCtrl(panel, wxID_ANY, wxEmptyString,
wxDefaultPosition, wxDefaultSize,
wxTE_DONTWRAP|wxTE_MULTILINE|wxTE_READONLY);
wxBoxSizer* bSizer = new wxBoxSizer(wxVERTICAL);
bSizer->Add(button, 0, wxALL, 5);
bSizer->Add(m_textCtrl, 1, wxALL|wxEXPAND, 5);
panel->SetSizer(bSizer);
Layout();
button->Bind(wxEVT_BUTTON,&MyFrame::OnButtonClick,this);
}
void MyFrame::OnButtonClick(wxCommandEvent& event)
{
if ( !HasCapture() )
{
CaptureMouse();
m_textCtrl->AppendText("Mouse captured.\n");
Bind(wxEVT_LEFT_DOWN, &MyFrame::OnLeftDown, this);
Bind(wxEVT_MOUSE_CAPTURE_LOST, &MyFrame::OnMouseCapLost, this);
}
}
void MyFrame::CleanUp()
{
if ( HasCapture() )
ReleaseMouse();
Unbind(wxEVT_LEFT_DOWN, &MyFrame::OnLeftDown, this);
Unbind(wxEVT_MOUSE_CAPTURE_LOST, &MyFrame::OnMouseCapLost, this);
}
void MyFrame::OnMouseCapLost(wxMouseCaptureLostEvent& event)
{
m_textCtrl->AppendText("Mouse cap lost.\n");
CleanUp();
}
void MyFrame::OnLeftDown(wxMouseEvent& event)
{
m_textCtrl->AppendText("Click recorded.\n");
CleanUp();
}
bool MyApp::OnInit()
{
MyFrame* frame = new MyFrame(NULL);
frame->Show();
return true;
}
wxIMPLEMENT_APP(MyApp);
希望对您有所帮助。
编辑:这里还有一个使用事件表的版本:
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
// for all others, include the necessary headers (this file is usually all you
// need because it includes almost all "standard" wxWidgets headers)
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#define BUTTON_ID 101
class MyFrame : public wxFrame
{
public:
MyFrame(wxWindow* parent);
protected:
void OnButtonClick(wxCommandEvent& event);
void OnMouseCapLost(wxMouseCaptureLostEvent& event);
void OnMouseEvent(wxMouseEvent&);
void CleanUp();
private:
wxTextCtrl* m_textCtrl;
wxDECLARE_EVENT_TABLE();
};
class MyApp : public wxApp
{
public:
virtual bool OnInit() wxOVERRIDE;
};
wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_BUTTON(BUTTON_ID, MyFrame::OnButtonClick)
EVT_MOUSE_EVENTS(MyFrame::OnMouseEvent)
EVT_MOUSE_CAPTURE_LOST(MyFrame::OnMouseCapLost)
wxEND_EVENT_TABLE()
MyFrame::MyFrame(wxWindow* parent)
:wxFrame(parent, wxID_ANY, "Demo", wxDefaultPosition, wxDefaultSize,
wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL)
{
wxPanel* panel = new wxPanel(this, wxID_ANY );
wxButton* button = new wxButton(panel, BUTTON_ID, "Click Me");
m_textCtrl = new wxTextCtrl(panel, wxID_ANY, wxEmptyString,
wxDefaultPosition, wxDefaultSize,
wxTE_DONTWRAP|wxTE_MULTILINE|wxTE_READONLY);
wxBoxSizer* bSizer = new wxBoxSizer(wxVERTICAL);
bSizer->Add(button, 0, wxALL, 5);
bSizer->Add(m_textCtrl, 1, wxALL|wxEXPAND, 5);
panel->SetSizer(bSizer);
Layout();
}
void MyFrame::OnButtonClick(wxCommandEvent& event)
{
if ( !HasCapture() )
{
CaptureMouse();
m_textCtrl->AppendText("Mouse captured.\n");
}
}
void MyFrame::CleanUp()
{
if ( HasCapture() )
ReleaseMouse();
}
void MyFrame::OnMouseCapLost(wxMouseCaptureLostEvent& event)
{
m_textCtrl->AppendText("Mouse cap lost.\n");
CleanUp();
}
void MyFrame::OnMouseEvent(wxMouseEvent& event)
{
if( HasCapture() && event.LeftIsDown() )
{
m_textCtrl->AppendText("Click recorded.\n");
CleanUp();
}
}
bool MyApp::OnInit()
{
MyFrame* frame = new MyFrame(NULL);
frame->Show();
return true;
}
wxIMPLEMENT_APP(MyApp);
我有一个包含一些按钮的简单框架。我的目标是,在单击 GetMousePosition 按钮 后,获取第一个鼠标单击位置。我尝试捕获鼠标点击,即使我在 运行 应用程序之外点击也是如此。
这是 Windows 上的桌面应用程序 运行。我尝试了一些wxwidgets提供的鼠标事件,但是无法处理下一个点击事件。我试图用下面的代码找到解决方案,但如果有一些不同的解决方案,我可以把那个代码扔进垃圾桶。
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_BUTTON(BUTTON_GetPos, MyFrame::OnButtonClick)
EVT_MOUSE_EVENTS(MyFrame::OnMouseEvent)
EVT_MOUSE_CAPTURE_LOST(MyFrame::OnMouseCaptureLost)
END_EVENT_TABLE()
//some more code
void MyFrame::OnButtonClick(wxCommandEvent & WXUNUSED(event))
{
//Start Capturing for next mouse left-click
if (!HasCapture())
CaptureMouse();
}
void MyFrame::OnMouseEvent(wxMouseEvent &event)
{
if (event.LeftDown()) {
//GetMousePosition
if (HasCapture())
ReleaseMouse();
}
}
void MyFrame::OnMouseCaptureLost(wxMouseCaptureLostEvent& WXUNUSED(event))
{
}
我希望获得鼠标位置,在按下按钮后的第一次左键单击。
您发布的代码看起来应该可以工作。如果有问题,它可能在您省略的代码中。无论如何,这是一个显示您想要的行为的小示例应用程序。此示例的基础逻辑与您发布的代码相同,只是此示例使用动态绑定而不是事件表。
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
// for all others, include the necessary headers (this file is usually all you
// need because it includes almost all "standard" wxWidgets headers)
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
class MyFrame : public wxFrame
{
public:
MyFrame(wxWindow* parent);
protected:
void OnButtonClick(wxCommandEvent& event);
void OnMouseCapLost(wxMouseCaptureLostEvent& event);
void OnLeftDown(wxMouseEvent&);
void CleanUp();
private:
wxTextCtrl* m_textCtrl;
};
class MyApp : public wxApp
{
public:
virtual bool OnInit() wxOVERRIDE;
};
MyFrame::MyFrame(wxWindow* parent)
:wxFrame(parent, wxID_ANY, "Demo", wxDefaultPosition, wxDefaultSize,
wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL)
{
wxPanel* panel = new wxPanel(this, wxID_ANY );
wxButton* button = new wxButton(panel, wxID_ANY, "Click Me");
m_textCtrl = new wxTextCtrl(panel, wxID_ANY, wxEmptyString,
wxDefaultPosition, wxDefaultSize,
wxTE_DONTWRAP|wxTE_MULTILINE|wxTE_READONLY);
wxBoxSizer* bSizer = new wxBoxSizer(wxVERTICAL);
bSizer->Add(button, 0, wxALL, 5);
bSizer->Add(m_textCtrl, 1, wxALL|wxEXPAND, 5);
panel->SetSizer(bSizer);
Layout();
button->Bind(wxEVT_BUTTON,&MyFrame::OnButtonClick,this);
}
void MyFrame::OnButtonClick(wxCommandEvent& event)
{
if ( !HasCapture() )
{
CaptureMouse();
m_textCtrl->AppendText("Mouse captured.\n");
Bind(wxEVT_LEFT_DOWN, &MyFrame::OnLeftDown, this);
Bind(wxEVT_MOUSE_CAPTURE_LOST, &MyFrame::OnMouseCapLost, this);
}
}
void MyFrame::CleanUp()
{
if ( HasCapture() )
ReleaseMouse();
Unbind(wxEVT_LEFT_DOWN, &MyFrame::OnLeftDown, this);
Unbind(wxEVT_MOUSE_CAPTURE_LOST, &MyFrame::OnMouseCapLost, this);
}
void MyFrame::OnMouseCapLost(wxMouseCaptureLostEvent& event)
{
m_textCtrl->AppendText("Mouse cap lost.\n");
CleanUp();
}
void MyFrame::OnLeftDown(wxMouseEvent& event)
{
m_textCtrl->AppendText("Click recorded.\n");
CleanUp();
}
bool MyApp::OnInit()
{
MyFrame* frame = new MyFrame(NULL);
frame->Show();
return true;
}
wxIMPLEMENT_APP(MyApp);
希望对您有所帮助。
编辑:这里还有一个使用事件表的版本:
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
// for all others, include the necessary headers (this file is usually all you
// need because it includes almost all "standard" wxWidgets headers)
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#define BUTTON_ID 101
class MyFrame : public wxFrame
{
public:
MyFrame(wxWindow* parent);
protected:
void OnButtonClick(wxCommandEvent& event);
void OnMouseCapLost(wxMouseCaptureLostEvent& event);
void OnMouseEvent(wxMouseEvent&);
void CleanUp();
private:
wxTextCtrl* m_textCtrl;
wxDECLARE_EVENT_TABLE();
};
class MyApp : public wxApp
{
public:
virtual bool OnInit() wxOVERRIDE;
};
wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_BUTTON(BUTTON_ID, MyFrame::OnButtonClick)
EVT_MOUSE_EVENTS(MyFrame::OnMouseEvent)
EVT_MOUSE_CAPTURE_LOST(MyFrame::OnMouseCapLost)
wxEND_EVENT_TABLE()
MyFrame::MyFrame(wxWindow* parent)
:wxFrame(parent, wxID_ANY, "Demo", wxDefaultPosition, wxDefaultSize,
wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL)
{
wxPanel* panel = new wxPanel(this, wxID_ANY );
wxButton* button = new wxButton(panel, BUTTON_ID, "Click Me");
m_textCtrl = new wxTextCtrl(panel, wxID_ANY, wxEmptyString,
wxDefaultPosition, wxDefaultSize,
wxTE_DONTWRAP|wxTE_MULTILINE|wxTE_READONLY);
wxBoxSizer* bSizer = new wxBoxSizer(wxVERTICAL);
bSizer->Add(button, 0, wxALL, 5);
bSizer->Add(m_textCtrl, 1, wxALL|wxEXPAND, 5);
panel->SetSizer(bSizer);
Layout();
}
void MyFrame::OnButtonClick(wxCommandEvent& event)
{
if ( !HasCapture() )
{
CaptureMouse();
m_textCtrl->AppendText("Mouse captured.\n");
}
}
void MyFrame::CleanUp()
{
if ( HasCapture() )
ReleaseMouse();
}
void MyFrame::OnMouseCapLost(wxMouseCaptureLostEvent& event)
{
m_textCtrl->AppendText("Mouse cap lost.\n");
CleanUp();
}
void MyFrame::OnMouseEvent(wxMouseEvent& event)
{
if( HasCapture() && event.LeftIsDown() )
{
m_textCtrl->AppendText("Click recorded.\n");
CleanUp();
}
}
bool MyApp::OnInit()
{
MyFrame* frame = new MyFrame(NULL);
frame->Show();
return true;
}
wxIMPLEMENT_APP(MyApp);