Solved

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
5
908 Views
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
0
Comment
Question by:robballi
  • 3
  • 2
5 Comments
 
LVL 3

Accepted Solution

by:
BTecho earned 500 total points
ID: 22713855
Hello,
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.


Answer:
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;
  ReleaseDC(NULL,dc);

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);
  if(BCBHandle)
  {
    // 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;
    Image1->Picture->Bitmap->Canvas->CopyRect(rect,
                                              ScreenCanvas,
                                              ScreenCanvas->ClipRect);
    delete ScreenCanvas;
    ReleaseDC(BCBHandle,dc);
  }

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
http://bcbjournal.org/articles/vol4/0010/Taking_a_screen_shot.htm

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

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

      Jpeg->Assign(Image1->Picture->Bitmap);
      //or Jpeg->Assign(Bitmap);
      Jpeg->CompressionQuality=50;
      Jpeg->SaveToFile("c:\\testResample.jpg");

    Jpeg->Free();


0
 

Author Comment

by:robballi
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:
Ctrl+V

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.

Roberto
0
 
LVL 3

Expert Comment

by:BTecho
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.  

Try

 ShowWindow(Win, SW_SHOWNORMAL);
 SetForegroundWindow(Win);  
 ::SetFocus(Win);

 ...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!


0
 
LVL 3

Expert Comment

by:BTecho
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
0
 

Author Closing Comment

by:robballi
ID: 31505781
Excelent feedback congratulation BTecho
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

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ā€¦
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.
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
The viewer will learn how to use and create new code templates in NetBeans IDE 8.0 for Windows.

746 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

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now