c++ - What's wrong with this screen capture code? -
i found screen capture code on here, when tried build it wouldn't build, fixed code myself , builds don't think works because when debugging vs says can't read hbitmap (no data?). i'm novice programmer have no idea @ point... , didn't fix code properly...
i appreciate help.
#include <windows.h> int main() { // device context of screen hdc hscreendc = createdc(l"display", null, null, null); // , device context put in hdc hmemorydc = createcompatibledc(hscreendc); int x = getdevicecaps(hscreendc, horzres); int y = getdevicecaps(hscreendc, vertres); // maybe worth checking these positive values hbitmap hbitmap = createcompatiblebitmap(hscreendc, x, y); // new bitmap hbitmap holdbitmap = (hbitmap)selectobject(hmemorydc, hbitmap); bitblt(hmemorydc, 0, 0, 640, 480, hscreendc, 0, 0, srccopy); hbitmap = (hbitmap)selectobject(hmemorydc, holdbitmap); // image held in hbitmap. can save or whatever }
short answer: there's nothing wrong.
hbitmap
contains handle bitmap has screencap data retrieved via bitblt
. when hover on hbitmap
in visual studio, merely informing hbitmap
not valid pointer memory, correct report- windows handles tokens resolve structures memory location , implementation managed privately windows api.
to demonstrate code indeed pulling screen, try writing file. helpful use gdi+ write file, save lot of initialization code have write hand.
here's quick console app emit png file using code , a helper function getencoderclsid
png encoder.
#include "stdafx.h" #include <windows.h> #include <gdiplus.h> using namespace gdiplus; int getencoderclsid(const wchar* format, clsid* pclsid) { uint num = 0; // number of image encoders uint size = 0; // size of image encoder array in bytes imagecodecinfo* pimagecodecinfo = null; getimageencoderssize(&num, &size); if (size == 0) return -1; // failure pimagecodecinfo = (imagecodecinfo*)(malloc(size)); if (pimagecodecinfo == null) return -1; // failure getimageencoders(num, size, pimagecodecinfo); (uint j = 0; j < num; ++j) { if (wcscmp(pimagecodecinfo[j].mimetype, format) == 0) { *pclsid = pimagecodecinfo[j].clsid; free(pimagecodecinfo); return j; // success } } free(pimagecodecinfo); return -1; // failure } int _tmain(int argc, _tchar* argv[]) { gdiplusstartupinput gdiplusstartupinput; ulong_ptr gdiplustoken; gdiplusstartup(&gdiplustoken, &gdiplusstartupinput, null); // device context of screen hdc hscreendc = createdc(l"display", null, null, null); // , device context put in hdc hmemorydc = createcompatibledc(hscreendc); int x = getdevicecaps(hscreendc, horzres); int y = getdevicecaps(hscreendc, vertres); // maybe worth checking these positive values hbitmap hbitmap = createcompatiblebitmap(hscreendc, x, y); // new bitmap hbitmap holdbitmap = (hbitmap)selectobject(hmemorydc, hbitmap); bitblt(hmemorydc, 0, 0, 640, 480, hscreendc, 0, 0, srccopy); hbitmap = (hbitmap)selectobject(hmemorydc, holdbitmap); // image held in hbitmap. can save or whatever clsid pngclsid; getencoderclsid(l"image/png", &pngclsid); bitmap *bmp = new bitmap(hbitmap, null); bmp->save(l"desktop_slice.png", &pngclsid, null); delete bmp; gdiplusshutdown(gdiplustoken); return 0; }
make sure add gdiplus.lib
list of source libraries in project settings. running create file called "desktop_slice.png" emitted.
if need additional work after retrieving bitmap containing screen data, should select compatible dc , call additional gdi functions dc, or perform other modifications hmemorydc
before swapping out bitmap selectobject
.
if need lower-level work @ pixel level, should @ creating dib section known pixel format meets needs, , working pointer returned ppvbits
argument.
Comments
Post a Comment