Taking and saving screenshots

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Natulux
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 226
Joined: Thu Aug 03, 2017 12:20 pm

Taking and saving screenshots

Post by Natulux » Tue Aug 29, 2017 6:52 am

Hey guys

I want to implement a screenshot tool into my application, which is able to capture the current screen and save it to a file. Even better would be a way to choose the size and position for the screenshot, but that is for the future.
(I am currently back at wxWidgets 2.9.x again)

I found and used this snipped:
http://www.omnicode.com/qa.php?id=23
Which I used as:

Code: Select all

	void MyFrame::Screenshot(wxString sSaveTo)
{
	wxFileName fnSaveTo(sSaveTo); // contains path and full name
	// ... doing stuff ...
	
	RECT rect;
	HWND wnd = GetDesktopWindow();
	HDC dc = GetDC(wnd);
	::GetClientRect(wnd, &rect);
	HDC dc1 = CreateCompatibleDC(dc);

	BITMAPINFO bi;
	memset( &bi, 0, sizeof(BITMAPINFO) );
	bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	bi.bmiHeader.biWidth = rect.right;
	bi.bmiHeader.biHeight = rect.bottom;
	bi.bmiHeader.biPlanes = 1;
	bi.bmiHeader.biBitCount = 24;
	bi.bmiHeader.biCompression = BI_RGB;
	void *bits = NULL;
	HBITMAP bm = CreateDIBSection(dc1, &bi, DIB_RGB_COLORS, (void **)(&bits), NULL, 0 );

	SelectObject(dc1, bm);
	BitBlt(dc1, 0, 0, rect.right, rect.bottom, dc, 0, 0, SRCCOPY);
	wxImage image;
	image.Create(rect.right, rect.bottom);
	for (int x = 0; x < rect.right; x++)
	{
		for (int y = 0; y < rect.bottom; y++)
		{
			COLORREF c = GetPixel(dc1, x, y);
			image.SetRGB(x, y, GetRValue(c), GetGValue(c), GetBValue(c));
		}
	}

	image.SaveFile(fnSaveTo.GetFullPath(), wxBITMAP_TYPE_BMP);
}
It is working, but it is awefully slow. A screenshot takes maybe about 5sec and Im not sure what the user is doing in that time to interrupt the process. Im not really experienced with graphical programming.
Do you have any ideas, how to speed that up or how other tools take the apporach? Several freeware tools are much faster than this. ;-)

Have a good one
Natu

User avatar
doublemax
Moderator
Moderator
Posts: 15491
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Taking and saving screenshots

Post by doublemax » Tue Aug 29, 2017 7:11 am

Code: Select all

COLORREF c = GetPixel(dc1, x, y);
image.SetRGB(x, y, GetRValue(c), GetGValue(c), GetBValue(c));
Reading and writing every single pixel in the inner loop makes this slow.

But fortunately there is an easier way without platform specific code:
viewtopic.php?p=32313#p32313
Use the source, Luke!

Natulux
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 226
Joined: Thu Aug 03, 2017 12:20 pm

Re: Taking and saving screenshots

Post by Natulux » Tue Aug 29, 2017 7:25 am

I didn't find that article, shame on me.
Thank you doublemax, I'll have a look at that!

[EDIT:]
Works like a charm. ;-)
Do you by any chance know another article about capturing mouse events outside of a (my) frame, so that I can tackle custom area screenshots?

Greetings
Natu

User avatar
doublemax
Moderator
Moderator
Posts: 15491
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Taking and saving screenshots

Post by doublemax » Tue Aug 29, 2017 10:08 am

No article, but wxWindow::CaptureMouse() is the key:
http://docs.wxwidgets.org/trunk/classwx ... 7ec85fcfef
Use the source, Luke!

Natulux
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 226
Joined: Thu Aug 03, 2017 12:20 pm

Re: Taking and saving screenshots

Post by Natulux » Tue Aug 29, 2017 2:41 pm

Hey

CaptureMouse() looks quite good. But I'm having trouble using it.

I have my Event Table:

Code: Select all

BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_LEFT_DOWN(MyFrame::OnMouseLeftDown)
EVT_LEFT_UP(MyFrame::OnMouseLeftUp)
EVT_RIGHT_DOWN(MyFrame::OnMouseRightDown)
END_EVENT_TABLE()
And the functions:

Code: Select all

//Start MouseCapture
void MyFrame::ScreenshotRect(wxString sSaveTo, Patient *p)
{
	m_screeneRect = wxRect(0,0,0,0);
	m_screenePointStart = wxPoint(0,0);
	m_screenePointEnd = wxPoint(0,0);
	if(!mb_mouseCaptured)
	{
		wxWindow::CaptureMouse();	
	}	
}

//Catch and save left mouse down
void MyFrame::OnMouseLeftDown(wxMouseEvent& event)
{
	m_screenePointStart = wxGetMousePosition();
}

//Catch and save left mouse up
void MyFrame::OnMouseLeftUp(wxMouseEvent& event)
{
	m_screenePointEnd = wxGetMousePosition();

	wxWindow::ReleaseMouse();
	FinishRectSave();
}

//Abort
void MyFrame::OnMouseRightDown(wxMouseEvent& event)
{
	//wxMessageBox("RightDown");
	wxWindow::ReleaseMouse();
}

//show the two positions
void MyFrame::FinishRectSave()
{
	wxString sA, sE = "";
	sA << m_screenePointStart.x << "\n" << m_screenePointStart.y;
	sE << m_screenePointEnd.x << "\n" << m_screenePointEnd.y;
	wxMessageBox(sA + "\n" + sE);
}
For my rect I want to capture the left mouse down event for the starting point and left mouse up for the finishing point of my rect.
If the right mouse button is pressed, the process should be aborted.
But the Left-Mouse-Button-Up-Event is fired together with Left-Mouse-Button-Down-Event, which I can see from the wxMessageBox of FinishRectSave(), where both points are exactly the same.

Is there any paticular reason why?

Thanks
Natu

ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 4699
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Taking and saving screenshots

Post by ONEEYEMAN » Tue Aug 29, 2017 3:05 pm

Hi,
I don't think you need to do a Mouse Capture.
You can use overlay and just handle mouse events.

I wrote something like this couple of years ago and it was working fine on both Windows and Mac.
Unfortunately the code is not on GitHub and I'm at work.

I can post it here when I come home.

Thank you.

User avatar
doublemax
Moderator
Moderator
Posts: 15491
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Taking and saving screenshots

Post by doublemax » Tue Aug 29, 2017 3:34 pm

How you you start the operation, which a mouse click, e.g. on a button? It's possible that you receive the mouse up event of that click first and the capture ends before it starts :)

Set the mb_mouseCaptured flag when capturing the mouse and check for it in the mouse up handler.
Use the source, Luke!

Natulux
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 226
Joined: Thu Aug 03, 2017 12:20 pm

Re: Taking and saving screenshots

Post by Natulux » Wed Aug 30, 2017 6:16 am

ONEEYEMAN wrote:Hi,
I don't think you need to do a Mouse Capture.
You can use overlay and just handle mouse events.
Im not sure, if I understand you. What do you mean by 'overlay' in this case? An invisible frame with the size of my screen, whcih captures the events?
I wrote something like this couple of years ago and it was working fine on both Windows and Mac.
Unfortunately the code is not on GitHub and I'm at work.

I can post it here when I come home.

Thank you.
That sounds good and I thank you! ;-)
How you you start the operation, which a mouse click, e.g. on a button? It's possible that you receive the mouse up event of that click first and the capture ends before it starts :)

Set the mb_mouseCaptured flag when capturing the mouse and check for it in the mouse up handler.
I start the operation by selecting an option from my menu context item (in another class) with a mouse click, that is right. And that starts the functions I posted above.
But the mouseCapture starts only after the menu item is clicked. You think, it is processing old mouse events from the stack? The same happens if I wait some time before making the next click, so Im not convinced. ;-) Furthermore, if I put wxMessageBoxes in my Left-Down/Up functions, those messages are only called after the next click, as it should be. Just that the LeftDown message is also send, even though I havent even released the mouse button ;-)

But as you said, I might just go with a boolean, like:

Code: Select all

void MyFrame::OnMouseLeftDown(wxMouseEvent& event)
{
	if(!bLeftMouseUp)
		return;
	else
		bLeftMouseUp = false;
	
	m_screenePointStart = wxGetMousePosition();
	event.Skip();
}
Greetings
Natu
Last edited by Natulux on Wed Aug 30, 2017 8:08 am, edited 2 times in total.

Natulux
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 226
Joined: Thu Aug 03, 2017 12:20 pm

Re: Taking and saving screenshots

Post by Natulux » Wed Aug 30, 2017 7:39 am

Hey again

Another test:

Code: Select all

void MyFrame::OnMouse(wxMouseEvent& event)
{
	if(event.GetEventType() == wxEVT_LEFT_DOWN)
	{
		wxLogMessage("LeftDown");
	}
	else if(event.GetEventType() == wxEVT_LEFT_UP)
	{
		wxLogMessage("LeftUp");
	}
	else if(event.GetEventType() == wxEVT_RIGHT_DOWN)
	{
		wxLogMessage("RightDown");
	}
}
LeftDown and LeftUp are at the same time directly after pressing down.
If I remember correctly, there is also a "click" event, which contains the up and down both. Is it possible, that internally, there is a click event, which then is slpit up into two simultaniusly send events: down and up?

If I protect the mouse up functionality with a boolean, I never catch a second event.
I could wait for 2 clicks, one click for the starting position and the other for the ending position. But that is a little counter-intuitive, because every freeware tool lets you draw a rect.

I could also make a screenshot and put that in a frame, where I have my native events, which might work better. Though I would have issues with scaling, since the frame then cuts some pixels of my original size.

Well, Im curious what ONEEYEMAN comes up with. :-)

Greets
Natu

[EDIT:]
Not even those 2 clicks are trivial:

Code: Select all

void MyFrame::OnMouse(wxMouseEvent& event)
{
	if(event.GetEventType() == wxEVT_LEFT_DOWN)
	{
		if(!mb_LeftMouseDown)
		{
			mb_LeftMouseDown = true;
			m_screenePointStart = wxGetMousePosition();
			wxWindow::ReleaseMouse();
			wxWindow::CaptureMouse();
		}
		else
		{
			mb_LeftMouseDown = false;
			m_screenePointEnd = wxGetMousePosition();
			wxWindow::ReleaseMouse();
			FinishRectSave();
		}
	}
}
It doesen't matter if I capture twice, release and capture again or capture just once and release once at the end: I get one click, and one click only. I don't even get another one, if I click the initial "Take screene" button again. (No right click either)

It seems like I can't get the CaptureMouse() to work this way.

User avatar
doublemax
Moderator
Moderator
Posts: 15491
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Taking and saving screenshots

Post by doublemax » Wed Aug 30, 2017 10:24 am

Can you show the complete, compilable code?
Use the source, Luke!

Natulux
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 226
Joined: Thu Aug 03, 2017 12:20 pm

Re: Taking and saving screenshots

Post by Natulux » Wed Aug 30, 2017 12:00 pm

Phu, that is not an easy task, as my screenshot tool is only a small add to a program, which I can't easily post here.

I have a really ugly compressed version with the not working toolbar tray icon and its context menu with "screenshot".
Start looking at function:

Code: Select all

void MyFrame::OnMouse(wxMouseEvent& event)
This one fires, after you clicked on menu item "Screenshot" and then tried to click and pull on the screen; but it does only once and with both events (up and down) at the same time.

And here comes the whole mess of compressed, but compileable, code
(used wxWidgets 2.9.2)

MyTaskBarIcon.cpp

Code: Select all

#include "MyTaskBarIcon.h"
#include <wx/cmdline.h>
#include <wx/menu.h>
#include <wx/filename.h>
#include <wx/textfile.h>
#include <wx/process.h>
#include <wx/stdpaths.h>

IMPLEMENT_APP(MyApp)

// 'Main program' equivalent: the program execution "starts" here
bool MyApp::OnInit()
{
     if ( !wxApp::OnInit() )
        return false;

	mfn_apppath = (new wxStandardPaths)->GetExecutablePath();
	
    // create the main application window
	m_frame = new MyFrame("Minimal wxWidgets App");

	// and show it (the frames, unlike simple controls, are not shown when
	// created initially)
	m_frame->Show(false);
	return true;
}



void MyApp::OnInitCmdLine(wxCmdLineParser& parser)
{

	static const wxCmdLineEntryDesc cmdLineDesc[] =
{
	{wxCMD_LINE_PARAM, NULL, NULL, "", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL}, 
    { wxCMD_LINE_NONE }
};
    parser.SetDesc (cmdLineDesc);  
}

DECLARE_APP(MyApp)

BEGIN_EVENT_TABLE(MyTaskBarIcon, wxTaskBarIcon)
    EVT_MENU(ID_TASK_EXIT,    MyTaskBarIcon::OnMenuExit)
	EVT_MENU(ID_TASK_SCREENSHOT_RECT, MyTaskBarIcon::OnScreenshotRect)
END_EVENT_TABLE()


wxMenu *MyTaskBarIcon::CreatePopupMenu()
{
    wxMenu *menu = new wxMenu;
    menu->Append(ID_TASK_SCREENSHOT_RECT,	wxT("Screenshot"));
	menu->Append(ID_TASK_EXIT,				wxT("exit"));
    return menu;
}

void MyTaskBarIcon::OnMenuExit(wxCommandEvent&)
{
	wxGetApp().m_frame->Close(true);
}

void MyTaskBarIcon::OnScreenshotRect(wxCommandEvent&)
{
	wxGetApp().m_frame->Screenshot_ToAppDir_rect();
}

DECLARE_APP(MyApp)

BEGIN_EVENT_TABLE(MyFrame, wxFrame)
   	EVT_MOUSE_EVENTS(MyFrame::OnMouse)
	EVT_TIMER(ID_TIMER, MyFrame::Go)
END_EVENT_TABLE()

MyFrame::MyFrame(const wxString& title)
       : wxFrame(NULL, wxID_ANY, title, wxPoint(10,10), wxSize(100,100), wxSTAY_ON_TOP|wxRESIZE_BORDER|wxFRAME_NO_TASKBAR)
{
    // set the frame icon
    SetIcon(wxICON(infoicon));

	wxInitAllImageHandlers();

	m_taskBarIcon = new MyTaskBarIcon();
	// we should be able to show up to 128 characters on recent Windows versions
    // (and 64 on Win9x)
    if ( !m_taskBarIcon->SetIcon(wxICON(infoicon), "Patientenhinweis-Dienst") )
    {
        wxLogError(wxT("Icon konnte nicht gesetzt werden."));
    }
#if defined(__WXOSX__) && wxOSX_USE_COCOA
    m_dockIcon = new MyTaskBarIcon(wxTaskBarIcon::DOCK);
    if ( !m_dockIcon->SetIcon(wxICON(infoicon)) )
    {
        wxLogError(wxT("Icon konnte nicht gesetzt werden."));
    }
#endif

	mb_mouseCaptured = false;
	mb_LeftMouseDown = false;
	mfn_DirPath = wxGetApp().mfn_apppath;

	ml_timerLapse = 500;
	mt_timer = new wxTimer(this, ID_TIMER);
	//mt_timer->Connect(ID_TIMER, wxEVT_TIMER, wxTimerEventHandler(MyFrame::Go), NULL, this);
	//mt_timer->Bind(wxEVT_TIMER, wxTimerEventHandler(MyFrame::Go), ID_TIMER, wxID_ANY, NULL);

	mt_timer->Start(1, true);
}

MyFrame::~MyFrame()
{
    delete m_taskBarIcon;
#if defined(__WXCOCOA__)
    delete m_dockIcon;
#endif
}

void MyFrame::Screenshot_ToAppDir_rect()
{
	mfn_DirPath = wxGetApp().mfn_apppath;
	ScreenshotRect(mfn_DirPath.GetFullPath());
}

void MyFrame::ScreenshotRect(wxString sSaveTo)
{
	m_screeneRect = wxRect(0,0,0,0);
	m_screenePointStart = wxPoint(0,0);
	m_screenePointEnd = wxPoint(0,0);

	mb_LeftMouseDown = false;
	if(!mb_mouseCaptured)
	{
		wxWindow::CaptureMouse();	
		mb_mouseCaptured = true;
	}
}

void MyFrame::OnMouse(wxMouseEvent& event)
{
	if(event.GetEventType() == wxEVT_LEFT_DOWN)
	{
		m_screenePointStart = wxGetMousePosition();
		
		if(!mb_LeftMouseDown)
		{
			mb_LeftMouseDown = true;
			m_screenePointStart = wxGetMousePosition();
			wxWindow::ReleaseMouse();
			wxWindow::CaptureMouse();
		}
		else
		{
			mb_LeftMouseDown = false;
			m_screenePointEnd = wxGetMousePosition();
			wxWindow::ReleaseMouse();
			FinishRectSave();
		}

		wxString s = "";
		s << "LeftDown: " << mb_LeftMouseDown;
		wxLogMessage(s);
	}
	else if(event.GetEventType() == wxEVT_LEFT_UP)
	{
		wxLogMessage("LeftUp");
	}
	else if(event.GetEventType() == wxEVT_RIGHT_DOWN)
	{
		wxLogMessage("RightDown");
	}
}

void MyFrame::FinishRectSave()
{
	wxString sA, sE = "";
	sA << m_screenePointStart.x << "\n" << m_screenePointStart.y;
	sE << m_screenePointEnd.x << "\n" << m_screenePointEnd.y;
	wxMessageBox(sA + "\n" + sE);
	wxSize screeneSize(m_screenePointEnd.x - m_screenePointStart.x, m_screenePointEnd.y - m_screenePointStart.y);
	if(screeneSize.x <= 0 || screeneSize.y <= 0)
		return;

	m_screeneRect = wxRect(m_screenePointStart, screeneSize);
	//Screenshot(mfn_DirPath.GetFullPath(), m_p, m_screeneRect);
	
}

void MyFrame::Go(wxTimerEvent &event)
{
	mt_timer->Stop();

	//other stuff [...]

	mt_timer->Start(ml_timerLapse);
}
MyTaskBarIcon.h

Code: Select all

#pragma once
#include <wx/taskbar.h>
#include "wx/wxprec.h"
#include <wx/filename.h>

#ifdef __BORLANDC__
    #pragma hdrstop
#endif

#ifndef WX_PRECOMP
    #include "wx/wx.h"
#endif

#if !defined(__WXMSW__) && !defined(__WXPM__)
    #include "../sample.xpm"
#endif

#ifndef _UNICODE
#define _UNICODE
#endif

#ifndef NDEBUG
#define NDEBUG
#endif


#ifndef WX_PRECOMP
    #include "wx/wx.h"
#endif




class MyTaskBarIcon : public wxTaskBarIcon
{
public:
#if defined(__WXOSX__) && wxOSX_USE_COCOA
    MyTaskBarIcon(wxTaskBarIconType iconType = DEFAULT_TYPE)
    :   wxTaskBarIcon(iconType)
#else
    MyTaskBarIcon()
#endif
    {}

public:

    void OnMenuExit(wxCommandEvent&);
	void OnScreenshot(wxCommandEvent&);
	void OnScreenshotRect(wxCommandEvent&);
	void OnCharHook(wxKeyEvent &event);
	void OnMouseLeftUp(wxMouseEvent& event);
	void OnMouseLeftDown(wxMouseEvent& event);
    virtual wxMenu *CreatePopupMenu();

    DECLARE_EVENT_TABLE()
};

enum
{
	//ID_TASK_SHOW,
	ID_TASK_EXIT,
	//ID_TASK_RESTART,
	//ID_TASK_TEAMVIEWER,	
	ID_TASK_SCREENSHOT,
	ID_TASK_SCREENSHOT_RECT
};


#ifndef myframe_h
#define myframe_h


// Define a new frame type: this is going to be our main frame
class MyFrame : public wxFrame
{
public:
    // ctor(s)
    MyFrame(const wxString& title);
	~MyFrame();

	wxFileName mfn_DirPath;
	
	//Screenshots - Vars
	bool mb_mouseCaptured;
	bool mb_LeftMouseDown ;
	wxRect	m_screeneRect;
	wxPoint	m_screenePointStart;
	wxPoint m_screenePointEnd;

	wxTimer *mt_timer;
	long ml_timerLapse;

	//Screenshots - Functions
	void FinishRectSave();
	void Screenshot_ToAppDir_rect();
	void ScreenshotRect(wxString sSaveTo);
	
	MyTaskBarIcon   *m_taskBarIcon;
#if defined(__WXOSX__) && wxOSX_USE_COCOA
    MyTaskBarIcon   *m_dockIcon;
#endif

	void OnMouse(wxMouseEvent& event);
	void Go(wxTimerEvent &event);

private:
    // any class wishing to process wxWidgets events must use this macro
    DECLARE_EVENT_TABLE()
};

// Define a new application type, each program should derive a class from wxApp
class MyApp : public wxApp
{
public:
    // override base class virtuals
    // ----------------------------
	
	MyFrame *m_frame;
	wxFileName mfn_apppath;
	wxFileName baseexe;
	//wxFileName mfn_dbpath;
	//wxFileName mfn_patConfigPath;
	int processid;

    // this one is called on application startup and is a good place for the app
    // initialization (doing it here and not in the ctor allows to have an error
    // return: if OnInit() returns false, the application terminates)
	virtual void OnInitCmdLine(wxCmdLineParser& parser);
	
  // virtual bool OnCmdLineParsed(wxCmdLineParser& parser);
    virtual bool OnInit();
};

// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------

// IDs for the controls and the menu commands
enum
{
    // menu items
    //Minimal_Quit = wxID_EXIT,

    // it is important for the id corresponding to the "About" command to have
    // this standard value as otherwise it won't be handled properly under Mac
    // (where it is special and put into the "Apple" menu)
    //Minimal_About = wxID_ABOUT,
	ID_TIMER
	
};


#endif // myframe_h

Functions of interest in correct order:

Code: Select all

void MyTaskBarIcon::OnScreenshotRect(wxCommandEvent&)
void MyFrame::Screenshot_ToAppDir_rect()
void MyFrame::ScreenshotRect(wxString sSaveTo)
void MyFrame::OnMouse(wxMouseEvent& event) //error
(void MyFrame::FinishRectSave())
Greets
Natu

User avatar
doublemax
Moderator
Moderator
Posts: 15491
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Taking and saving screenshots

Post by doublemax » Wed Aug 30, 2017 1:12 pm

A little messy indeed ;)

I'll take a closer look when i get home in a few hours.
Use the source, Luke!

Natulux
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 226
Joined: Thu Aug 03, 2017 12:20 pm

Re: Taking and saving screenshots

Post by Natulux » Wed Aug 30, 2017 1:23 pm

A little? xD

Thank you.
But don't ruin your free time with it (not too much). Using a frame or, if I get the code, an overlay is good as well.
At the moment I am playing with a borderless panel in a frame with a screenshot in it. This is almost as good as drawing on the screen itself. ;-)

coderrc
Earned some good credits
Earned some good credits
Posts: 141
Joined: Tue Nov 01, 2016 2:46 pm

Re: Taking and saving screenshots

Post by coderrc » Wed Aug 30, 2017 1:27 pm

try this instead

Code: Select all


void MyFrame::OnMouse(wxMouseEvent& event)
{
   if(event.GetEventType() == wxEVT_LEFT_DOWN)
   {
      m_screenePointStart = wxGetMousePosition();
      
      if(!mb_LeftMouseDown && event.LeftIsDown()) // left button held down ie user is dragging
      {
         mb_LeftMouseDown = true;
         m_screenePointStart = wxGetMousePosition();
         wxWindow::ReleaseMouse();
         wxWindow::CaptureMouse();
      }

      wxString s = "";
      s << "LeftDown: " << mb_LeftMouseDown;
      wxLogMessage(s);
   }
   else if(event.GetEventType() == wxEVT_LEFT_UP)
   {
      wxLogMessage("LeftUp");
      if(mb_LeftMouseDown && event.LeftUp())
      {
         mb_LeftMouseDown = false;
         m_screenePointEnd = wxGetMousePosition();
         wxWindow::ReleaseMouse();
         FinishRectSave();
      }
   }
   else if(event.GetEventType() == wxEVT_RIGHT_DOWN)
   {
      wxLogMessage("RightDown");
   }
}

you might also want to look at creating a custom "StartScreenShotEvent" in order to decouple the Menu Event from the Mouse Event
something like

Code: Select all

void MyTaskBarIcon::OnScreenshotRect(wxCommandEvent&)
{
   wxCommandEvent* evt = new wxCommandEvent(StartScreenShet);
   GetEventHandler()->QueueEvent(evt);
}

void MyTaskBarIcon::OnStartScreenShet(wxCommandEvent&)
{
  wxGetApp().m_frame->Screenshot_ToAppDir_rect();
}

ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 4699
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Taking and saving screenshots

Post by ONEEYEMAN » Wed Aug 30, 2017 1:55 pm

Hi,
Here it is.
Compile and try to run. It uses libcurl for sending and receiving the data.
Or just follow the logic.

Let me know if you can't open the file. I will try to re-pack as zip.

Thank you.
Attachments
project.7z
(46.65 KiB) Downloaded 50 times

Post Reply