I use wxWidget-3.1.4 under windows 10
I try to process mouse events from my class.
Header class:
#include "wx/wxprec.h"
#include <wx/wfstream.h>
class MainWindow : public wxFrame
{
public:
MainWindow(const wxString& title);
void OnQuit(wxCommandEvent& event);
void OnOpenImage(wxCommandEvent& WXUNUSED);
void OnEditImage(wxCommandEvent& WXUNUSED);
//will redirect mouse event to class ImageDrawing
void OnMouseWheel(wxMouseEvent& event);
void OnMouseMove(wxMouseEvent& event);
void OnMouseDown(wxMouseEvent& event);
void OnMouseUp(wxMouseEvent& event);
private:
//wx Panel for drawing image
wxPanel* m_background;
wxImage* m_Image;
...
};
Cpp file:
MainWindow::MainWindow(const wxString& title): wxFrame(NULL, wxID_ANY, title)
{
m_background = new wxPanel(this, wxID_ANY);
m_background->Bind(wxEVT_PAINT, &MainWindow::OnPaint, this);
}
void MainWindow::OnQuit(wxCommandEvent& WXUNUSED(event))
{
Close(true);
}
void MainWindow::OnOpenImage(wxCommandEvent& WXUNUSED(event))
{
wxString file = OpenFileDialog("Open Image file", "png files (*.png)|*.png");
openImage(file, true);
}
void MainWindow::OnEditImage(wxCommandEvent& WXUNUSED(event))
{
wxString file = OpenFileDialog("Open Image file", "png files (*.png)|*.png");
// some logic
}
void MainWindow::OnMouseWheel(wxMouseEvent& event)
{
std::cout<<"OnMouseWheel(event)";
}
void MainWindow::OnMouseMove(wxMouseEvent& event)
{
std::cout<<"OnMouseMove(event)";
}
void MainWindow::OnMouseDown(wxMouseEvent& event)
{
std::cout<<"OnMouseDown(event)";
}
void MainWindow::OnMouseUp(wxMouseEvent& event)
{
std::cout<<"OnMouseUp(event)";
}
wxBEGIN_EVENT_TABLE(MainWindow, wxFrame)
EVT_MENU(Minimal_Quit, MainWindow::OnQuit)
EVT_MENU(Open_Image, MainWindow::OnOpenImage)
EVT_MENU(Edit_Image, MainWindow::OnEditImage)
EVT_MOTION(MainWindow::OnMouseMove)
EVT_MOUSEWHEEL(MainWindow::OnMouseWheel)
EVT_LEFT_DOWN(MainWindow::OnMouseDown)
EVT_LEFT_UP(MainWindow::OnMouseUp)
EVT_RIGHT_DOWN(MainWindow::OnMouseDown)
EVT_RIGHT_UP(MainWindow::OnMouseUp)
wxEND_EVENT_TABLE()
the problem is that event menu works fine, also OnMouseWheel works, but all other mouse events are not working. Googling problem shows that a reason for this is because a parent component, in my case wxFrame is included some child, like wxPanel, and this child component could intercept events.
So why OnMouseWheel is working and all other is not. the same behaviour if I change wxFrame to wxPanel in event table and if I didn't use m_background.
I was able to solve this problem by applying the following changes in constructor:
MainWindow::MainWindow(const wxString& title): wxFrame(NULL, wxID_ANY, title)
{
m_background = new wxPanel(this, wxID_ANY);
m_background->Bind(wxEVT_PAINT, &MainWindow::OnPaint, this);
m_background->Connect(wxEVT_MOTION, wxMouseEventHandler(MainWindow::OnMouseMove));
m_background->Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(MainWindow::OnMouseDown));
m_background->Connect(wxEVT_LEFT_UP, wxMouseEventHandler(MainWindow::OnMouseUp));
}
in each function that if you want to access to some class member or parameter you need to do the following:
void MainWindow::OnMouseMove(wxMouseEvent& event)
{
MainWindow* pointer = dynamic_cast<MainWindow*>(this->GetParent());
if(pointer->m_path.size() > 0)
pointer->m_drawing->OnMove(event);
}
and instead of this, you need to use a pointer, the reason for this because this now point to m_background.
Last step is to delete this function from wx_EVENT_TABLE
Related
I am having trouble capturing and handling mouse events within a panel.
Binding mouse events to my main window frame works as expected. However, when I bind events to a child panel, they successfully don't go my frame, but are not correctly handled by my panel. Any help would be appreciated.
I am using wxWidgets v3.1.5
Below is my simplest example: a single panel inside a parent frame.
Clicking the panel should turn itself yellow. Clicking the surrounding frame area should turn the panel green.
// wxWidgets in full of strcpy
#pragma warning(disable : 4996)
#include <wx/wx.h>
class cPanel : public wxPanel {
public:
cPanel(wxWindow* parent, wxSize size)
: wxPanel(parent, wxID_ANY, wxDefaultPosition, size) {
this->Bind(wxEVT_LEFT_DOWN, &cPanel::OnLeftClick, this);
}
void OnLeftClick(wxMouseEvent& event) {
SetBackgroundColour(wxColour("yellow"));
Refresh();
};
};
class cFrame : public wxFrame {
public:
wxPanel* child;
cFrame()
: wxFrame(nullptr, wxID_ANY, "Example Title", wxPoint(200, 200),
wxSize(800, 500)) {
child = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(300, 300));
auto top = new wxBoxSizer(wxHORIZONTAL);
top->Add(child, 0, wxALL, 20);
SetSizer(top);
this->Bind(wxEVT_LEFT_DOWN, &cFrame::OnLeftClick, this);
};
void OnLeftClick(wxMouseEvent& event) {
child->SetBackgroundColour(wxColour("green"));
child->Refresh();
}
};
class cApp : public wxApp {
public:
cFrame* frame = nullptr;
cApp(){};
~cApp(){};
virtual bool OnInit() {
frame = new cFrame();
frame->Show();
return true;
}
};
wxIMPLEMENT_APP(cApp);
Only wxCommandEvents (and classes derived from it) will filter up to parent windows. wxMouseEvent does not derive from wxCommandEvent, so a mouse event on the panel that is not handled by the panel will not filter up to the frame.
Consequently, you'll need to Bind the mouse event handler to the panel instead of the frame. Here's an example of how to change the last few lines of your cFrame class to do that.
this->Bind(wxEVT_LEFT_DOWN, &cFrame::OnLeftClick, this);
child->Bind(wxEVT_LEFT_DOWN, &cFrame::OnChildLeftClick, this);
};
void OnLeftClick(wxMouseEvent& event) {
child->SetBackgroundColour(wxColour("green"));
child->Refresh();
}
void OnChildLeftClick(wxMouseEvent& event) {
child->SetBackgroundColour(wxColour("yellow"));
child->Refresh();
}
};
There are many ways of accomplishing the same thing, but I think something like this is probably the simplest.
I have made an application using wxWidgets 3.1.5 in C++ and everything is working fine except a test button that I have on my main window.
Here's a pic:
The menubar, menus and their functions work perfectly but the button covers the entire client area.
Here's the code:
main.h
#pragma once
#include <wx\wx.h>
#include "mainFrame.h"
class main : public wxApp
{
private:
mainFrame* frame;
public:
virtual bool OnInit();
};
main.cpp
#include "main.h"
wxIMPLEMENT_APP(main);
bool main::OnInit()
{
frame = new mainFrame("Kill Me", wxPoint(15, 10), wxSize(640, 480));
frame->Show();
return true;
}
mainFrame.h
#pragma once
#include "About.h"
using str = std::string;
class mainFrame : public wxFrame
{
public:
mainFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
~mainFrame();
private:
About* abtF = NULL;
wxButton* hewwo = NULL;
wxMenuBar* mbar = NULL;
wxMenu* sett = NULL;
wxMenu* quitApp = NULL;
wxMenu* abt = NULL;
void onHewwo(wxCommandEvent& evt);
void onSett(wxCommandEvent& evt);
void quit(wxCommandEvent& evt);
void about(wxCommandEvent& evt);
wxDECLARE_EVENT_TABLE();
};
enum {
ID_SETT = 1,
ID_BTN = 2
};
mainFrame.cpp
#include "mainFrame.h"
wxBEGIN_EVENT_TABLE(mainFrame, wxFrame)
EVT_BUTTON(ID_BTN, onHewwo)
EVT_MENU(ID_SETT, onSett)
EVT_MENU(wxID_EXIT, quit)
EVT_MENU(wxID_ABOUT, about)
wxEND_EVENT_TABLE()
mainFrame::mainFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
:
wxFrame(nullptr, wxID_ANY, title, pos, size) {
hewwo = new wxButton(this, ID_BTN, "Hewwo World", wxPoint(15, 15), wxSize(70, 20));
sett = new wxMenu();
sett->AppendSeparator();
sett->Append(ID_SETT, "&Settings");
quitApp = new wxMenu();
quitApp->AppendSeparator();
quitApp->Append(wxID_EXIT, "&Quit this crap");
abt = new wxMenu();
abt->AppendSeparator();
abt->Append(wxID_ABOUT, "&About");
mbar = new wxMenuBar();
mbar->Append(sett, "&Settings");
mbar->Append(abt, "&About");
mbar->Append(quitApp, "&Quit");
SetMenuBar(mbar);
}
void mainFrame::onHewwo(wxCommandEvent& evt) {
wxMessageBox("Hewwo", "Hewwo", wxOK | wxICON_INFORMATION, this);
}
void mainFrame::onSett(wxCommandEvent& evt) {
wxMessageBox("Settings", "Settings", wxOK | wxICON_INFORMATION, this); // Just a test
}
void mainFrame::about(wxCommandEvent& evt) {
abtF = new About(wxPoint(10, 10), wxSize(480, 320));
abtF->Show();
}
void mainFrame::quit(wxCommandEvent& evt) {
Close(true);
}
mainFrame::~mainFrame() {
delete abtF;
}
I'm using Visual Studio 2019.
(I followed OneLoneCoder's (javidx9) youtube video on wxWidgets)
That is how a wxFrame with only one child behaves.
If you don't want that, use a wxSizer to layout your button (position, align, expand etc).
Reference:
if the frame has exactly one child window, not counting the status and toolbar, this child is resized to take the entire frame client area. If two or more windows are present, they should be laid out explicitly either by manually handling wxEVT_SIZE or using sizers
wxFrame docs -> Default event processing -> wxEVT_SIZE
Hi i am trying to create a wxApp that will have not have a titlebar(including the minimize, maximize and close) icons that are by default provided. The code that i have is as follows:
main.h
class MyApp : public wxApp
{
public:
virtual bool OnInit();
};
main.cpp
bool MyApp::OnInit()
{
MyFrame *prop = new MyFrame(wxT("MyFrame"));
prop->Show(true);
return true;
}
myframe.h
class MyFrame : public wxFrame
{
public:
MyFrame(const wxString& title);
void OnClick(wxMouseEvent& event);
};
myframe.cpp
MyFrame::MyFrame(const wxString& title)
: wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(250, 130))
{
MyPanel *panel = new MyPanel(this, wxID_ANY);
panel->SetBackgroundColour(wxColour(255,255,255));
MyButton *button = new MyButton(panel, wxID_ANY, wxT("Ok"));
Connect( wxEVT_LEFT_UP,
wxMouseEventHandler(MyFrame::OnClick));
panel->Centre();
}
void MyFrame::OnClick(wxMouseEvent& event)
{
std::cout << "event reached frame class" << std::endl;
}
mypanel.h
class MyPanel : public wxPanel
{
public:
MyPanel(wxFrame *frame, int id);
void OnClick(wxMouseEvent& event);
};
mypanel.cpp
MyPanel::MyPanel(wxFrame *frame, int id)
: wxPanel(frame, id)
{
Connect( wxEVT_LEFT_UP,
wxMouseEventHandler(MyPanel::OnClick));
}
void MyPanel::OnClick(wxMouseEvent& event)
{
std::cout << "event reached panel class" << std::endl;
}
mybutton.h
class MyButton : public wxPanel
{
public:
MyButton(wxPanel *panel, int id, const wxString &label);
void OnClick(wxMouseEvent& event);
};
mybutton.cpp
void MyButton::onClick(wxMouseEvent &event)
{
}
What i want is:
There should be no title bar(including the 3 maximize, minimize & close buttons) at the top.
Now since there is no titlebar at the top of the frame, there is no way to drag or close or maximize or minimize the window. For that i want to create a custom titlebar at the top which should have the three customized maximized,minimized and close button and also i should be able to drag the frame by double clicking and holding and dragging the topmost part of the newly created frame.
Is this possible in wxWidgets? If yes, how can i achieve this?
I am not proposing any new way of dragging. The new frame/window that we will have should also be dragged only by its own customized title bar. It's exactly like dragging the old frame by double clicking and dragging the frame in the native case. I just want to customize the native title bar. Like increase its height, change it's colour, change how to three buttons(minimize, maximize and close) look.
Here's the simplest example I can think of how to create a frame with a pseudo titlebar that can be clicked to drag the frame around. This example shows which mouse events need to be handled to drag the window around and how to do the calculations needed in those event handlers.
Note that moving the frame needs to be done in screen coordinates, but the coordinates received in the event handlers will be in client coordinates for the title bar. This example also shows how to do those coordinate conversions.
#include "wx/wx.h"
class CustomTitleBar:public wxWindow
{
public:
CustomTitleBar(wxWindow* p) : wxWindow(p,wxID_ANY)
{
m_dragging = false;
SetBackgroundColour(*wxGREEN);
Bind(wxEVT_LEFT_DOWN,&CustomTitleBar::OnMouseLeftDown,this);
Bind(wxEVT_MOUSE_CAPTURE_LOST, &CustomTitleBar::OnMouseCaptureLost,
this);
}
wxSize DoGetBestClientSize() const override
{
return wxSize(-1,20);
}
private:
void OnMouseLeftDown(wxMouseEvent& event)
{
if ( !m_dragging )
{
Bind(wxEVT_LEFT_UP,&CustomTitleBar::OnMouseLeftUp,this);
Bind(wxEVT_MOTION,&CustomTitleBar::OnMouseMotion,this);
m_dragging = true;
wxPoint clientStart = event.GetPosition();
m_dragStartMouse = ClientToScreen(clientStart);
m_dragStartWindow = GetParent()->GetPosition();
CaptureMouse();
}
}
void OnMouseLeftUp(wxMouseEvent&)
{
FinishDrag();
}
void OnMouseMotion(wxMouseEvent& event)
{
wxPoint curClientPsn = event.GetPosition();
wxPoint curScreenPsn = ClientToScreen(curClientPsn);
wxPoint movementVector = curScreenPsn - m_dragStartMouse;
GetParent()->SetPosition(m_dragStartWindow + movementVector);
}
void OnMouseCaptureLost(wxMouseCaptureLostEvent&)
{
FinishDrag();
}
void FinishDrag()
{
if ( m_dragging )
{
Unbind(wxEVT_LEFT_UP,&CustomTitleBar::OnMouseLeftUp,this);
Unbind(wxEVT_MOTION,&CustomTitleBar::OnMouseMotion,this);
m_dragging = false;
}
if ( HasCapture() )
{
ReleaseMouse();
}
}
wxPoint m_dragStartMouse;
wxPoint m_dragStartWindow;
bool m_dragging;
};
class Customframe : public wxFrame
{
public:
Customframe(wxWindow* p)
:wxFrame(p, wxID_ANY, wxString(), wxDefaultPosition, wxSize(150,100),
wxBORDER_NONE)
{
CustomTitleBar* t = new CustomTitleBar(this);
SetBackgroundColour(*wxBLUE);
wxBoxSizer* szr = new wxBoxSizer(wxVERTICAL);
szr->Add(t,wxSizerFlags(0).Expand());
SetSizer(szr);
Layout();
}
};
class MyFrame: public wxFrame
{
public:
MyFrame():wxFrame(NULL, wxID_ANY, "Custom frame Demo", wxDefaultPosition,
wxSize(400, 300))
{
wxPanel* bg = new wxPanel(this, wxID_ANY);
wxButton* btn = new wxButton(bg, wxID_ANY, "Custom frame");
wxBoxSizer* szr = new wxBoxSizer(wxVERTICAL);
szr->Add(btn,wxSizerFlags(0).Border(wxALL));
bg->SetSizer(szr);
Layout();
btn->Bind(wxEVT_BUTTON, &MyFrame::OnButton, this);
m_customFrame = NULL;
}
private:
void OnButton(wxCommandEvent&)
{
if ( m_customFrame )
{
m_customFrame->Close();
m_customFrame = NULL;
}
else
{
m_customFrame = new Customframe(this);
m_customFrame->CenterOnParent();
m_customFrame->Show();
}
}
wxFrame* m_customFrame;
};
class MyApp : public wxApp
{
public:
virtual bool OnInit()
{
MyFrame* frame = new MyFrame();
frame->Show();
return true;
}
};
wxIMPLEMENT_APP(MyApp);
On windows, it looks like this.
You should be able to add whatever buttons you want to the custom title bar exactly as you would add buttons to any other window.
"Is this possible in wxWidgets?"
Yes. You need to use a wxWindow instead of a wxFrame and set some style for it. like wxBORDER_NONE. But you will have to implement many things that wxFrame already provides.
And your proposed way of dragging seems wrong/confusing to me. 99.99% of users prefer a UI they are used to it, avoiding to learn a new way of doing simple things they already know.
If you just want to avoid resizing then you have two ways:
a) Catch the size-event and do nothing. Calling event.Skip(false)
(to prevent handling in parent) is not neccessary.
b) Once you have created your window and correctly sized, get its size and set it as max and min.
In both cases the user will see a "resize" mouse pointer when hovering the mouse at any border, but nothing else, no resizing, will be done.
#JasonLiam,
Don't forget to place the application icon in the top left corner of you title bar and handle the right/left mouse clicks appropriately (as in native application) (if you want to go this route and get rid of the native frame window).
Thank you.
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. I try to capture mouse click, even if I click outside of the running application.
This is a desktop application running on Windows. I tried some mouse events that wxwidgets provides, but I couldn't handle the next click event. 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);
i just started to learn wxWidgets and I'm trying to create some kind of Image Opener.
But i cant understand how to add an image...
i seen some stuff about wxImage, wxBitMap,wxStaticBitmap, but i couldn't understand any of them or the difference between them.
#include <wx/wx.h>
#include <wx/filedlg.h>
#include <wx/wfstream.h>
class MyApp : public wxApp
{
public:
virtual bool OnInit();
};
class MyFrame : public wxFrame
{
public:
MyFrame (const wxString& event);
void OnOpen(wxCommandEvent& event);
void OnQuit(wxCommandEvent& event);
private:
DECLARE_EVENT_TABLE();
};
DECLARE_APP(MyApp);
IMPLEMENT_APP(MyApp);
bool MyApp::OnInit()
{
MyFrame *frame = new MyFrame(wxT("Minimal wxWidgets App"));
frame->Show(true);
return true;
}
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(wxID_OPEN, MyFrame::OnOpen)
EVT_MENU(wxID_EXIT, MyFrame::OnQuit)
END_EVENT_TABLE()
void MyFrame::OnOpen(wxCommandEvent& event)
{
wxFileDialog openFileDialog(this, ("Open JPEG file"), "", "", "JPEG files (*.jpg)|*jpg", wxFD_OPEN|wxFD_FILE_MUST_EXIST);
if(openFileDialog.ShowModal() == wxID_CANCEL)
return;
wxFileInputStream input_stream(openFileDialog.GetPath());
if(!input_stream.IsOk())
{
wxLogError("Cannot Open File '%s'.", openFileDialog.GetPath());
return;
}
}
void MyFrame::OnQuit(wxCommandEvent& event)
{
Close(true);
}
MyFrame::MyFrame(const wxString& title) : wxFrame(NULL, wxID_ANY, title)
{
wxMenuBar * menuBar = new wxMenuBar;
wxMenu * exitMenu = new wxMenu;
wxMenu * openMenu = new wxMenu;
exitMenu->Append(wxID_EXIT);
openMenu->Append(wxID_OPEN);
menuBar->Append(openMenu, "&Open");
menuBar->Append(exitMenu, "&Exit");
SetMenuBar(menuBar);
CreateStatusBar(2);
SetStatusText(wxT("Image Opener !"));
}
can someone show an example of adding an image on wxwidgets ? or adding it to my code .
thanks for help !
wxImage is a portable representation of an image, wxBitmap is a platform-specific but more efficient equivalent. Generally speaking, wxImage is convenient for working with image data, but it needs to be converted to wxBitmap to be displayed.
Both of these classes are just abstract images, while wxStaticBitmap is a control showing an image, i.e. something you can really see on screen.
The image sample (under samples directory of your wxWidgets distribution) shows how to use the different classes and draw images directly.
wxImage and wxBitmap are almost same and conversion between them is easy. wxStaticBitmap is used to display a wxBitmap.it can be done by following example(StaticBitmap1 is your wxStaticBitmap and btmp is your wxBitmap):
StaticBitmap1->SetBitmap(btmp);