-
May 6th, 2014, 08:25 AM
#31
Re: Capture of Window
Now (after I use your code) it produces error 8
ERROR_NOT_ENOUGH_MEMORY
8 (0x8)
Not enough storage is available to process this command.
-
May 6th, 2014, 08:38 AM
#32
Re: Capture of Window
Originally Posted by crazy boy
Code:
DWORD dw = GetLastError();
dw is 127
Where and how to search what is meaning of the error is? I try to search the net for the code but not success. Tell me the secret how you do it to find the error codes.
In Visual Studio, Tools, Error Lookup then enter the error value and click Look Up. This will show a description of the error code.
Note that the value returned by GetLastError() is only valid if the proceeding function call failed. If the function succeeded then no reliance can be placed on the value returned by GetLastError(). You need to know whether the function call failed before calling GetLastError().
Last edited by 2kaud; May 6th, 2014 at 08:43 AM.
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, 09:57 AM
#33
Re: Capture of Window
That is great advice. It is very simple to look for the error now, but I must distinguish between system errors and GDI+ errors which are different (Status enumeration).
-
May 6th, 2014, 11:06 AM
#34
Re: Capture of Window
Originally Posted by crazy boy
That is great advice. It is very simple to look for the error now, but I must distinguish between system errors and GDI+ errors which are different (Status enumeration).
Yeah. You'll have to do a bit of work to first capture the errors and then look in msdn to interpret them based on the api they came from.
-
May 6th, 2014, 03:28 PM
#35
Re: Capture of Window
OH ****! I have found, that it works! Even that this
Code:
HBitmap = CreateDIBSection(HDevice, &info, DIB_RGB_COLORS, (void**)&memory, NULL, NULL);
DWORD dw = GetLastError(); // THIS PRODUCES ERROR 8 EVEN THAT PROGRAM WORKS!
dw produces error 8, but it seems that there is not really error.
I found that if I call
Code:
DWORD dw = GetLastError();
just after the start of main function so it returns error 127.
So now I don't know if I can trust to the command. It will always show some error even that may not be error.
-
May 6th, 2014, 03:38 PM
#36
Re: Capture of Window
I give you what I got as an output. There are two images on black background. The image on right is my window from which I want to get the map in the window including the black triangles. On the left side is what I got. It problably has bad dimensions because I did not calculated with all dimensions of window needed like the Window caption bar. I need to correct it.
http://oi59.tinypic.com/rho0f8.jpg
Do you have some tips how to correct it or what to look on?
Last edited by crazy boy; May 6th, 2014 at 03:40 PM.
-
May 6th, 2014, 03:43 PM
#37
Re: Capture of Window
just after the start of main function so it returns error 127.
So now I don't know if I can trust to the command. It will always show some error even that may not be error
Note my comment in my post #32. The value returned by GetLastError() is only valid if proceeded by a function call whose documentation states that the error code on failure can be obtained by a call to GetLastError(). If the function hasn't failed or if the function documentation doesn't mention GetLastError() then the value returned by GetLastError() is indeterminate and cannot be relied upon. So calling GetLastError() just after the start of main function is meaningless as at that point a function that sets last error hasn't been called and hasn't failed.
Only call GetLastError() after a function that sets last error has been called and has failed. Using GetLastError() to see if the function has failed is not valid. The specific function documentation has to be read to see how function failure is reported and consequently how it is tested.
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:46 PM
#38
Re: Capture of Window
You still ignore reading MSDN...
You still ignore accept what you were told a lot as well
Again:
- you must read MSDN about every API function you are going to use!
- If MSDN claims you should call GetLastError in case of API function failed - do it!
- If API function call succeeds - you are lucky and must not call GetLastError (if MSDN does not claim to call it.)
Victor Nijegorodov
-
May 6th, 2014, 03:53 PM
#39
Re: Capture of Window
I tried two functions GetWindowRect and GetClientRect but both gives me same result. How to get the inner area without the fram and caption area/bar?
-
May 6th, 2014, 03:53 PM
#40
Re: Capture of Window
I give you what I got as an output.
Please don't provide info by using an external web link. Many members don't open unknown links. If you want to provide info like this, just click the 'Insert image' icon.
PS I've just tried to look at the link on my test virtualised computer and the anti-virus program reported a problem with the site!
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, 04:02 PM
#41
Re: Capture of Window
Originally Posted by crazy boy
I tried two functions GetWindowRect and GetClientRect but both gives me same result. How to get the inner area without the fram and caption area/bar?
GetClientRect() always returns the size of the whole window except borders and title bar. If a window has a title bar and borders then GetWindowRect() and GetClientRect() produce different results. Post the code you're using.
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, 04:17 PM
#42
Re: Capture of Window
Originally Posted by 2kaud
GetClientRect() always returns the size of the whole window except borders and title bar. If a window has a title bar and borders then GetWindowRect() and GetClientRect() produce different results. Post the code you're using.
What it is good to send you my code, when you don't use the program which I am making bitmap from and you dont use same them... You surprised me with the information that the link is problematic. I hear that first time. I gave this image hundret times on different forums and nobody ever complained. It is tinypic.com which enable to upload images for free.
I CANNOT DISPLAY the image here because it is not possible insert image here by button - it prints report - it is PNG with jpg extension and I cannot affect that how the site uploads the image.
Edit: But the img tag works, so I will use it. Never mind.
Here is the code, it is with all the comments.
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;
// get window dimensions
RECT rect; //GetWindowRect(HCapture, &rect);
GetClientRect(HCapture, &rect);
size_t dx = rect.right - rect.left;
size_t dy = rect.bottom - rect.top;
// create BITMAPINFO structure
// used by CreateDIBSection
BITMAPINFO info = {0};
// memset(&info, 0, sizeof(info));
info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
info.bmiHeader.biWidth = dx;
info.bmiHeader.biHeight = dy;
info.bmiHeader.biPlanes = 1;
info.bmiHeader.biBitCount = 24;
info.bmiHeader.biCompression = BI_RGB;
/*info.bmiHeader.biSizeImage = 0;
info.bmiHeader.biXPelsPerMeter = 0;
info.bmiHeader.biYPelsPerMeter = 0;
info.bmiHeader.biClrUsed = 0;
info.bmiHeader.biClrImportant = 0;*/
// 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 = CreateCompatibleBitmap(HDevice, dx, dy);
HBitmap = CreateDIBSection(HDevice, &info, DIB_RGB_COLORS, (void**)&memory, NULL, NULL);
// DWORD dw = GetLastError(); // THIS PRODUCES ERROR 8 EVEN THAT PROGRAM WORKS!
// 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;
// INIT GDI
ULONG_PTR gdiplusToken;
GdiplusStartupInput gdiplusStartupInput;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
if (!gdiplusToken) return 3;
// pBitmap is null.
int state = 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);
GdiplusShutdown(gdiplusToken);
/** 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;
}
Last edited by crazy boy; May 6th, 2014 at 04:22 PM.
-
May 6th, 2014, 04:21 PM
#43
Re: Capture of Window
Originally Posted by crazy boy
I tried two functions GetWindowRect and GetClientRect but both gives me same result. How to get the inner area without the fram and caption area/bar?
This program
Code:
#include <Windows.h>
#include <iostream>
using namespace std;
int main()
{
HWND curwnd;
if ((curwnd = GetForegroundWindow()) == NULL) {
cout << "GetForegroundWindow failed\n";
return 1;
}
RECT rect;
if (GetWindowRect(curwnd, &rect))
cout << "Window Rect " << rect.top << " " << rect.bottom << " " << rect.left << " " << rect.right << endl;
else
cout << "GetWindowRect failed. Error " << GetLastError() << endl;
if (GetClientRect(curwnd, &rect))
cout << "Client Rect " << rect.top << " " << rect.bottom << " " << rect.left << " " << rect.right << endl;
else
cout << "GetClientrect failed. Error " << GetLastError() << endl;
return 0;
}
produces on my system the output
Code:
Window Rect 60 609 60 1603
Client Rect 0 500 0 1500
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, 04:43 PM
#44
Re: Capture of Window
So I should use the Client Area.
-
May 6th, 2014, 04:50 PM
#45
Re: Capture of Window
It still does not fit. But console coords was fine. So where is my mistake?
Code:
RECT rect;
GetClientRect(HCapture, &rect);
size_t dx = rect.right;
size_t dy = rect.bottom;
Shouldn't the
Code:
PrintWindow(HCapture, HDevice, PW_CLIENTONLY)
print only the area inside the Window?
But the window caption area and border is still there.
Last edited by crazy boy; May 6th, 2014 at 05:03 PM.
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
|