tags:

views:

32

answers:

0

Hi,

I have been busy creating a screen capture function in Java using JNA (java native access). So far I have been able to do a lot, but I am baffled about some things a bit. The OS is Windows, if you wonder....

  1. I find it easy to capture, for example, a region, or a window, but find it hard to draw over it. The reason for this is the following: If I draw something around a window, like a border using its DC or a DC to the whole desktop, it gets drawn, but then if some other nearby overlapping window gets its WM_PAINT message, its area will erase what I have drawn on my active window. Also clipping regions seem like a big nuisance. Should I call LockWindowUpdate() after having drawn on my window.

  2. I am sure that most screen capturing software does the following: creates a snapshot of the system (by snapshot I don't mean screenshot, but rather an enumeration of all objects of interest) in memory and then probably calls LockWindowUpdate(HWND hWnd) for the whole screen. The user then actually interacts with a snapshot of the desktop, not with the desktop itself. As a Java programmer, I find it a difficult matter to use enums and pointers to such a big extent, so I might be missing something.

Here is the Java code i use:

                     int hDc = gdi32.CreateDCA("DISPLAY", null, null, null);
                     int brush=user32.GetSysColorBrush(13);
                     Rectangle rect = getWindowParentRectangle(handler); //my function, no problem here for sure
                     int rgn1=gdi32.CreateRectRgn(rect.x+1, rect.y+1, rect.x+rect.width-1, rect.y+rect.height-1); //this is a rather idiotic way to send a WM_PAINT message, I know, if anybody has a better way, say it
                     int rgn2=gdi32.CreateRectRgn(rect.x+4, rect.y+4, rect.x+rect.width-4, rect.y+rect.height-4);
                     user32.ShowWindow(parentHandler, 5);
                     gdi32.CombineRgn(rgn1, rgn1, rgn2, 3);
                     gdi32.FillRgn(hDc, rgn1, brush);
                     gdi32.DeleteObject(rgn2);
                     gdi32.DeleteObject(rgn1);
                     gdi32.DeleteDC(hDc);

This code actually momentarily draws around the ACTIVE window (not only around its client area, but around the whole window as it should). But then if ANOTHER window that overlaps the ACTIVE gets resized, has some info running on it or whatever,then the resized area of the ANOTHER window kinda removes what I have drawn on the ACTIVE window.
So any pointers (no pun intended) ?

P.S I use gdi32 and user32 and would prefer to restrain from newer libraries for compatibility (with XP) purposes. I also believe gdi+ is an overkill for the purpose. Here is a visualization of the problem:

Normal result: (put an H here)ttp://img840.imageshack.us/img840/2769/correctv.png

Inexpected/Undesired result: (put an H here)ttp://img836.imageshack.us/img836/6935/incorrect.png