Starts screenshot taking code in LCL-CustomDrawn-Cocoa, already works, but the colors are switched

git-svn-id: trunk@34268 -
This commit is contained in:
sekelsenmat 2011-12-19 08:36:19 +00:00
parent 2a70b1b482
commit d2c89a1ff3
6 changed files with 77 additions and 294 deletions

View File

@ -239,7 +239,7 @@ begin
javaEnvRef^^.CallVoidMethod(javaEnvRef, javaActivityObject, javaMethod_LCLDoShowMessageBox);
end;
(*{------------------------------------------------------------------------------
{------------------------------------------------------------------------------
Function: RawImage_FromDevice
Params: ADC:
ARect:
@ -255,27 +255,9 @@ end;
So get this internal bitmap and pass it to RawImage_FromBitmap
------------------------------------------------------------------------------}
function TQtWidgetSet.RawImage_FromDevice(out ARawImage: TRawImage; ADC: HDC; const ARect: TRect): Boolean;
var
Desc: TRawImageDescription absolute ARawImage.Description;
//SrcWidth, SrcHeight: Integer;
WinID: Cardinal;
DCSize: TSize;
Pixmap: TQtPixmap;
Image: QImageH;
Context: TQtDeviceContext;
procedure RawImage_FromImage(AImage: QImageH);
begin
ARawImage.DataSize := QImage_numBytes(AImage);
ARawImage.Data := GetMem(ARawImage.DataSize);
Move(QImage_bits(AImage)^, ARawImage.Data^, ARawImage.DataSize);
ARawImage.Mask := nil;
end;
begin
{$ifdef VerboseQtWinAPI}
WriteLn('Trace:> [WinAPI GetRawImageFromDevice] SrcDC: ', dbghex(ADC),
{$ifdef VerboseCDWinAPI}
DebugLn('Trace:> [WinAPI GetRawImageFromDevice] SrcDC: ', dbghex(ADC),
' SrcWidth: ', dbgs(ARect.Right - ARect.Left),
' SrcHeight: ', dbgs(ARect.Bottom - ARect.Top));
{$endif}
@ -285,56 +267,7 @@ begin
Result := True;
ARawImage.Init;
FillStandardDescription(ARawImage.Description);
Context := TQtDeviceContext(ADC);
with DCSize, Context.getDeviceSize do
begin
cx := x;
cy := y;
end;
if Context.Parent <> nil then
begin
Pixmap := TQtPixmap.Create(@DCSize);
WinID := QWidget_winId(Context.Parent);
try
// if you have dual monitors then getDeviceSize return
// more width than screen width, but grabWindow will only grab one
// screen, so its width will be less
// Solution: we can either pass prefered size to grabWindow or
// correct Description size after. I see the first solution as more correct.
Pixmap.grabWindow(WinID, 0, 0, DCSize.cx, DCSize.cy);
Image := QImage_Create;
Pixmap.toImage(Image);
RawImage_FromImage(Image);
QImage_destroy(Image);
finally
Pixmap.Free;
end;
end else
begin
if Context.vImage <> nil then
RawImage_FromImage(Context.vImage.FHandle)
else
if Context.ParentPixmap <> nil then
begin
Image := QImage_create();
QPixmap_toImage(Context.ParentPixmap, Image);
RawImage_FromImage(Image);
QImage_destroy(Image);
end else
Result := False;
end;
// In this case we use the size of the context
Desc.Width := DCSize.cx;
Desc.Height := DCSize.cy;
{$ifdef VerboseQtWinAPI}
WriteLn('Trace:< [WinAPI GetRawImageFromDevice]');
{$endif}
end;*)
end;
procedure TCDWidgetSet.ShowVirtualKeyboard;
begin

View File

@ -128,7 +128,7 @@ function TCDWidgetSet.PromptUser(const DialogCaption : string;
begin
end;
(*{------------------------------------------------------------------------------
{------------------------------------------------------------------------------
Function: RawImage_FromDevice
Params: ADC:
ARect:
@ -142,88 +142,64 @@ end;
MWE: exept for the desktop, there is always a bitmep selected in the DC.
So get this internal bitmap and pass it to RawImage_FromBitmap
Reference documentation:
Technical Q&A QA1509 Getting the pixel data from a CGImage object
http://developer.apple.com/library/mac/#qa/qa1509/_index.html
CGDisplayCreateImage
http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Reference/Quartz_Services_Ref/Reference/reference.html
http://lists.apple.com/archives/cocoa-dev/2011/Feb/msg00704.html
CFDataRef
http://developer.apple.com/library/ios/#DOCUMENTATION/CoreFoundation/Reference/CFDataRef/Reference/reference.html
------------------------------------------------------------------------------}
function TQtWidgetSet.RawImage_FromDevice(out ARawImage: TRawImage; ADC: HDC; const ARect: TRect): Boolean;
function TCDWidgetSet.RawImage_FromDevice(out ARawImage: TRawImage; ADC: HDC; const ARect: TRect): Boolean;
var
Desc: TRawImageDescription absolute ARawImage.Description;
//SrcWidth, SrcHeight: Integer;
WinID: Cardinal;
DCSize: TSize;
Pixmap: TQtPixmap;
Image: QImageH;
Context: TQtDeviceContext;
procedure RawImage_FromImage(AImage: QImageH);
begin
ARawImage.DataSize := QImage_numBytes(AImage);
ARawImage.Data := GetMem(ARawImage.DataSize);
Move(QImage_bits(AImage)^, ARawImage.Data^, ARawImage.DataSize);
ARawImage.Mask := nil;
end;
screenshotImage: CGImageRef;
imageDataProv: CGDataProviderRef;
imageData: CFDataRef;
lBitsPerComponent, lBitsPerPixel, lBytesPerRow: size_t;
lDataPtr: UnivPtr;
lDataLength: CFIndex;
begin
{$ifdef VerboseQtWinAPI}
WriteLn('Trace:> [WinAPI GetRawImageFromDevice] SrcDC: ', dbghex(ADC),
' SrcWidth: ', dbgs(ARect.Right - ARect.Left),
' SrcHeight: ', dbgs(ARect.Bottom - ARect.Top));
{$endif}
// todo: copy only passed rectangle
Result := True;
ARawImage.Init;
FillStandardDescription(ARawImage.Description);
Context := TQtDeviceContext(ADC);
ARawImage.Description.Init_BPP32_B8G8R8A8_BIO_TTB(0, 0);
with DCSize, Context.getDeviceSize do
begin
cx := x;
cy := y;
end;
// Take the screenshot and obtain the pixel data
screenshotImage := CGDisplayCreateImage(CGMainDisplayID()); // Requires 10.6+
imageDataProv := CGImageGetDataProvider(screenshotImage); // Requires 10.5+
imageData := CGDataProviderCopyData(imageDataProv);
if Context.Parent <> nil then
begin
Pixmap := TQtPixmap.Create(@DCSize);
WinID := QWidget_winId(Context.Parent);
try
// if you have dual monitors then getDeviceSize return
// more width than screen width, but grabWindow will only grab one
// screen, so its width will be less
// Solution: we can either pass prefered size to grabWindow or
// correct Description size after. I see the first solution as more correct.
Pixmap.grabWindow(WinID, 0, 0, DCSize.cx, DCSize.cy);
Image := QImage_Create;
Pixmap.toImage(Image);
RawImage_FromImage(Image);
QImage_destroy(Image);
finally
Pixmap.Free;
end;
end else
begin
if Context.vImage <> nil then
RawImage_FromImage(Context.vImage.FHandle)
else
if Context.ParentPixmap <> nil then
begin
Image := QImage_create();
QPixmap_toImage(Context.ParentPixmap, Image);
RawImage_FromImage(Image);
QImage_destroy(Image);
end else
Result := False;
end;
// Now read the image description and convert it to our own
lBitsPerComponent := CGImageGetBitsPerComponent(screenshotImage);
ARawImage.Description.AlphaPrec := 0;
ARawImage.Description.RedPrec := lBitsPerComponent;
ARawImage.Description.GreenPrec := lBitsPerComponent;
ARawImage.Description.BluePrec := lBitsPerComponent;
ARawImage.Description.RedShift := 0;
ARawImage.Description.GreenShift := 8;
ARawImage.Description.BlueShift := 16;
// In this case we use the size of the context
Desc.Width := DCSize.cx;
Desc.Height := DCSize.cy;
ARawImage.Description.Width := CGImageGetWidth(screenshotImage);
ARawImage.Description.Height := CGImageGetHeight(screenshotImage);
{$ifdef VerboseQtWinAPI}
WriteLn('Trace:< [WinAPI GetRawImageFromDevice]');
{$endif}
end;*)
lBitsPerPixel := CGImageGetBitsPerPixel(screenshotImage); // For now support it will give us 32
lBytesPerRow := CGImageGetBytesPerRow(screenshotImage);
// Now copy the data
lDataPtr := CFDataGetBytePtr(imageData);
lDataLength := CFDataGetLength(imageData);
ARawImage.CreateData(False);
lDataLength := Min(lDataLength, ARawImage.DataSize);
System.Move(lDataPtr^, ARawImage.Data^, lDataLength);
end;
procedure TCDWidgetset.ShowVirtualKeyboard();
begin

View File

@ -129,7 +129,7 @@ function TCDWidgetSet.PromptUser(const DialogCaption : string;
begin
end;
(*{------------------------------------------------------------------------------
{------------------------------------------------------------------------------
Function: RawImage_FromDevice
Params: ADC:
ARect:
@ -144,87 +144,12 @@ end;
MWE: exept for the desktop, there is always a bitmep selected in the DC.
So get this internal bitmap and pass it to RawImage_FromBitmap
------------------------------------------------------------------------------}
function TQtWidgetSet.RawImage_FromDevice(out ARawImage: TRawImage; ADC: HDC; const ARect: TRect): Boolean;
var
Desc: TRawImageDescription absolute ARawImage.Description;
//SrcWidth, SrcHeight: Integer;
WinID: Cardinal;
DCSize: TSize;
Pixmap: TQtPixmap;
Image: QImageH;
Context: TQtDeviceContext;
procedure RawImage_FromImage(AImage: QImageH);
begin
ARawImage.DataSize := QImage_numBytes(AImage);
ARawImage.Data := GetMem(ARawImage.DataSize);
Move(QImage_bits(AImage)^, ARawImage.Data^, ARawImage.DataSize);
ARawImage.Mask := nil;
end;
function TCDWidgetSet.RawImage_FromDevice(out ARawImage: TRawImage; ADC: HDC; const ARect: TRect): Boolean;
begin
{$ifdef VerboseQtWinAPI}
WriteLn('Trace:> [WinAPI GetRawImageFromDevice] SrcDC: ', dbghex(ADC),
' SrcWidth: ', dbgs(ARect.Right - ARect.Left),
' SrcHeight: ', dbgs(ARect.Bottom - ARect.Top));
{$endif}
// todo: copy only passed rectangle
Result := True;
ARawImage.Init;
FillStandardDescription(ARawImage.Description);
Context := TQtDeviceContext(ADC);
with DCSize, Context.getDeviceSize do
begin
cx := x;
cy := y;
end;
if Context.Parent <> nil then
begin
Pixmap := TQtPixmap.Create(@DCSize);
WinID := QWidget_winId(Context.Parent);
try
// if you have dual monitors then getDeviceSize return
// more width than screen width, but grabWindow will only grab one
// screen, so its width will be less
// Solution: we can either pass prefered size to grabWindow or
// correct Description size after. I see the first solution as more correct.
Pixmap.grabWindow(WinID, 0, 0, DCSize.cx, DCSize.cy);
Image := QImage_Create;
Pixmap.toImage(Image);
RawImage_FromImage(Image);
QImage_destroy(Image);
finally
Pixmap.Free;
end;
end else
begin
if Context.vImage <> nil then
RawImage_FromImage(Context.vImage.FHandle)
else
if Context.ParentPixmap <> nil then
begin
Image := QImage_create();
QPixmap_toImage(Context.ParentPixmap, Image);
RawImage_FromImage(Image);
QImage_destroy(Image);
end else
Result := False;
end;
// In this case we use the size of the context
Desc.Width := DCSize.cx;
Desc.Height := DCSize.cy;
{$ifdef VerboseQtWinAPI}
WriteLn('Trace:< [WinAPI GetRawImageFromDevice]');
{$endif}
end;*)
end;
procedure TCDWidgetset.ShowVirtualKeyboard();
begin

View File

@ -129,7 +129,7 @@ function TCDWidgetSet.PromptUser(const DialogCaption : string;
begin
end;
(*{------------------------------------------------------------------------------
{------------------------------------------------------------------------------
Function: RawImage_FromDevice
Params: ADC:
ARect:
@ -145,27 +145,9 @@ end;
So get this internal bitmap and pass it to RawImage_FromBitmap
------------------------------------------------------------------------------}
function TCDWidgetSet.RawImage_FromDevice(out ARawImage: TRawImage; ADC: HDC; const ARect: TRect): Boolean;
var
Desc: TRawImageDescription absolute ARawImage.Description;
//SrcWidth, SrcHeight: Integer;
WinID: Cardinal;
DCSize: TSize;
Pixmap: TQtPixmap;
Image: QImageH;
Context: TQtDeviceContext;
procedure RawImage_FromImage(AImage: QImageH);
begin
ARawImage.DataSize := QImage_numBytes(AImage);
ARawImage.Data := GetMem(ARawImage.DataSize);
Move(QImage_bits(AImage)^, ARawImage.Data^, ARawImage.DataSize);
ARawImage.Mask := nil;
end;
begin
{$ifdef VerboseQtWinAPI}
WriteLn('Trace:> [WinAPI GetRawImageFromDevice] SrcDC: ', dbghex(ADC),
{$ifdef VerboseCDWinAPI}
DebugLn('Trace:> [WinAPI GetRawImageFromDevice] SrcDC: ', dbghex(ADC),
' SrcWidth: ', dbgs(ARect.Right - ARect.Left),
' SrcHeight: ', dbgs(ARect.Bottom - ARect.Top));
{$endif}
@ -175,56 +157,7 @@ begin
Result := True;
ARawImage.Init;
FillStandardDescription(ARawImage.Description);
Context := TQtDeviceContext(ADC);
with DCSize, Context.getDeviceSize do
begin
cx := x;
cy := y;
end;
if Context.Parent <> nil then
begin
Pixmap := TQtPixmap.Create(@DCSize);
WinID := QWidget_winId(Context.Parent);
try
// if you have dual monitors then getDeviceSize return
// more width than screen width, but grabWindow will only grab one
// screen, so its width will be less
// Solution: we can either pass prefered size to grabWindow or
// correct Description size after. I see the first solution as more correct.
Pixmap.grabWindow(WinID, 0, 0, DCSize.cx, DCSize.cy);
Image := QImage_Create;
Pixmap.toImage(Image);
RawImage_FromImage(Image);
QImage_destroy(Image);
finally
Pixmap.Free;
end;
end else
begin
if Context.vImage <> nil then
RawImage_FromImage(Context.vImage.FHandle)
else
if Context.ParentPixmap <> nil then
begin
Image := QImage_create();
QPixmap_toImage(Context.ParentPixmap, Image);
RawImage_FromImage(Image);
QImage_destroy(Image);
end else
Result := False;
end;
// In this case we use the size of the context
Desc.Width := DCSize.cx;
Desc.Height := DCSize.cy;
{$ifdef VerboseQtWinAPI}
WriteLn('Trace:< [WinAPI GetRawImageFromDevice]');
{$endif}
end;*)
end;
procedure TCDWidgetset.ShowVirtualKeyboard();
begin

View File

@ -67,7 +67,7 @@ function RawImage_DescriptionFromBitmap(ABitmap: HBITMAP; out ADesc: TRawImageDe
function RawImage_DescriptionFromDevice(ADC: HDC; out ADesc: TRawImageDescription): Boolean; override;
function RawImage_FromBitmap(out ARawImage: TRawImage; ABitmap, AMask: HBITMAP; ARect: PRect = nil): Boolean; override;
//function RawImage_FromDevice(out ARawImage: TRawImage; ADC: HDC; const ARect: TRect): Boolean; override;
function RawImage_FromDevice(out ARawImage: TRawImage; ADC: HDC; const ARect: TRect): Boolean; override;
function RawImage_QueryDescription(AFlags: TRawImageQueryFlags; var ADesc: TRawImageDescription): Boolean; override;
(*function ReleaseDesignerDC(Window: HWND; DC: HDC): Integer; override;

View File

@ -114,7 +114,7 @@ end;"/>
<License Value="modified LGPL-2
"/>
<Version Major="1" Release="1"/>
<Files Count="384">
<Files Count="388">
<Item1>
<Filename Value="carbon/agl.pp"/>
<AddToUsesPkgSection Value="False"/>
@ -1908,6 +1908,22 @@ end;"/>
<AddToUsesPkgSection Value="False"/>
<UnitName Value="customdrawnprivate"/>
</Item384>
<Item385>
<Filename Value="customdrawn/customdrawnlclintf_android.inc"/>
<Type Value="Include"/>
</Item385>
<Item386>
<Filename Value="customdrawn/customdrawnlclintf_cocoa.inc"/>
<Type Value="Include"/>
</Item386>
<Item387>
<Filename Value="customdrawn/customdrawnlclintf_win.inc"/>
<Type Value="Include"/>
</Item387>
<Item388>
<Filename Value="customdrawn/customdrawnlclintf_x11.inc"/>
<Type Value="Include"/>
</Item388>
</Files>
<LazDoc Paths="../../docs/xml/lcl"/>
<i18n>