Solved

how do I feed hwnd to screencapture?

Posted on 2007-11-26
21
481 Views
Last Modified: 2013-11-13
this is by using windows sdk and I am calling its functions and objects.

I have my handle from this line



HWND hwnd = FindWindow(NULL,"Notepad");


how do I feed it to this function?


note that this function is from a demonstration of how to capture screen.


Void CaptureScreen()
{
    int nScreenWidth = GetSystemMetrics(SM_CXSCREEN);
    int nScreenHeight = GetSystemMetrics(SM_CYSCREEN);
    HWND hDesktopWnd = GetDesktopWindow();
    HDC hDesktopDC = GetDC(hDesktopWnd);
    HDC hCaptureDC = CreateCompatibleDC(hDesktopDC);
    HBITMAP hCaptureBitmap =CreateCompatibleBitmap(hDesktopDC,
                            nScreenWidth, nScreenHeight);
    SelectObject(hCaptureDC,hCaptureBitmap);
    BitBlt(hCaptureDC,0,0,nScreenWidth,nScreenHeight,
           hDesktopDC,0,0,SRCCOPY|CAPTUREBLT);
    SaveCapturedBitmap(hCaptureBitmap); //Place holder - Put your code
                                //here to save the captured image to disk
    ReleaseDC(hDesktopWnd,hDesktopDC);
    DeleteDC(hCaptureDC);
    DeleteObject(hCaptureBitmap);
}





and then eventually I want to use this function to get pixel color data in RGB form,  how do I feed hdc from above to this function?


COLORREF GetPixel(
  HDC hdc,    // handle to DC
  int nXPos,  // x-coordinate of pixel
  int nYPos   // y-coordinate of pixel
);



what does this function return?


thanks for reading
0
Comment
Question by:Troudeloup
  • 11
  • 7
  • 3
21 Comments
 

Author Comment

by:Troudeloup
ID: 20352641
Void CaptureScreen()
{
    int nScreenWidth = GetSystemMetrics(SM_CXSCREEN);
    int nScreenHeight = GetSystemMetrics(SM_CYSCREEN);
    HWND hDesktopWnd = GetDesktopWindow();
    HDC hDesktopDC = GetDC(hDesktopWnd);
    HDC hCaptureDC = CreateCompatibleDC(hDesktopDC);
    HBITMAP hCaptureBitmap =CreateCompatibleBitmap(hDesktopDC,
                            nScreenWidth, nScreenHeight);
    SelectObject(hCaptureDC,hCaptureBitmap);

    //  I run this to prepare to capture screen, and after this I can run


    // I run this to capture. but I can't make it out the part to pass it to the getpixel function

    BitBlt(hCaptureDC,0,0,nScreenWidth,nScreenHeight,
           hDesktopDC,0,0,SRCCOPY|CAPTUREBLT);



    SaveCapturedBitmap(hCaptureBitmap);
    //Place holder - Put your code
    //here to save the captured image to disk

    // what does this do?



    ReleaseDC(hDesktopWnd,hDesktopDC);
    DeleteDC(hCaptureDC);
    DeleteObject(hCaptureBitmap);
   
    // I run these 3 only when I am done capturing right?
}
0
 
LVL 86

Assisted Solution

by:jkr
jkr earned 250 total points
ID: 20352862
>>what does this function return?

COLORREF is a 32-bit value used to specify an RGB color and has the following hexadecimal form:

0x00bbggrr
 
The low-order byte contains a value for the relative intensity of red; the second byte contains a value for green; and the third byte contains a value for blue. The high-order byte must be zero. The maximum value for a single byte is 0xFF.

0
 
LVL 55

Assisted Solution

by:Jaime Olivares
Jaime Olivares earned 250 total points
ID: 20352875
Should be something like:

HBITMAP CaptureWindow(HWND hWnd)
{
     RECT rect;
     if  (!GetWindowRect(hWnd, &rect))
          return NULL;
     HDC hWindowDC = ::GetDC(hWnd);
     if (!hWindowDC)
          return NULL;
     HDC hCaptureDC = CreateCompatibleDC(hWindowDC);
     if (!hCaptureDC)
          return NULL;
     HBITMAP hBitmap = CreateCompatibleBitmap(hWindowDC, rect.right-rect.left+1, rect.top-rect.bottom+1));
     if (!hBitmap) {
          DeleteDC(hCaptureDC);
          return NULL;
     }
     HBITMAP oldBmp = (HBITMAP)SelectObject(hCaptureDC, hBitmap);
     int result = PrintWindow(hWnd, hCaptureDC, 0);
     SelectObject(hCaptureDC, oldBmp);
 
     DeleteDC(hCaptureDC);
     DeleteObject(hBitmap);
 
     if (!return)
          return NULL;
     else
          return hBitmap;
}

Open in new window

0
Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

 
LVL 86

Assisted Solution

by:jkr
jkr earned 250 total points
ID: 20352910
IOW, to get the single colors ot of a COLORREF, you need to use some bit operations, e.g.

#define RED(x) (x & 0x000000ff)
#define GREEN(x) (x & 0x0000ff00)
#define BLUE(x) (x & 0x00ff0000)
0
 

Author Comment

by:Troudeloup
ID: 20352944
in your code example,

return hBitmap



is this what I feed to getpixel?
0
 

Author Comment

by:Troudeloup
ID: 20352951
a problem, I don't get your code is doing.


    BitBlt(hCaptureDC,0,0,nScreenWidth,nScreenHeight,
           hDesktopDC,0,0,SRCCOPY|CAPTUREBLT);



where is the equivalent of this one?
0
 
LVL 55

Assisted Solution

by:Jaime Olivares
Jaime Olivares earned 250 total points
ID: 20352971
Oh, wait, use my function this way:

void CaptureWindow(HWND hWnd)
{
     RECT rect;
     if  (!GetWindowRect(hWnd, &rect))
          return NULL;
     HDC hWindowDC = ::GetDC(hWnd);
     if (!hWindowDC)
          return NULL;
     HDC hCaptureDC = CreateCompatibleDC(hWindowDC);
     if (!hCaptureDC)
          return NULL;
     HBITMAP hBitmap = CreateCompatibleBitmap(hWindowDC, rect.right-rect.left+1, rect.top-rect.bottom+1));
     if (!hBitmap) {
          DeleteDC(hCaptureDC);
          return NULL;
     }
     HBITMAP oldBmp = (HBITMAP)SelectObject(hCaptureDC, hBitmap);
     int result = PrintWindow(hWnd, hCaptureDC, 0);
 

     // you can use getpixel right here, passing hCaptureDC
 

     // cleaning tasks before returning
     SelectObject(hCaptureDC, oldBmp);
     DeleteDC(hCaptureDC);
     DeleteObject(hBitmap);
 }
0
 
LVL 55

Assisted Solution

by:Jaime Olivares
Jaime Olivares earned 250 total points
ID: 20352979
Retouched version:


void CaptureWindow(HWND hWnd)
{
     RECT rect;
     if  (!GetWindowRect(hWnd, &rect))
          return;
     HDC hWindowDC = ::GetDC(hWnd);
     if (!hWindowDC)
          return;
     HDC hCaptureDC = CreateCompatibleDC(hWindowDC);
     if (!hCaptureDC)
          return;
     HBITMAP hBitmap = CreateCompatibleBitmap(hWindowDC, rect.right-rect.left+1, rect.top-rect.bottom+1));
     if (!hBitmap) {
          DeleteDC(hCaptureDC);
          return;
     }
     HBITMAP oldBmp = (HBITMAP)SelectObject(hCaptureDC, hBitmap);
     int result = PrintWindow(hWnd, hCaptureDC, 0);
  
 
     // you can use getpixel right here, passing hCaptureDC
 
 
     // cleaning tasks before returning
     SelectObject(hCaptureDC, oldBmp);
     DeleteDC(hCaptureDC);
     DeleteObject(hBitmap);
 }

Open in new window

0
 

Author Comment

by:Troudeloup
ID: 20353045
void CaptureWindow(HWND hWnd)             //     maybe I need to split this into 3 functions
                                          //     see below
{
     RECT rect;
     if  (!GetWindowRect(hWnd, &rect))
          return NULL;
     HDC hWindowDC = ::GetDC(hWnd);
     if (!hWindowDC)
          return NULL;
     HDC hCaptureDC = CreateCompatibleDC(hWindowDC);
     if (!hCaptureDC)
          return NULL;
     HBITMAP hBitmap = CreateCompatibleBitmap(hWindowDC, rect.right-rect.left+1, rect.top-rect.bottom+1));
     if (!hBitmap) {
          DeleteDC(hCaptureDC);
          return NULL;
     }


     HBITMAP oldBmp = (HBITMAP)SelectObject(hCaptureDC, hBitmap);
     int result = PrintWindow(hWnd, hCaptureDC, 0);
 
   
     //     does it help speed to keep the same DC and then reuse it by capturing onto it?
     //     if it helps, i would do
     //    
     //     //  a function to create a empty DC, return it
     //     //  capture onto this DC,            return it
     //     //  finishe with the DC,             run below
     //     //  to use this DC, see bottom


     // cleaning tasks before returning
     SelectObject(hCaptureDC, oldBmp);
     DeleteDC(hCaptureDC);
     DeleteObject(hBitmap);
 }








// you can use getpixel right here, passing hCaptureDC
//I need to access a lot of points with a function like this
//so I need to return hCaptureDC from above function somehow


getpixel ( ?type,   hCaptureDC,  x, y)
{
  //  place holder
  return color;
}






does this make sense?
0
 
LVL 86

Assisted Solution

by:jkr
jkr earned 250 total points
ID: 20353563
Actually, there is already a 'GetPixel()' (http://msdn2.microsoft.com/en-us/library/ms532282.aspx) that you can use:

#define RED(x) (x & 0x000000ff)
#define GREEN(x) (x & 0x0000ff00)
#define BLUE(x) (x & 0x00ff0000)

COLORREF cr = GetPixel(hCaptureDC,x,y);

BYTE red = RED(cr);
BYTE green = GREEN(cr);
BYTE blue = BLUE(cr);
0
 

Author Comment

by:Troudeloup
ID: 20353603
yeah that's one i planned to use.


would it help it to run faster if I keep the same dc?
0
 
LVL 86

Assisted Solution

by:jkr
jkr earned 250 total points
ID: 20353645
Well, which DC do you mean? You can read the pixel values directly from the Window DC, bu that would not make a big difference in speed, just a small one.
0
 

Author Comment

by:Troudeloup
ID: 20353661
how about doing this in 3 functions?

1st to return dc with capture on it
2nd given dc return getpixel
3rd  release dc.
0
 
LVL 86

Assisted Solution

by:jkr
jkr earned 250 total points
ID: 20353690
Um, you can directly call 'GetPixel()' on

 HDC hWindowDC = ::GetDC(hWnd);

given that the contents do not change during the time you need.
0
 

Author Comment

by:Troudeloup
ID: 20353711
i am, not sure how to do it, you mean


HDC hWindowDC = ::GetDC(hWnd);

byte bytecolor = getpixel ( hWindowDC, x, y );


?
0
 
LVL 86

Assisted Solution

by:jkr
jkr earned 250 total points
ID: 20353722
Yes, that would work, however it will fail if the window repaints. I'd actually use the function above "as is", looks good to me.
0
 

Author Comment

by:Troudeloup
ID: 20353726
that't ALL I need ?
0
 
LVL 86

Accepted Solution

by:
jkr earned 250 total points
ID: 20353751
Well, as a first step towards OCR, it is. Once you have a copy of the DC, you can start analyzing it.
0
 

Author Comment

by:Troudeloup
ID: 20353752
HDC hWindowDC = ::GetDC(hWnd);
(?)          COLORREF GetPixel(   HDC hWindowDC, int x, int y );



I have problem with the (?) part.

I didn't get the type of variable I need to store the values

also, how do I convert those values into

int red
int green
int blue

?
0
 

Author Comment

by:Troudeloup
ID: 20353756
oh party begins with that :p
0
 

Author Comment

by:Troudeloup
ID: 20360325
0

Featured Post

Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Image decoding from Camera 3 85
Currency Conversion? 1 84
Safe conversion? 4 67
gdb doesn't stop on breakpoint 2 67
Whether you’re a college noob or a soon-to-be pro, these tips are sure to help you in your journey to becoming a programming ninja and stand out from the crowd.
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …

805 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