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
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 500 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

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Visual Studio 2015 -- ONLINE benefits ? 2 119
Fast data scrub 19 101
how to bring to back always mid parent image form 21 85
Configure a Local PHP Interpreter for Phpstorm 2 427
Programmer's Notepad is, one of the best free text editing tools available, simply because the developers appear to have second-guessed every weird problem or issue a programmer is likely to run into. One of these problems is selecting and deleti…
Update (December 2011): Since this article was published, the things have changed for good for Android native developers. The Sequoyah Project ( automates most of the tasks discussed in this article. You can even fin…
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
The viewer will learn how to use and create keystrokes in Netbeans IDE 8.0 for Windows.

749 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