我有一个简单的框架,其中包含一些按钮。我的目的是,在单击 GetMousePosition按钮之后,获得鼠标的第一个单击位置。我试图捕获鼠标单击,即使我在正在运行的应用程序之外单击也是如此。
这是Windows上运行的桌面应用程序。我尝试了wxwidgets提供的一些鼠标事件,但是无法处理下一个click事件。我试图用下面的代码找到一个解决方案,但是如果有其他解决方案,我可以将该代码丢进垃圾箱。
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))
{
}
我希望在按下按钮后的第一个左键单击中获得鼠标位置。
答案 0 :(得分:2)
您发布的代码看起来应该可以工作。如果有问题,可能是在您省略的代码中。无论如何,这是一个小示例应用程序,显示了您想要的行为。此示例的基本逻辑与您发布的代码相同,除了此示例使用动态绑定而不是事件表。
// 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);