Solved

how do I feed hwnd to screencapture?

Posted on 2007-11-26
21
489 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
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!

 
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

Featured Post

Get 15 Days FREE Full-Featured Trial

Benefit from a mission critical IT monitoring with Monitis Premium or get it FREE for your entry level monitoring needs.
-Over 200,000 users
-More than 300,000 websites monitored
-Used in 197 countries
-Recommended by 98% of users

Question has a verified solution.

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

Whether you've completed a degree in computer sciences or you're a self-taught programmer, writing your first lines of code in the real world is always a challenge. Here are some of the most common pitfalls for new programmers.
When there is a disconnect between the intentions of their creator and the recipient, when algorithms go awry, they can have disastrous consequences.
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 …
In this fourth video of the Xpdf series, we discuss and demonstrate the PDFinfo utility, which retrieves the contents of a PDF's Info Dictionary, as well as some other information, including the page count. We show how to isolate the page count in a…

717 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