Home » Developing U++ » UppHub » SysInfo - some bug fixes (Window_SaveCapture/Window_Top)
SysInfo - some bug fixes [message #47094] |
Fri, 02 December 2016 14:02  |
luoganda
Messages: 211 Registered: November 2016
|
Experienced Member |
|
|
Both is for windows version - v10502:
1)For all 3 this kind'a functions:
void Window_Top(int64 windowId){
SetWindowPos(reinterpret_cast<HWND>(windowId), HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE || SWP_NOSIZE || SWP_SHOWWINDOW);
}
from || into | -> thats SWP_NOMOVE | SWP_NOSIZE ...
Note: Window_Top will not set foreground window properly(at least not on windows xp) - to reproduce this
fully maximize some window(eg TheIDE) and use Window_Top/Window_TopMost on some background window - it won't work.
For one who want's properly set-foreground-window, try this link(scroll down to SwitchToWindow)
https:// groups.google.com/forum/#!topic/comp.os.ms-windows.programme r.win32/loryh6U6KFg
Note for code in link: SwitchToThisWindow seems that it doesnt need to be loaded by LoadLibrary - can be used directly.
On windows xp sp3/4 it works as expected.
2)Window_SaveCapture - gdi mem leak and incorrect results for lets say 16 bit screen depth:
end:
SelectObject(hDC, oldBM); into -> SelectObject(memDC, oldBM);
returned Image does not return proper 'bitmap', because requesting dib is not set:
-setting requested dib to 24bit(because generally 32bit seems to not work correctly?)
-convert to Image format, that's from requested 24bit-pixels to Image 32bit-pixels
Should do the trick.
The optimized way would be to copy pixels directly from ScreenDC(GetDC(0)) to 32Bit Image format.
[Updated on: Fri, 02 December 2016 14:06] Report message to a moderator
|
|
|
|
Re: SysInfo - some bug fixes [message #47099 is a reply to message #47094] |
Tue, 06 December 2016 15:07   |
luoganda
Messages: 211 Registered: November 2016
|
Experienced Member |
|
|
Window_top:
on windowsxp it doesn't show up, at least not programmatically with many windows on - yet to check,
but suggested ver works always
Window_SaveCapture:
Excelent example is Reference/CaptureScreenDll - it properly DeSelects oldBM, but it is a little buggy,
so here is patched version, without the patch img is invisible:
Image ScreenShot(int x, int y, int cx, int cy){
HDC dcScreen = CreateDC("DISPLAY", NULL, NULL, NULL);
RGBA *pixels;
Buffer<byte> data;
data.Alloc(sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*256);
BITMAPINFOHEADER *hi = (BITMAPINFOHEADER *) ~data;;
memset(hi, 0, sizeof(BITMAPINFOHEADER));
hi->biSize = sizeof(BITMAPINFOHEADER);
hi->biPlanes = 1;
hi->biBitCount = 32;
hi->biCompression = BI_RGB;
hi->biSizeImage = 0;
hi->biClrUsed = 0;
hi->biClrImportant = 0;
hi->biWidth = cx;
hi->biHeight = -cy;
HBITMAP hbmp = CreateDIBSection(dcScreen, (BITMAPINFO *)hi, DIB_RGB_COLORS, (void **)&pixels, NULL, 0);
HDC dcMem = ::CreateCompatibleDC(dcScreen);
HBITMAP hbmpOld = (HBITMAP) ::SelectObject(dcMem, hbmp);
HDC hdcCompatible = CreateCompatibleDC(dcScreen);
::BitBlt(dcMem, 0, 0, cx, cy, dcScreen, x, y, SRCCOPY);
//ver-1: use this version or down 2 - whichever is faster
//Image img; <= direct to image could be used here to optimize, since now it's into buffer and then to Image
//mint 32on32Bit/64on64bit machine dependant int to speed up
//for(register mint i=0,j=cx*cy; i<j; i++)pixels[i].a=0xff;
ImageBuffer ib(cx, cy);
memcpy(~ib, pixels, cx * cy * sizeof(RGBA));
//ver-2: use this version or up 1 - whichever is faster
//mint 32on32Bit/64on64bit machine dependant int to speed up
dword *pix=(dword*)~ib;
for(register mint i=0,j=cx*cy; i<j; i++)pix[i]=*(dword*)&pixels[i]|0xff000000;
::DeleteObject(::SelectObject(dcMem, hbmpOld));
::DeleteDC(dcMem);
::DeleteDC(dcScreen);
return ib;
};
And the test code:
Image img=ScreenShot(200,200,400,400);
ImageCtrl ic; ic.SetImage(img); //qbox(img.ToString());
TopWindow w; w.Add(ic.TopPos(0,400).LeftPos(0,400)); w.LeftPos(0,440).TopPos(0,440);
w.Execute();
[Updated on: Tue, 06 December 2016 15:39] Report message to a moderator
|
|
|
Re: SysInfo - some bug fixes [message #47102 is a reply to message #47099] |
Wed, 07 December 2016 08:50   |
 |
koldo
Messages: 3432 Registered: August 2008
|
Senior Veteran |
|
|
Hello luoganda
- Window_top
I have reviewed SetWindowPos() use in some forums and it seems it is properly used in SysInfo. In fact it is very simple. I could not find complains about using it in XP.
Could it be that the problem you have found came from that initially it had SWP_NOMOVE || SWP_NOSIZE instead of SWP_NOMOVE | SWP_NOSIZE?
Please check the latest version in XP if it works.
- Window_SaveCapture
Sorry luoganda but I cannot see any advantage in Reference/CaptureScreenDll implementation.
SysInfo implementation does not suppose any screen bit depth, it selects, deselects and releases objects and in addition it checks for API errors.
You can see an example in Bazaar/GrabYourScreen. It uses it extensively.
Best regards
Iñaki
[Updated on: Wed, 07 December 2016 11:57] Report message to a moderator
|
|
|
|
Re: SysInfo - some bug fixes [message #47115 is a reply to message #47109] |
Fri, 09 December 2016 23:05  |
 |
koldo
Messages: 3432 Registered: August 2008
|
Senior Veteran |
|
|
Thank you Luoganda
To fix the problem with 16 bits desktop now it is added
bmi.bmiHeader.biBitCount = 32;
This way bitmap is compatible with ImageBuffer format.
Best regards
Iñaki
|
|
|
Goto Forum:
Current Time: Fri Apr 25 12:22:00 CEST 2025
Total time taken to generate the page: 0.01066 seconds
|