43

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?

Vishnu
  • 11,614
  • 6
  • 51
  • 90
  • [`SetWindowDisplayAffinity`](https://msdn.microsoft.com/en-us/library/windows/desktop/dd375340.aspx)`( hWnd, WDA_MONITOR );` – IInspectable Jun 18 '15 at 07:58
  • 1
    @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 Jun 18 '15 at 08:58
  • 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 Jun 18 '15 at 15:56
  • @IInspectable Is it possible to simulate the process by painting the hWnd backside of that window on the hdcMemDC? – Vishnu Jul 16 '15 at 11:31

2 Answers2

1

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).
Marcx
  • 6,806
  • 5
  • 46
  • 69
  • Sorry. I want to capture the desktop screen, not the flex app. – Vishnu Aug 27 '15 at 11:05
  • That causes a blinking effect on the screen. Bitblt takes 200 ms to capture the screen. I have tried that. And you cannot use `this.minimize` or `this.alpha` of flex app in java – Vishnu Aug 27 '15 at 11:13
  • Can you warn the user and add a minimal timeout to avoid the blinking effect (ie. 500ms)? – Marcx Aug 27 '15 at 11:14
  • I am using this to continuously share the screen. That's not user friendly. – Vishnu Aug 27 '15 at 11:17
  • Sorry I ran out of ideas :D – Marcx Aug 27 '15 at 11:28
  • There are plenty of screensharing options, why bake your own? Screensharing apps will capture the entire screen, themselves included, that's why often they minimize themselves into a tray icon. – Josep Valls Sep 03 '15 at 22:49
0

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();
KaO
  • 313
  • 1
  • 3
  • 13