SysInfo: Refurbished Snap functions, now fully equal in Windows and Linux. Deprecated XWD support, now unnecessary.

git-svn-id: svn://ultimatepp.org/upp/trunk@7350 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
koldo 2014-05-04 13:53:38 +00:00
parent 0bdf80bfee
commit 4e211bafb9
4 changed files with 231 additions and 68 deletions

View file

@ -934,6 +934,7 @@ void GetWindowsList(Array<int64> &hWnd, Array<int64> &processId, Array<String> &
DWORD dwThreadId, dwProcessId;
HINSTANCE hInstance;
WCHAR str[MAX_PATH];
int count;
EnumWindows(EnumGetWindowsList, (LPARAM)&hWnd);
for (int i = 0; i < hWnd.GetCount(); ++i) {
@ -942,7 +943,6 @@ void GetWindowsList(Array<int64> &hWnd, Array<int64> &processId, Array<String> &
dwThreadId = GetWindowThreadProcessId(reinterpret_cast<HWND>(hWnd[i]), &dwProcessId);
processId.Add(dwProcessId);
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessId);
int count;
if (count = GetModuleFileNameExW(hProcess, hInstance, str, sizeof(str)/sizeof(WCHAR))) {
sstr = WString(str, count).ToString();
fileName << sstr;
@ -958,7 +958,7 @@ void GetWindowsList(Array<int64> &hWnd, Array<int64> &processId, Array<String> &
if (sstr == "TPClnt.dll") // VMWare Thinprint crashes SendMessageW()
caption << "";
else if (IsWindowVisible(reinterpret_cast<HWND>(hWnd[i]))) {
int count = int(SendMessageW(reinterpret_cast<HWND>(hWnd[i]), WM_GETTEXT, sizeof(str)/sizeof(WCHAR), (LPARAM)str));
count = int(SendMessageW(reinterpret_cast<HWND>(hWnd[i]), WM_GETTEXT, sizeof(str)/sizeof(WCHAR), (LPARAM)str));
caption << WString(str, count).ToString();
} else
caption << "";
@ -1189,7 +1189,7 @@ void GetWindowsList(Array<int64> &hWnd, Array<int64> &processId, Array<String> &
if((ret == Success || ret > 0) && list != NULL) {
String sret;
for(i = 0; i < count; i++)
sret << list[i]; // << " ";
sret << list[i];
XFreeStringList(list);
caption.Add(FromSystemCharset(sret));
} else
@ -1666,15 +1666,33 @@ bool TakeWindowPlacement(HWND hwnd, RECT &rcNormalPosition, POINT &ptMinPosition
place.length = sizeof(place);
bool ret = GetWindowPlacement(hwnd, &place);
if (!ret)
return false;
ptMinPosition = place.ptMinPosition;
ptMaxPosition = place.ptMaxPosition;
rcNormalPosition = place.rcNormalPosition;
showcmd = place.showCmd; //SW_SHOWMAXIMIZED, SW_SHOWMINIMIZED, SW_SHOWNORMAL
//flags = place.flags; // Always 0
return ret;
}
int Window_GetStatus(int64 windowId)
{
WINDOWPLACEMENT place;
place.length = sizeof(place);
bool ret = GetWindowPlacement((HWND)windowId, &place);
if (!ret)
return Null;
switch(place.showCmd) {
case SW_SHOWMAXIMIZED: return WINDOW_MAXIMIZED;
case SW_SHOWMINIMIZED: return WINDOW_MINIMIZED;
case SW_SHOWNORMAL: return WINDOW_NORMAL;
}
return Null;
}
bool Window_GetRect(int64 windowId, long &left, long &top, long &right, long &bottom)
{
RECT rcNormalPosition;

View file

@ -57,6 +57,16 @@ void GetWindowsList(Upp::Array<int64> &wid, Upp::Array<int64> &pid, Upp::Array<S
Upp::Array<String> &fileName, Upp::Array<String> &title);
Upp::Array<int64> GetWindowsList();
bool Window_GetRect(int64 windowId, long &left, long &top, long &right, long &bottom);
bool Window_SetRect(int64 windowId, long left, long top, long right, long bottom);
void Window_Bottom(int64 windowId);
void Window_Top(int64 windowId);
void Window_TopMost(int64 windowId);
enum WINDOW_STATUS {
WINDOW_MAXIMIZED, WINDOW_MINIMIZED, WINDOW_NORMAL};
int Window_GetStatus(int64 windowId);
/////////////////////////////////////////////////////////////////////
// Process list
bool GetProcessList(Upp::Array<int64> &pid, Upp::Array<String> &pNames);
@ -109,13 +119,6 @@ bool CloseCDTray(String drive);
/////////////////////////////////////////////////////////////////////
// Key and mouse keys
bool Window_GetRect(int64 windowId, long &left, long &top, long &right, long &bottom);
bool Window_SetRect(int64 windowId, long left, long top, long right, long bottom);
void Window_Bottom(int64 windowId);
void Window_Top(int64 windowId);
void Window_TopMost(int64 windowId);
bool Mouse_GetPos(long &x, long &y);
bool Mouse_SetPos(long x, long y, int64 windowId);
@ -135,10 +138,14 @@ void Mouse_RightDblClick();
void Keyb_SendKeys(String text, long finalDelay = 100, long delayBetweenKeys = 50);
bool Window_SaveCapture(int64 windowId, String fileName, int left = -1, int top = -1, int width = -1, int height = -1);
Image Window_SaveCapture(int64 windowId, int left = -1, int top = -1, int width = -1, int height = -1);
bool Snap_Desktop(String fileName);
bool Snap_DesktopRectangle(String fileName, int left, int top, int width, int height);
bool Snap_Window(String fileName, int64 handle);
Image Snap_Desktop();
Image Snap_DesktopRectangle(int left, int top, int width, int height);
Image Snap_Window(int64 handle);
bool GetKeyLockStatus(bool &caps, bool &num, bool &scroll);
bool SetKeyLockStatus(bool caps, bool num, bool scroll);
@ -153,7 +160,6 @@ bool Record_Window(String fileName, int duration, int64 handle, double secsFrame
void SetDesktopWallPaper(const char *path);
struct SystemSignature : DeepCopyOption<SystemSignature> {
String manufacturer, productName, version, mbSerial;
int numberOfProcessors;

View file

@ -1,7 +1,31 @@
#include "SysInfo_in.h"
#include <plugin/png/png.h>
#include <plugin/jpg/jpg.h>
#include <plugin/bmp/bmp.h>
NAMESPACE_UPP
bool Window_SaveCapture(int64 windowId, String fileName, int left, int top, int width, int height)
{
Image img = Window_SaveCapture(windowId, left, top, width, height);
if (IsNull(img))
return false;
if (GetFileExt(fileName) == ".png") {
PNGEncoder encoder;
return encoder.SaveFile(fileName, img);
} else if (GetFileExt(fileName) == ".jpg") {
JPGEncoder encoder(90);
return encoder.SaveFile(fileName, img);
} else if (GetFileExt(fileName) == ".bmp") {
BMPEncoder encoder;
return encoder.SaveFile(fileName, img);
} else
return false;
}
#if defined(PLATFORM_WIN32) || defined (PLATFORM_WIN64)
#if defined(__MINGW32__)
@ -10,65 +34,66 @@ NAMESPACE_UPP
#define labs(x) abs(x)
#endif
bool Window_SaveCapture(int64 windowId, String fileName, int left, int top, int width, int height)
Image Window_SaveCapture(int64 windowId, int left, int top, int width, int height)
{
HWND windowIdH = reinterpret_cast<HWND>(windowId);
if (windowIdH == 0)
windowIdH = GetDesktopWindow();
if (GetFileExt(fileName) != ".bmp")
fileName += ".bmp";
HWND wH = reinterpret_cast<HWND>(windowId);
if (wH == 0)
wH = GetDesktopWindow();
RECT rc;
GetWindowRect (windowIdH, &rc);
if (!GetWindowRect(wH, &rc))
return Null;
if (left == -1)
left = rc.left;
if (top == -1)
top = rc.top;
if (width == -1)
width = rc.right-rc.left;
width = rc.right - rc.left;
if (height == -1)
height = rc.bottom-rc.top;
height = rc.bottom - rc.top;
HDC hDC = GetDC(0);
HDC memDC = CreateCompatibleDC (hDC);
HBITMAP hb = CreateCompatibleBitmap (hDC, width, height);
HBITMAP OldBM = (HBITMAP)SelectObject(memDC, hb);
BitBlt(memDC, 0, 0, width, height , hDC, left, top , SRCCOPY);
FILE *file = NULL;
HDC hDC = NULL;
HDC memDC = NULL;
HBITMAP hb = NULL;
HBITMAP oldBM = NULL;
Image img = Null;
ImageBuffer b;
if ((hDC = GetDC(0)) == NULL)
goto end;
if ((memDC = CreateCompatibleDC(hDC)) == NULL)
goto end;
if ((hb = CreateCompatibleBitmap(hDC, width, height)) == NULL)
goto end;
if ((oldBM = (HBITMAP)SelectObject(memDC, hb)) == NULL)
goto end;
if (!BitBlt(memDC, 0, 0, width, height , hDC, left, top, SRCCOPY))
goto end;
BITMAPINFO bmpInfo;
BITMAPFILEHEADER bmpFileHeader;
ZeroMemory(&bmpInfo, sizeof(BITMAPINFO));
bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
GetDIBits(hDC, hb, 0, 0, NULL, &bmpInfo, DIB_RGB_COLORS);
if (!GetDIBits(hDC, hb, 0, 0, NULL, &bmpInfo, DIB_RGB_COLORS))
goto end;
if(bmpInfo.bmiHeader.biSizeImage <= 0)
bmpInfo.bmiHeader.biSizeImage = bmpInfo.bmiHeader.biWidth*labs(bmpInfo.bmiHeader.biHeight)*(bmpInfo.bmiHeader.biBitCount+7)/8;
char *cbuf = new char[bmpInfo.bmiHeader.biSizeImage];
LPVOID buf = cbuf;
bmpInfo.bmiHeader.biCompression = BI_RGB;
GetDIBits(hDC, hb, 0, bmpInfo.bmiHeader.biHeight, buf, &bmpInfo, DIB_RGB_COLORS);
if((file = _wfopen(fileName.ToWString(),L"wb")) == NULL)
return false;
bmpFileHeader.bfReserved1 = 0;
bmpFileHeader.bfReserved2 = 0;
bmpFileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)+bmpInfo.bmiHeader.biSizeImage;
bmpFileHeader.bfType = 19778;
bmpFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
fwrite(&bmpFileHeader, sizeof(BITMAPFILEHEADER), 1, file);
fwrite(&bmpInfo.bmiHeader,sizeof(BITMAPINFOHEADER), 1, file);
fwrite(buf,bmpInfo.bmiHeader.biSizeImage, 1, file);
delete[] cbuf;
fclose(file);
bmpInfo.bmiHeader.biHeight = -height;
SelectObject(hDC, OldBM);
b.Create(width, height);
if (!GetDIBits(hDC, hb, 0, height, ~b, (BITMAPINFO *)&bmpInfo.bmiHeader, DIB_RGB_COLORS))
goto end;
img = b;
end:
SelectObject(hDC, oldBM);
DeleteObject(hb);
DeleteDC(memDC);
ReleaseDC(0, hDC);
return true;
return img;
}
class ScreenGrab {
@ -425,19 +450,87 @@ bool ScreenGrab::GrabSnapshot()
#ifdef PLATFORM_POSIX
bool Window_SaveCapture(int64 windowId, String fileName, int left, int top, int width, int height)
Window GetToplevelParent(_XDisplay *display, Window window) {
Window parent;
Window root;
Window *children;
unsigned int numChildren;
while (true) {
if (0 == XQueryTree(display, window, &root, &parent, &children, &numChildren))
return -1;
if (children)
XFree(children);
if (window == root || parent == root)
return window;
else
window = parent;
}
}
Image Window_SaveCapture(int64 windowId, int left, int top, int width, int height)
{
if (GetFileExt(fileName) != ".xwd")
fileName += ".xwd";
SetSysInfoX11ErrorHandler();
String command;
_XDisplay *dpy = XOpenDisplay (NULL);
if (!dpy) {
SetX11ErrorHandler();
return Null;
}
int screen = DefaultScreen(dpy);
if (windowId == 0)
command = "xwd -root -silent -out \"" + fileName + "\"";
else
command = "xwd -id " + FormatLong(windowId) + " -silent -out \"" + fileName + "\"";
windowId = RootWindow(dpy, screen);
else {
windowId = GetToplevelParent(dpy, windowId);
if (windowId < 0)
return Null;
}
String strret;
return Sys(command, strret) >= 0;
XWindowAttributes rc;
if (!XGetWindowAttributes(dpy, windowId, &rc)) {
XCloseDisplay(dpy);
SetX11ErrorHandler();
return Null;
}
if (left == -1)
left = rc.x;
if (top == -1)
top = rc.y;
if (width == -1)
width = rc.width;
if (height == -1)
height = rc.height;
XImage *image = XGetImage(dpy, windowId, 0, 0, width, height, XAllPlanes(), ZPixmap);
if (image == NULL)
return Null;
ImageBuffer ib(width, height);
unsigned long red_mask = image->red_mask;
unsigned long green_mask = image->green_mask;
unsigned long blue_mask = image->blue_mask;
for (int y = 0; y < height; y++) {
RGBA *row = ib[y];
for (int x = 0; x < width ; x++) {
unsigned long pixel = XGetPixel(image, x, y);
unsigned char blue = pixel & blue_mask;
unsigned char green = (pixel & green_mask) >> 8;
unsigned char red = (pixel & red_mask) >> 16;
(row + x)->r = red;
(row + x)->g = green;
(row + x)->b = blue;
}
}
XCloseDisplay(dpy);
SetX11ErrorHandler();
Image img;
img = ib;
return img;
}
#endif
@ -457,4 +550,19 @@ bool Snap_Window(String fileName, int64 handle)
return Window_SaveCapture(handle, fileName);
}
Image Snap_Desktop()
{
return Window_SaveCapture(0);
}
Image Snap_DesktopRectangle(int left, int top, int width, int height)
{
return Window_SaveCapture(0, left, top, width, height);
}
Image Snap_Window(int64 handle)
{
return Window_SaveCapture(handle);
}
END_UPP_NAMESPACE

View file

@ -348,18 +348,33 @@ om])&]
[s2; Giving this function the [%-*@3 windowId], it returns the window
location in the screen in [%-*@3 left], [%-*@3 top], [%-*@3 right]
and [%-*@3 bottom].&]
[s0; -|Returns true if the values got are valid.&]
[s2; Returns true if the values got are valid.&]
[s3; &]
[s4; &]
[s5;:Window`_SetRect`(long`,long`,long`,long`,long`):%- [@(0.0.255) void]_[* Window`_SetR
ect]([@(0.0.255) int64]_[*@3 windowId], [@(0.0.255) long]_[*@3 left],
[s4;%- &]
[s5;:Window`_SetRect`(int64`,long`,long`,long`,long`):%- [@(0.0.255) bool]_[* Window`_Set
Rect]([_^int64^ int64]_[*@3 windowId], [@(0.0.255) long]_[*@3 left],
[@(0.0.255) long]_[*@3 top], [@(0.0.255) long]_[*@3 right], [@(0.0.255) long]_[*@3 bottom])&]
[s2; Giving this function the [%-*@3 windowId], it sets the window
location in the screen in [%-*@3 left], [%-*@3 top], [%-*@3 right]
and [%-*@3 bottom].&]
[s2; -|Returns true if the window is relocated correctly..&]
[s0; &]
[s2; Returns true if the values got are valid.&]
[s3; &]
[s4;%- &]
[s5;:Window`_Bottom`(int64`):%- [@(0.0.255) void]_[* Window`_Bottom]([_^int64^ int64]_[*@3 wi
ndowId])&]
[s2; Moves [%-*@3 windowId] to the bottom of all windows.&]
[s3; &]
[s4;%- &]
[s5;:Window`_Top`(int64`):%- [@(0.0.255) void]_[* Window`_Top]([_^int64^ int64]_[*@3 windowId
])&]
[s2; Moves [%-*@3 windowId] to the top of the windows.&]
[s3; &]
[s4;%- &]
[s5;:Window`_TopMost`(int64`):%- [@(0.0.255) void]_[* Window`_TopMost]([_^int64^ int64]_[*@3 w
indowId])&]
[s2; Moves [%-*@3 windowId] as the topmost window.&]
[s3; &]
[s0; &]
[ {{10000@1 [s0; [* Mouse and keyboard handling]]}}&]
[s3; &]
[s5;:Mouse`_GetPos`(long`&`,long`&`):%- [@(0.0.255) bool]_[* Mouse`_GetPos]([@(0.0.255) lon
@ -368,7 +383,7 @@ g]_`&[*@3 x], [@(0.0.255) long]_`&[*@3 y])&]
left corner is (0, 0).&]
[s2; Returns true if the operation has been done successfully.&]
[s3; &]
[s4;%- &]
[s4; &]
[s5;:Mouse`_SetPos`(long`,long`,int64`):%- [@(0.0.255) bool]_[* Mouse`_SetPos]([@(0.0.255) l
ong]_[*@3 x], [@(0.0.255) long]_[*@3 y], [@(0.0.255) int64]_[*@3 windowId])&]
[s2; Sets the mouse position to [%-*@3 x] [%-*@3 y] referenced to the
@ -473,7 +488,7 @@ ileName])&]
[s2; Saves the desktop in [%-*@3 fileName].as an image file.&]
[s2; Allowed formats are:&]
[s2;i150;O0; Posix:-|xwd&]
[s2;i150;O0; Windows:-|bmp&]
[s2;i150;O0; Windows:-|bmp, png, jpg&]
[s3; &]
[s4;%- &]
[s5;:Snap`_DesktopRectangle`(String`,int`,int`,int`,int`):%- [@(0.0.255) bool]_[* Snap`_D
@ -483,7 +498,7 @@ esktopRectangle]([_^String^ String]_[*@3 fileName], [@(0.0.255) int]_[*@3 left],
[%-*@3 width ]and [%-*@3 height].in [%-*@3 fileName] as an image file.&]
[s2; Allowed formats are:&]
[s2;i150;O0; Posix:-|xwd&]
[s2;i150;O0; Windows:-|bmp&]
[s2;i150;O0; Windows:-|bmp, png, jpg&]
[s3; &]
[s4;%- &]
[s5;:Snap`_Window`(String`,int64`):%- [@(0.0.255) bool]_[* Snap`_Window]([_^String^ String]_
@ -492,7 +507,23 @@ esktopRectangle]([_^String^ String]_[*@3 fileName], [@(0.0.255) int]_[*@3 left],
as an image file.&]
[s2; Allowed formats are:&]
[s2;i150;O0; Posix:-|xwd&]
[s2;i150;O0; Windows:-|bmp&]
[s2;i150;O0; Windows:-|bmp, png, jpg&]
[s3; &]
[s4;%- &]
[s5;:Snap`_Desktop`(`):%- [_^Image^ Image]_[* Snap`_Desktop]()&]
[s2; Returns the desktop image.&]
[s3;%- &]
[s4;%- &]
[s5;:Snap`_DesktopRectangle`(int`,int`,int`,int`):%- [_^Image^ Image]_[* Snap`_DesktopRec
tangle]([@(0.0.255) int]_[*@3 left], [@(0.0.255) int]_[*@3 top], [@(0.0.255) int]_[*@3 width],
[@(0.0.255) int]_[*@3 height])&]
[s2; Returns the image of a desktop rectangle defined by [%-*@3 left],
[%-*@3 top], [%-*@3 width ]and [%-*@3 height].&]
[s3; &]
[s4;%- &]
[s5;:Snap`_Window`(int64`):%- [_^Image^ Image]_[* Snap`_Window]([_^int64^ int64]_[*@3 handle])
&]
[s2; Returns a window image defined by its [%-*@3 handle].&]
[s3; &]
[s4;%- &]
[s5;:Record`_Desktop`(String`,int`,int`,bool`):%- [@(0.0.255) bool]_[* Record`_Desktop]([_^String^ S