Mouse click sending me message multiple times in c++ - c++

This is my code:-
DWORD WINAPI ThreadMouse(void* data){
while (1){
//Check the mouse left button is pressed or not
if ((GetKeyState(VK_LBUTTON) & 0x8000) != 0)
{
MessageBox(NULL, L"Left Clicked", L"", NULL);
break;
}
//Check the mouse right button is pressed or not
if ((GetKeyState(VK_RBUTTON) & 0x100) != 0)
{
MessageBox(NULL, L"Right Clicked", L"", NULL);
break;
}
}
return 0;
}
I am getting the message multiple times instead of once

This looks like a thread, which polls the state of the mouse.
Not something that gets mouse events.
Windows can receive events.
I have a project with :-
class CImageDisplay :
public wxScrolledWindow,
public IToolTarget
{
/// omitted
void OnMouseDClick( wxMouseEvent& mouseEvent );
void OnMouseUp( wxMouseEvent& mouseEvent );
};
Where wxScrolledWindow is derived from wxWindow.
That declares functions for the mouse events.
In the cpp file, I have...
BEGIN_EVENT_TABLE(CImageDisplay, wxScrolledWindow)
EVT_MOTION(CImageDisplay::OnMouseMove )
EVT_LEFT_DOWN(CImageDisplay::OnMouseDown )
EVT_LEFT_DCLICK(CImageDisplay::OnMouseDClick )
EVT_LEFT_UP(CImageDisplay::OnMouseUp )
// omitted
END_EVENT_TABLE()
This tells wx to call my functions when the events (EVT_* occurs).
Then I can track the mouse events as they happen, but otherwise my code is not doing anything.
Check out the wx documentation (e.g. wx documentation mouse events for what events are available, and what limitations they have.
Check out the samples - e.g. plot.cpp which uses mouse events.

Your thread does not have a GUI for the user to interact with, so its key state is never updated. Each thread has its own key state, which is updated during UI message processing.
If you want to monitor the mouse in a thread without a GUI, you have two choices:
use SetWindowsHookEx() to hook the mouse using a WH_MOUSE or WH_MOUSE_LL hook. The thread will need a message loop to service the hook.
Have your thread create a hidden window (and message loop) and then use RegisterRawInputDevices() to have the mouse send WM_INPUT messages to your window.

Related

Why is the owning window showing up above the owned window?

I have this very strange issue. I'm trying to get a window hierarchy to be replicated. So on creating the 1st level dialog, I'm start the instance of the 2nd level dialog.
I've done this in many different ways, but it always shows up as the 2nd level being below the 1st level and then usually a zorder inversion happens (they flip positions). Occasionally, the inversion doesn't happen, but if I click on the owner, the owned immediately jumps to the top of the zorder.
Here are the main parts of a small example to show this happening:
const unsigned short WMA_DIALOGACTION = WM_APP+1;
// Button event handler for the 0th level
void CdialogcallingdialogsDlg::OnBnClickedDlgLvl1()
{
CDlgLvl1 x(this);
x.DoModal();
}
BEGIN_MESSAGE_MAP(CDlgLvl1, CDialogEx)
ON_WM_WINDOWPOSCHANGED()
ON_MESSAGE(WMA_DIALOGACTION, OnDialogAction)
END_MESSAGE_MAP()
void CDlgLvl1::OnWindowPosChanged(WINDOWPOS* lpwndpos)
{
if (!m_shownDlg) {
m_shownDlg = true;
PostMessage(WMA_DIALOGACTION);
}
}
// Level 1 dialog opening up level 2 dialog
LRESULT CDlgLvl1::OnDialogAction(WPARAM wParam, LPARAM lParam)
{
ShowWindow(SW_SHOW);
CDlgLvl2 x(this);
x.DoModal();
return LRESULT();
}
BEGIN_MESSAGE_MAP(CDlgLvl2, CDialogEx)
ON_WM_WINDOWPOSCHANGING()
END_MESSAGE_MAP()
// Level 2 dialog offseting its position
void CDlgLvl2::OnWindowPosChanging(WINDOWPOS* lpwndpos)
{
ASSERT(lpwndpos->hwnd == m_hWnd);
// Offset dialog to see the problem of dlg2 showing up below dlg1
if (!(lpwndpos->flags & SWP_NOMOVE)) {
lpwndpos->x += 10;
lpwndpos->y += 10;
}
}
In the example, you click on the button in the main dialog. That then starts up CDlgLvl1 which then starts up CDlgLvl2. The dialogs are the default dialogs except for the message handling that is shown here and a button on the main application dialog. If you look at it carefully, you can see the inversion.
What am I doing wrong? Perhaps there is a better way to do this?
In case it makes a difference, the issue is more pronounced under Windows 10 and doesn't seem to be visible on Windows 8.1.
A copy of the solution can be pulled from my git repo here:
https://github.com/Ma-XX-oN/dialog-calling-dialogs.git
I've just added some bitmaps on the dialogs to really show the issue, but I've not tested on my 8.1 box yet.
I did a recording of how it pops up and here is frame 0, 2, and 3 of that recording:
Frame 0
Frame 2
Frame 3
As you can see, LVL1 appears over LVL2 in Frame 2, and then flips position in Frame 3.
Full video can be found here.
Using this example project, I've not been able to replicate LVL1 staying overtop of LVL2, but I believe that the behaviour of the zorder inversion not happening is some sort of race condition.
The problem is caused when windows "transition animation" is enabled. WM_WINDOWPOSCHANGED is being sent before the animation is finished.
To fix this problem, you can simply disable the transition for the dialog:
BOOL CDlgLvl2::OnInitDialog()
{
BOOL res = CDialogEx::OnInitDialog();
BOOL attrib = TRUE;
DwmSetWindowAttribute(m_hWnd, DWMWA_TRANSITIONS_FORCEDISABLED, &attrib, sizeof(attrib));
return res;
}
If you don't want to disable the transition, you have to wait until this transition is finished. I don't know how to detect it or how to determine the transition time. It seems to be 250 milliseconds. SystemParametersInfo(SPI_SETMENUSHOWDELAY...) gives a value of 400 milliseconds which seems a bit too long.
Assuming we know the time, use SetTimer to run the function after transition is over:
BOOL CDlgLvl2::OnInitDialog()
{
BOOL res = CDialogEx::OnInitDialog();
ANIMATIONINFO info = { sizeof info };
SystemParametersInfo(SPI_GETANIMATION, sizeof(ANIMATIONINFO), &info, 0);
if (info.iMinAnimate)
SetTimer(1, 250, nullptr);
else
SetTimer(1, 1, nullptr);
return res;
}
void CDlgLvl2::OnTimer(UINT_PTR nIDEvent)
{
CDialogEx::OnTimer(nIDEvent);
if(nIDEvent == 1)
{
KillTimer(nIDEvent);
CDlgLvl2(this).DoModal();//note, PostMessage is not needed in SetTimer
}
}
Maybe the problem is caused because the 1st level dialog creates the 2nd one before it has a chance to display itself. And yes, this can vary from system to system. There's no really a fix, but I would suggest a workaround, employing a timer. Below is some code.
Header file for CDlgLvl1:
class CDlgLvl1 : public CDialogEx
{
.
.
.
protected:
UINT_PTR nIDTimer = 0; // Add this
};
Source file for CDlgLvl1:
BEGIN_MESSAGE_MAP(CDlgLvl1, CDialogEx)
.
.
ON_MESSAGE(WMA_DIALOGACTION, OnDialogAction)
ON_WM_TIMER()
END_MESSAGE_MAP()
BOOL CDlgLvl1::OnInitDialog()
{
CDialogEx::OnInitDialog();
nIDTimer = SetTimer(1, 250, NULL);
return TRUE;
}
void CDlgLvl1::OnTimer(UINT_PTR nIDEvent)
{
if (nIDTimer && nIDEvent == nIDTimer)
{
KillTimer(nIDTimer);
nIDTimer = 0;
PostMessage(WMA_DIALOGACTION);
return;
}
CDialogEx::OnTimer(nIDEvent);
}
LRESULT CDlgLvl1::OnDialogAction(WPARAM wParam, LPARAM lParam)
{
CDlgLvl2 x(this);
x.DoModal();
return 0;
}
The mechanism you provided to prevent the 2nd window being displayed multiple times (the m_shownDlg variable) has been replaced by the nIDTimer check.
Please experiment with the timer's elapse value. The one I suggest (250 - 1/4 sec) is OK for most systems and imperceptible to to the user.
I wrote this in the SO editor, no actual test in VS (so it may contain some few syntax errors - pls fix them if so).
Note: You do not need to override OnWindowPosChanging() if you only want to set the position of the 2nd dialog. It's relative to its parent, so you can simply set the X Pos and Y Pos properties of the dialog's resource.
I tried your project in Visual Studio 2019:
I ran it in DEBUG mode and it works fine. The third dialogue showed up as a child of the second dialog (that is, with the correct ZORDER). The same is true for RELEASE build.
See: https://www.dropbox.com/s/8f5z5ltq3vfc10r/Test.mp4?dl=0
Update
If one of my classes I had a timer and I did this:
void CChristianLifeMinistryEditorDlg::OnTimer(UINT_PTR nIDEvent)
{
READYSTATE eState = READYSTATE_UNINITIALIZED;
if (nIDEvent == PRINT_PREVIEW_TIMER)
{
eState = m_pPrintHtmlPreview->GetReadyState();
if (eState == READYSTATE_COMPLETE)
{
KillTimer(m_uPreviewTimer);
PostMessage(WM_COMMAND,
MAKELONG(IDC_BUTTON_PRINT_PREVIEW2, BN_CLICKED));
}
}
CResizingDialog::OnTimer(nIDEvent);
}
You could adapt the principle and then just simulate pressing the button to display the second next dialog. Might work.

How to use keyboard arrows for input in a VCL forms application with TButtons

I have a VCL forms application where I'm intercepting keys pressed in the OnKeyPress and OnKeyDown handlers. This works fine for regular characters and keys like VK_ESC for example.
However, when trying to catch the arrow keys (VK_UP and VK_DOWN), it does not work as they seem only to be changing the focus of the controls on the main form, and are not triggering the main forms OnKeyDown handler.
How does one catch/process those key presses?
Update:
Trying the following, based on answer below, but still no success.
void __fastcall TMain::WndProc(TMessage& Message)
{
switch (Message.Msg)
{
case WM_GETDLGCODE:
Log(lInfo) << "Got WM_GETDLGCODE";
break;
case CM_WANTSPECIALKEY:
Log(lInfo) << "Got WM_WANTSPECIALKEY";
break;
None of the above cases are triggered by using the up/down arrows in my application.
I have made the following observation. If creating an empty vcl form, the above cases are triggered, CM_WANSPECIALKEY is triggered first, followed by WM_GETDLGCODE.
However, as soon as a TButton is placed on the form, the cases are not triggered anymore.
I'm using C++ Builder XE3.
Arrow keys are reserved by Windows for navigation purposes. If a window wants to handle arrow key messages, it must respond to the WM_GETDLGCODE message and include the DLGC_WANTARROWS (or DLGC_WANTALLKEYS) flag in its return value.
Most VCL UI components (including TForm) return 0 for WM_GETDLGCODE. Only a handful of standard VCL components respond with DLGC_WANTARROWS (or DLGC_WANTALLKEYS):
TColorGrid, TToolBar, TCustomGrid, TMediaPlayer, TCustomRibbon, TRibbonSpinButton, TSpinButton, TTabbedNotebook, TCustomCombo, and TTabSet
In your TForm class, override its virtual WndProc() method, or declare a message handler, to handle WM_GETDLGCODE, then you can return whatever flag(s) you need.
void __fastcall TMyForm::WndProc(TMessage &Message)
{
TForm::WndProc(Message);
if (Message.Msg == WM_GETDLGCODE)
Message.Result |= DLGC_WANTARROWS;
}
Update: If WM_GETDLGCODE doesn't work, try responding to the CM_WANTSPECIALKEY message instead:
void __fastcall TMyForm::WndProc(TMessage &Message)
{
TForm::WndProc(Message);
if (Message.Msg == CM_WANTSPECIALKEY)
{
switch (reinterpret_cast<TCMWantSpecialKey&>(Message).CharCode)
{
case VK_LEFT:
case VK_RIGHT:
case VK_UP:
case VK_DOWN:
Message.Result = 1;
break;
}
}
}
Update: you are trying to process key events in the Form itself, which will only work when:
the Form window itself has input focus.
a child VCL window receives key messages, and the Form's KeyPreview property is true.
When a windowed child control, like a button, has the input focus, key messages go to that window, not to the Form window. In order for the KeyPreview property to work for arrow keys, the focused child must respond to the WM_GETDLGCODE message asking the OS to send arrow key messages. Only then can the child forward the messages to the Form for processing.
A button doesn't ask for arrow key messages by default, so you would have to subclass the button to handle the WM_GETDLGCODE message manually, eg:
class TMain : public TForm
{
__published:
TButton *Button1;
void __fastcall FormKeyDown(TObject *Sender, Word &Key, TShiftState Shift);
void __fastcall FormKeyPress(TObject *Sender, Char &Key);
private:
TWndMethod PrevBtnWndProc;
void __fastcall BtnWndProc(TMessage &Message);
public:
__fastcall TMain(TComponent *Owner);
};
__fastcall TMain::TMain(TComponent *Owner)
: TForm(Owner)
{
PrevBtnWndProc = Button1->WindowProc;
Button1->WindowProc = &BtnWndProc;
}
void __fastcall TMain::BtnWndProc(TMessage &Message
{
PrevBtnWndProc(Message);
if (Message.Msg == WM_GETDLGCODE)
Message.Result |= DLGC_WANTARROWS;
}
void __fastcall TMain::FormKeyDown(TObject *Sender, Word &Key, TShiftState Shift)
{
// works now!
}
void __fastcall TForm7::FormKeyPress(TObject *Sender, Char &Key)
{
// works now!
}
That is fine if you have only a few controls to subclass, but if you have a lot of controls, an alternative solution would be to have your Form class handle the CM_DIALOGKEY message instead:
void __fastcall TMyForm::WndProc(TMessage &Message)
{
TForm::WndProc(Message);
if (Message.Msg == CM_DIALOGKEY)
{
switch (reinterpret_cast<TCMDialogKey&>(Message).CharCode)
{
case VK_LEFT:
case VK_RIGHT:
case VK_UP:
case VK_DOWN:
// process key as needed...
// set Message.Result to suppress the message further...
Message.Result = 1;
break;
}
}
}
You should read the following article on EDN, it has a good explanation of how the VCL processes key messages, and how the VCL implements various hooks you can use to intercept key messages:
A Key’s Odyssey
I am doing this a bit differently (no WinAPI needed). If your VCL app has no focus on any sub component (like TButton,TEdit,TMemo...) then Main form keyboard events (OnKeyDown and OnKeyUp) will fire on arrow keys use. There are 2 approaches for this I know of:
do not use components with focus
it may sound silly but you can have TSpeedButton instead of TButton. but essentially you can place all focusable components in some sub-window or page and make it invisible if not needed (like setup window).
disable focus when arrows are needed
Simply I make an unfocus function like this:
void main_unfocus()
{
Main->bt_unfocus->Visible=true;
Main->bt_unfocus->SetFocus();
Main->bt_unfocus->Visible=false;
}
where bt_unfocus is invisible 2x2 TButton placed in top left corner of main window Main. Now whenever I need to capture events like mouse wheel, arrow keys etc in the main form events then I just call the main_unfocus();
I usually call it on mouse click on some viewing area or mouse move over it etc and Also I call this on hitting escape on any such component like TButton,TMemo,TEdit as they usually share the same event handlers in my Apps. All depends on what functionality you need/want.
PS hope you set the KeyPreview property to true.

How to use WM_INPUT to detect continus mouse clicks?

I am using WM_INPUT to detect my mouse updates, when I click my mouse button 1, I will detect that button 1 is down. However if i hold down the button, the subsequent updates for the mouse will show that button 1 is not depressed.
MSDN shows that usButtonFlags can detect transition state of the mouse buttons. This means rawinput can detect the mouse at the time of press and release but cannot detect the pressed or released state of mouse buttons.
But is it possible for the rawinput to detect the pressed or released state of mouse buttons instead of a transition state?
I used OSG to render a full screen scene, thus, all the mouse clicks should be associated with the current window. I use eventTraversal function of osgViewer::Viewer to update the raw input data:
class CustomViewer : public osgViewer::Viewer
{
public:
CustomViewer() : osgViewer::Viewer() {}
virtual ~CustomViewer() {}
virtual void eventTraversal()
{
RawInputEventRegistry::instance()->updateState( _eventQueue.get() );
osgViewer::Viewer::eventTraversal();
}
}
void RawInputEventRegistry::updateState( osgGA::EventQueue* eventQueue )
{
MSG msg;
if( GetMessage( &msg, c_handle, WM_INPUT, WM_INPUT ) != -1)
{
HRAWINPUT test = (HRAWINPUT)msg.lParam;
add_to_raw_mouse_x_and_y((HRAWINPUT)msg.lParam);
}
osg::ref_ptr<RawInputEvent> event = new RawInputEvent;
event->SetMouseData(raw_mice);
eventQueue->userEvent( event.get() );
}
The add_to_raw_mouse_x_and_y() function is responsible for button click checking, such as:
if (raw->data.mouse.usButtonFlags & RI_MOUSE_LEFT_BUTTON_DOWN) raw_mice[i].buttonpressed[0] = 1;

Keep window active while being dragged (SDL on Win32)

At first my code set up the SDL environment, and proceeded to update the OpenGL context, without performing any SDL_Event processing whatsoever. This causes the window, as long as it was open, to appear to Windows to be unresponsive. The window flickers a bit. The titlebar would get "(Not Responding)" appended to it, and upon clicking inside the window it becomes grayed out, as Windows does this by default on non responsive windows. However in this state (even as and after it becomes grayed out), the OpenGL display continues to update and animate, and here's the kicker, it even does so while the window is being dragged. Clearly in this case the application isn't handling events from windows correctly, causing windows to think that it is in a hanged state. But there is clear evidence that the opengl continues to render.
Now I make one single modification to the code, which is these three lines placed in an appropriate spot inside the loop (which also does the OpenGL draw):
SDL_Event event;
if (SDL_PollEvent(&event) && event.type == SDL_QUIT)
break;
All this is doing is flushing the message queue using SDL.
Now the behavior is that Windows no longer thinks it is "Not Responding" and it does not get grayed out. No flicker. Everything seems to run swimmingly. But once I click and drag the title bar to drag the window, rendering gets blocked. I haven't debugged it to be sure, but I suspect that SDL_PollEvent blocks for the duration of the window drag.
Is there a way around this? This is interesting because part of the behavior exhibited by failing to handle events is proof that what I want is possible in theory.
Update: I found this thread: http://www.gamedev.net/topic/488074-win32-message-pump-and-opengl---rendering-pauses-while-draggingresizing/
The verdict seems to be that it comes down to certain choices that Microsoft made for us... It basically gets stuck in DefWindowProc() till the mouse is released. It would get very messy to hack a fix for this and I might be able to do a work around by rendering in another thread. But I don't even want to begin to think about juggling an OpenGL context from multiple threads, if that's even something that's possible.
Some workaround that works for me - add event filter for SDL_WINDOWEVENT_SIZE_CHANGED event and do additional SetViewport and draw frame.
int SDLApp::eventFilter(void* pthis, const SDL_Event *event)
{
if (event->type == SDL_WINDOWEVENT &&
event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
{
SDLApp* app = (SDLApp*)pthis;
// Note: NULL rectangle is the entire window
SDL_RenderSetViewport(app->renderer_, NULL);
app->DrawFrame();
}
return 1;
}
...
SDL_SetEventFilter((SDL_EventFilter)SDLApp::eventFilter, this);
This question is old, but the solution I'm using doesn't seem to be mentioned anywhere else, so here it is.
I got my inspiration from this answer, and it doesn't use additional threads.
#include <SDL.h>
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <Windows.h>
#include <SDL_syswm.h>
#define SIZE_MOVE_TIMER_ID 1
bool sizeMoveTimerRunning = false;
int eventWatch(void*, SDL_Event* event) {
if (event->type == SDL_SYSWMEVENT) {
const auto& winMessage = event->syswm.msg->msg.win;
if (winMessage.msg == WM_ENTERSIZEMOVE) {
// the user started dragging, so create the timer (with the minimum timeout)
// if you have vsync enabled, then this shouldn't render unnecessarily
sizeMoveTimerRunning = SetTimer(GetActiveWindow(), SIZE_MOVE_TIMER_ID, USER_TIMER_MINIMUM, nullptr);
}
else if (winMessage.msg == WM_TIMER) {
if (winMessage.wParam == SIZE_MOVE_TIMER_ID) {
// call your render function
render();
}
}
}
return 0;
}
// rendering function
void render() {
/* do your rendering here */
}
// event loop - call this function after setting up your window to start the event loop
void eventLoop() {
SDL_AddEventWatch(eventWatch, nullptr); // register the event watch function
SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE); // we need the native Windows events, so we can listen to WM_ENTERSIZEMOVE and WM_TIMER
while (true) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (sizeMoveTimerRunning) {
// modal drag/size loop ended, so kill the timer
KillTimer(GetActiveWindow(), SIZE_MOVE_TIMER_ID);
sizeMoveTimerRunning = false;
}
/* handle the events here */
}
render();
}
}
Of course, if your rendering function needs to keep additional state (e.g. if you're using OOP), use the void* parameter of eventWatch(void*, SDL_Event*) to pass the state.
I had a similar problem in which it would freeze video playback when the window was dragged or resized. The solution I found was to spawn a separate thread for rendering and use the main thread for input.
Example:
DWORD RenderThread(SDL_Window* window)
{
//Rendering stuff here...
}
int main()
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Window* window = SDL_CreateWindow("Title Here",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, h, w, SDL_WINDOW_RESIZABLE);
HANDLE hRenderThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)RenderThread, window, 0, NULL);
SDL_Event event;
while (1)
{
SDL_PollEvent(&event);
switch (event.type)
{
//Event handling here...
}
}
}
Keep in mind that you MUST create the window in the thread that does event handling. If not it won't work. You can create the window in your event handling thread then pass that window pointer to your rendering thread.
I propose you created 2 threads:
Thread 1: loops calling SDL_PollEvent() (without rendering anything)
Thread 2: does OpenGL rendering (without calling SDL_PollEvent())
This way, your OpenGL context would be manipulated from a single thread. The whole solution has a minimum impact the architecture of your application.
Many windows procedures run a separate message loop until a certain event occurs, so you shouldn't rely on your main loop to do the drawing. If possible, application logic and rendering should always be handled in a separate thread.
Your main thread (that only handles message processing) doesn't need GL context at all, so you wouldn't need to worry about sharing.

wxWidgets - Creating a borderless frame movable

I am attempting to convert one of my application written in C# - Windows Forms to C++ - wxWidgets.
My app is borderless and has a thin, transparent panel on top of the form which can be used to move the form. (I used the technique from this question: Make a borderless form movable?)
Now, I basically want to do the same thing in wxWidgets, I've searched around the internet on how to handle a mouse down event over a wxPanel and found a couple examples but both used wxPython in their article/question and I have no knowledge about Python at all.
So how to do the same thing in C++ - wxWidgets?
One way is for the window to register an event handler for each of its child windows' mouse down events. That way the window can take control of the mouse if a certain condition is met (e.g. the Alt key is held down while clicking).
Some of this stuff is illustrated in the wxwidgets\samples\shaped\shaped.cpp sample but basically you do this:
Add a method to your window that you call after all the child windows have been added:
void MyFrame::BindChildEvents()
{
visit_recursively(this,
[] (wxWindow *window, MyFrame *thiz) {
// Bind all but the main window's event
if(window != thiz)
{
window->Bind(wxEVT_LEFT_DOWN, &MyFrame::OnChildLeftDown, thiz);
}
},
this
);
}
You can roll your own window tree traversal but I use this little helper function here:
template<typename F, typename... Args>
void
visit_recursively(wxWindow *window, F func, Args&&... args)
{
for(auto&& child : window->GetChildren())
{
visit_recursively(child, func, std::forward<Args>(args)...);
}
func(window, std::forward<Args>(args)...);
}
Then you set up your mouse down event interception handler:
void MyFrame::OnChildLeftDown(wxMouseEvent& event)
{
// If Alt is pressed while clicking the child window start dragging the window
if(event.GetModifiers() == wxMOD_ALT)
{
// Capture the mouse, i.e. redirect mouse events to the MyFrame instead of the
// child that was clicked.
CaptureMouse();
const auto eventSource = static_cast<wxWindow *>(event.GetEventObject());
const auto screenPosClicked = eventSource->ClientToScreen(event.GetPosition());
const auto origin = GetPosition();
mouseDownPos_ = screenPosClicked - origin;
}
else
{
// Do nothing, i.e. pass the event on to the child window
event.Skip();
}
}
And you handle mouse motion by moving the window along with the mouse:
void MyFrame::OnMouseMove(wxMouseEvent& event)
{
if(event.Dragging() && event.LeftIsDown())
{
const auto screenPosCurrent = ClientToScreen(event.GetPosition());
Move(screenPosCurrent - mouseDownPos_);
}
}
Be sure to call ReleaseMouse() in the wxEVT_LEFT_UP and wxEVT_MOUSE_CAPTURE_LOST events.
"how to fire a mouse down event?". You do not need to worry about 'firing' the event - the OS does that. You need to handle the event which is EVT_LEFT_DOWN. Is your question about how to handle wxWidgets events? Have you looked at the sample programs? http://docs.wxwidgets.org/2.6/wx_samples.html They are all in C++.
There is a description of how to handle events here: http://docs.wxwidgets.org/2.6/wx_eventhandlingoverview.html#eventhandlingoverview
If you question is about something more specific in the details of handling the EVT_LEFT_DOWN event, then please post your code, describe what you want it to do and what it does instead.