是否可以捕获全局鼠标事件

时间:2019-03-28 06:43:45

标签: c++ wxwidgets

我有一个简单的框架,其中包含一些按钮。我的目的是,在单击 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))
{
}

我希望在按下按钮后的第一个左键单击中获得鼠标位置。

1 个答案:

答案 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);