[Webinar] Streamline your web hosting managementRegister Today


How to send key strokes to Paint for pasting a screen shot and then saving the file as jpg on the Desktop

Posted on 2008-10-13
Medium Priority
Last Modified: 2013-11-17
How to send key strokes to Paint for pasting a screen shot and then saving the file as jpg on the Desktop
Question by:robballi
  • 3
  • 2

Accepted Solution

BTecho earned 2000 total points
ID: 22713855
If you like you can completely bypass MS Paint to save the screen shot as jpg.

Back when BCBDEV was online they had this article:

Q: Screen capture the desktop.

This FAQ is an extension to the FAQ on how to create a TCanvas object for the entire screen. This technique first creates a TCanvas object for the screen. An Image control then calls the TCanvas::CopyRect function to copy the screen image into the TImage object.

  // First, get an HDC for the entire screen with the API GetDC function.
  // Then create a Canvas based on the DC.
  HDC dc = GetDC(0);
  Graphics::TCanvas *ScreenCanvas = new Graphics::TCanvas;
  ScreenCanvas->Handle = dc;

  // Resize the TImage control to match the size of the screen.
  // Then copy from the screen Canvas to the TImage Canvas.
  Image1->Picture->Bitmap->Width = Screen->Width;
  Image1->Picture->Bitmap->Height= Screen->Height;
  TRect rect = Rect(0,0,Screen->Width, Screen->Height);
  Image1->Picture->Bitmap->Canvas->CopyRect(rect, ScreenCanvas, rect);

  // cleanup
  delete ScreenCanvas;

You can capture a specific window by obtaining a DC for that window instead of getting a DC for the entire screen. This code captures the C++Builder main window if it's visible.

  // The BCB IDE window has the window class "TAppBuilder"
  HWND BCBHandle = FindWindow("TAppBuilder",NULL);
    // Create a TCanvas for the BCB IDE window. GetWindowDC returns a DC for the
    // whole window, including the menu, title bar and border.
    HDC dc = GetWindowDC(BCBHandle);
    Graphics::TCanvas *ScreenCanvas = new Graphics::TCanvas;
    ScreenCanvas->Handle = dc;

    // need to create a TRect that is the same width and height as the ClipRect
    // of the Canvas, but whose left and top members are zero.
    TRect rect = ScreenCanvas->ClipRect;
    rect.Right  = rect.Right  - rect.Left;
    rect.Bottom = rect.Bottom - rect.Top;
    rect.Top = rect.Left = 0;

    // resize the bitmap of the Image, and then copy the contents of the
    // BCB ide canvas to the bitmap's canvas. Then clean up the canvas and DC
    Image1->Picture->Bitmap->Width = rect.Right;
    Image1->Picture->Bitmap->Height= rect.Bottom;
    delete ScreenCanvas;

Note: The ClipRect property of TCanvas is recalculated every time the property is read. This is good, because the clipping rect of a window changes every time the window is moved or resized. ClipRect re-reads the info so the Canvas keeps up with changes to its underlying HWND and HDC (this did not play a role in the example code)

Note: You must remember to call ReleaseDC for the HDC handle.

Note: Both GetDC and GetWindowDC take an HWND as their argument. GetDC returns a DC for the client area of the specified window. GetWindowDC returns a DC that can draw on both the non-client and client areas of the window. In other words, you can paint the title bar and menu of a window if you obtain the DC with GetWindowDC.

Here is one more link

The links show you how to save to BMP. To convert a BMP to JPG

#include <jpeg.hpp>
  TJPEGImage *Jpeg = new TJPEGImage;

      //or Jpeg->Assign(Bitmap);



Author Comment

ID: 22715149
Hello BTecho:

A couple of things:

The first:

It is wonderfull your solution for the complete screen:
On the second solution for the partial screen:
The compiler is stopping on this line:
    rect.Top = rect.Left = 0;

and issues the following errors:
[C++ Error] User.cpp(139): E2492 Properties may only be assigned using a simple statement, e.g. "prop = value;"
[C++ Error] User.cpp(139): E2369 Cannot use the result of a property assignment as an rvalue

you have alredy solved the problem using another technique i just would like to see what is the problem i have just explained. I am thinking of opening a new question with your solution as the winner!!

The Second:

I specified Paint since it seems the easiest. But we would like to control for instance WorPad, i think it is the same principle as the solution you send me yesterday using keybd_event:
but for instance to send the sequence:

Win = FindWindow("MSPaintApp", "untitled - Paint"); ??????
keybd_event (VK_LCONTROL, 0, 0, 0);
keybd_event(?) for the V to paste for instance the picture ???
keybd_event (VK_LCONTROL, 0, 0, 0);  ???
keybd_event(?) for the S ???

then appears the dialog box that i don't know what is the principle of how to get a handle of it?

Looking forward to hearing from you.


Expert Comment

ID: 22717912
Hi Roberto,

For the error , please replace that one line with two lines

    rect.Top = 0;
    rect.Left = 0;

To simulate ctrl+c
    keybd_event(VK_CONTROL, 0, 0, 0);  //press down ctrl key
    keybd_event('C', 0, 0, 0);                     //press down C key
    keybd_event('C', 0, KEYEVENTF_KEYUP, 0);  //release C
    keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);  //release ctrl

What you're doing with FindWindow is good , you're getting the handle but then you also have to bring the window into focus then emulate the key press.  


 ShowWindow(Win, SW_SHOWNORMAL);

 ...keybd_event code after

What might be better, use either PostMessage or SendMessage to send key presses to the main window / application handle with the WM_KEYDOWN message. This way you don't have to put actual focus on the window. I have some code on my other computer I will get to later if you still need it.

FindWindow("MSPaintApp", "untitled - Paint");  Looks right to me.

Or you can try like this ,
HWND Win=FindWindow("MSPaintApp", 0); keep the class name but dont search for the title, just in case the caption bar changes. If you're sure the window you're searching for has exactly "untitled - Paint" as the title then use what you have already.

Good luck!


Expert Comment

ID: 22717922
oh I'm sorry, I posted code for Ctrl+C. Ctrl+V is very similar

To simulate ctrl+c
    keybd_event(VK_CONTROL, 0, 0, 0);  //press down ctrl key
    keybd_event('V', 0, 0, 0);                     //press down V key
    keybd_event('V', 0, KEYEVENTF_KEYUP, 0);  //release V
    keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);  //release ctrl

Author Closing Comment

ID: 31505781
Excelent feedback congratulation BTecho

Featured Post

Receive 1:1 tech help

Solve your biggest tech problems alongside global tech experts with 1:1 help.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Here is a helpful source code for C++ Builder programmers that allows you to manage and manipulate HTML content from C++ code, while also handling HTML events like onclick, onmouseover, ... Some objects defined and used in this source include: …
Jaspersoft Studio is a plugin for Eclipse that lets you create reports from a datasource.  In this article, we'll go over creating a report from a default template and setting up a datasource that connects to your database.
The viewer will learn how to use NetBeans IDE 8.0 for Windows to connect to a MySQL database. Open Services Panel: Create a new connection using New Connection Wizard: Create a test database called eetutorial: Create a new test tabel called ee…
The viewer will learn how to use and create new code templates in NetBeans IDE 8.0 for Windows.

607 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question