Screen capture a web browser
-
Dear All; I want to capture a screen shot of a web browser control (m_webBrowser) which is hosted in a dialog box. Here is the code which i used to do that but its not working properly (ie. capturing other windows):confused:!
RECT rc; LPOLEWINDOW pOWin = 0; HWND hWnd; m_webBrowser.GetControlUnknown()->QueryInterface(IID_IOleWindow, (LPVOID*)&pOWin); pOWin->GetWindow(&hWnd); HWND hwFirst = ::GetWindow( hWnd, GW_CHILD ); HWND hwSecond = ::GetWindow( hwFirst, GW_CHILD ); ::GetWindowRect (hwSecond,&rc); HDC hDC = ::GetDC(0); HDC memDC = ::CreateCompatibleDC ( hDC ); HBITMAP memBM = ::CreateCompatibleBitmap ( hDC, rc.right-rc.left, rc.bottom-rc.top ); ::SelectObject ( memDC, memBM ); ::BitBlt( memDC, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top , hDC, 0, 0 , SRCCOPY ); int size = 3 * ( (rc.right-rc.left) * (rc.bottom-rc.top) ); BYTE *lpBits = new BYTE[size]; ::GetBitmapBits( memBM, size, lpBits ); char* imageName; imageName =(char*)"2.jpg"; SaveBitmap(imageName, memBM); // this method saves the bit map into the HD delete [] lpBits; ::DeleteObject(memBM); ::DeleteObject(memDC); ::ReleaseDC( 0, hDC )
Can someone please help me? Thank youllp00na
Maybe you need to use EnumChildWindows() instead of GetWindow() to find the appropriate window. Just a guess since I have no idea what your window hierarchy looks like :) Mark
"Great job, team. Head back to base for debriefing and cocktails." (Spottswoode "Team America")
-
Maybe you need to use EnumChildWindows() instead of GetWindow() to find the appropriate window. Just a guess since I have no idea what your window hierarchy looks like :) Mark
"Great job, team. Head back to base for debriefing and cocktails." (Spottswoode "Team America")
-
thanx for your reply; I only have a dialog box (main window) which hosts the webBrowser control.
llp00na
So where is this code being called from?
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
-
thanx for your reply; I only have a dialog box (main window) which hosts the webBrowser control.
llp00na
Continuing from Mr Crow's question... ...and which window's pixels is it grabbing? Mark
"Great job, team. Head back to base for debriefing and cocktails." (Spottswoode "Team America")
-
So where is this code being called from?
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
-
Continuing from Mr Crow's question... ...and which window's pixels is it grabbing? Mark
"Great job, team. Head back to base for debriefing and cocktails." (Spottswoode "Team America")
-
The code is being called from a button click handler. (The user clicks a button "Grab Screen").
llp00na
llp00na wrote:
The code is being called from a button click handler.
Then just use the web control's
GetWindowRect()
method (instead of callingGetWindow()
twice).
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
-
its grabbing part of the Microsoft VC++, parts of the dialog window (and not the web browser at all). The remaining of the screenshot is all black.
llp00na
The black is probably because the bitmap bits size (in bytes) is calculated wrong. Try something like BITMAP bitmap; ::GetObject(memBM, sizeof(BITMAP), &bitmap); long size = bitmap.bmWidthBytes * bitmap.bmHeight; BYTE *lpBits = new BYTE[size]; ... or BITMAP bitmap; ::GetObject(memBM, sizeof(BITMAP), &bitmap); long size = (((bitmap.bmWidth * (long)bmBitsPixel + 15L) & (~15L)) / 8L) * bitmap.bmHeight; BYTE *lpBits = new BYTE[size]; ...
"Great job, team. Head back to base for debriefing and cocktails." (Spottswoode "Team America")
-
llp00na wrote:
The code is being called from a button click handler.
Then just use the web control's
GetWindowRect()
method (instead of callingGetWindow()
twice).
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
I have tried what you suggested but it stil gives me the same result (ie. similar to the one i got when i called getWindow() twice) It grabs part of the MVStudio, part of the dialog which hosts the web browser and the remaining of the screen shot is painted in black. Any other ideas would be appreciated
llp00na
-
The black is probably because the bitmap bits size (in bytes) is calculated wrong. Try something like BITMAP bitmap; ::GetObject(memBM, sizeof(BITMAP), &bitmap); long size = bitmap.bmWidthBytes * bitmap.bmHeight; BYTE *lpBits = new BYTE[size]; ... or BITMAP bitmap; ::GetObject(memBM, sizeof(BITMAP), &bitmap); long size = (((bitmap.bmWidth * (long)bmBitsPixel + 15L) & (~15L)) / 8L) * bitmap.bmHeight; BYTE *lpBits = new BYTE[size]; ...
"Great job, team. Head back to base for debriefing and cocktails." (Spottswoode "Team America")
-
Dear All; I want to capture a screen shot of a web browser control (m_webBrowser) which is hosted in a dialog box. Here is the code which i used to do that but its not working properly (ie. capturing other windows):confused:!
RECT rc; LPOLEWINDOW pOWin = 0; HWND hWnd; m_webBrowser.GetControlUnknown()->QueryInterface(IID_IOleWindow, (LPVOID*)&pOWin); pOWin->GetWindow(&hWnd); HWND hwFirst = ::GetWindow( hWnd, GW_CHILD ); HWND hwSecond = ::GetWindow( hwFirst, GW_CHILD ); ::GetWindowRect (hwSecond,&rc); HDC hDC = ::GetDC(0); HDC memDC = ::CreateCompatibleDC ( hDC ); HBITMAP memBM = ::CreateCompatibleBitmap ( hDC, rc.right-rc.left, rc.bottom-rc.top ); ::SelectObject ( memDC, memBM ); ::BitBlt( memDC, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top , hDC, 0, 0 , SRCCOPY ); int size = 3 * ( (rc.right-rc.left) * (rc.bottom-rc.top) ); BYTE *lpBits = new BYTE[size]; ::GetBitmapBits( memBM, size, lpBits ); char* imageName; imageName =(char*)"2.jpg"; SaveBitmap(imageName, memBM); // this method saves the bit map into the HD delete [] lpBits; ::DeleteObject(memBM); ::DeleteObject(memDC); ::ReleaseDC( 0, hDC )
Can someone please help me? Thank youllp00na
Sorry I should have looked more closely at your code. Try changing your BitBlt() call from ::BitBlt( memDC, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top , hDC, 0, 0 , SRCCOPY ); to ::BitBlt( memDC, 0, 0, rc.right-rc.left, rc.bottom-rc.top , hDC, rc.left, rc.top , SRCCOPY ); :)
"Great job, team. Head back to base for debriefing and cocktails." (Spottswoode "Team America")
-
Sorry I should have looked more closely at your code. Try changing your BitBlt() call from ::BitBlt( memDC, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top , hDC, 0, 0 , SRCCOPY ); to ::BitBlt( memDC, 0, 0, rc.right-rc.left, rc.bottom-rc.top , hDC, rc.left, rc.top , SRCCOPY ); :)
"Great job, team. Head back to base for debriefing and cocktails." (Spottswoode "Team America")
Oh thanx so much man, you are a genius;). your code captures a screen shot of the visible area of the web browser. Do you know how to capture all area of the web browser -including the invisible parts (That is when the user has to scroll down to view the rest of the page). Because this is when i need to do.
llp00na
-
Sorry I should have looked more closely at your code. Try changing your BitBlt() call from ::BitBlt( memDC, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top , hDC, 0, 0 , SRCCOPY ); to ::BitBlt( memDC, 0, 0, rc.right-rc.left, rc.bottom-rc.top , hDC, rc.left, rc.top , SRCCOPY ); :)
"Great job, team. Head back to base for debriefing and cocktails." (Spottswoode "Team America")
-
Oh thanx so much man, you are a genius;). your code captures a screen shot of the visible area of the web browser. Do you know how to capture all area of the web browser -including the invisible parts (That is when the user has to scroll down to view the rest of the page). Because this is when i need to do.
llp00na
Since your grabbing pixels from the display, you won't be able to get the non-visible pixels that way. Maybe there's an overridable method in the browser control where you can force the HTML to be rendered to a dc of your choice instead of the screen...? Mark
"Great job, team. Head back to base for debriefing and cocktails." (Spottswoode "Team America")