1{%MainUnit customdrawnint.pas} 2{****************************************************************************** 3 All CustomDrawn interface support routines 4 Initial Revision : Sat Jan 17 19:00:00 2004 5 6 7 !! Keep alphabetical !! 8 9 ****************************************************************************** 10 Implementation 11 ****************************************************************************** 12 13 ***************************************************************************** 14 This file is part of the Lazarus Component Library (LCL) 15 16 See the file COPYING.modifiedLGPL.txt, included in this distribution, 17 for details about the license. 18 ***************************************************************************** 19} 20 21//##apiwiz##sps## // Do not remove 22 23(* 24 25function TQtWidgetSet.AddEventHandler(AHandle: THandle; AFlags: dword; 26 AEventHandler: TWaitHandleEvent; AData: PtrInt): PEventHandler; 27{ 28 QSocketNotifier requires 1 notifier per event type 29 and doesn't provide userdata in the callback. We need to 30 make a map of socket -> userdata to store userdata 31 and also create 3 notifiers for each event. We also need to 32 use our own constants for the event types in the userland callback. 33 For simplicity same as GTK G_IO values are used here and 34 their ORs will be emulated. The callback will always only get 35 1 event tho. 36} 37 38 function CreateQt4NotifierRec(aNR: PWaitHandleEventHandler; 39 const aType: QSocketNotifierType; aCallback: QSocketNotifier_activated_Event): PWaitHandleEventHandler; 40 var 41 qsn: QSocketNotifierH; 42 qsn_hook: QSocketNotifier_hookH; 43 i: QSocketNotifierType; 44 begin 45 if aNR = nil then begin 46 Result := new(PWaitHandleEventHandler); 47 for i := QSocketNotifierRead to QSocketNotifierException do begin 48 Result^.qsn[i] := nil; // nil them so removeeventhandler can find out what to free 49 Result^.qsn_hook[i] := nil; 50 end; 51 end else 52 Result := aNR; 53 54 qsn := QSocketNotifier_create(aHandle, aType); 55 qsn_hook := QSocketNotifier_hook_create(qsn); 56 QSocketNotifier_hook_hook_activated(qsn_hook, aCallback); // todo: !! 57 58 Result^.qsn[aType] := qsn; 59 Result^.qsn_hook[aType] := qsn_hook; 60 end; 61 62begin 63 Result := nil; 64 65 if AFlags and (EVE_IO_READ or EVE_IO_WRITE or EVE_IO_ERROR) = 0 then 66 Exit; // no flag set, no dice 67 68 if AFlags and EVE_IO_READ = EVE_IO_READ then 69 Result := CreateQt4NotifierRec(Result, QSocketNotifierRead, @SocketNotifierRead_cb); 70 71 if AFlags and EVE_IO_WRITE = EVE_IO_WRITE then 72 Result := CreateQt4NotifierRec(Result, QSocketNotifierWrite, @SocketNotifierWrite_cb); 73 74 if AFlags and EVE_IO_ERROR = EVE_IO_ERROR then 75 Result := CreateQt4NotifierRec(Result, QSocketNotifierException, @SocketNotifierError_cb); 76 77 PWaitHandleEventHandler(Result)^.user_callback := AEventHandler; 78 PWaitHandleEventHandler(Result)^.udata := aData; 79 PWaitHandleEventHandler(Result)^.socket := AHandle; 80 81 if FSocketEventMap.HasId(aHandle) then begin // if we encounter this (shouldn't happen) 82 Debugln('TQtWidgetSet.AddEventHandler Duplicate handle: ' + IntToStr(aHandle)); 83 FSocketEventMap.Delete(aHandle); // delete the previous one, potentially losing it.. 84 end; 85 FSocketEventMap.Add(AHandle, Result); 86end; 87 88function TQtWidgetSet.AddPipeEventHandler(AHandle: THandle; 89 AEventHandler: TPipeEvent; AData: PtrInt): PPipeEventHandler; 90begin 91 // todo 92 Result := nil; 93end; 94 95function TQtWidgetSet.AddProcessEventHandler(AHandle: THandle; 96 AEventHandler: TChildExitEvent; AData: PtrInt): PProcessEventHandler; 97begin 98 // todo 99 Result := nil; 100end;*) 101 102{------------------------------------------------------------------------------ 103 Function: CreateEmptyRegion 104 Params: 105 Returns: valid empty region 106 ------------------------------------------------------------------------------} 107function TCDWidgetSet.CreateEmptyRegion: hRGN; 108begin 109 Result:= HRGN(TLazRegion.Create()); 110end; 111 112(*{------------------------------------------------------------------------------ 113 Function: CreateStandardCursor 114 Params: 115 Returns: 116 ------------------------------------------------------------------------------} 117function TQtWidgetSet.CreateStandardCursor(ACursor: SmallInt): HCURSOR; 118var 119 CursorShape: QtCursorShape; 120begin 121 Result := 0; 122 if ACursor < crLow then Exit; 123 if ACursor > crHigh then Exit; 124 125 // TODO: map is better 126 case ACursor of 127 crNone : CursorShape := QtBlankCursor; 128 crArrow : CursorShape := QtArrowCursor; 129 crCross : CursorShape := QtCrossCursor; 130 crIBeam : CursorShape := QtIBeamCursor; 131 crSizeAll : CursorShape := QtSizeAllCursor; 132 crSizeNESW : CursorShape := QtSizeBDiagCursor; 133 crSizeNS : CursorShape := QtSizeVerCursor; 134 crSizeNWSE : CursorShape := QtSizeFDiagCursor; 135 crSizeWE : CursorShape := QtSizeHorCursor; 136 crSizeNW : CursorShape := QtSizeFDiagCursor; 137 crSizeN : CursorShape := QtSizeVerCursor; 138 crSizeNE : CursorShape := QtSizeBDiagCursor; 139 crSizeW : CursorShape := QtSizeHorCursor; 140 crSizeE : CursorShape := QtSizeHorCursor; 141 crSizeSW : CursorShape := QtSizeBDiagCursor; 142 crSizeS : CursorShape := QtSizeVerCursor; 143 crSizeSE : CursorShape := QtSizeFDiagCursor; 144 crUpArrow : CursorShape := QtUpArrowCursor; 145 crHourGlass : CursorShape := QtWaitCursor; 146 crHSplit : CursorShape := QtSplitHCursor; 147 crVSplit : CursorShape := QtSplitVCursor; 148 crNo : CursorShape := QtForbiddenCursor; 149 crAppStart : CursorShape := QtBusyCursor; 150 crHelp : CursorShape := QtWhatsThisCursor; 151 crHandPoint : CursorShape := QtPointingHandCursor; 152 else 153 CursorShape := QtCursorShape(-1); 154 end; 155 if CursorShape <> QtCursorShape(-1) then 156 Result := HCURSOR(TQtCursor.Create(CursorShape)); 157end; 158 159function TQtWidgetSet.CreateRubberBand(const ARect: TRect; const ABrush: HBrush): HWND; 160begin 161 // todo: think of ABrush 162 Result := HWND(QRubberBand_create(QRubberBandRectangle)); 163 QRubberBand_setGeometry(QRubberBandH(Result), @ARect); 164 QWidget_show(QRubberBandH(Result)); 165end; 166 167procedure TQtWidgetSet.DrawDefaultDockImage(AOldRect, ANewRect: TRect; AOperation: TDockImageOperation); 168begin 169 if FDockImage = nil then 170 FDockImage := QRubberBand_create(QRubberBandRectangle); 171 172 QRubberBand_setGeometry(FDockImage, @ANewRect); 173 case AOperation of 174 disShow: QWidget_show(FDockImage); 175 disHide: QWidget_hide(FDockImage); 176 end; 177end; 178 179procedure TQtWidgetSet.DrawGrid(DC: HDC; const R: TRect; DX, DY: Integer); 180var 181 QtDC: TQtDeviceContext absolute DC; 182 X, Y: Integer; 183 W, H: Integer; 184begin 185 if not IsValidDC(DC) then 186 exit; 187 QtDC.save; 188 try 189 W := (R.Right - R.Left - 1) div DX; 190 H := (R.Bottom - R.Top - 1) div DY; 191 192 for X := 0 to W do 193 for Y := 0 to H do 194 QtDC.drawPoint(R.Left + X * DX, R.Top + Y * DY + 1); 195 finally 196 QtDC.restore; 197 end; 198end; 199 200procedure TQtWidgetSet.DestroyRubberBand(ARubberBand: HWND); 201begin 202 QWidget_destroy(QRubberBandH(ARubberBand)); 203end; 204 205{------------------------------------------------------------------------------ 206 Function: FontIsMonoSpace 207 Params: 208 Returns: 209 ------------------------------------------------------------------------------} 210function TQtWidgetSet.FontIsMonoSpace(Font: HFont): Boolean; 211var 212 QtFontInfo: QFontInfoH; 213begin 214 Result := IsValidGDIObject(Font); 215 if Result then 216 begin 217 QtFontInfo := QFontInfo_create(TQtFont(Font).FHandle); 218 try 219 Result := QFontInfo_fixedPitch(QtFontInfo); 220 finally 221 QFontInfo_destroy(QtFontInfo); 222 end; 223 end; 224end;*) 225 226function TCDWidgetSet.GetAvailableNativeCanvasTypes(DC: HDC; AAllowFallbackToParent: Boolean = False): TNativeCanvasTypes; 227begin 228 Result := [nctLazCanvas]; 229end; 230 231function TCDWidgetSet.GetAvailableNativeHandleTypes(Handle: HWND; AAllowFallbackToParent: Boolean = False): TNativeHandleTypes; 232var 233 lBaseControl: TCDBaseControl absolute Handle; 234begin 235 Result := []; 236 {$ifdef CD_HasNativeFormHandle} 237 if Handle = 0 then Exit; 238 if (lBaseControl is TCDForm) or AAllowFallbackToParent then 239 Result := [CDBackendNativeHandle]; 240 {$endif} 241end; 242 243(*function TQtWidgetSet.GetDesignerDC(WindowHandle: HWND): HDC; 244var 245 Widget: TQtWidget; 246begin 247 Widget := TQtWidget(WindowHandle); 248 249 if (Widget <> nil) and (Widget is TQtDesignWidget) then 250 Result := TQtDesignWidget(Widget).DesignContext 251 else 252 Result := 0; 253 254 if Result = 0 then 255 Result := GetDC(WindowHandle); 256end;*) 257 258function TCDWidgetSet.GetNativeCanvas(DC: HDC; AHandleType: TNativeCanvasType; AAllowFallbackToParent: Boolean = False): PtrInt; 259begin 260 Result := 0; 261 if AHandleType = nctLazCanvas then Result := PtrInt(DC); 262end; 263 264function TCDWidgetSet.GetNativeHandle(Handle: HWND; AHandleType: TNativeHandleType; AAllowFallbackToParent: Boolean = False): PtrInt; 265var 266 lBaseControl: TCDBaseControl absolute Handle; 267 lFormHandle: TCDForm; 268 lForm: TCustomForm; 269begin 270 Result := 0; 271 {$ifdef CD_HasNativeFormHandle} 272 if Handle = 0 then Exit; 273 if (lBaseControl is TCDForm) or AAllowFallbackToParent then 274 begin 275 if (lBaseControl is TCDWinControl) then 276 begin 277 lForm := Forms.GetParentForm((lBaseControl as TCDWinControl).WinControl); 278 if lForm = nil then Exit; 279 lFormHandle := TCDForm(lForm.Handle); 280 end 281 else 282 lFormHandle := TCDForm(lBaseControl); 283 284 if AHandleType = CDBackendNativeHandle then 285 begin 286 Result := lFormHandle.NativeHandle; 287 end; 288 end; 289 {$endif} 290end; 291 292(*function TQtWidgetSet.IsDesignerDC(WindowHandle: HWND; DC: HDC): Boolean; 293begin 294 Result := (WindowHandle <> 0) and (TQtWidget(WindowHandle) is TQtDesignWidget); 295 if Result then 296 Result := TQtDesignWidget(WindowHandle).DesignContext = DC; 297end;*) 298 299function TCDWidgetSet.IsScreenDC(ADC: HDC): Boolean; 300begin 301 Result := (ADC = HDC(Self.ScreenDC)); 302end; 303 304function TCDWidgetSet.IsCDIntfControl(AWinControl: TObject): Boolean; 305begin 306 Result := IsIntfControl(TWinControl(AWinControl)); 307end; 308 309function TCDWidgetSet.RadialPie(DC: HDC; x1, y1, x2, y2, Angle1, Angle2: Integer): Boolean; 310begin 311 Result := IsValidDC(DC); 312{ if Result then 313 QPainter_drawPie(TQtDeviceContext(DC).Widget, x1, y1, x2, y2, Angle1, Angle2);} 314end; 315 316{------------------------------------------------------------------------------ 317 Function: RawImage_CreateBitmaps 318 Params: ARawImage: 319 ABitmap: 320 AMask: 321 ASkipMask: When set, no mask is created 322 Returns: 323 324 This functions is for TBitmap support 325 326 The memory allocation code was added because it is necessary for 327 TBitmap.LoadFromDevice support. For other operations it isnt needed 328 329 Make sure to copy the image into a new buffer here!!! If we just pass the memory 330 from our main TLazIntfImage then it will make a double release and corrupt the memory 331 See bug 21274 332 ------------------------------------------------------------------------------} 333function TCDWidgetSet.RawImage_CreateBitmaps(const ARawImage: TRawImage; out ABitmap, AMask: HBitmap; ASkipMask: Boolean): Boolean; 334var 335 NewData, NewMaskData: PByte; 336 lRawImage: TRawImage; 337 lBitmap: TCDBitmap; 338begin 339 {$ifdef VerboseCDBitmap} 340 DebugLn(Format(':>[TCDWidgetSet.RawImage_CreateBitmaps] ARawImage.Description=%s', [ARawImage.Description.AsString])); 341 {$endif} 342 343 Result := False; 344 ABitmap := 0; 345 AMask := 0; 346 NewMaskData := nil; 347 348 // Copy the data (see bug 21274 as to why it is necessary) 349 if ARawImage.DataSize > 0 then 350 begin 351 NewData := AllocMem(ARawImage.DataSize); 352 System.Move(ARawImage.Data^, NewData^, ARawImage.DataSize); 353 end 354 else 355 NewData := nil; 356 {$ifdef VerboseCDBitmap} 357 DebugLn(Format(':[TCDWidgetSet.RawImage_CreateBitmaps] Data=%x Data size=%d NewData=%x', 358 [PtrUInt(ARawImage.Data), ARawImage.DataSize, PtrUInt(NewData)])); 359 {$endif} 360 361 // this is only a rough implementation, there is no check against bitsperpixel 362 lBitmap := TCDBitmap.Create; 363 ABitmap := HBITMAP(lBitmap); 364 System.Move(ARawImage, lRawImage, SizeOf(TRawImage)); 365 lRawImage.Data := NewData; 366 lRawImage.Mask := nil;//Setting it to NewMaskData crashes 367 lRawImage.Palette := nil; 368 lBitmap.Image := TLazIntfImage.Create(lRawImage, True); 369 Result := ABitmap <> 0; 370 371 // Also create a bitmap for the mask 372 if (not ASkipMask) then 373 begin 374 // The Mask data 375 if (ARawImage.Mask <> nil) and (ARawImage.MaskSize > 0) then 376 begin 377 NewMaskData := GetMem(ARawImage.MaskSize); 378 System.Move(ARawImage.Mask^, NewMaskData^, ARawImage.MaskSize); 379 end 380 else 381 NewMaskData := nil; 382 383 lBitmap := TCDBitmap.Create; 384 AMask := HBITMAP(lBitmap); 385 lRawImage.Description.Init_BPP1(ARawImage.Description.Width, ARawImage.Description.Height); 386 lRawImage.Data := NewMaskData; 387 lRawImage.DataSize := ARawImage.MaskSize; 388 lRawImage.Mask := nil; 389 lRawImage.Palette := nil; 390 lBitmap.Image := TLazIntfImage.Create(lRawImage, True); 391 end; 392 393 {$ifdef VerboseCDBitmap} 394 DebugLn(Format(':<[TCDWidgetSet.RawImage_CreateBitmaps] out ABitmap=%x AMask=%x', [ABitmap, AMask])); 395 {$endif} 396end; 397 398{------------------------------------------------------------------------------ 399 Function: RawImage_DescriptionFromBitmap 400 Params: ABitmap: 401 ADesc: 402 Returns: 403 404 Describes the inner format utilized by CustomDrawn + the specific information for this image 405 ------------------------------------------------------------------------------} 406function TCDWidgetSet.RawImage_DescriptionFromBitmap(ABitmap: HBITMAP; out ADesc: TRawImageDescription): Boolean; 407var 408 CDBitmap: TCDBitmap; 409 lRawImage: TRawImage; 410begin 411 {$ifdef VerboseCDBitmap} 412 DebugLn(Format('[TCDWidgetSet.RawImage_DescriptionFromBitmap] ABitmap=%x', [ABitmap])); 413 {$endif} 414 415 Result := IsValidBitmap(ABitmap); 416 if not Result then 417 begin 418 DebugLn('[RawImage_DescriptionFromBitmap] Invalid ABitmap'); 419 Exit; 420 end; 421 422 CDBitmap := TCDBitmap(ABitmap); 423 424 CDBitmap.Image.GetRawImage(lRawImage); 425 ADesc := lRawImage.Description; 426end; 427 428{------------------------------------------------------------------------------ 429 Function: RawImage_DescriptionFromDevice 430 Params: ADC: 431 ADesc: 432 Returns: 433 ------------------------------------------------------------------------------} 434function TCDWidgetSet.RawImage_DescriptionFromDevice(ADC: HDC; out ADesc: TRawImageDescription): Boolean; 435var 436 lSize: TPoint; 437begin 438 Result := true; 439 440 if ADC = 0 then 441 begin 442 GetDeviceSize(ADC, lSize); 443 ADesc.Init_BPP32_A8R8G8B8_BIO_TTB(lSize.X, lSize.Y); 444 Exit; 445 end; 446 447 ADesc := TLazIntfImage(TLazCanvas(ADC).Image).DataDescription; 448end; 449 450{------------------------------------------------------------------------------ 451 Function: RawImage_FromBitmap 452 Params: ABitmap: 453 AMask: 454 ARect: 455 ARawImage: 456 Returns: 457 458 Creates a raw image from a bitmap 459 ------------------------------------------------------------------------------} 460function TCDWidgetSet.RawImage_FromBitmap(out ARawImage: TRawImage; ABitmap, AMask: HBITMAP; ARect: PRect = nil): Boolean; 461var 462 Desc: TRawImageDescription absolute ARawImage.Description; 463 CDBitmap: TCDBitmap; 464 lBmpRawImage: TRawImage; 465 NewData: PByte; 466 (*var 467 Image: TQtImage absolute ABitmap; 468 Mask: TQtImage absolute AMask; 469 470 WorkImage, WorkMask: TQtImage; 471 R: TRect; 472 Width, Height: Integer; 473 InvertPixels: Boolean; 474 Px: QRgb;*) 475begin 476 {$ifdef VerboseCDBitmap} 477 DebugLn(Format('[TCDWidgetSet.RawImage_FromBitmap] ABitmap=%x', [ABitmap])); 478 {$endif} 479 480 Result := IsValidBitmap(ABitmap); 481 if not Result then 482 begin 483 DebugLn('[RawImage_FromBitmap] Invalid ABitmap'); 484 Exit; 485 end; 486 487 CDBitmap := TCDBitmap(ABitmap); 488 489 ARawImage.Init; 490 RawImage_DescriptionFromBitmap(ABitmap, Desc); 491 492 // Copy the data 493 CDBitmap.Image.GetRawImage(lBmpRawImage); 494 if lBmpRawImage.DataSize > 0 then 495 begin 496 NewData := AllocMem(lBmpRawImage.DataSize); 497 System.Move(lBmpRawImage.Data^, NewData^, lBmpRawImage.DataSize); 498 end 499 else 500 NewData := nil; 501 502 ARawImage.Data := NewData; 503 ARawImage.DataSize := lBmpRawImage.DataSize; 504 505(* if ARect = nil 506 then begin 507 Width := Image.Width; 508 Height := Image.Height; 509 R := Rect(0, 0, Width, Height) 510 end 511 else begin 512 R := ARect^; 513 Width := R.Right - R.Left; 514 Height := R.Bottom - R.Top; 515 end; 516 517 if (Width = Image.Width) and (Height = Image.Height) 518 then begin 519 WorkImage := Image; 520 WorkMask := Mask; 521 end 522 else begin 523 WorkImage := TQtImage.Create; 524 WorkImage.CopyFrom(Image.FHandle, R.Left, R.Top, Width, Height); 525 if Mask <> nil then 526 begin 527 WorkMask := TQtImage.Create; 528 WorkMask.CopyFrom(Mask.FHandle, R.Left, R.Top, Width, Height); 529 end 530 else 531 WorkMask := nil; 532 end; 533 534 Desc.Width := WorkImage.width; 535 Desc.Height := WorkImage.height; 536 537 // copy data 538 ARawImage.DataSize := WorkImage.numBytes; 539 ReAllocMem(ARawImage.Data, ARawImage.DataSize); 540 if ARawImage.DataSize > 0 then 541 Move(WorkImage.bits^, ARawImage.Data^, ARawImage.DataSize); 542 543 if WorkMask <> nil then 544 begin 545 Desc.MaskLineEnd := rileDWordBoundary; 546 Desc.MaskBitOrder := riboReversedBits; 547 Desc.MaskBitsPerPixel := 1; 548 ARawImage.MaskSize := WorkMask.numBytes; 549 ReAllocMem(ARawImage.Mask, ARawImage.MaskSize); 550 if ARawImage.MaskSize > 0 then 551 begin 552 InvertPixels := False; 553 if WorkImage <> nil then 554 begin 555 Px := QImage_pixel(WorkImage.FHandle, 0, 0); 556 InvertPixels := 557 not QImage_hasAlphaChannel(WorkMask.FHandle) and 558 not QImage_hasAlphaChannel(WorkImage.FHandle) and 559 // invert only if WorkImage is RGB32 fmt and allGray 560 (WorkImage.getFormat = QImageFormat_RGB32) and 561 QImage_allGray(WorkImage.FHandle) and 562 ((Px = 0) or (Px = $FF)) 563 end; 564 if InvertPixels then 565 WorkMask.invertPixels(QImageInvertRGB); 566 Move(WorkMask.bits^, ARawImage.Mask^, ARawImage.MaskSize); 567 if InvertPixels then 568 WorkMask.invertPixels(QImageInvertRGB); 569 end; 570 end; 571 572 if WorkImage <> Image then 573 WorkImage.Free; 574 if WorkMask <> Mask then 575 WorkMask.Free;*) 576 577 Result := True; 578end; 579 580(*{------------------------------------------------------------------------------ 581 Function: RawImage_FromDevice 582 Params: ADC: 583 ARect: 584 ARawImage: 585 Returns: 586 587 This function is utilized when the function TBitmap.LoadFromDevice is called 588 589 The main use for this function is to get a screenshot. It may have other uses, 590 but this is the only one implemented here. 591 592 MWE: exept for the desktop, there is always a bitmep selected in the DC. 593 So get this internal bitmap and pass it to RawImage_FromBitmap 594 ------------------------------------------------------------------------------} 595function TQtWidgetSet.RawImage_FromDevice(out ARawImage: TRawImage; ADC: HDC; const ARect: TRect): Boolean; 596var 597 Desc: TRawImageDescription absolute ARawImage.Description; 598 599 //SrcWidth, SrcHeight: Integer; 600 WinID: Cardinal; 601 DCSize: TSize; 602 Pixmap: TQtPixmap; 603 Image: QImageH; 604 Context: TQtDeviceContext; 605 606 procedure RawImage_FromImage(AImage: QImageH); 607 begin 608 ARawImage.DataSize := QImage_numBytes(AImage); 609 ARawImage.Data := GetMem(ARawImage.DataSize); 610 Move(QImage_bits(AImage)^, ARawImage.Data^, ARawImage.DataSize); 611 ARawImage.Mask := nil; 612 end; 613 614begin 615 {$ifdef VerboseQtWinAPI} 616 WriteLn('Trace:> [WinAPI GetRawImageFromDevice] SrcDC: ', dbghex(ADC), 617 ' SrcWidth: ', dbgs(ARect.Right - ARect.Left), 618 ' SrcHeight: ', dbgs(ARect.Bottom - ARect.Top)); 619 {$endif} 620 621 // todo: copy only passed rectangle 622 623 Result := True; 624 625 ARawImage.Init; 626 FillStandardDescription(ARawImage.Description); 627 Context := TQtDeviceContext(ADC); 628 629 with DCSize, Context.getDeviceSize do 630 begin 631 cx := x; 632 cy := y; 633 end; 634 635 if Context.Parent <> nil then 636 begin 637 Pixmap := TQtPixmap.Create(@DCSize); 638 WinID := QWidget_winId(Context.Parent); 639 try 640 // if you have dual monitors then getDeviceSize return 641 // more width than screen width, but grabWindow will only grab one 642 // screen, so its width will be less 643 // Solution: we can either pass prefered size to grabWindow or 644 // correct Description size after. I see the first solution as more correct. 645 Pixmap.grabWindow(WinID, 0, 0, DCSize.cx, DCSize.cy); 646 Image := QImage_Create; 647 Pixmap.toImage(Image); 648 RawImage_FromImage(Image); 649 QImage_destroy(Image); 650 finally 651 Pixmap.Free; 652 end; 653 end else 654 begin 655 if Context.vImage <> nil then 656 RawImage_FromImage(Context.vImage.FHandle) 657 else 658 if Context.ParentPixmap <> nil then 659 begin 660 Image := QImage_create(); 661 QPixmap_toImage(Context.ParentPixmap, Image); 662 RawImage_FromImage(Image); 663 QImage_destroy(Image); 664 end else 665 Result := False; 666 end; 667 668 // In this case we use the size of the context 669 Desc.Width := DCSize.cx; 670 Desc.Height := DCSize.cy; 671 672 {$ifdef VerboseQtWinAPI} 673 WriteLn('Trace:< [WinAPI GetRawImageFromDevice]'); 674 {$endif} 675end;*) 676 677{------------------------------------------------------------------------------ 678 Function: RawImage_QueryDescription 679 Params: AFlags: 680 ADesc: 681 Returns: 682 ------------------------------------------------------------------------------} 683function TCDWidgetSet.RawImage_QueryDescription(AFlags: TRawImageQueryFlags; var ADesc: TRawImageDescription): Boolean; 684begin 685 {$ifdef VerboseCDBitmap} 686 DebugLn(Format('[TCDWidgetSet.RawImage_QueryDescription] AFlags=%s', [RawImageQueryFlagsToString(AFlags)])); 687 {$endif} 688 689 // The default implementation is good enough, don't change this without a very good reason 690 Result := inherited RawImage_QueryDescription(AFlags, ADesc); 691end; 692 693(*function TQtWidgetSet.ReleaseDesignerDC(Window: HWND; DC: HDC): Integer; 694begin 695 Result := 1; 696end; 697 698procedure TQtWidgetSet.RemoveEventHandler(var AHandler: PEventHandler); 699var 700 wheh: PWaitHandleEventHandler; 701 i: QSocketNotifierType; 702begin 703 wheh := PWaitHandleEventHandler(aHandler); 704 FSocketEventMap.Delete(wheh^.socket); // delete from the map 705 706 for i := QSocketNotifierRead to QSocketNotifierException do 707 if Assigned(wheh^.qsn[i]) then begin 708 QSocketNotifier_destroy(wheh^.qsn[i]); 709 QSocketNotifier_hook_destroy(wheh^.qsn_hook[i]); 710 end; 711 dispose(wheh); 712 aHandler := nil; 713end; 714 715procedure TQtWidgetSet.RemovePipeEventHandler(var AHandler: PPipeEventHandler); 716begin 717 // todo 718end; 719 720procedure TQtWidgetSet.RemoveProcessEventHandler(var AHandler: PProcessEventHandler); 721begin 722 // todo 723end; 724 725procedure TQtWidgetSet.SetEventHandlerFlags(AHandler: PEventHandler; 726 NewFlags: dword); 727var 728 wheh: PWaitHandleEventHandler; 729 do_read: boolean; 730 do_write: boolean; 731 do_error: boolean; 732begin 733 wheh := PWaitHandleEventHandler(aHandler); 734 735 do_read := NewFlags and EVE_IO_READ = EVE_IO_READ; 736 do_write := NewFlags and EVE_IO_WRITE = EVE_IO_WRITE; 737 do_error := NewFlags and EVE_IO_ERROR = EVE_IO_ERROR; 738 739 QSocketNotifier_setEnabled(wheh^.qsn[QSocketNotifierRead], do_read); 740 QSocketNotifier_setEnabled(wheh^.qsn[QSocketNotifierWrite], do_write); 741 QSocketNotifier_setEnabled(wheh^.qsn[QSocketNotifierException], do_error); 742end; 743 744procedure TQtWidgetSet.SetRubberBandRect(const ARubberBand: HWND; const ARect: TRect); 745begin 746 QRubberBand_setGeometry(QRubberBandH(ARubberBand), @ARect); 747end;*) 748 749{$ifndef CD_HasNativeSelectItemDialog} 750function TCDWidgetset.ShowSelectItemDialog(const AItems: TStrings; APos: TPoint): Boolean; 751var 752 i: Integer; 753 lPopUpMenu: TPopUpMenu; 754 lCurItem: TMenuItem; 755begin 756 lPopUpMenu := TPopUpMenu.Create(nil); 757 for i := 0 to AItems.Count-1 do 758 begin 759 lCurItem := TMenuItem.Create(lPopUpMenu); 760 lPopUpMenu.Items.Add(lCurItem); 761 lCurItem.Caption := AItems[i]; 762 end; 763 lPopUpMenu.OnClose := @HandleSelectItemDialogClose; 764 lPopUpMenu.PopUp(APos.X, APos.Y); 765 Result := True; 766end; 767 768procedure TCDWidgetset.HandleSelectItemDialogClose(ASender: TObject); 769begin 770 //ASender.Free; Crashes in X11 =( Fix me!!! 771end; 772 773{$endif} 774 775(*function TQtWidgetSet.TextUTF8Out(DC: HDC; X, Y: Integer; Str: PChar; Count: Longint): Boolean; 776begin 777 Result := False; 778 if IsValidDC(DC) then 779 Result := TextOut(DC, X, Y, Str, Count); 780end;*) 781 782//##apiwiz##eps## // Do not remove, no wizard declaration after this line 783