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

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