简体   繁体   English

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

[英]Is it possible to catch global mouse events

I have a simple frame which is containing some buttons. 我有一个简单的框架,其中包含一些按钮。 My aim is that, after clicking the GetMousePosition button , getting the first mouse click position. 我的目的是,在单击GetMousePosition按钮之后 ,获得鼠标的第一个单击位置。 I try to capture mouse click, even if I click outside of the running application. 我尝试捕获鼠标单击,即使我在正在运行的应用程序之外单击也是如此。

This is a desktop application running on Windows. 这是在Windows上运行的桌面应用程序。 I tried some mouse events that wxwidgets provides, but I couldn't handle the next click event. 我尝试了wxwidgets提供的一些鼠标事件,但是无法处理下一个click事件。 I tried to find a solution with following code, but if there is some different solution, I can throw that code in the trash. 我试图用以下代码找到一个解决方案,但是如果有其他解决方案,我可以将该代码丢进垃圾箱。

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))
{
}

I expect to get the mouse position, in the first left click after the button is pressed. 我希望在按下按钮后的第一个左键单击中获得鼠标位置。

The code you posted looks like it should work. 您发布的代码看起来应该可以工作。 If there's a problem, it might be in the code you omitted. 如果有问题,可能是在您省略的代码中。 Anyway, here's a small example application showing the behavior you want. 无论如何,这是一个小示例应用程序,显示了您想要的行为。 The underlying logic of this example is the same as the code you posted, except this example uses dynamic binding instead of event tables. 此示例的基本逻辑与您发布的代码相同,除了此示例使用动态绑定而不是事件表。

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

I hope this helps. 我希望这有帮助。

edit: Here's a version using event tables as well: 编辑:这也是使用事件表的版本:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM