Learn how to a build a cloud-first strategyRegister Now


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

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

Question has a verified solution.

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

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.
How to install Selenium IDE and loops for quick automated testing. Get Selenium IDE from http://seleniumhq.org Go to that link and select download selenium in the right hand column That will then direct you to their download page. From that p…
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
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…
Suggested Courses

810 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