-
May 5th, 2014, 04:12 PM
#1
Capture of Window
I want program to make bitmap from my Window. I also want to do add some additional steps which I will try to add later. But now I want to ask you how to fix the code. For some reason when I debug the code (break on line 73 of capture.cpp) there the pointer pBitmap is 0x00000000 . So how to correct the code to successfully capture Window? Here I give the complete codes:
stdafx.h
Code:
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <fstream>
#include <stdio.h>
#include <wingdi.h>
#include <gdiplus.h>
#include <ostream>
capture.cpp
Code:
/*Window capture example*/
#include "stdafx.h"
using namespace Gdiplus;
using namespace Gdiplus::DllExports;
// using namespace GdiPlus;
// #define SCREENWIDTH GetSystemMetrics(SM_CXSCREEN)
// #define SCREENHEIGHT GetSystemMetrics(SM_CYSCREEN)
int main()
{
/////////////////////////////////////////////////////////////////////////////////////////////////////
// PART 1 - PREPARATION OF THE BASIC BITMAP
/////////////////////////////////////////////////////////////////////////////////////////////////////
HWND HCapture = FindWindow(NULL, _T("Map Viewer") ); // get window handle
// HWND HCapture = GetDesktopWindow(); // get desktop handle (but can be handle of any window)
if(!IsWindow(HCapture)) return 1;
/*
BOOL PrintWindow(
HWND hwnd, // A handle to the window that will be copied.
HDC hdcBlt, // A handle to the device context.
UINT nFlags // The drawing options: PW_CLIENTONLY
// Only the client area of the window is copied to hdcBlt. By default, the entire window is copied.
);
*/
// get window dimensions
RECT rect; GetWindowRect(HCapture, &rect);
size_t dx = rect.right - rect.left;
size_t dy = rect.bottom - rect.top;
// create BITMAPINFO structure
// used by CreateDIBSection
BITMAPINFO info;
info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
info.bmiHeader.biWidth = dx;
info.bmiHeader.biHeight = dy;
// a bitmap handle and a pointer its bit data
HBITMAP HBitmap = 0;
BYTE* memory = 0; // ppvBits - A pointer to a variable that will receive a pointer to the location of the DIB bit values. See CreateDIBSection()
/** We should create Bitmap first and then Device Context,
however when I want to create snapshot of window, I need to use
fnc PrintWindow to copy the visual window to Device Context.
So I need to create DC first. The DC will be compatible with
current screen.
*/
// 1. FIRST we need to Create DC for PrintWindow function
// HDC HDevice = GetDC(HCapture);
HDC HDevice = CreateCompatibleDC(NULL);
// 2. SECOND we need to CREATE BITMAP (Device Independent Bitmap)
HBitmap = CreateDIBSection(HDevice, &info, DIB_RGB_COLORS, (void**)&memory, 0, 0);
// 3. Make HBitmap to be destination of the following work
SelectObject(HDevice, HBitmap);
///////////////////////////////////////////////////////////////////////////////////////////
// PART 2 - GET VISUAL CONTENT OF WINDOW //
// AND SAVE IT TO BITMAP //
///////////////////////////////////////////////////////////////////////////////////////////
// THIS WAS WRONG DECLARATION: unsigned int * pBitmap;
GpBitmap *pBitmap = NULL; // type Gdiplus::GpBitmap
if (!PrintWindow(HCapture, HDevice, PW_CLIENTONLY)) return 2;
// pBitmap is null.
Gdiplus::DllExports::GdipCreateBitmapFromHBITMAP(HBitmap, 0, &pBitmap);
ReleaseDC(HCapture, HDevice);
if(!HBitmap || !memory) return 1;
/*
The GetWindowDC function retrieves the device context (DC) for
the entire window, including title bar, menus, and scroll bars.
A window device context permits painting anywhere in a window */
// blit the contents of the desktop (winDC)
// to the bitmap (selected in memDC)
HDC winDC = GetWindowDC(HCapture);
HDC memDC = CreateCompatibleDC(winDC);
SelectObject(memDC, HBitmap);
BitBlt(memDC, 0, 0, dx, dy, winDC, 0, 0, SRCCOPY);
DeleteDC(memDC);
ReleaseDC(HCapture, winDC);
/** THIS IS WRONG! VARIABLE CANNOT POINT TO NOWHERE!*/
// char *buffer; // First set the type and range and then make pointer:
char *buffer = new char[50]; // RIGHT DECLARATION
sprintf(buffer,"capture%d%d.bmp",dx,dy);
// create bitmap file
std::basic_ofstream <char> file(buffer, std::ios::binary);
if(!file) { DeleteObject(HBitmap); return 1; }
// initialize bitmap file headers
BITMAPFILEHEADER fileHeader;
BITMAPINFOHEADER infoHeader;
fileHeader.bfType = 0x4d42;
fileHeader.bfSize = 0;
fileHeader.bfReserved1 = 0;
fileHeader.bfReserved2 = 0;
fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
infoHeader.biSize = sizeof(infoHeader);
infoHeader.biWidth = dx;
infoHeader.biHeight = dy;
infoHeader.biPlanes = 1;
infoHeader.biBitCount = 24;
infoHeader.biCompression = BI_RGB;
infoHeader.biSizeImage = 0;
infoHeader.biXPelsPerMeter = 0;
infoHeader.biYPelsPerMeter = 0;
infoHeader.biClrUsed = 0;
infoHeader.biClrImportant = 0;
// save file headers
file.write((char*)&fileHeader, sizeof(fileHeader));
file.write((char*)&infoHeader, sizeof(infoHeader));
// save 24-bit bitmap data
int wbytes = (((24*dx + 31) & (~31))/8);
int tbytes = (((24*dx + 31) & (~31))/8)*dy;
file.write((char*)memory, tbytes);
// delete bitmap
DeleteObject(HBitmap);
HBitmap = 0;
memory = 0;
return 0;
}
Libraries settings:
gdiplus.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
Feel free to set correct name of Window on line 17 for FindWindow() function.
PS: The code is remake of script to capture screen, which saved the bitmap to file. This is not what I want because I would be content if I could send (or maybe share!) the bitmap to ahk script which will ask my C++ program for the bitmap.
Last edited by crazy boy; May 5th, 2014 at 04:17 PM.
-
May 6th, 2014, 02:12 AM
#2
-
May 6th, 2014, 02:47 AM
#3
Re: Capture of Window
Originally Posted by crazy boy
I want program to make bitmap from my Window. I also want to do add some additional steps which I will try to add later. But now I want to ask you how to fix the code. For some reason when I debug the code (break on line 73 of capture.cpp) there the pointer pBitmap is 0x00000000 .
And where is this "line 73"?
Victor Nijegorodov
-
May 6th, 2014, 02:53 AM
#4
Re: Capture of Window
Originally Posted by VictorN
And where is this "line 73"?
I gave you complete code. Why don't you copy&paste&see????
-
May 6th, 2014, 02:58 AM
#5
Re: Capture of Window
Originally Posted by mesajflaviu
The apps you refer are too complicated but I want to create my own simple application, that's why you did not answer my question, regarding my code.
-
May 6th, 2014, 03:48 AM
#6
Re: Capture of Window
Originally Posted by crazy boy
I gave you complete code. Why don't you copy&paste&see????
Because life's too short. Either show separately the line in question or highlight it in the provided code.
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
May 6th, 2014, 03:50 AM
#7
-
May 6th, 2014, 04:06 AM
#8
Re: Capture of Window
Originally Posted by 2kaud
Because life's too short. Either show separately the line in question or highlight it in the provided code.
Why ******** I wasted my time to paste the code here, when it is not highlighted and is not numbered? I give you this one. Go to line 68
http://paste.ofcode.org/UJLw7HW8HGQVn2JpuEN5bJ
Since line 53 it is described in the code what exactly I am trying to do.
I start declaration of the pBitmap pointer on line 69
Then I try to copy visual window with HCapture handle to the Device Context named HDevice
on Line 74 I try to Create Bitmap from HBitmap into pBitmap
Here the pointer is 0x00000000 instead valid value.
Why I don't get valid pointer?
-
May 6th, 2014, 04:10 AM
#9
Re: Capture of Window
Originally Posted by 2kaud
Because life's too short. Either show separately the line in question or highlight it in the provided code.
Why ******** I wasted my time to paste the code here, when it is not highlighted and is not numbered? I give you this one. Go to line 68
http://paste.ofcode.org/UJLw7HW8HGQVn2JpuEN5bJ
Since line 53 it is described in the code what exactly I am trying to do.
I start declaration of the pBitmap pointer on line 69:
Code:
GpBitmap *pBitmap = NULL; // type Gdiplus::GpBitmap
if (!PrintWindow(HCapture, HDevice, PW_CLIENTONLY)) return 2;
Then I try to copy visual window with HCapture handle to the Device Context named HDevice
on Line 74 I try to Create Bitmap from HBitmap into pBitmap
Code:
Gdiplus::DllExports::GdipCreateBitmapFromHBITMAP(HBitmap, 0, &pBitmap);
Here the pointer is 0x00000000 instead valid value.
Why I don't get valid pointer?
-
May 6th, 2014, 04:26 AM
#10
Re: Capture of Window
Originally Posted by crazy boy
...
on Line 74 I try to Create Bitmap from HBitmap into pBitmap
Code:
Gdiplus::DllExports::GdipCreateBitmapFromHBITMAP(HBitmap, 0, &pBitmap);
Here the pointer is 0x00000000 instead valid value.
Why I don't get valid pointer?
What does GdipCreateBitmapFromHBITMAP return?
I guess it could help you to understand the reason why "the pointer is 0x00000000 instead valid value".
Victor Nijegorodov
-
May 6th, 2014, 04:36 AM
#11
Re: Capture of Window
GdipCreateBitmapFromHBITMAP returns (int) 18
-
May 6th, 2014, 05:00 AM
#12
Re: Capture of Window
Originally Posted by crazy boy
GdipCreateBitmapFromHBITMAP returns (int) 18
Well, according to the info from http://stackoverflow.com/questions/5...o-use-gdi-in-c
status 18 means GdiplusNotInitialized
Victor Nijegorodov
-
May 6th, 2014, 05:33 AM
#13
-
May 6th, 2014, 05:47 AM
#14
Re: Capture of Window
Now after GDI successful startup, I receive error 7 - Indicates that the method generated a Win32 error.
The HBitmap handle is 0x00000000 invalid
So my question is now here (step 2.):
Code:
// 1. FIRST we need to Create DC for PrintWindow function
// HDC HDevice = GetDC(HCapture);
HDC HDevice = CreateCompatibleDC(NULL);
// 2. SECOND we need to CREATE BITMAP (Device Independent Bitmap)
HBitmap = CreateDIBSection(HDevice, &info, DIB_RGB_COLORS, (void**)&memory, 0, 0);
// 3. Make HBitmap to be destination of the following work
SelectObject(HDevice, HBitmap);
Notice:
HDevice hanlder is valid.
info.bmiHeader.biWidth is 306
info.bmiHeader.biHeight is 342
Last edited by crazy boy; May 6th, 2014 at 05:49 AM.
-
May 6th, 2014, 05:56 AM
#15
Re: Capture of Window
From MSDN article "CreateDIBSection":
Return Values
If the function succeeds, the return value is a handle to the newly created DIB, and *ppvBits points to the bitmap's bit values.
If the function fails, the return value is NULL, and *ppvBits is NULL.
...
To get extended error information, call GetLastError.
Victor Nijegorodov
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|