wxWidgets can't receive Right mouse click - windows

I'm trying to add a context menu to a grid control in wxWidgets 2.9.4 on Windows 10, and while I can get the context menu key to work right clicking doesn't. Right now I have the following in the header
void handle_contextMenu(wxContextMenuEvent& event);
void handle_rightButton(wxMouseEvent& event);
and in the constructor
Bind(wxEVT_CONTEXT_MENU, &DataGrid::handle_contextMenu, this);
Bind(wxEVT_RIGHT_UP, &DataGrid::handle_rightButton, this);
neither work for the right mouse button.

The reason you can't bind to these events on wxGrid itself is that it's a composite window as explained in the "Accessors for component windows" section of the documentation. So to make this code work you need to call GetGridWindow()->Bind(...), for example.
Alternatively, you could, and probably should, if they're enough, use the higher level events such as the already mentioned wxEVT_GRID_CELL_RIGHT_CLICK.

Related

GtkButton label updates

I am designing a GUI using C, Glade, and Gtk.
I have some signals configured in glade to update the labels of various widgets, mainly GtkButton and GtkLabel. The overall functionality is that when a certain radio button is clicked, all button and labels change in response (language selection).
I am using the function gtk_label_set_label(...) in the widgets _draw() function and it works as expected (text changes, g_print occurs (once)).
gboolean on_lblMyLabel_draw(GtkLabel *label, gpointer *user_data) {
gtk_label_set_label(label, "custom text");
g_print("%s\n", "custom text");
return FALSE;
}
However, when I attempt the same from a button,
gboolean on_btnMyButton_draw(GtkButton *button, gpointer *user_data) {
gtk_button_set_label(button, "custom text");
g_print("%s\n", "custom text");
return FALSE;
}
The text does not update, but dissappears, and the g_print() statement prints forever (as if the draw is recursively calling itself).
Funnily, if I move the button code from _draw to _click, it works as expected, however, I need the GUI to redraw itself, so updating on click is impractical.
Is there a way, using _draw() to prevent this?
Is there a better way to do this?
thx!
Is there a way, using _draw() to prevent this?
No, and you shouldn’t be using the draw signal for this either. It has an entirely different purpose, and will be called each time a widgets redraws itself. That’s also the reason why your button is going into an infinite recursion: you changed its label so it figures it needs to be redrawn; that redraw leads to your callback being called, which again changes the label, etc etc
Is there a better way to do this?
Yes, and you mention it yourself already: make sure you do the logic of changing the widgets in the appropriate place (for example, on a click event), and let the GTK widgets take care of redrawing themselves.
Unless you’re doing something very exotic (like not running an event loop, which you automatically get with GtkApplication), this will all work fine.

wxWidgets event focus textcontrol

I have another wxWidgets question regarding events and focus.
I have already looked at the tutorials and this old question here but I am still running into problems C++ Event (Focus) Handling
Basically I have a dialog with two wxTextCtrl elements and a Button.
What I would like to achieve is, that when I click on button it needs to tell me which of the two elements previously had the focus.
In the constructor of my Dialog I created all the elements and then connected them to the eventhandler like this: Ttop->Connect(TOP,wxEVT_KILL_FOCUS,(wxObjectEventFunction)&UI_ADDENTRY::hasfocus);
Tbottom->Connect(BOTTOM,wxEVT_KILL_FOCUS,(wxObjectEventFunction)&UI_ADDENTRY::hasfocus);
then there is the eventhandler that safes the id into focus
void UI_ADDENTRY::hasfocus(wxFocusEvent& event){
focus= event.GetId();
event.Skip();}
however when i try to access focus in the Button function it always tells me: 0 instead of TOP or BOTTOM / the ids that I gave the textcontrols
void UI_ADDENTRY::OnRecord(wxCommandEvent &event){
wxString tmp;
tmp << this->focus;
wxMessageBox(tmp);}
What am I doing wrong? is there another way of finding out which of the two textbox has been in focus last?
Thank you
The most fool proof way is to catch EVT_SET_FOCUS in your text controls and remember the last one that received it. This is not more difficult than what you are doing but should work without problems.
FWIW EVT_KILL_FOCUS can't, unfortunately, be consistently implemented on all platforms, in particular GTK+ doesn't give any information about the window focus is being lost to.
In think u mean event.GetWindow().GetId(). Though I'm not sure how ur casting from int to string.

Intercepting and Disabling Global Mouse Events

I have a problem with my mouse. Every now and then it will double click when I only single click. I know this is a problem with the mouse, and I've contacted the manufacturer, still waiting for a reply. But in the meantime I was wondering if there was a way that I could find out when the left mouse button had been clicked twice within a very short period (probably 1-10 milliseconds) of time, and disable the second click.
I mostly know how to use hooks, so that's not the problem, my main question is how to stop an event from happening, if that's possible.
The information on how to prevent the mouse message from being processed is in the documentation of the "LowLevelMouseProc callback function" in MSDN:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644986(v=vs.85).aspx
Specifically, it says: "If the hook procedure processed the message, it may return a nonzero value to prevent the system from passing the message to the rest of the hook chain or the target window procedure." So, if you know about windows hooks, you know how to do it.
EDIT: Actually, now that I think more about it, you don't want to discard any event. You simply want to transform the doubleclick event into just another left-button-down event. I believe you can do it from within the hook handler, and it will work. Have you tried it?
In C#'s WinForms, you write an event handler involving the mouse receiving a MouseEventArgs object. Inside it, you can access certain info such as the number of times it was clicked, for example.
protected void RowClicked(object sender, MouseEventArgs evt)
{
// Trigger it when the mouse was clicked only once
if( evt.Button.Clicks == 1 ) {
// ... more things ...
}
return;
}
Other GUI libraries have other possibilities. That said, your problem has nothing to do with GUI libraries. You have to change the sensitivity of your mouse, in the configuration options of your operating system. For example, in the Windows' control panel, you can change how much time has to pass between a click and another one to be considered a doble-click. In lUbuntu, you can do the very same, in System menu >> Preferences >> Keyboard and Mouse.

Create a windows panel that is invisible that still accepts click message

I'm using c++/cli with visual studio 2010 express edition.
What I want to do is create a panel that is invisible but that still accepts/receives the click and double click messages and possibly other mouse input. If I set the controls visibility to FALSE then this seems to disable any mouse input.
I have tried getting the paint message and doing nothing (as was suggested by other sources) to try and make the panel simply not draw but not be invisible however the panel still seems to be drawing.
What should I be doing in the paint message to tell windows that I have draw the panel?
My panel drawing function is:
private: System::Void panel1_Paint(System::Object^ sender, System::Windows::Forms::PaintEventArgs^ e) {
}
If there are any other suggestions about how I could achieve this then that would be helpful.
In the end I scrapped this idea all together, the problem was to get a way of getting the mouse input from a window that had been "parentented" by a NativeWindow class. This meant that the window I was expecting to receive messages (the child window) was not receiving the messages.
In order to get the messages you need to override the event handler in your parent NativeWindow class. Here you can handle the event This is where I got the solution:
http://msdn.microsoft.com/en-us/library/system.windows.forms.nativewindow.createhandle.aspx

Attaching double click event to a label

How can I attach a "clicked" event to a label? I tried GtkEventBox but had no luck with it.
Connect to the button-press-event signal on the EventBox.
Gtk# differentiates between Widgets and 'Containers'. Most widgets placed on a Gtk# form will NOT receive mouse click events. In order to receive a mouse event you need to place the widget inside a specific container - like EventBox:
Add an EventBox containter to your form. You can place it behind other Widgets or since it is not visible, unless you specifically select it to be (or change its background color).
Put your label widget inside this EventBox. Notice that the label will get the shape and size of the EventBox.
Add to this EventBox the signal 'ButtonPressEvent' out of the "Common Widget Signals".
If you need to identify the button that was clicked while handling this event, use the uint value in: args.Event.Button typically '1' will be the left mouse button, '2' the center button and '3' the right button ('2' might be also when both left and right buttons are clicked).
It seems you don't need EventBox at all: Since the problem is that labels don't have any associated X11 window, just give it one with set_has_window(True)! The following works for me:
self.label = Gtk.Label()
self.label.set_has_window(True)
self.label.set_events(Gdk.EventMask.BUTTON_PRESS_MASK)
self.label.connect("button-press-event", self.click_label)
The documentation says it should only be used for implementing widgets - but hey, it works. Who cares about "should"?
2019-04-17 Update:
ptomato here is right, GtkLabel is one of the exceptions that indeed requires an eventbox, so you should connect to the button-press-event signal of the eventbox. For other widgets, the set/add events APIs in my original answer should be still relevant.
Original (wrong) answer:
Connect to the button-press-event signal, but directly on the GtkLabel. I'd say you don't need an eventbox here, as GtkLabel already inherits this signal from GtkWidget. To enable the GtkLabel to receive those events, you need first to call gtk_widget_set_events or gtk_widget_add_events, and add the sensitivity to the GDK_BUTTON_PRESS_MASK event.

Resources