43
votes

I have created an AIR application which has two windows. First one is main window(spark Windowed Application) and the second one is a component(spark window). I am using Java to capture the Desktop screen with Flex-Java Bridge Flerry.

Here is the code to capture the screen which is:-

HDC hdcWindow = User32.INSTANCE.GetDC(hWnd);
HDC hdcMemDC = GDI32.INSTANCE.CreateCompatibleDC(hdcWindow);
RECT bounds = new RECT();
User32Extra.INSTANCE.GetClientRect(hWnd, bounds);

int width = bounds.right;
int height = bounds.bottom ;
HBITMAP hBitmap = GDI32.INSTANCE.CreateCompatibleBitmap(hdcWindow, width, height);

HANDLE hOld = GDI32.INSTANCE.SelectObject(hdcMemDC, hBitmap);
GDI32Extra.INSTANCE.BitBlt(hdcMemDC, 0, 0, width, height, hdcWindow, 0, 0, WinGDIExtra.SRCCOPY);

I don't want the main flex window to be captured. It should skipped(transparent) from being captured.

Is that possible by changing the configuration of flex project?

If it cannot be done in flex and java, in what platform it can be done?

2
SetWindowDisplayAffinity( hWnd, WDA_MONITOR );IInspectable
@iinspectable SetWindowDisplayAffinity doesn't skip the window from being captured. It will just protect the window from being captured. I don't want black screen in place of that window, I want the window backside of it to be displayed.Vishnu
How is anyone supposed to know what you want, when your question does not even remotely specify the desired behavior? What have asked for in your comment is - in general - not possible.IInspectable
@IInspectable Is it possible to simulate the process by painting the hWnd backside of that window on the hdcMemDC?Vishnu

2 Answers

1
votes

If I understood correctly your problem.

You can use built in Flex/as3 function to take a screenshot of the entire application or a particular component then convert into bytearray and PngEncoder (or JPGEncoder if you prefer), than save it...

Here's an example:

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
                       xmlns:s="library://ns.adobe.com/flex/spark" 
                       xmlns:mx="library://ns.adobe.com/flex/mx">   
    <fx:Script>
        <![CDATA[
            import mx.graphics.codec.PNGEncoder;

            private function takeSnapshot(comp:DisplayObject):void {
                var bitmapData:BitmapData = new BitmapData(comp.width,comp.height,false,0x00000000);
                bitmapData.draw(comp, new Matrix());

                var fileStream:FileStream = new FileStream();
                fileStream.open(File.desktopDirectory.resolvePath("screenshot.png"), FileMode.UPDATE);
                fileStream.writeBytes(new PNGEncoder().encode(bitmapData));
            }
        ]]>
    </fx:Script>    
    <s:BorderContainer width="100%" height="100%" backgroundColor="#ff00ff">
        <s:Label text="this text and box should be saved"/>
        <s:BorderContainer width="25%" height="25%" backgroundColor="#ffff00" horizontalCenter="0"
                           id="extended"
                           verticalCenter="0">
            <s:Label text="this text and box should be saved" width="100%" maxDisplayedLines="5"/>
        </s:BorderContainer>
    </s:BorderContainer>    
    <s:Button bottom="0" left="0" label="screen" click="takeSnapshot(extended)"/>
</s:WindowedApplication>

EDIT:

As I thought I misunderstood the request..

The only way I can think of is to:

  1. Minimize the application (this.minimize();) or setting the alpha to 0 (this.alpha=0).
  2. Take the screenshot
  3. Maximize the application (this.maximize();) or setting the alpha to 1 (this.alpha=0).
0
votes

A solution I can think of is that you can move the "unwanted" windows out of capture are like. (Below 0,0 coordinate) with some code like this.

public void foo(){
this.xCoord = -this.xCoord;
this.yCoord = -this.yCoord;
}   
//Im not sure about the exact syntax but you should get the idea.

and than

foo();
capture();
foo();