1{%MainUnit customdrawnint.pp} 2{****************************************************************************** 3 All CustomDrawn backend independent Winapi implementations. 4 5 !! Keep alphabetical !! 6 7 8 ****************************************************************************** 9 Implementation 10 ****************************************************************************** 11 12 ***************************************************************************** 13 This file is part of the Lazarus Component Library (LCL) 14 15 See the file COPYING.modifiedLGPL.txt, included in this distribution, 16 for details about the license. 17 ***************************************************************************** 18} 19 20//##apiwiz##sps## // Do not remove, no wizard declaration before this line 21 22{------------------------------------------------------------------------------ 23 Function: Arc 24 Params: DC: HDC; Left,Top,Right,Bottom,angle1,angle2 : Integer 25 Returns: Boolean 26 ------------------------------------------------------------------------------} 27function TCDWidgetSet.Arc(DC: HDC; Left,Top,Right,Bottom,angle1,angle2 : Integer): Boolean; 28var 29 LazDC: TLazCanvas absolute DC; 30begin 31 {$ifdef VerboseCDWinAPI} 32 DebugLn(Format(':>[WinAPI Polygon] DC=%s', [dbghex(DC)])); 33 {$endif} 34 35 if not IsValidDC(DC) then Exit(False); 36 37 //LazDC.Arc(...); 38 Result := True; 39end; 40 41(*{------------------------------------------------------------------------------ 42 Function: AngleChord 43 Params: DC: HDC; x1, y1, x2, y2, angle1, angle2: Integer 44 Returns: Boolean 45 ------------------------------------------------------------------------------} 46function TQtWidgetSet.AngleChord(DC: HDC; x1, y1, x2, y2, angle1, angle2: Integer): Boolean; 47begin 48 {$ifdef VerboseQtWinAPI} 49 WriteLn('[WinAPI AngleChord] DC: ', dbghex(DC)); 50 {$endif} 51 Result := IsValidDC(DC); 52 if Result then 53 QPainter_drawChord(TQtDeviceContext(DC).Widget, x1, y1, x2, y2, Angle1, Angle2); 54end;*) 55 56{------------------------------------------------------------------------------ 57 Function: BeginPaint 58 Params: 59 Returns: 60 61 This function is Called: 62 - Once on every OnPaint event 63 ------------------------------------------------------------------------------} 64function TCDWidgetSet.BeginPaint(Handle: hWnd; Var PS : TPaintStruct): hdc; 65begin 66 {$ifdef VerboseCDDrawing} 67 DebugLn('Trace:> [WinAPI BeginPaint] Handle=', dbghex(Handle)); 68 {$endif} 69 Result := 0; 70 71 if Handle = 0 then Exit; 72 73 (* Widget := TQtWidget(Handle); 74 if Widget <> nil then 75 DC := TQtDeviceContext.Create(Widget.PaintData.PaintWidget, True) 76 else 77 DC := TQtDeviceContext.Create(nil, True); 78 79 PS.hdc := HDC(DC); 80 81 if Handle<>0 then 82 begin 83 // if current handle has paintdata information, 84 // setup hdc with it 85 //DC.DebugClipRect('BeginPaint: Before'); 86 if Widget.PaintData.ClipRegion <> nil then 87 begin 88 //Write('>>> Setting Paint ClipRegion: '); 89 //DebugRegion('PaintData.ClipRegion: ', Widget.PaintData.ClipRegion); 90 DC.setClipRegion(Widget.PaintData.ClipRegion); 91 DC.setClipping(True); 92 end; 93 if Widget.PaintData.ClipRect <> nil then 94 begin 95 New(DC.vClipRect); 96 DC.vClipRect^ := Widget.PaintData.ClipRect^; 97 end; 98 end; 99 100 Result := PS.hdc; 101 102 {$ifdef VerboseQtWinAPI} 103 WriteLn('Trace:< [WinAPI BeginPaint] Result=', dbghex(Result)); 104 {$endif}*) 105end; 106 107function TCDWidgetSet.BitBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC; XSrc, YSrc: Integer; Rop: DWORD): Boolean; 108begin 109 {$ifdef VerboseCDDrawing} 110 WriteLn('Trace:> [TCDWidgetSet.BitBlt]'); 111 {$endif} 112 113 Result := StretchBlt(DestDC, X, Y, Width, Height, SrcDC, XSrc, YSrc, Width, 114 Height, ROP); 115 116 {$ifdef VerboseCDDrawing} 117 WriteLn('Trace:< [TCDWidgetSet.BitBlt]'); 118 {$endif} 119end; 120 121(*function TQtWidgetSet.CallNextHookEx(hHk: HHOOK; ncode : Integer; wParam: WParam; lParam : LParam) : Integer; 122begin 123 {$ifdef VerboseQtWinAPI_MISSING_IMPLEMENTATION} 124 WriteLn('***** [WinAPI TQtWidgetSet.CallNextHookEx] missing implementation '); 125 {$endif} 126 Result := 0; 127end; 128 129function TQtWidgetSet.CallWindowProc(lpPrevWndFunc : TFarProc; Handle : HWND; Msg : UINT; wParam: WParam; lParam : lParam) : Integer; 130begin 131 {$ifdef VerboseQtWinAPI_MISSING_IMPLEMENTATION} 132 WriteLn('***** [WinAPI TQtWidgetSet.CallWindowProc] missing implementation '); 133 {$endif} 134 Result := -1; 135end; 136 137{------------------------------------------------------------------------------ 138 Method: ClientToScreen 139 Params: Handle - 140 Returns: 141 ------------------------------------------------------------------------------} 142function TQtWidgetSet.ClientToScreen(Handle: HWND; var P: TPoint) : Boolean; 143var 144 APoint: TQtPoint; 145 Pt: TPoint; 146begin 147 Result := IsValidHandle(Handle); 148 if Result then 149 begin 150 APoint := QtPoint(P.X, P.Y); 151 152 QWidget_mapToGlobal(TQtWidget(Handle).GetContainerWidget, @APoint, @APoint); 153 if TQtWidget(Handle).ChildOfComplexWidget = ccwScrollingWinControl then 154 begin 155 Pt := TQtCustomControl(Handle).viewport.ScrolledOffset; 156 dec(APoint.X, Pt.X); 157 dec(APoint.Y, Pt.Y); 158 end; 159 P := Point(APoint.x, APoint.y); 160 end; 161end;*) 162 163{------------------------------------------------------------------------------ 164 Method: ClipboardFormatToMimeType 165 Params: FormatID - a registered format identifier (can't be a predefined format) 166 Returns: the corresponding mime type as string 167 ------------------------------------------------------------------------------} 168function TCDWidgetSet.ClipboardFormatToMimeType(FormatID: TClipboardFormat): string; 169begin 170 {$ifdef VerboseCDClipboard} 171 DebugLn(Format('[TCDWidgetSet.ClipboardFormatToMimeType] FormatID=%d', [FormatID])); 172 {$endif} 173 if FClipBoardFormats.Count > Integer(FormatID) then 174 Result := FClipBoardFormats[FormatID] 175 else 176 Result := ''; 177end; 178 179function TCDWidgetSet.ClipboardGetFormats(ClipboardType: TClipboardType; 180 var Count: integer; var List: PClipboardFormat): boolean; 181var 182 i: Integer; 183 Str: string; 184begin 185 {$ifdef VerboseCDClipboard} 186 DebugLn('[TCDWidgetSet.GenericClipboardGetFormats]'); 187 {$endif} 188 Result := False; 189 Count := 0; 190 List := nil; 191 192 Count := FClipBoardFormats.Count; 193 GetMem(List, Count * SizeOf(TClipboardFormat)); 194 195 for i := 0 to Count - 1 do 196 begin 197 Str := FClipBoardFormats.Strings[i]; 198 List[i] := ClipboardRegisterFormat(Str); 199 end; 200 201 Result := True; 202end; 203 204{------------------------------------------------------------------------------ 205 Method: ClipboardRegisterFormat 206 Params: AMimeType - a string (usually a MIME type) identifying a new format 207 type to register 208 Returns: the registered Format identifier (TClipboardFormat) 209 ------------------------------------------------------------------------------} 210function TCDWidgetSet.ClipboardRegisterFormat(const AMimeType: string): TClipboardFormat; 211var 212 Index: Integer; 213begin 214 Index := FClipBoardFormats.IndexOf(AMimeType); 215 if Index < 0 then 216 Index := FClipBoardFormats.Add(AMimeType); 217 Result := Index; 218 {$ifdef VerboseCDClipboard} 219 DebugLn(Format('[TCDWidgetSet.ClipboardRegisterFormat] AMimeType=%s Result=%d', [AMimeType, Index])); 220 {$endif} 221end; 222 223{------------------------------------------------------------------------------ 224 Function: CombineRgn 225 Params: Dest, Src1, Src2, fnCombineMode 226 Returns: longint 227 228 Combine the 2 Source Regions into the Destination Region using the specified 229 Combine Mode. The Destination must already be initialized. The Return value 230 is the Destination's Region type, or ERROR. 231 232 The Combine Mode can be one of the following: 233 RGN_AND : Gets a region of all points which are in both source regions 234 235 RGN_COPY : Gets an exact copy of the first source region 236 237 RGN_DIFF : Gets a region of all points which are in the first source 238 region but not in the second.(Source1 - Source2) 239 240 RGN_OR : Gets a region of all points which are in either the first 241 source region or in the second.(Source1 + Source2) 242 243 RGN_XOR : Gets all points which are in either the first Source Region 244 or in the second, but not in both. 245 246 The result can be one of the following constants 247 Error 248 NullRegion 249 SimpleRegion 250 ComplexRegion 251 ------------------------------------------------------------------------------} 252function TCDWidgetSet.CombineRgn(Dest, Src1, Src2: HRGN; fnCombineMode: Longint): Longint; 253var 254 DestRgn: TLazRegion absolute Dest; 255 Src1Rgn: TLazRegion absolute Src1; 256 Src2Rgn: TLazRegion absolute Src2; 257begin 258 Result := ERROR; 259 260 if not IsValidGDIObject(Dest) or not IsValidGDIObject(Src1) then Exit; 261 262 if (fnCombineMode<>RGN_COPY) and not IsValidGDIObject(Src2) then Exit; 263 264 // If the operation is a copy, execute it now, as it will not involve Src2 265 // The common code would not work in this case 266 if fnCombineMode = RGN_COPY then 267 begin 268 if Dest <> Src1 then DestRgn.Assign(Src1Rgn); 269 Result := DestRgn.GetRegionKind(); 270 Exit; 271 end; 272 273 // Now operations which involve Src2, consider both cases: Dest=Src1 and Dest<>Src1 274 if Dest = Src1 then 275 DestRgn.CombineWith(Src2Rgn, fnCombineMode) 276 else 277 begin 278 DestRgn.Assign(Src1Rgn); 279 DestRgn.CombineWith(Src2Rgn, fnCombineMode); 280 end; 281 282 Result := DestRgn.GetRegionKind(); 283end; 284 285{------------------------------------------------------------------------------ 286 Method: CreateBitmap 287 Params: 288 Returns: 289 290 This functions is for TBitmap support. 291 Specifically it is utilized on when a handle for a bitmap is needed 292 ------------------------------------------------------------------------------} 293function TCDWidgetSet.CreateBitmap(Width, Height: Integer; 294 Planes, BitCount: Longint; BitmapBits: Pointer): HBITMAP; 295var 296 lRawImage: TRawImage; 297 lMask: HBitmap; 298 NewBits: Pointer; 299 NewBitsSize: PtrUInt; 300 RSS: PtrUInt; 301 ARowStride: PtrUInt; 302begin 303 {$ifdef VerboseCDBitmap} 304 DebugLn('Trace:> [WinAPI CreateBitmap]', 305 ' Width:', dbgs(Width), 306 ' Height:', dbgs(Height), 307 ' Planes:', dbgs(Planes), 308 ' BitCount:', dbgs(BitCount), 309 ' BitmapBits: ', dbgs(BitmapBits)); 310 {$endif} 311 312 // for win32 data is aligned to WORD 313 // for ARM speed optimization the best is realign data to DWORD 314 315 Result := 0; 316 NewBits := nil; 317 lRawImage.Init; 318 319 case BitCount of 320 1: lRawImage.Description.Init_BPP1(Width, Height); 321 15, 16: lRawImage.Description.Init_BPP16_R5G6B5(Width, Height); 322 24: lRawImage.Description.Init_BPP24_B8G8R8_BIO_TTB(Width, Height); 323 32: lRawImage.Description.Init_BPP32_A8R8G8B8_BIO_TTB(Width, Height); 324 else 325 lRawImage.Description.Init_BPP32_A8R8G8B8_BIO_TTB(Width, Height); 326 end; 327 328 RSS := GetBytesPerLine(Width, BitCount, rileWordBoundary); 329 if BitmapBits <> nil then 330 begin 331 {$ifdef VerboseCDBitmap} 332 DebugLn('Trace: [WinAPI CreateBitmap] BitmapBits <> nil'); 333 {$endif} 334 ARowStride := GetBytesPerLine(Width, BitCount, rileDWordBoundary); 335 if not CopyImageData(Width, Height, RSS, BitCount, BitmapBits, Types.Rect(0, 0, Width, Height), 336 riloBottomToTop, riloBottomToTop, rileDWordBoundary, NewBits, NewBitsSize) then 337 begin 338 {$ifdef VerboseCDBitmap} 339 DebugLn('Trace: [WinAPI CreateBitmap] CopyImageData failed'); 340 {$endif} 341 // this was never tested 342 ARowStride := RSS; 343 NewBitsSize := RSS * Height; 344 NewBits := AllocMem(NewBitsSize); 345 System.Move(BitmapBits^, NewBits^, NewBitsSize); 346 end; 347 lRawImage.Data := NewBits; 348 lRawImage.DataSize := NewBitsSize; 349 //Result := HBitmap(TQtImage.Create(NewBits, Width, Height, ARowStride, Format, True)); 350 RawImage_CreateBitmaps(lRawImage, Result, lMask, True); 351 end 352 else 353 begin 354 {$ifdef VerboseCDBitmap} 355 DebugLn('Trace: [WinAPI CreateBitmap] Creating Data'); 356 {$endif} 357 lRawImage.CreateData(True); 358 RawImage_CreateBitmaps(lRawImage, Result, lMask, True); 359 end; 360 361 {$ifdef VerboseCDBitmap} 362 DebugLn('Trace:< [WinAPI CreateBitmap] Bitmap:', dbghex(Result)); 363 {$endif} 364end; 365 366{------------------------------------------------------------------------------ 367 Function: CreateBrushIndirect 368 Params: none 369 Returns: Nothing 370 ------------------------------------------------------------------------------} 371function TCDWidgetSet.CreateBrushIndirect(const LogBrush: TLogBrush): HBRUSH; 372var 373 lBrush: TFPCustomBrush; 374begin 375 lBrush := TFPCustomBrush.Create; 376 Result := HBRUSH(lBrush); 377 378 {$ifdef VerboseCDDrawing} 379 DebugLn(Format(':>[TCDWidgetSet.CreateBrushIndirect] Style: %d, Color: %8x Result:%x', 380 [LogBrush.lbStyle, LogBrush.lbColor, Result])); 381 {$endif} 382 383 // brush color 384 lBrush.FPColor := TColorToFPColor(LogBrush.lbColor); 385 386 // brush style 387 case LogBrush.lbStyle of 388 BS_NULL: lBrush.Style := bsClear; // Same as BS_HOLLOW. 389 BS_SOLID: lBrush.Style := bsSolid; 390{ BS_HATCHED: // Hatched brushes. 391 begin 392 case LogBrush.lbHatch of 393 HS_BDIAGONAL: QtBrush.Style := QtBDiagPattern; 394 HS_CROSS: QtBrush.Style := QtCrossPattern; 395 HS_DIAGCROSS: QtBrush.Style := QtDiagCrossPattern; 396 HS_FDIAGONAL: QtBrush.Style := QtFDiagPattern; 397 HS_HORIZONTAL: QtBrush.Style := QtHorPattern; 398 HS_VERTICAL: QtBrush.Style := QtVerPattern; 399 else 400 QtBrush.Style := QtSolidPattern; 401 end; 402 end; 403 404 BS_DIBPATTERN, // A pattern brush defined by a device-independent 405 // bitmap (DIB) specification. If lbStyle is BS_DIBPATTERN, the 406 // lbHatch member contains a handle to a packed DIB.Windows 95: 407 // Creating brushes from bitmaps or DIBs larger than 8x8 pixels 408 // is not supported. If a larger bitmap is given, only a portion 409 // of the bitmap is used. 410 BS_DIBPATTERN8X8, // Same as BS_DIBPATTERN. 411 BS_DIBPATTERNPT, // A pattern brush defined by a device-independent 412 // bitmap (DIB) specification. If lbStyle is BS_DIBPATTERNPT, the 413 // lbHatch member contains a pointer to a packed DIB. 414 BS_PATTERN, // Pattern brush defined by a memory bitmap. 415 BS_PATTERN8X8: // Same as BS_PATTERN. 416 begin 417 QtBrush.setTextureImage(TQtImage(LogBrush.lbHatch).FHandle); 418 QtBrush.Style := QtTexturePattern; 419 end; } 420 else 421 DebugLn(Format('Unsupported Brush Style %d',[LogBrush.lbStyle])); 422 end; 423 424 {$ifdef VerboseCDDrawing} 425 DebugLn(':<[WinAPI CreateBrushIndirect] Result: ', dbghex(Result)); 426 {$endif} 427end; 428 429(*function TQtWidgetSet.CreateCaret(Handle: HWND; Bitmap: hBitmap; Width, Height: Integer): Boolean; 430begin 431 Result := (Handle <> 0) and 432 QtCaret.CreateCaret(TQtWidget(Handle), Bitmap, Width, Height); 433end;*) 434 435{ In LCL-CustomDrawn it is completely irrelevant if a Bitmap is compatible with the screen, 436 so just create any standard bitmap } 437function TCDWidgetSet.CreateCompatibleBitmap(DC: HDC; Width, Height: Integer): HBITMAP; 438begin 439 Result := CreateBitmap(Width, Height, 1, 32, nil); 440end; 441 442{------------------------------------------------------------------------------ 443 Function: CreateCompatibleDC 444 Params: DC - handle to memory device context 445 Returns: handle to a memory device context 446 447 Creates a memory device context (DC) compatible with the specified device. 448 449 This is utilized for example for creating a Canvas for a Bitmap, by later using 450 SelectObject to select the bitmap 451 ------------------------------------------------------------------------------} 452function TCDWidgetSet.CreateCompatibleDC(DC: HDC): HDC; 453begin 454 {$ifdef VerboseCDDrawing} 455 DebugLn('[WinAPI CreateCompatibleDC] DC: ', dbghex(DC)); 456 {$endif} 457 Result := HDC(TLazCanvas.Create(nil)); 458end; 459 460{------------------------------------------------------------------------------ 461 Function: CreateEllipticRgn 462 Params: p1 - X position of the top-left corner 463 p2 - Y position of the top-left corner 464 p3 - X position of the bottom-right corner 465 p4 - Y position of the bottom-right corner 466 Returns: HRGN 467 ------------------------------------------------------------------------------} 468function TCDWidgetSet.CreateEllipticRgn(p1, p2, p3, p4: Integer): HRGN; 469var 470 lRegion: TLazRegion; 471begin 472 {$ifdef VerboseCDRegions} 473 DebugLn('[WinAPI CreateEllipticRgn] '); 474 {$endif} 475 lRegion := TLazRegion.Create; 476 lRegion.AddEllipse(p1, p2, p3, p4); 477 Result := HRGN(lRegion); 478end; 479 480{------------------------------------------------------------------------------ 481 Function: CreateFontIndirect 482 Params: const LogFont: TLogFont 483 Returns: HFONT 484 485 Creates a font GDIObject. 486 ------------------------------------------------------------------------------} 487function TCDWidgetSet.CreateFontIndirect(const LogFont: TLogFont): HFONT; 488begin 489 Result := CreateFontIndirectEx(LogFont, ''); 490end; 491 492{------------------------------------------------------------------------------ 493 Function: CreateFontIndirectEx 494 Params: const LogFont: TLogFont 495 Returns: HFONT 496 497 Creates a font GDIObject. 498 ------------------------------------------------------------------------------} 499function TCDWidgetSet.CreateFontIndirectEx(const LogFont: TLogFont; const LongFontName: string): HFONT; 500var 501 lFont: TLazCDCustomFont; 502// FamilyName: string; 503begin 504 {$ifdef VerboseCDDrawing} 505 DebugLn(Format('[TCDWidgetSet.CreateFontIndirectEx] LongFontName=%s lfHeight=%d', 506 [LongFontName, LogFont.lfHeight])); 507 {$endif} 508 509 lFont := TLazCDCustomFont.Create; 510 Result := HFONT(lFont); 511 512 {$ifndef CD_UseNativeText} 513 lFont.ftFont.Name := BackendGetFontPath(LogFont, LongFontName); 514 lFont.ftFont.Hinted := true; 515 lFont.ftFont.ClearType := true; 516 lFont.ftFont.Quality := grqHighQuality; 517 {$endif} 518 519(*const 520 QStyleStategy: array [DEFAULT_QUALITY..CLEARTYPE_NATURAL_QUALITY] of QFontStyleStrategy = ( 521 { DEFAULT_QUALITY } QFontPreferDefault, 522 { DRAFT_QUALITY } QFontPreferMatch, 523 { PROOF_QUALITY } QFontPreferQuality, 524 { NONANTIALIASED_QUALITY } QFontNoAntialias, 525 { ANTIALIASED_QUALITY } QFontPreferAntialias, 526 { CLEARTYPE_QUALITY } QFontPreferAntialias, 527 { CLEARTYPE_NATURAL_QUALITY } QFontPreferAntialias 528 );*) 529 530 lFont.Size := Abs(LogFont.lfHeight); 531 532(* // Some values at available on Qt documentation at a table 533 // Others are guesses. The best would be to test different values for those 534 // See: http://doc.trolltech.com/4.1/qfont.html#Weight-enum 535 case LogFont.lfWeight of 536 FW_THIN : QtFont.setWeight(10); 537 FW_EXTRALIGHT : QtFont.setWeight(15); 538 FW_LIGHT : QtFont.setWeight(25); 539 FW_NORMAL : QtFont.setWeight(50); 540 FW_MEDIUM : QtFont.setWeight(55); 541 FW_SEMIBOLD : QtFont.setWeight(63); 542 FW_BOLD : QtFont.setWeight(75); 543 FW_EXTRABOLD : QtFont.setWeight(80); 544 FW_HEAVY : QtFont.setWeight(87); 545 end; 546 547 QtFont.Angle := LogFont.lfEscapement; 548 549 //LogFont.lfOrientation; 550 551 QtFont.setItalic(LogFont.lfItalic = High(Byte)); 552 QtFont.setUnderline(LogFont.lfUnderline = High(Byte)); 553 QtFont.setStrikeOut(LogFont.lfStrikeOut = High(Byte)); 554 555 FamilyName := StrPas(LogFont.lfFaceName); 556 557 if (CompareText(FamilyName, 'default') <> 0) then 558 QtFont.setFamily(FamilyName) 559 else 560 QtFont.setFamily(UTF16ToUTF8(GetDefaultAppFontName)); 561 562 if (LogFont.lfQuality >= Low(QStyleStategy)) and (LogFont.lfQuality <= High(QStyleStategy)) then 563 QtFont.setStyleStrategy(QStyleStategy[LogFont.lfQuality]);*) 564end; 565 566function TCDWidgetSet.CreateIconIndirect(IconInfo: PIconInfo): HICON; 567//var 568// AIcon: TCDIcon; 569{ APixmap, ATemp: QPixmapH; 570 AMask: QBitmapH;} 571begin 572 Result := 0; 573{ if IsValidGDIObject(IconInfo^.hbmColor) then 574 begin 575 APixmap := QPixmap_create(); 576 QPixmap_fromImage(APixmap, TQtImage(IconInfo^.hbmColor).FHandle); 577 if IconInfo^.hbmMask <> 0 then 578 begin 579 ATemp := QPixmap_create(); 580 QPixmap_fromImage(ATemp, TQtImage(IconInfo^.hbmMask).FHandle); 581 AMask := QBitmap_create(ATemp); 582 QPixmap_setMask(APixmap, AMask); 583 QPixmap_destroy(ATemp); 584 QBitmap_destroy(AMask); 585 end; 586 if IconInfo^.fIcon then 587 begin 588 AIcon := TQtIcon.Create; 589 AIcon.addPixmap(APixmap); 590 Result := HICON(AIcon); 591 end else 592 Result := HCURSOR(TQtCursor.Create(APixmap, IconInfo^.xHotspot, IconInfo^.yHotspot)); 593 QPixmap_destroy(APixmap); 594 end;} 595end; 596 597(*{------------------------------------------------------------------------------ 598 Function: CreatePatternBrush 599 Params: HBITMAP 600 Returns: HBRUSH 601 ------------------------------------------------------------------------------} 602function TCDWidgetSet.CreatePatternBrush(ABitmap: HBITMAP): HBRUSH; 603{var 604 Image: QImageH; 605 QtBrush: TQtBrush;} 606begin 607 {$ifdef VerboseQtWinAPI} 608 WriteLn('[WinAPI CreatePatternBrush]',' Bitmap=', dbghex(ABitmap)); 609 {$endif} 610 Result := 0; 611{ if ABitmap = 0 then 612 exit; 613 QtBrush := TQtBrush.Create(True); 614 Image := QImage_create(TQtImage(ABitmap).FHandle); 615 try 616 QtBrush.setTextureImage(Image); 617 finally 618 QImage_destroy(Image); 619 end; 620 621 Result := //HBRUSH(QtBrush);} 622end;*) 623 624{------------------------------------------------------------------------------ 625 Function: CreatePenIndirect 626 Params: none 627 Returns: HPEN 628 ------------------------------------------------------------------------------} 629function TCDWidgetSet.CreatePenIndirect(const LogPen: TLogPen): HPEN; 630var 631 lPen: TFPCustomPen; 632begin 633 lPen := TFPCustomPen.Create; 634 Result := HBRUSH(lPen); 635 636 {$ifdef VerboseCDDrawing} 637 DebugLn(Format(':>[TCDWidgetSet.CreatePenIndirect] Style: %d, Color: %8x Result:"%x', 638 [LogPen.lopnStyle, LogPen.lopnColor, Result])); 639 {$endif} 640 641 lPen.FPColor := TColorToFPColor(LogPen.lopnColor); 642 643 case LogPen.lopnStyle and PS_STYLE_MASK of 644 PS_SOLID: lPen.Style := psSolid; 645 PS_DASH: lPen.Style := psDash; 646 PS_DOT: lPen.Style := psDot; 647 PS_DASHDOT: lPen.Style := psDashDot; 648 PS_DASHDOTDOT:lPen.Style := psDashDotDot; 649 PS_NULL: lPen.Style := psClear; 650 else 651 lPen.Style := psSolid; 652 end; 653 654 lPen.Width := Max(1, LogPen.lopnWidth.X); 655end; 656 657{------------------------------------------------------------------------------ 658 Function: CreatePolygonRgn 659 Params: none 660 Returns: HRGN 661 ------------------------------------------------------------------------------} 662function TCDWidgetSet.CreatePolygonRgn(Points: PPoint; NumPts: Integer; FillMode: integer): HRGN; 663var 664 lLazRegion: TLazRegion; 665 lPoints: array of TPoint; 666 i: Integer; 667 lFillMode: TLazRegionFillMode; 668begin 669 lLazRegion := TLazRegion.Create; 670 SetLength(lPoints, NumPts); 671 for i := 0 to NumPts-1 do 672 lPoints[i] := Points[i]; 673 674 {fillmode can be ALTERNATE or WINDING as msdn says} 675 if FillMode = ALTERNATE then lFillMode := rfmOddEven 676 else lFillMode := rfmWinding; 677 678 lLazRegion.AddPolygon(lPoints, lFillMode); 679 Result := HRGN(lLazRegion); 680 681 {$ifdef VerboseCDWinAPI} 682 DebugLn('[WinAPI CreatePolygonRgn] Result: ', dbghex(Result)); 683 {$endif} 684end; 685 686{------------------------------------------------------------------------------ 687 Function: CreateRectRgn 688 Params: none 689 Returns: HRGN 690 ------------------------------------------------------------------------------} 691function TCDWidgetSet.CreateRectRgn(X1,Y1,X2,Y2 : Integer): HRGN; 692var 693 lLazRegion: TLazRegion; 694begin 695 lLazRegion := TLazRegion.Create; 696 lLazRegion.SetAsSimpleRectRegion(Types.Rect(X1, Y1, X2, Y2)); 697 Result := HRGN(lLazRegion); 698 {$ifdef VerboseCDWinAPI} 699 DebugLn('Trace: [WinAPI CreateRectRgn] Result: ', dbghex(Result)); 700 {$endif} 701end; 702 703{------------------------------------------------------------------------------ 704 Procedure: DeleteCriticalSection 705 Params: var CritSection: TCriticalSection 706 Returns: Nothing 707 ------------------------------------------------------------------------------} 708procedure TCDWidgetSet.DeleteCriticalSection(var CritSection: TCriticalSection); 709var 710 ACritSec: System.PRTLCriticalSection; 711begin 712 ACritSec:=System.PRTLCriticalSection(CritSection); 713 System.DoneCriticalsection(ACritSec^); 714 Dispose(ACritSec); 715 CritSection:=0; 716end; 717 718{------------------------------------------------------------------------------ 719 Function: DeleteDC 720 Params: none 721 Returns: Nothing 722 ------------------------------------------------------------------------------} 723function TCDWidgetSet.DeleteDC(hDC: HDC): Boolean; 724begin 725 {$ifdef VerboseCDWinAPI} 726 DebugLn('[WinAPI DeleteDC] Handle: ', dbghex(hDC)); 727 {$endif} 728 729 Result := False; 730 if not IsValidDC(hDC) then exit; 731 Result := True; 732 TLazCanvas(hDC).Free; 733end; 734 735{------------------------------------------------------------------------------ 736 Function: DeleteObject 737 Params: none 738 Returns: Nothing 739 740 ------------------------------------------------------------------------------} 741function TCDWidgetSet.DeleteObject(GDIObject: HGDIOBJ): Boolean; 742var 743 aObject: TObject; 744 {$if defined(VerboseCDDrawing) or defined(VerboseCDBitmap)} 745 ObjType: string; 746 {$endif} 747begin 748 {$if defined(VerboseCDDrawing) or defined(VerboseCDBitmap)} 749 DebugLn('Trace:> [WinAPI DeleteObject] GDIObject: ', dbghex(GDIObject)); 750 ObjType := 'Unidentifyed'; 751 {$endif} 752 753 Result := False; 754 755 if GDIObject = 0 then Exit(True); 756 757 if not IsValidGDIObject(GDIObject) then Exit; 758 759 aObject := TObject(GDIObject); 760 761(* if (aObject is TQtResource) and TQtResource(aObject).FShared then 762 Exit(True);*) 763 764 {------------------------------------------------------------------------------ 765 Font 766 ------------------------------------------------------------------------------} 767 if aObject is TFPCustomFont then 768 begin 769 {$if defined(VerboseCDDrawing) or defined(VerboseCDBitmap)} 770 ObjType := 'Font'; 771 {$endif} 772 end 773 {------------------------------------------------------------------------------ 774 Brush 775 ------------------------------------------------------------------------------} 776 else if aObject is TFPCustomBrush then 777 begin 778 {$if defined(VerboseCDDrawing) or defined(VerboseCDBitmap)} 779 ObjType := 'Brush'; 780 {$endif} 781 end 782 {------------------------------------------------------------------------------ 783 Image 784 ------------------------------------------------------------------------------} 785 else if aObject is TCDBitmap then 786 begin 787 {$if defined(VerboseCDDrawing) or defined(VerboseCDBitmap)} 788 ObjType := 'Image'; 789 {$endif} 790 end 791 {------------------------------------------------------------------------------ 792 Region 793 ------------------------------------------------------------------------------} 794 else if aObject is TLazRegion then 795 begin 796 {$if defined(VerboseCDDrawing) or defined(VerboseCDBitmap)} 797 ObjType := 'Region'; 798 {$endif} 799 end 800 {------------------------------------------------------------------------------ 801 Pen 802 ------------------------------------------------------------------------------} 803 else if aObject is TFPCustomPen then 804 begin 805 {$if defined(VerboseCDDrawing) or defined(VerboseCDBitmap)} 806 ObjType := 'Pen'; 807 {$endif} 808 end; 809 810(* if AObject is TQtResource then 811 if TQtResource(AObject).Owner <> nil then 812 begin 813 // this is an owned (default) resource, let owner free it 814 DebugLn('WARNING: Trying to Free a default resource'); 815 AObject := nil; 816 end;*) 817 818 if AObject <> nil then 819 begin 820 //WriteLn('Delete object: ', PtrUInt(AObject)); 821 FreeThenNil(AObject); 822 end; 823 824 Result := True; 825 826 {$if defined(VerboseCDDrawing) or defined(VerboseCDBitmap)} 827 DebugLn('Trace:< [WinAPI DeleteObject] Result=', dbgs(Result), ' ObjectType=', ObjType); 828 {$endif} 829end; 830 831(*function TQtWidgetSet.DestroyCaret(Handle: HWND): Boolean; 832begin 833 Result := (Handle <> 0) and QtCaret.DestroyCaret; 834end; 835 836{------------------------------------------------------------------------------ 837 Method: DestroyIcon 838 Params: Handle 839 Returns: Result of destroying 840 ------------------------------------------------------------------------------} 841 842function TQtWidgetSet.DestroyIcon(Handle: HICON): Boolean; 843begin 844 Result := (Handle <> 0) and 845 ( 846 (TObject(Handle) is TQtIcon) or 847 (TObject(Handle) is TQtCursor) 848 ); 849 if Result then 850 TObject(Handle).Free; 851end; 852 853{------------------------------------------------------------------------------ 854 Method: DPtoLP 855 Params: DC: HDC; var Points; Count: Integer 856 Returns: Boolean 857 ------------------------------------------------------------------------------} 858function TQtWidgetSet.DPtoLP(DC: HDC; var Points; Count: Integer): BOOL; 859var 860 P: PPoint; 861 QtPoint: TQtPoint; 862 Matrix: QTransformH; 863 MatrixInv: QTransformH; 864 QtDC: TQtDeviceContext; 865 Inverted: Boolean; 866begin 867 {$ifdef VerboseQtWinAPI} 868 WriteLn('[WinAPI DPtoLP] '); 869 {$endif} 870 871 Result := False; 872 873 if not IsValidDC(DC) then 874 Exit; 875 876 QtDC := TQtDeviceContext(DC); 877 878 Matrix := QTransform_create; 879 MatrixInv := QTransform_create; 880 QPainter_combinedTransform(QtDC.Widget, Matrix); 881 P := @Points; 882 try 883 while Count > 0 do 884 begin 885 Dec(Count); 886 Inverted := QTransform_isInvertible(Matrix); 887 QTransform_inverted(Matrix, MatrixInv, @Inverted); 888 QtPoint.X := P^.X; 889 QtPoint.Y := P^.Y; 890 QTransform_map(MatrixInv, PQtPoint(@QtPoint), PQtPoint(@QtPoint)); 891 P^.X := QtPoint.X; 892 P^.Y := QtPoint.Y; 893 Inc(P); 894 end; 895 896 Result := True; 897 finally 898 QTransform_destroy(MatrixInv); 899 QTransform_destroy(Matrix); 900 end; 901end; 902 903{------------------------------------------------------------------------------ 904 Method: DrawEdge 905 Params: DC: HDC; var Rect: TRect; edge: Cardinal; grfFlags: Cardinal 906 Returns: Boolean 907 ------------------------------------------------------------------------------} 908function TQtWidgetSet.DrawEdge(DC: HDC; var Rect: TRect; edge: Cardinal; grfFlags: Cardinal): Boolean; 909var 910 Brush: HBRUSH; 911 ColorDark, ColorLight: TColorRef; 912 ClientRect: TRect; 913 QtDC: TQtDeviceContext; 914 915 procedure InternalDrawEdge(Outer: Boolean; const R: TRect); 916 var 917 X1, Y1, X2, Y2: Integer; 918 ColorLeftTop, ColorRightBottom: TColor; 919 EdgeQtColor: TQColor; 920 APen, OldPen: TQtPen; 921 begin 922 X1 := R.Left; 923 Y1 := R.Top; 924 X2 := R.Right; 925 Y2 := R.Bottom; 926 927 ColorLeftTop := clNone; 928 ColorRightBottom := clNone; 929 930 if Outer then 931 begin 932 if Edge and BDR_RAISEDOUTER <> 0 then 933 begin 934 ColorLeftTop := ColorLight; 935 ColorRightBottom := ColorDark; 936 end 937 else if Edge and BDR_SUNKENOUTER <> 0 then 938 begin 939 ColorLeftTop := ColorDark; 940 ColorRightBottom := ColorLight; 941 end; 942 end 943 else 944 begin 945 if Edge and BDR_RAISEDINNER <> 0 then 946 begin 947 ColorLeftTop := ColorLight; 948 ColorRightBottom := ColorDark; 949 end 950 else if Edge and BDR_SUNKENINNER <> 0 then 951 begin 952 ColorLeftTop := ColorDark; 953 ColorRightBottom := ColorLight; 954 end; 955 end; 956 957 if grfFlags and BF_DIAGONAL = 0 then 958 begin 959 960 APen := TQtPen.Create(True); 961 ColorRefToTQColor(TColorRef(ColorLeftTop), EdgeQtColor); 962 APen.setColor(EdgeQtColor); 963 OldPen := QtDC.setPen(APen); 964 965 if grfFlags and BF_LEFT <> 0 then 966 QtDC.DrawLine(X1, Y1, X1, Y2); 967 if grfFlags and BF_TOP <> 0 then 968 QtDC.DrawLine(X1, Y1, X2, Y1); 969 970 QtDC.setPen(OldPen); 971 APen.Free; 972 APen := TQtPen.Create(True); 973 974 ColorRefToTQColor(TColorRef(ColorRightBottom), EdgeQtColor); 975 APen.setColor(EdgeQtColor); 976 OldPen := QtDC.SetPen(APen); 977 978 if grfFlags and BF_RIGHT <> 0 then 979 QtDC.DrawLine(X2, Y1, X2, Y2); 980 if grfFlags and BF_BOTTOM <> 0 then 981 QtDC.DrawLine(X1, Y2, X2, Y2); 982 QtDC.SetPen(OldPen); 983 APen.Free; 984 end 985 else 986 begin 987 988 APen := TQtPen.Create(True); 989 ColorRefToTQColor(TColorRef(ColorLeftTop), EdgeQtColor); 990 APen.setColor(EdgeQtColor); 991 OldPen := QtDC.setPen(APen); 992 993 if (grfFlags and BF_DIAGONAL_ENDTOPLEFT = BF_DIAGONAL_ENDTOPLEFT) or 994 (grfFlags and BF_DIAGONAL_ENDBOTTOMRIGHT = BF_DIAGONAL_ENDBOTTOMRIGHT) then 995 QtDC.DrawLine(X1, Y1, X2, Y2) 996 else 997 QtDC.DrawLine(X1, Y2, X2, Y1); 998 QtDC.setPen(OldPen); 999 APen.Free; 1000 end; 1001 end; 1002 1003begin 1004 {$ifdef VerboseQtWinAPI} 1005 WriteLn('[WinAPI DrawEdge] '); 1006 {$endif} 1007 1008 Result := False; 1009 if not IsValidDC(DC) or IsRectEmpty(Rect) then exit; 1010 1011 QtDC := TQtDeviceContext(DC); 1012 1013 ClientRect := Rect; 1014 Dec(ClientRect.Right, 1); 1015 Dec(ClientRect.Bottom, 1); 1016 QtDC.save; 1017 try 1018 ColorDark := ColorToRGB(cl3DDkShadow); 1019 ColorLight := ColorToRGB(cl3DLight); 1020 if grfFlags and BF_FLAT <> 0 then 1021 ColorLight := clSilver; 1022 if grfFlags and BF_MONO <> 0 then 1023 begin 1024 ColorDark := TColorRef(clBlack); 1025 ColorLight := TColorRef(clWhite); 1026 end; 1027 try 1028 if Edge and (BDR_SUNKENOUTER or BDR_RAISEDOUTER) <> 0 then 1029 InternalDrawEdge(True, ClientRect); 1030 InflateRect(ClientRect, -1, -1); 1031 if grfFlags and BF_MONO = 0 then 1032 begin 1033 ColorLight := ColorToRGB(clBtnHiLight); 1034 ColorDark := ColorToRGB(clBtnShadow); 1035 end; 1036 if Edge and (BDR_SUNKENINNER or BDR_RAISEDINNER) <> 0 then 1037 begin 1038 InternalDrawEdge(False, ClientRect); 1039 InflateRect(ClientRect, -1, -1); 1040 end; 1041 finally 1042 end; 1043 1044 inc(ClientRect.Right); 1045 inc(ClientRect.Bottom); 1046 1047 if grfFlags and BF_MIDDLE <> 0 then 1048 begin 1049 Brush := CreateSolidBrush(TColorRef(clBtnFace)); 1050 try 1051 FillRect(DC, ClientRect, Brush); 1052 finally 1053 DeleteObject(Brush); 1054 end; 1055 end; 1056 1057 if grfFlags and BF_ADJUST <> 0 then 1058 Rect := ClientRect; 1059 1060 Result := True; 1061 finally 1062 QtDC.Restore; 1063 end; 1064 1065end;*) 1066 1067{------------------------------------------------------------------------------ 1068 Method: DrawFocusRect 1069 Params: DC: HDC; const Rect: TRect 1070 Returns: Boolean 1071 ------------------------------------------------------------------------------} 1072function TCDWidgetSet.DrawFocusRect(DC: HDC; const Rect: TRect): boolean; 1073var 1074 LazDC: TLazCanvas absolute DC; 1075begin 1076 {$ifdef VerboseCDWinAPI} 1077 DebugLn(Format('[DrawFocusRect] DC: %x', [PtrUInt(DC)])); 1078 {$endif} 1079 Result := False; 1080 1081 if not IsValidDC(DC) then exit; 1082 1083 // Drawer.DrawFocusRect alters the Pen and Brush, so we save the state here 1084 LazDC.SaveState(); 1085 GetDefaultDrawer().DrawFocusRect(LazDC, Types.Point(Rect.Left, Rect.Top), 1086 Types.Size(Rect.Right - Rect.Left, Rect.Bottom - Rect.Top)); 1087 LazDC.RestoreState(-1); 1088end; 1089 1090function TCDWidgetSet.DrawFrameControl(DC: HDC; const Rect: TRect; uType, 1091 uState: Cardinal): Boolean; 1092var 1093 LazDC: TLazCanvas absolute DC; 1094 lControlStateEx: TCDControlStateEx; 1095 lState: TCDControlState; 1096 lSize: Types.TSize; 1097begin 1098 Result := False; 1099 1100 if not IsValidDC(DC) then 1101 begin 1102 {$ifdef VerboseCDDrawing} 1103 DebugLn(':<[WinAPI DrawFrameControl] Invalid DC!'); 1104 {$endif} 1105 Exit(False); 1106 end; 1107 1108 case uType of 1109 DFC_BUTTON: 1110 begin 1111 lSize := Types.Size(Rect.Right-Rect.Left, Rect.Bottom-Rect.Top); 1112 1113 if (DFCS_BUTTONPUSH and uState) <> 0 then 1114 lControlStateEx := TCDButtonStateEx.Create 1115 else 1116 lControlStateEx := TCDControlStateEx.Create; 1117 1118 try 1119 lControlStateEx.Font := TFont.Create; 1120 lControlStateEx.ParentRGBColor := clSilver; 1121 lControlStateEx.FPParentRGBColor := colSilver; 1122 lControlStateEx.RGBColor := GetDefaultDrawer().FallbackPalette.BtnFace; 1123 lControlStateEx.FPRGBColor := TColorToFPColor(lControlStateEx.RGBColor); 1124 1125 //if uState and DFCS_FLAT <> 0 then lState := [csfEnabled]; 1126 if uState and DFCS_INACTIVE = 0 then lState := lState + [csfEnabled]; 1127 if uState and DFCS_PUSHED <> 0 then lState := lState + [csfSunken]; 1128 1129 if (uState and $1F) in [DFCS_BUTTONCHECK, DFCS_BUTTON3STATE] then 1130 begin 1131 //Element := QStyleCE_CheckBox 1132 end 1133 else if (DFCS_BUTTONRADIO and uState) <> 0 then 1134 begin 1135 //Element := QStyleCE_RadioButton 1136 end 1137 else if (DFCS_BUTTONPUSH and uState) <> 0 then 1138 begin 1139 GetDefaultDrawer().DrawButton(LazDC, Types.Point(0,0), lSize, lState, TCDButtonStateEx(lControlStateEx)); 1140 end 1141 else if (DFCS_BUTTONRADIOIMAGE and uState) <> 0 then 1142 begin 1143 //Element := QStyleCE_RadioButton 1144 //TODO: what to implement here ? 1145 end 1146 else if (DFCS_BUTTONRADIOMASK and uState) <> 0 then 1147 begin 1148 //Element := QStyleCE_RadioButton 1149 //TODO: what to implement here ? 1150 end; 1151 finally 1152 lControlStateEx.Font.Free; 1153 lControlStateEx.Free; 1154 end; 1155 end; 1156 DFC_CAPTION: ; // title bar captions 1157 DFC_MENU: ; // menu 1158 DFC_SCROLL: 1159 begin 1160 end;//DrawScrollBarArrows; 1161 end; 1162 {function uStatetoQStyleState: QStyleState; 1163 begin 1164 Result := QStyleState_None; 1165 if (uState and DFCS_INACTIVE = 0) then 1166 Result := Result or QStyleState_Enabled; 1167 1168 if (uState and DFCS_PUSHED <> 0) then 1169 Result := Result or QStyleState_MouseOver or QStyleState_Sunken 1170 else 1171 Result := Result or QStyleState_Raised; 1172 1173 if (uState and DFCS_CHECKED <> 0) then 1174 Result := Result or QStyleState_On 1175 else 1176 Result := Result or QStyleState_Off; 1177 1178 if ((uState and DFCS_HOT <> 0) or (uState and DFCS_PUSHED <> 0)) then 1179 Result := Result or QStyleState_MouseOver or QStyleState_Active; 1180 1181 if (uType <> DFC_BUTTON) and 1182 ((uState and DFCS_FLAT <> 0) and not (uState and DFCS_PUSHED <> 0)) then 1183 Result := Result and not QStyleState_Raised; 1184 1185 // DFCS_TRANSPARENT = 2048; 1186 //DFCS_ADJUSTRECT = 8192; 1187 //DFCS_FLAT = 16384; 1188 //DFCS_MONO = 32768; 1189 end; 1190 1191 procedure DrawScrollBarArrows; 1192 var 1193 Opt: QStyleOptionH; 1194 Element: QStylePrimitiveElement; 1195 State: QStyleState; 1196 begin 1197 //TODO: DFCS_SCROLLCOMBOBOX and DFCS_SCROLLSIZEGRIP 1198 State := uStatetoQStyleState; 1199 Element := QStylePE_CustomBase; 1200 if (uState and $1F) in [DFCS_SCROLLUP] then 1201 Element := QStylePE_IndicatorArrowUp 1202 else 1203 if (uState and $1F) in [DFCS_SCROLLDOWN] then 1204 Element := QStylePE_IndicatorArrowDown 1205 else 1206 if (uState and $1F) in [DFCS_SCROLLLEFT] then 1207 Element := QStylePE_IndicatorArrowLeft 1208 else 1209 if (uState and $1F) in [DFCS_SCROLLRIGHT] then 1210 Element := QStylePE_IndicatorArrowRight; 1211 1212 if Element = QStylePE_CustomBase then 1213 exit; 1214 Opt := QStyleOption_create(1, 0); 1215 QStyleOption_setRect(Opt, @Rect); 1216 QStyleOption_setState(Opt, State); 1217 QStyle_drawPrimitive(QApplication_style(), Element, Opt, Painter, Widget); 1218 QStyleOption_destroy(Opt); 1219 end;} 1220end; 1221 1222(*{------------------------------------------------------------------------------ 1223 Method: DrawText 1224 Params: DC, Str, Count, Rect, Flags 1225 Returns: If the string was drawn, or CalcRect run 1226 1227 if DT_CALCRECT is one of the Flags passed to this function, then: 1228 1229 * DrawText should not draw the text, but determine the size that would be required to write it. 1230 * If there are multiple lines of text, this function will keep Rect.Width fixed and 1231 expand Rect.Height to fit the text. 1232 * If there is one line of text, Rect is reduced or expanded to fit it. 1233 * The result will the height of the text. 1234 ------------------------------------------------------------------------------} 1235function TQtWidgetSet.DrawText(DC: HDC; Str: PChar; Count: Integer; 1236 var ARect: TRect; Flags: Cardinal): Integer; 1237var 1238 WideStr: WideString; 1239 R: TRect; 1240 QtDC: TQtDeviceContext; 1241 F: Integer; 1242 Pt: TPoint; 1243 ClipRect: TRect; 1244 B: Boolean; 1245 S: String; 1246 i: Integer; 1247 1248 procedure CalculateOffsetWithAngle(const AFontAngle: Integer; 1249 var TextLeft,TextTop: Integer); 1250 var 1251 OffsX, OffsY: integer; 1252 Angle: Integer; 1253 Size: TSize; 1254 begin 1255 OffsX := R.Right - R.Left; 1256 OffsY := R.Bottom - R.Top; 1257 Size.cX := OffsX; 1258 Size.cy := OffsY; 1259 Angle := AFontAngle div 10; 1260 if Angle < 0 then 1261 Angle := 360 + Angle; 1262 1263 if Angle <= 90 then 1264 begin 1265 OffsX := 0; 1266 OffsY := Trunc(Size.cx * sin(Angle * Pi / 180)); 1267 end else 1268 if Angle <= 180 then 1269 begin 1270 OffsX := Trunc(Size.cx * -cos(Angle * Pi / 180)); 1271 OffsY := Trunc(Size.cx * sin(Angle * Pi / 180) + 1272 Size.cy * cos((180 - Angle) * Pi / 180)); 1273 end else 1274 if Angle <= 270 then 1275 begin 1276 OffsX := Trunc(Size.cx * -cos(Angle * Pi / 180) + 1277 Size.cy * sin((Angle - 180) * Pi / 180)); 1278 OffsY := Trunc(Size.cy * sin((270 - Angle) * Pi / 180)); 1279 end else 1280 if Angle <= 360 then 1281 begin 1282 OffsX := Trunc(Size.cy * sin((360 - Angle) * Pi / 180)); 1283 OffsY := 0; 1284 end; 1285 TextTop := OffsY; 1286 TextLeft := OffsX; 1287 end; 1288 1289begin 1290 {$ifdef VerboseQtWinAPI} 1291 WriteLn('[WinAPI DrawText] DC: ', dbghex(DC), ' Str: ', string(Str), 1292 ' CalcRect: ', dbgs((Flags and DT_CALCRECT) = DT_CALCRECT),' ARect ',dbgs(ARect)); 1293 {$endif} 1294 1295 Result := 0; 1296 1297 if not IsValidDC(DC) then 1298 Exit; 1299 1300 QtDC :=TQtDeviceContext(DC); 1301 1302 if Count >= 0 then 1303 WideStr := GetUtf8String(Copy(Str, 1, Count)) 1304 else 1305 WideStr := GetUtf8String(Str); 1306 1307 1308 B := QtDC.getClipping; 1309 if B and 1310 (Flags and DT_NOCLIP = DT_NOCLIP) and 1311 (Flags and DT_WORDBREAK = DT_WORDBREAK) then 1312 begin 1313 ClipRect := QtDC.getClipRegion.getBoundingRect; 1314 //this is just to get same behaviour as gtk2 and win32 1315 //IMO, we should change ARect.Left and/or ARect.Top if smaller than 1316 //clip rect (map to clipRect). Then multiline text is drawn ok. 1317 //look at issue http://bugs.freepascal.org/view.php?id=17678 . zeljko. 1318 if (ARect.Left < ClipRect.Left) or (ARect.Top < ClipRect.Top) then 1319 begin 1320 {$note remove ifdef if I'm wrong about DT_WORDBREAK OBSERVATION} 1321 {$IFDEF QT_DRAWTEXT_MAP_TO_CLIPRECT} 1322 if ARect.Left < ClipRect.Left then 1323 ARect.Left := ClipRect.Left; 1324 if ARect.Top < ClipRect.Top then 1325 ARect.Top := ClipRect.Top; 1326 {$ELSE} 1327 Flags := Flags and not DT_WORDBREAK; 1328 {$ENDIF} 1329 end; 1330 end; 1331 1332 F := DTFlagsToQtFlags(Flags); 1333 1334 QtDC.Metrics.BoundingRect(@R, @ARect, F, @WideStr); 1335 1336 //TODO: result should be different when DT_VCENTER or DT_BOTTOM is set 1337 Result := R.Bottom - R.Top; 1338 1339 if (Flags and DT_CALCRECT) = DT_CALCRECT then 1340 begin 1341 if (Flags and DT_WORDBREAK = DT_WORDBREAK) and 1342 ((R.Bottom - R.Top) > (ARect.Bottom - ARect.Top)) then 1343 // MSDN says do not touch rect width when we have DT_WORDBREAK flag 1344 // and new text is multiline (if R height > ARect height).See #17329. 1345 else 1346 ARect.Right := ARect.Left + R.Right - R.Left; 1347 ARect.Bottom := ARect.Top + R.Bottom - R.Top; 1348 {$ifdef VerboseQtWinAPI} 1349 WriteLn('[WinAPI DrawText] Rect=', dbgs(ARect)); 1350 {$endif} 1351 Exit; 1352 end; 1353 1354 // if our Font.Orientation <> 0 we must recalculate X,Y offset 1355 // also it works only with DT_TOP DT_LEFT. Qt can handle multiline 1356 // text in this case too. 1357 Pt := Point(0, 0); 1358 if (QtDC.Font.Angle <> 0) and 1359 (Flags and DT_VCENTER = 0) and (Flags and DT_CENTER = 0) and 1360 (Flags and DT_RIGHT = 0) and (Flags and DT_BOTTOM = 0) then 1361 begin 1362 Pt := Point(ARect.Left, ARect.Top); 1363 CalculateOffsetWithAngle(QtDC.font.Angle, Pt.X, Pt.Y); 1364 end; 1365 1366 // we cannot fit into rectangle, so use DT_SINGLELINE.See #17329. 1367 // http://msdn.microsoft.com/en-us/library/dd162498%28v=VS.85%29.aspx 1368 if B and 1369 (Flags and DT_NOCLIP = DT_NOCLIP) and 1370 (Flags and DT_WORDBREAK = DT_WORDBREAK) and 1371 (Flags and DT_SINGLELINE = DT_SINGLELINE) and 1372 ((R.Bottom - R.Top) >= (ARect.Bottom - ARect.Top)) then 1373 begin 1374 Flags := Flags and not DT_WORDBREAK; 1375 F := DTFlagsToQtFlags(Flags); 1376 end; 1377 1378 {$warning HARDCODED WORKAROUND for qt-4.7.1 QPainter bug.} 1379 { Bug triggers when we try to paint multiline text which contains 1 1380 space. eg "Save project\nCtrl+S". In this case QPainter draws 1381 Save 1382 project (in two lines, so Ctrl+S is invisible. See issue #18631. 1383 But does not trigger with qt-4.6.XX and maybe with 4.7.0. 1384 Opened nokia issue: http://bugreports.qt.nokia.com/browse/QTBUG-17020 1385 UPDATE: it's fixed in qt-4.7.4 git and qt-4.8} 1386 if (QtVersionMajor = 4) and (QtVersionMinor = 7) and (QtVersionMicro < 4) and 1387 (Flags and DT_WORDBREAK = DT_WORDBREAK) and 1388 ((Flags and DT_VCENTER = DT_VCENTER) or (Flags and DT_CENTER = DT_CENTER)) 1389 and not (Flags and DT_NOCLIP = DT_NOCLIP) and 1390 not (Flags and DT_MODIFYSTRING = DT_MODIFYSTRING) and 1391 not (Flags and DT_END_ELLIPSIS = DT_END_ELLIPSIS) then 1392 begin 1393 S := StrPas(Str); 1394 if length(S) > 0 then 1395 begin 1396 i := Pos(' ', S); 1397 if (AnsiPos(LineEnding, S) > i) and 1398 (S[length(S)] <> LineEnding) then 1399 begin 1400 Flags := Flags and not DT_WORDBREAK; 1401 F := DTFlagsToQtFlags(Flags); 1402 end; 1403 end; 1404 end; 1405 1406 if (Flags and DT_MODIFYSTRING = DT_MODIFYSTRING) and 1407 (Flags and DT_END_ELLIPSIS = DT_END_ELLIPSIS) and 1408 (Flags and DT_WORDBREAK = 0) then 1409 begin 1410 // windows are removing trailing spaces in this case 1411 // and we are doing same thing too. 1412 WideStr := TrimLeft(WideStr); 1413 with ARect do 1414 WideStr := QtDC.Metrics.elidedText(WideStr, QtElideRight, Right - Left, 0); 1415 end; 1416 1417 with ARect do 1418 QtDC.DrawText(Left + Pt.X, Top + Pt.Y, Right-Left, Bottom-Top, F, @WideStr); 1419end;*) 1420 1421{------------------------------------------------------------------------------ 1422 Method: Ellipse 1423 Params: X1, Y1, X2, Y2 1424 Returns: Nothing 1425 1426 Use Ellipse to draw a filled circle or ellipse. 1427 ------------------------------------------------------------------------------} 1428function TCDWidgetSet.Ellipse(DC: HDC; X1, Y1, X2, Y2: Integer): Boolean; 1429var 1430 LazDC: TLazCanvas absolute DC; 1431 R: TRect; 1432begin 1433 {$ifdef VerboseCDDrawing} 1434 DebugLn(Format(':>[WinAPI Ellipse] DC=%s', [dbghex(DC)])); 1435 {$endif} 1436 1437 if not IsValidDC(DC) then 1438 begin 1439 {$ifdef VerboseCDDrawing} 1440 DebugLn(':<[WinAPI Rectangle] Invalid DC!'); 1441 {$endif} 1442 Exit(False); 1443 end; 1444 1445// R := NormalizeRect(Rect(X1, Y1, X2, Y2)); 1446// if IsRectEmpty(R) then Exit(True); 1447 1448 LazDC.Ellipse(X1, Y1, X2, Y2); 1449 Result := True; 1450end; 1451 1452(*function TQtWidgetSet.EnableScrollBar(Wnd: HWND; wSBflags, wArrows: Cardinal): Boolean; 1453begin 1454 {maybe we can put creating of scrollbar here instead of SetScrollInfo() } 1455 Result := False; 1456 {$ifdef VerboseQtWinAPI_MISSING_IMPLEMENTATION} 1457 WriteLn('***** [WinAPI TQtWidgetSet.EnableScrollbar] missing implementation '); 1458 {$endif} 1459end; 1460 1461function TQtWidgetSet.EnableWindow(hWnd: HWND; bEnable: Boolean): Boolean; 1462begin 1463 {$ifdef VerboseQtWinAPI} 1464 WriteLn('[WinAPI EnableWindow] '); 1465 {$endif} 1466 Result := False; 1467 if HWND <> 0 then 1468 begin 1469 Result := not TQtWidget(hwnd).getEnabled; 1470 TQtWidget(hWnd).setEnabled(bEnable); 1471 end; 1472end; 1473 1474{------------------------------------------------------------------------------ 1475 Function: EndPaint 1476 Params: 1477 Returns: 1478 1479 ------------------------------------------------------------------------------} 1480function TQtWidgetSet.EndPaint(Handle: hwnd; var PS: TPaintStruct): Integer; 1481begin 1482 {$ifdef VerboseQtWinAPI} 1483 WriteLn('[WinAPI EndPaint] Handle: ', dbghex(Handle), 1484 ' PS.HDC: ', dbghex(PS.HDC)); 1485 {$endif} 1486 1487 Result := 1; 1488 1489 if IsValidDC(PS.HDC) and (TObject(PS.HDC) is TQtDeviceContext) then 1490 begin 1491 {$ifdef VerboseQtWinAPI} 1492 WriteLn('Freeing resources'); 1493 {$endif} 1494 TQtDeviceContext(PS.HDC).Free; 1495 end; 1496end;*) 1497 1498{------------------------------------------------------------------------------ 1499 Procedure: EnterCriticalSection 1500 Params: var CritSection: TCriticalSection 1501 Returns: Nothing 1502 ------------------------------------------------------------------------------} 1503procedure TCDWidgetSet.EnterCriticalSection(var CritSection: TCriticalSection); 1504var 1505 ACritSec: System.PRTLCriticalSection; 1506begin 1507 ACritSec:=System.PRTLCriticalSection(CritSection); 1508 System.EnterCriticalsection(ACritSec^); 1509end; 1510 1511{$ifndef CD_UseNativeMonitors} 1512function TCDWidgetSet.EnumDisplayMonitors(hdc: HDC; lprcClip: PRect; 1513 lpfnEnum: MonitorEnumProc; dwData: LPARAM): LongBool; 1514begin 1515 Result := lpfnEnum(1, 0, nil, dwData); 1516end; 1517{$endif} 1518 1519(* 1520function CharsetToQtCharSet(const ALCLCharset: Byte): QFontDatabaseWritingSystem; 1521begin 1522 Result := QFontDatabaseAny; 1523 case ALCLCharset of 1524 SYMBOL_CHARSET: Result := QFontDatabaseSymbol; 1525 FCS_ISO_8859_1 .. FCS_ISO_8859_4, 1526 FCS_ISO_8859_9,FCS_ISO_8859_10, 1527 FCS_ISO_8859_15, 1528 EASTEUROPE_CHARSET: Result := QFontDatabaseLatin; 1529 FCS_ISO_8859_5, 1530 RUSSIAN_CHARSET: Result := QFontDatabaseCyrillic; 1531 FCS_ISO_8859_6, 1532 ARABIC_CHARSET: Result := QFontDatabaseArabic; 1533 FCS_ISO_8859_7, 1534 GREEK_CHARSET: Result := QFontDatabaseGreek; 1535 FCS_ISO_8859_8, 1536 HEBREW_CHARSET: Result := QFontDatabaseHebrew; 1537 SHIFTJIS_CHARSET: Result := QFontDatabaseJapanese; 1538 HANGEUL_CHARSET: Result := QFontDatabaseKorean; 1539 GB2312_CHARSET: Result := QFontDatabaseSimplifiedChinese; 1540 CHINESEBIG5_CHARSET: Result := QFontDatabaseTraditionalChinese; 1541 THAI_CHARSET: Result := QFontDatabaseThai; 1542 end; 1543end; 1544 1545function QtCharsetToCharset(AWritingSystem: QFontDatabaseWritingSystem; 1546 AList: TFPList): Byte; 1547begin 1548 Result := DEFAULT_CHARSET; 1549 case AWritingSystem of 1550 QFontDatabaseAny: 1551 begin 1552 Result := FCS_ISO_10646_1; 1553 AList.Add(TObject(PtrUInt(Result))); 1554 end; 1555 QFontDatabaseSymbol: 1556 begin 1557 Result := SYMBOL_CHARSET; 1558 AList.Add(TObject(PtrUInt(Result))); 1559 end; 1560 QFontDatabaseThai: 1561 begin 1562 Result := THAI_CHARSET; 1563 AList.Add(TObject(PtrUInt(Result))); 1564 end; 1565 QFontDatabaseTraditionalChinese: 1566 begin 1567 Result := CHINESEBIG5_CHARSET; 1568 AList.Add(TObject(PtrUInt(Result))); 1569 end; 1570 QFontDatabaseSimplifiedChinese: 1571 begin 1572 Result := GB2312_CHARSET; 1573 AList.Add(TObject(PtrUInt(Result))); 1574 end; 1575 QFontDatabaseKorean: 1576 begin 1577 Result := HANGEUL_CHARSET; 1578 AList.Add(TObject(PtrUInt(Result))); 1579 end; 1580 QFontDatabaseJapanese: 1581 begin 1582 Result := SHIFTJIS_CHARSET; 1583 AList.Add(TObject(PtrUInt(Result))); 1584 end; 1585 QFontDatabaseHebrew: 1586 begin 1587 Result := HEBREW_CHARSET; 1588 AList.Add(TObject(PtrUInt(Result))); 1589 AList.Add(TObject(PtrUInt(FCS_ISO_8859_8))); 1590 end; 1591 QFontDatabaseGreek: 1592 begin 1593 Result := GREEK_CHARSET; 1594 AList.Add(TObject(PtrUInt(Result))); 1595 AList.Add(TObject(PtrUInt(FCS_ISO_8859_7))); 1596 end; 1597 QFontDatabaseArabic: 1598 begin 1599 Result := ARABIC_CHARSET; 1600 AList.Add(TObject(PtrUInt(Result))); 1601 end; 1602 QFontDatabaseCyrillic: 1603 begin 1604 Result := RUSSIAN_CHARSET; 1605 AList.Add(TObject(PtrUInt(Result))); 1606 AList.Add(TObject(PtrUInt(FCS_ISO_8859_5))); 1607 end; 1608 QFontDatabaseLatin: 1609 begin 1610 Result := FCS_ISO_10646_1; 1611 AList.Add(TObject(PtrUInt(Result))); 1612 AList.Add(TObject(PtrUInt(ANSI_CHARSET))); 1613 AList.Add(TObject(PtrUInt(FCS_ISO_8859_1))); 1614 AList.Add(TObject(PtrUInt(FCS_ISO_8859_2))); 1615 AList.Add(TObject(PtrUInt(FCS_ISO_8859_3))); 1616 AList.Add(TObject(PtrUInt(FCS_ISO_8859_4))); 1617 AList.Add(TObject(PtrUInt(FCS_ISO_8859_9))); 1618 AList.Add(TObject(PtrUInt(FCS_ISO_8859_10))); 1619 AList.Add(TObject(PtrUInt(FCS_ISO_8859_15))); 1620 AList.Add(TObject(PtrUInt(EASTEUROPE_CHARSET))); 1621 end; 1622 end; 1623end; 1624 1625{------------------------------------------------------------------------------ 1626 Function: EnumFontFamiliesEx 1627 Params: 1628 hdc 1629 [in] Handle to the device context. 1630 lpLogfont 1631 [in] Pointer to a LOGFONT structure that contains information about the 1632 fonts to enumerate. The function examines the following members. 1633 1634 Member Description 1635 lfCharset If set to DEFAULT_CHARSET, the function enumerates all fonts 1636 in all character sets. If set to a valid character set value, 1637 the function enumerates only fonts in the specified character 1638 set. 1639 lfFaceName If set to an empty string, the function enumerates one font 1640 in each available typeface name. If set to a valid typeface 1641 name, the function enumerates all fonts with the 1642 specified name. 1643 1644 lfPitchAndFamily Must be set to zero for all language versions of 1645 the operating system. 1646 1647 lpEnumFontFamExProc 1648 [in] Pointer to the application definedcallback function. For more 1649 information, see the EnumFontFamExProc function. 1650 lParam 1651 [in] Specifies an applicationdefined value. The function passes this value 1652 to the callback function along with font information. 1653 dwFlags 1654 This parameter is not used and must be zero. 1655 1656 Returns: 1657 1658 The return value is the last value returned by the callback function. 1659 This value depends on which font families are available for the 1660 specified device. 1661 1662 ------------------------------------------------------------------------------} 1663function TQtWidgetSet.EnumFontFamiliesEx(DC: HDC; lpLogFont: PLogFont; Callback: FontEnumExProc; Lparam: LParam; Flags: dword): longint; 1664var 1665 EnumLogFont: TEnumLogFontEx; 1666 Metric: TNewTextMetricEx; 1667 FontList: TStringList; 1668 FontType: Integer; 1669 FontDB: QFontDatabaseH; 1670 i: Integer; 1671 y: Integer; 1672 AStyle: String; 1673 StylesCount: Integer; 1674 StylesList: QStringListH; 1675 ScriptList: QStringListH; 1676 CharsetList: TFPList; 1677 1678 function QtGetFontFamiliesDefault(var List:TStringList; 1679 const AWritingSystem: QFontDatabaseWritingSystem = QFontDatabaseAny):integer; 1680 var 1681 StrLst: QStringlistH; 1682 WStr: WideString; 1683 j: integer; 1684 begin 1685 Result := -1; 1686 StrLst := QStringList_create; 1687 try 1688 QFontDatabase_families(FontDB, StrLst, AWritingSystem); 1689 Result := QStringList_size(StrLst); 1690 for j := 0 to Result - 1 do 1691 begin 1692 QStringList_at(StrLst, @WStr, j); 1693 List.Add(UTF16ToUTF8(WStr)); 1694 end; 1695 finally 1696 QStringList_destroy(StrLst); 1697 end; 1698 end; 1699 1700 function QtGetFontFamilies(var List: TStringList; 1701 const APitch: Byte; 1702 const AFamilyName: String; 1703 const AWritingSystem: QFontDatabaseWritingSystem = QFontDatabaseAny): Integer; 1704 var 1705 StrLst: QStringlistH; 1706 NewList: QStringListH; 1707 WStr: WideString; 1708 j: integer; 1709 begin 1710 Result := -1; 1711 StrLst := QStringList_create(); 1712 NewList := QStringList_create(); 1713 1714 try 1715 QFontDatabase_families(FontDB, StrLst, AWritingSystem); 1716 for j := 0 to QStringList_size(StrLst) - 1 do 1717 begin 1718 QStringList_at(StrLst, @WStr, j); 1719 if APitch <> DEFAULT_PITCH then 1720 begin 1721 case APitch of 1722 FIXED_PITCH, MONO_FONT: 1723 begin 1724 if QFontDatabase_isFixedPitch(FontDB, @WStr) then 1725 QStringList_append(NewList, @WStr); 1726 end; 1727 VARIABLE_PITCH: 1728 begin 1729 if QFontDatabase_isScalable(FontDB, @WStr) then 1730 QStringList_append(NewList, @WStr); 1731 end; 1732 end; 1733 end else 1734 QStringList_append(NewList, @WStr); 1735 end; 1736 1737 if AFamilyName <> '' then 1738 begin 1739 for j := QStringList_size(NewList) - 1 downto 0 do 1740 begin 1741 QStringList_at(NewList, @WStr, j); 1742 if UTF16ToUTF8(WStr) <> AFamilyName then 1743 QStringList_removeAt(NewList, j); 1744 end; 1745 end; 1746 for j := 0 to QStringList_size(NewList) - 1 do 1747 begin 1748 QStringList_at(NewList, @WStr, j); 1749 List.Add(UTF16ToUTF8(WStr)); 1750 end; 1751 Result := List.Count; 1752 finally 1753 QStringList_destroy(StrLst); 1754 QStringList_destroy(NewList); 1755 end; 1756 end; 1757 1758 function GetStyleAt(AIndex: Integer): String; 1759 var 1760 WStr: WideString; 1761 begin 1762 Result := ''; 1763 if (AIndex >= 0) and (AIndex < QStringList_size(StylesList)) then 1764 begin 1765 QStringList_at(StylesList, @WStr, AIndex); 1766 Result := UTF16ToUTF8(WStr); 1767 end; 1768 end; 1769 1770 function GetWritingSystems(AFontName: String; AList: QStringListH; 1771 ACharsetList: TFPList): Boolean; 1772 var 1773 WStr: WideString; 1774 Arr: TPtrIntArray; 1775 j: Integer; 1776 begin 1777 Result := False; 1778 QStringList_clear(AList); 1779 if Assigned(CharSetList) then 1780 CharSetList.Clear; 1781 WStr := UTF8ToUTF16(AFontName); 1782 QFontDatabase_writingSystems(FontDB, @Arr, @WStr); 1783 Result := length(Arr) > 0; 1784 for j := 0 to High(Arr) do 1785 begin 1786 if Assigned(ACharsetList) then 1787 QtCharsetToCharset(QFontDatabaseWritingSystem(Arr[j]), ACharsetList); 1788 QFontDatabase_writingSystemName(@WStr, QFontDatabaseWritingSystem(Arr[j])); 1789 QStringList_append(AList, @WStr); 1790 end; 1791 end; 1792 1793 function FillLogFontA(AFontName: String; var ALogFontA: TLogFontA; 1794 var AMetric: TNewTextMetricEx; var AFontType: Integer; 1795 out AStyle: String): Integer; 1796 var 1797 Font: QFontH; 1798 WStr: WideString; 1799 begin 1800 WStr := UTF8ToUTF16(AFontName); 1801 Font := QFont_create(@WStr); 1802 ALogFontA.lfItalic := Byte(QFont_italic(Font)); 1803 ALogFontA.lfWeight := QFont_weight(Font); 1804 ALogFontA.lfHeight := QFont_pointSize(Font); 1805 ALogFontA.lfUnderline := Byte(QFont_underline(Font)); 1806 ALogFontA.lfStrikeOut := Byte(QFont_strikeOut(Font)); 1807 1808 if QFont_styleStrategy(Font) = QFontPreferBitmap then 1809 AFontType := AFontType or RASTER_FONTTYPE; 1810 if QFont_styleStrategy(Font) = QFontPreferDevice then 1811 AFontType := AFontType or DEVICE_FONTTYPE; 1812 1813 if not (QFont_styleStrategy(Font) = QFontPreferDefault) then 1814 AFontType := AFontType and not TRUETYPE_FONTTYPE; 1815 1816 QStringList_clear(StylesList); 1817 QFontDatabase_styles(FontDB, StylesList, @WStr); 1818 AStyle := ''; 1819 Result := QStringList_size(StylesList); 1820 1821 if Result > 0 then 1822 AStyle := GetStyleAt(0); 1823 // fill script and charset list 1824 GetWritingSystems(AFontName, ScriptList, CharsetList); 1825 1826 QFont_destroy(Font); 1827 end; 1828 1829begin 1830 {$ifdef VerboseQtWinAPI} 1831 WriteLn('[WinAPI EnumFontFamiliesEx] Charset=',lpLogFont^.lfCharSet, 1832 ' face ',lpLogFont^.lfFaceName,' pitchAndFamily=',lpLogFont^.lfPitchAndFamily); 1833 {$endif} 1834 Result := 0; 1835 Metric.ntmentm.ntmAvgWidth := 0; // just to shutup compiler 1836 FontDB := QFontDatabase_create(); 1837 try 1838 if (lpLogFont^.lfCharSet = DEFAULT_CHARSET) and 1839 (lpLogFont^.lfFaceName= '') and 1840 (lpLogFont^.lfPitchAndFamily = 0) then 1841 begin 1842 FontType := 0; 1843 FontList := TStringList.create; 1844 try 1845 if QtGetFontFamiliesDefault(FontList) > 0 then 1846 begin 1847 for i := 0 to FontList.Count - 1 do 1848 begin 1849 EnumLogFont.elfLogFont.lfFaceName := FontList[i]; 1850 Result := Callback(EnumLogFont, Metric, FontType, LParam); 1851 end; 1852 end; 1853 finally 1854 FontList.free; 1855 end; 1856 end else 1857 begin 1858 Result := 0; 1859 FontType := TRUETYPE_FONTTYPE; 1860 FontList := TStringList.create; 1861 StylesList := QStringList_create(); 1862 ScriptList := QStringList_create(); 1863 CharsetList := TFPList.Create; 1864 try 1865 if QtGetFontFamilies(FontList, lpLogFont^.lfPitchAndFamily, 1866 lpLogFont^.lfFaceName, CharsetToQtCharSet(lpLogFont^.lfCharSet)) > 0 then 1867 begin 1868 StylesList := QStringList_create(); 1869 for i := 0 to FontList.Count - 1 do 1870 begin 1871 EnumLogFont.elfLogFont.lfFaceName := FontList[i]; 1872 EnumLogFont.elfLogFont.lfPitchAndFamily := lpLogFont^.lfPitchAndFamily; 1873 EnumLogFont.elfFullName := FontList[i]; 1874 1875 StylesCount := FillLogFontA(FontList[i], EnumLogFont.elfLogFont, Metric, FontType, 1876 AStyle); 1877 EnumLogFont.elfStyle := AStyle; 1878 if CharSetList.Count > 0 then 1879 EnumLogFont.elfLogFont.lfCharSet := PtrUInt(CharsetList.Items[0]); 1880 Result := Callback(EnumLogFont, Metric, FontType, LParam); 1881 for y := 1 to StylesCount - 1 do 1882 begin 1883 AStyle := GetStyleAt(y); 1884 EnumLogFont.elfStyle := AStyle; 1885 Result := Callback(EnumLogFont, Metric, FontType, LParam); 1886 end; 1887 for y := 1 to CharsetList.Count - 1 do 1888 begin 1889 EnumLogFont.elfLogFont.lfCharSet := PtrUInt(CharsetList.Items[y]); 1890 Result := Callback(EnumLogFont, Metric, FontType, LParam); 1891 end; 1892 end; 1893 end; 1894 finally 1895 FontList.free; 1896 QStringList_destroy(StylesList); 1897 CharSetList.Free; 1898 end; 1899 end; 1900 finally 1901 QFontDatabase_destroy(FontDB); 1902 end; 1903end; 1904 1905 1906{------------------------------------------------------------------------------ 1907 Function: ExcludeClipRect 1908 Params: none 1909 Returns: Nothing 1910 1911 ------------------------------------------------------------------------------} 1912function TQtWidgetSet.ExcludeClipRect(dc: hdc; Left, Top, Right, Bottom : Integer) : Integer; 1913var 1914 Region: QRegionH; 1915 ClipRegion: QRegionH; 1916 ExRegion: QRegionH; 1917 QtDC: TQtDeviceContext; 1918 R: TRect; 1919begin 1920 {$ifdef VerboseQtWinAPI} 1921 WriteLn('[WinAPI ExcludeClipRect]'); 1922 {$endif} 1923 1924 Result := ERROR; 1925 if not IsValidDC(DC) then Exit; 1926 1927 QtDC := TQtDeviceContext(DC); 1928 1929 {ExcludeClipRect on X11 paint engine is pretty slow with complex regions 1930 eg. setting clipRegion with hundreds of rects (usually created by 1931 calling ExcludeClipRect for many children on widget) dramatically kills 1932 performance of our application. 1933 To get rid of it we are using trick from webkit. If numRects is over 1934 25 then create an new rect region with boundsRect of NewRegion. 1935 see issue http://bugs.freepascal.org/view.php?id=19698. 1936 If you want accurate ExcludeClipRect use graphicssystem Raster or 1937 see comment in TQtWidgetSet.ExtSelectClipRgn} 1938 ExRegion := QRegion_create(Left, Top, Right - Left, Bottom - Top, QRegionRectangle); 1939 Region := QRegion_create; 1940 ClipRegion := QRegion_create; 1941 try 1942 QPainter_clipRegion(QtDC.Widget, ClipRegion); 1943 QRegion_subtracted(ClipRegion, Region, ExRegion); 1944 1945 // only for X11 paintEngine. 1946 if (QPaintEngine_type(QtDC.PaintEngine) = QPaintEngineX11) and 1947 not QRegion_isEmpty(Region) and 1948 (QRegion_numRects(Region) > 25) then 1949 begin 1950 QRegion_boundingRect(Region, @R); 1951 QRegion_setRects(Region, @R, 1); 1952 end; 1953 1954 QtDC.setClipRegion(Region); 1955 QtDC.setClipping(True); 1956 if QRegion_isEmpty(Region) then 1957 Result := NULLREGION 1958 else 1959 if QRegion_numRects(Region) = 1 then 1960 Result := SIMPLEREGION 1961 else 1962 Result := COMPLEXREGION; 1963 1964 finally 1965 QRegion_destroy(ClipRegion); 1966 QRegion_destroy(Region); 1967 QRegion_destroy(ExRegion); 1968 end; 1969end;*) 1970 1971function TCDWidgetSet.ExtCreatePen(dwPenStyle, dwWidth: DWord; 1972 const lplb: TLogBrush; dwStyleCount: DWord; lpStyle: PDWord): HPEN; 1973var 1974 lPen: TFPCustomPen; 1975begin 1976 lPen := TFPCustomPen.Create; 1977 Result := HBRUSH(lPen); 1978// QtPen.IsExtPen := True; 1979 1980// {$ifdef VerboseCDDrawing} 1981// DebugLn(Format(':>[TCDWidgetSet.ExtCreatePen] Style: %d, Color: %8x Result:"%x', 1982// [LogPen.lopnStyle, LogPen.lopnColor, Result])); 1983// {$endif} 1984 1985 case dwPenStyle and PS_STYLE_MASK of 1986 PS_SOLID: lPen.Style := psSolid; 1987 PS_DASH: lPen.Style := psDash; 1988 PS_DOT: lPen.Style := psDot; 1989 PS_DASHDOT: lPen.Style := psDashDot; 1990 PS_DASHDOTDOT:lPen.Style := psDashDotDot; 1991// PS_USERSTYLE: QtPen.setStyle(QtCustomDashLine); 1992 PS_NULL: lPen.Style := psClear; 1993 else 1994 lPen.Style := psSolid; 1995 end; 1996 1997 lPen.Width := 1; 1998 if (dwPenStyle and PS_TYPE_MASK) = PS_COSMETIC then 1999 lPen.Width := 1 2000 else if (dwPenStyle and PS_TYPE_MASK) = PS_GEOMETRIC then 2001 begin 2002 lPen.Width := dwWidth; 2003 {case dwPenStyle and PS_JOIN_MASK of 2004 PS_JOIN_ROUND: QtPen.setJoinStyle(QtRoundJoin); 2005 PS_JOIN_BEVEL: QtPen.setJoinStyle(QtBevelJoin); 2006 PS_JOIN_MITER: QtPen.setJoinStyle(QtMiterJoin); 2007 end; 2008 2009 case dwPenStyle and PS_ENDCAP_MASK of 2010 PS_ENDCAP_ROUND: QtPen.setCapStyle(QtRoundCap); 2011 PS_ENDCAP_SQUARE: QtPen.setCapStyle(QtSquareCap); 2012 PS_ENDCAP_FLAT: QtPen.setCapStyle(QtFlatCap); 2013 end;} 2014 end; 2015 2016{ if (dwPenStyle and PS_STYLE_MASK) = PS_USERSTYLE then 2017 QtPen.setDashPattern(lpStyle, dwStyleCount);} 2018 2019 lPen.FPColor := TColorToFPColor(ColorToRGB(lplb.lbColor)); 2020 2021 Result := HPEN(lPen); 2022end; 2023 2024function TCDWidgetSet.ExtSelectClipRGN(dc: hdc; rgn: hrgn; Mode: Longint) : Integer; 2025var 2026 LazDC: TLazCanvas absolute DC; 2027 lRegion: TLazRegion absolute rgn; 2028begin 2029 {$ifdef VerboseCDWinAPI} 2030 DebugLn('[TCDWidgetSet.SelectClipRGN] DC=', dbgs(DC),' RGN=', dbghex(RGN)); 2031 {$endif} 2032 2033 Result := ERROR; 2034 2035 // Activating this code break the drawing of TStringGrid. ToDo: Find out why 2036{ if not IsValidDC(DC) then exit; 2037 2038 // RGN=0 indicates that the clipping region should be removed 2039 if (RGN = 0) then 2040 begin 2041 TLazCanvas(LazDC.ClipRegion).Clear; 2042 LazDC.Clipping := False; 2043 Result := NullRegion; 2044 Exit; 2045 end; 2046 2047 if LazDC.ClipRegion = nil then 2048 LazDC.ClipRegion := TLazRegion.Create; 2049 2050 // Never use LazDC.ClipRegion := RGN because we really need to make a copy of it 2051 // The original handle might be freed afterwards 2052 CombineRgn(HRGN(LazDC.ClipRegion), HRGN(LazDC.ClipRegion), RGN, Mode); 2053 LazDC.Clipping := True; 2054 Result := TLazRegion(RGN).GetRegionKind();} 2055end; 2056 2057{$ifndef CD_UseNativeText} 2058{------------------------------------------------------------------------------ 2059 Function: ExtTextOut 2060 Params: none 2061 Returns: Nothing 2062 ------------------------------------------------------------------------------} 2063function TCDWidgetSet.ExtTextOut(DC: HDC; X, Y: Integer; Options: Longint; 2064 Rect: PRect; Str: PChar; Count: Longint; Dx: PInteger): Boolean; 2065var 2066 lDestCanvas: TLazCanvas absolute DC; 2067 lDestIntfImage: TLazIntfImage; 2068 lFontSize: Integer; 2069 FTDrawer: TIntfFreeTypeDrawer; 2070 ftFont: TFreeTypeFont; 2071 RealX, RealY: Integer; 2072 FreeFTFont: Boolean = false; 2073 lLogFont: TLogFont; 2074begin 2075 {$ifdef VerboseCDText} 2076 DebugLn(Format(':>[WinAPI ExtTextOut] DC=%x Str=%s X=%d Y=%d', 2077 [DC, StrPas(Str), X, Y])); 2078 {$endif} 2079 2080 Result := False; 2081 2082 if (Str = nil) or (Str = '') then Exit; 2083 2084 if ((Options and (ETO_OPAQUE + ETO_CLIPPED)) <> 0) and (Rect = nil) then 2085 exit; 2086 2087 if Rect <> nil then Rect^ := Bounds(0, 0, 0, 0); 2088 2089 if not IsValidDC(DC) then Exit; 2090 lDestIntfImage := TLazIntfImage(lDestCanvas.Image); 2091 2092 if (lDestCanvas.Font = nil) or (lDestCanvas.Font.Size = 0) then lFontSize := DefaultFontSize 2093 else lFontSize := Abs(lDestCanvas.Font.Size); 2094 2095 // Preparations finished, draw it using LazFreeType 2096 2097 FTDrawer := TIntfFreeTypeDrawer.Create(lDestIntfImage); 2098 ftFont := TFreeTypeFont(lDestCanvas.ExtraFontData); 2099 if ftFont = nil then 2100 begin 2101 ftFont := TFreeTypeFont.Create; 2102 ftFont.Name := BackendGetFontPath(lLogFont, ''); 2103 ftFont.Hinted := true; 2104 ftFont.ClearType := true; 2105 ftFont.Quality := grqHighQuality; 2106 FreeFTFont := True; 2107 end; 2108 try 2109 ftFont.SizeInPoints:= lFontSize; 2110 //lFontSize:= MulDiv(lFontSize,72,ftFont.DPI); // convert points to pixels 2111 lFontSize := Round(ftFont.TextHeight(Str) * 0.75);// ToDo: Find out why this 75% factor works 2112 RealX := X + lDestCanvas.WindowOrg.X + lDestCanvas.BaseWindowOrg.X; 2113 RealY := Y + lDestCanvas.WindowOrg.Y + lDestCanvas.BaseWindowOrg.Y + lFontSize; 2114 FTDrawer.DrawText(Str, ftFont, RealX, RealY, colBlack, 255); 2115 finally 2116 if FreeFTFont then ftFont.Free; 2117 FTDrawer.Free; 2118 end; 2119 2120 {$ifdef VerboseCDText} 2121 DebugLn(':<[WinAPI ExtTextOut]'); 2122 {$endif} 2123 2124 Result := True; 2125 2126{ if ((Options and ETO_OPAQUE) <> 0) then 2127 QtDC.fillRect(Rect^.Left, Rect^.Top, Rect^.Right - Rect^.Left, Rect^.Bottom - Rect^.Top); 2128 2129 if Str <> nil then 2130 begin 2131 if Count >= 0 then 2132 WideStr := GetUtf8String(Copy(Str, 1, Count)) 2133 else 2134 WideStr := GetUtf8String(Str); 2135 2136 if (Options and ETO_CLIPPED <> 0) then 2137 begin 2138 B := QtDC.getClipping; 2139 if not B then 2140 begin 2141 QtDC.save; 2142 QtDC.setClipRect(Rect^); 2143 end; 2144 QtDC.drawText(X, Y, Rect^.Right - Rect^.Left, Rect^.Bottom - Rect^.Top, 0, @WideStr); 2145 if not B then 2146 QtDC.restore; 2147 end else 2148 QtDC.drawText(X, Y, @WideStr); 2149 end;} 2150 2151 Result := True; 2152end; 2153{$endif} 2154 2155{------------------------------------------------------------------------------ 2156 Function: FillRect 2157 Params: none 2158 Returns: Nothing 2159 ------------------------------------------------------------------------------} 2160function TCDWidgetSet.FillRect(DC: HDC; const Rect: TRect; Brush: HBRUSH): Boolean; 2161var 2162 LazDC: TLazCanvas absolute DC; 2163 lOldBrush: HGDIOBJ; 2164begin 2165 Result := False; 2166 2167 {$ifdef VerboseCDDrawing} 2168 DebugLn('[WinAPI FillRect Rect=', dbgs(Rect),' Brush=', dbghex(Brush)); 2169 {$endif} 2170 2171 if not IsValidDC(DC) then 2172 exit; 2173 if not IsValidGdiObject(Brush) then 2174 exit; 2175 2176 lOldBrush := SelectObject(DC, Brush); 2177 LazDC.FillRect(Rect); 2178 SelectObject(DC, lOldBrush); 2179 2180 Result := True; 2181end; 2182 2183{------------------------------------------------------------------------------ 2184 Function: FillRgn 2185 Params: DC: HDC; RegionHnd: HRGN; hbr: HBRUSH 2186 Returns: Boolean 2187 ------------------------------------------------------------------------------} 2188function TCDWidgetSet.FillRgn(DC: HDC; RegionHnd: HRGN; hbr: HBRUSH): Bool; 2189var 2190 LazDC: TLazCanvas absolute DC; 2191 lRegion: TLazRegion absolute RegionHnd; 2192 lRegionRect: TRect; 2193 lOldBrush: HGDIOBJ; 2194 lOldRegion: TLazRegion; 2195begin 2196 {$ifdef VerboseCDWinAPI} 2197 DebugLn('[TCDWidgetSet.FillRgn] Rgn=', dbgs(RegionHnd),' Brush=', dbghex(hbr)); 2198 {$endif} 2199 2200 Result := False; 2201 2202 if not IsValidDC(DC) then exit; 2203 if hbr = 0 then Exit; 2204 if RegionHnd = 0 then Exit; 2205 2206 lOldBrush := SelectObject(DC, hbr); 2207 try 2208 lOldRegion := TLazRegion.Create; 2209 lOldRegion.Assign(TLazRegion(LazDC.ClipRegion)); 2210 lRegionRect := lRegion.GetBoundingRect(); 2211 LazDC.Rectangle(lRegionRect); 2212 finally 2213 TLazRegion(LazDC.ClipRegion).Assign(lOldRegion); 2214 lOldRegion.Free; 2215 SelectObject(DC, lOldBrush); 2216 end; 2217 2218 Result := True; 2219end; 2220 2221{------------------------------------------------------------------------------ 2222 Function: Frame3D 2223 Params: none 2224 Returns: Nothing 2225 2226 Draws a 3d border in the native drawer style. 2227 ------------------------------------------------------------------------------} 2228function TCDWidgetSet.Frame3d(DC : HDC; var ARect : TRect; 2229 const FrameWidth : integer; const Style : TBevelCut) : boolean; 2230var 2231 LazDC: TLazCanvas; 2232begin 2233 {$ifdef VerboseCDWinAPI} 2234 DebugLn('[TCDWidgetSet.Frame3d Rect=', dbgs(ARect)); 2235 {$endif} 2236 2237 Result := False; 2238 2239 if not IsValidDC(DC) then exit; 2240 2241 LazDC := TLazCanvas(DC); 2242 2243 GetDefaultDrawer().DrawFrame3D(LazDC, Types.Point(ARect.Left, ARect.Top), 2244 Types.Size(ARect), FrameWidth, Style); 2245 2246 InflateRect(ARect, -FrameWidth, -FrameWidth); 2247 2248 Result := True; 2249end; 2250 2251{------------------------------------------------------------------------------ 2252 Function: FrameRect 2253 Params: none 2254 Returns: Nothing 2255 ------------------------------------------------------------------------------} 2256function TCDWidgetSet.FrameRect(DC: HDC; const ARect: TRect; hBr: HBRUSH): Integer; 2257var 2258 LazDC: TLazCanvas absolute DC; 2259 lOldBrush, lOldPen, lFramePen, lFrameBrush: HGDIOBJ; 2260 lLogPen: TLogPen; 2261 lLogBrush: TLogBrush; 2262begin 2263 Result := 0; 2264 2265 {$ifdef VerboseCDDrawing} 2266 DebugLn('[WinAPI FillRect Rect=', dbgs(ARect),' Brush=', dbghex(hBr)); 2267 {$endif} 2268 2269 if not IsValidDC(DC) then 2270 exit; 2271 if not IsValidGdiObject(hBr) then 2272 exit; 2273 2274 // Creates temporary pen and brush to help the drawing 2275 lLogPen.lopnStyle := PS_SOLID; 2276 lLogPen.lopnWidth := Types.Point(1, 1); 2277 lLogPen.lopnColor := FPColorToTColor(TFPCustomBrush(hBR).FPColor); 2278 lFramePen := CreatePenIndirect(lLogPen); 2279 2280 lLogBrush.lbStyle := BS_NULL; 2281 lFrameBrush := CreateBrushIndirect(lLogBrush); 2282 2283 // Do the drawing 2284 lOldBrush := SelectObject(DC, lFrameBrush); 2285 lOldPen := SelectObject(DC, lFramePen); 2286 LazDC.Rectangle(ARect); 2287 SelectObject(DC, lOldBrush); 2288 SelectObject(DC, lOldPen); 2289 2290 // Delete the helper objects 2291 DeleteObject(lFramePen); 2292 DeleteObject(lFrameBrush); 2293 2294 Result := 1; 2295end; 2296 2297(*function TQtWidgetSet.GetActiveWindow: HWND; 2298var 2299 Widget: QWidgetH; 2300 W: TQtWidget; 2301 SubW: TQtWidget; 2302 Area: QMdiAreaH; 2303begin 2304 Widget := QApplication_activeWindow; 2305 if Widget <> nil then 2306 begin 2307 W := QtObjectFromWidgetH(Widget); 2308 if W <> nil then 2309 begin 2310 if TQtMainWindow(W).MDIAreaHandle <> nil then 2311 begin 2312 Area := QMdiAreaH(TQtMainWindow(W).MDIAreaHandle.Widget); 2313 SubW := QtObjectFromWidgetH(QMdiArea_activeSubWindow(Area)); 2314 if SubW <> nil then 2315 Result := HWND(SubW) 2316 else 2317 Result := HWND(W); 2318 end else 2319 Result := HWND(W); 2320 end; 2321 end else 2322 Result := 0; 2323end; 2324 2325 2326{------------------------------------------------------------------------------ 2327 Method: TQtWidgetSet.GetBitmapBits 2328 Params: none 2329 Returns: 2330 2331 ------------------------------------------------------------------------------} 2332function TQtWidgetSet.GetBitmapBits(Bitmap: HBITMAP; Count: Longint; Bits: Pointer): Longint; 2333var 2334 Image: QImageH; 2335begin 2336 {$ifdef VerboseQtWinAPI} 2337 WriteLn('[WinAPI GetBitmapBits]',' Bitmap=', dbghex(Bitmap),' Count=',Count); 2338 {$endif} 2339 2340 Result := 0; 2341 2342 if (Bitmap = 0) or (Count <= 0) then 2343 Exit; 2344 2345 Image := QImage_create(TQtImage(Bitmap).FHandle); 2346 try 2347 Result := (QImage_width(Image) * QImage_height(Image) * QImage_depth(Image) + 7) div 8; 2348 if Count < Result then 2349 Result := Count; 2350 if Result > 0 then 2351 Move(QImage_bits(Image)^, Bits^, Result); 2352 finally 2353 QImage_destroy(Image); 2354 end; 2355end; 2356 2357function TQtWidgetSet.GetBkColor(DC: HDC): TColorRef; 2358var 2359 QtDC: TQtDeviceContext; 2360begin 2361 Result := CLR_INVALID; 2362 if not IsValidDC(DC) then Exit; 2363 QtDC := TQtDeviceContext(DC); 2364 Result := QtDC.GetBkColor; 2365end; 2366 2367function TQtWidgetSet.GetCapture: HWND; 2368var 2369 w: QWidgetH; 2370 Widget: TQtWidget; 2371 {$IFDEF MSWINDOWS} 2372 AWin: HWND; 2373 {$ENDIF} 2374begin 2375 {$IFDEF MSWINDOWS} 2376 AWin := Windows.GetCapture; 2377 if AWin <> 0 then 2378 w := QWidget_find(AWin) 2379 else 2380 w := nil; 2381 2382 if (w = nil) and (QApplication_mouseButtons() > 0) then 2383 w := QApplication_focusWidget() 2384 else 2385 if w <> QWidget_mouseGrabber then 2386 w := QWidget_mouseGrabber; 2387 2388 {$ELSE} 2389 w := QWidget_mouseGrabber(); 2390 {$ENDIF} 2391 2392 if w <> nil then 2393 begin 2394 // Capture widget can be child of complex control. In any case we should return TQtWidget as result. 2395 // So we will look for parent while not found apropriate LCL handle. 2396 Widget := GetFirstQtObjectFromWidgetH(w); 2397 Result := HWND(Widget); 2398 end 2399 else 2400 Result := 0; 2401 {$ifdef VerboseQtWinAPI} 2402 WriteLn('[WinAPI GetCapture] Capture = ', Result); 2403 {$endif} 2404end; 2405 2406function TQtWidgetSet.GetCaretPos(var lpPoint: TPoint): Boolean; 2407begin 2408 Result := QtCaret.GetCaretPos(lpPoint); 2409end; 2410 2411function TQtWidgetSet.GetCaretRespondToFocus(handle: HWND; var ShowHideOnFocus: boolean): Boolean; 2412begin 2413 ShowHideOnFocus := QtCaret.GetQtCaretRespondToFocus; 2414 Result := True; 2415end;*) 2416 2417{------------------------------------------------------------------------------ 2418 Function: GetClientBounds 2419 Params: handle: 2420 Result: 2421 Returns: true on success 2422 2423 Returns the client bounds of a control. The client bounds is the rectangle of 2424 the inner area of a control, where the child controls are visible. The 2425 coordinates are relative to the control's left and top. 2426 ------------------------------------------------------------------------------} 2427function TCDWidgetSet.GetClientBounds(handle : HWND; var ARect : TRect) : Boolean; 2428var 2429 lObject: TObject; 2430begin 2431 {$ifdef VerboseCDWinAPI} 2432 DebugLn(Format(':>[WinAPI GetClientBounds] Handle=%x', [Handle])); 2433 {$endif} 2434 // ToDO check if the window is native or not and process accordingly 2435 // For now just assume it is native 2436 Result := False; 2437 if Handle=0 then Exit; 2438 lObject := TObject(Handle); 2439 if lObject is TCDForm then 2440 begin 2441 // Initial size guessed 2442 if TCDForm(lObject).Image <> nil then 2443 ARect := Bounds(0, 0, TCDForm(lObject).Image.Width, TCDForm(lObject).Image.Height) 2444 else ARect := Bounds(0, 0, 0, 0); 2445 2446 // Now ask for the real size 2447 Result := BackendGetClientBounds(Handle, ARect) 2448 end 2449 else 2450 begin 2451 // If we return WinControl.BoundsRect then the controls get a x2 factor 2452 // when Align=alClient, strange. Region.GetBoundingRect() works fine. 2453 // ARect := TCDWinControl(lObject).WinControl.BoundsRect; <<-- don't do this 2454 2455 ARect := TCDWinControl(lObject).Region.GetBoundingRect(); 2456 end; 2457 {$ifdef VerboseCDWinAPI} 2458 DebugLn(Format(':<[WinAPI GetClientBounds] ARect.Left=%d ARect.Top=%d' 2459 + ' ARect.Right=%d ARect.Bottom=%d', 2460 [ARect.Left, ARect.Top, ARect.Right, ARect.Bottom])); 2461 {$endif} 2462end; 2463 2464{------------------------------------------------------------------------------ 2465 Function: GetClientRect 2466 Params: handle: 2467 Result: 2468 Returns: true on success 2469 2470 Returns the client bounds of a control. The client bounds is the rectangle of 2471 the inner area of a control, where the child controls are visible. The 2472 coordinates are relative to the control's left and top. 2473 Left and Top are always 0,0 2474 ------------------------------------------------------------------------------} 2475function TCDWidgetSet.GetClientRect(handle : HWND; var ARect : TRect) : Boolean; 2476begin 2477 {$ifdef VerboseCDWinAPI} 2478 DebugLn(Format('[WinAPI GetClientRect] Handle=%x', [Handle])); 2479 {$endif} 2480 GetClientBounds(Handle, ARect); 2481 OffsetRect(ARect, -ARect.Left, -ARect.Top); 2482 2483 Result := True; 2484end; 2485 2486{------------------------------------------------------------------------------ 2487 Function: GetClipBox 2488 Params: dc, lprect 2489 Returns: Integer 2490 2491 Returns the smallest rectangle which includes the entire current 2492 Clipping Region, or if no Clipping Region is set, the current 2493 dimensions of the Drawable. 2494 2495 The result can be one of the following constants 2496 Error 2497 NullRegion 2498 SimpleRegion 2499 ComplexRegion 2500 ------------------------------------------------------------------------------} 2501function TCDWidgetSet.GetClipBox(DC: hDC; lpRect: PRect): Longint; 2502var 2503 LazDC: TLazCanvas; 2504 lClipRegion: TFPCustomRegion; 2505begin 2506 {$ifdef VerboseCDWinAPI} 2507 DebugLn('[WinAPI GetClipBox] DC ' + dbghex(DC)); 2508 {$endif} 2509 2510 Result := NULLREGION; 2511 if lpRect <> nil then 2512 lpRect^ := Types.Rect(0,0,0,0); 2513 2514 if DC = 0 then DC := HDC(ScreenDC); 2515 2516 if not IsValidDC(DC) then 2517 Result := ERROR; 2518 2519 if Result = ERROR then Exit; 2520 2521 LazDC := TLazCanvas(DC); 2522 2523 if (lpRect<>nil) then 2524 begin 2525 lClipRegion := LazDC.ClipRegion; 2526 if lClipRegion = nil then 2527 begin 2528 Result := NULLREGION; 2529 lpRect^ := Types.Bounds(0, 0, LazDC.Width, LazDC.Height); 2530 end 2531 else 2532 begin 2533 Result := SIMPLEREGION; 2534 lpRect^ := lClipRegion.GetBoundingRect(); 2535 end; 2536 end; 2537end; 2538 2539{------------------------------------------------------------------------------ 2540 Function: GetClipRGN 2541 Params: dc, rgn 2542 Returns: Integer 2543 2544 This routine assumes that RGN has been created previously 2545 and it copies the current Clipping Region to RGN 2546 2547 The result can be one of the following constants 2548 0 = no clipping set 2549 1 = ok 2550 -1 = error 2551 ------------------------------------------------------------------------------} 2552function TCDWidgetSet.GetClipRGN(DC : hDC; RGN : hRGN): Longint; 2553var 2554 LazDC: TLazCanvas absolute DC; 2555 lDestRegion: TLazRegion absolute RGN; 2556 lDCRegion: TLazRegion; 2557begin 2558 {$ifdef VerboseCDWinAPI} 2559 DebugLn('[WinAPI GetClipRGN] DC ' + dbghex(DC)); 2560 {$endif} 2561 2562 Result := -1; 2563 if not IsValidDC(DC) then exit; 2564 if Rgn = 0 then Exit; 2565 2566 lDCRegion := TLazRegion(LazDC.ClipRegion); 2567 if lDCRegion = nil then 2568 Result := 0 2569 else 2570 begin 2571 lDestRegion.Assign(lDCRegion); 2572 Result := 1; 2573 end; 2574end; 2575 2576(*function TQtWidgetSet.GetCmdLineParamDescForInterface: string; 2577 function b(const s: string): string; 2578 begin 2579 Result:=BreakString(s,75,22)+LineEnding+LineEnding; 2580 end; 2581begin 2582 Result:= 2583 b(rsqtOptionNoGrab) 2584 +b(rsqtOptionDoGrab) 2585 +b(rsqtOptionSync) 2586 +b(rsqtOptionStyle) 2587 +b(rsqtOptionStyleSheet) 2588 +b(rsqtOptionGraphicsStyle) 2589 +b(rsqtOptionSession) 2590 +b(rsqtOptionWidgetCount) 2591 +b(rsqtOptionReverse) 2592 {$IFDEF HASX11} 2593 +b(rsqtOptionX11Display) 2594 +b(rsqtOptionX11Geometry) 2595 +b(rsqtOptionX11Font) 2596 +b(rsqtOptionX11BgColor) 2597 +b(rsqtOptionX11FgColor) 2598 +b(rsqtOptionX11BtnColor) 2599 +b(rsqtOptionX11Name) 2600 +b(rsqtOptionX11Title) 2601 +b(rsqtOptionX11Visual) 2602 +b(rsqtOptionX11NCols) 2603 +b(rsqtOptionX11CMap) 2604 +b(rsqtOptionX11IM) 2605 +b(rsqtOptionX11InputStyle) 2606 {$ENDIF} 2607 ; 2608end;*) 2609 2610{------------------------------------------------------------------------------ 2611 Method: GetCurrentObject 2612 Params: 2613 DC - A handle to the DC 2614 uObjectType - The object type to be queried 2615 Returns: If the function succeeds, the return value is a handle to the specified object. 2616 If the function fails, the return value is NULL. 2617 ------------------------------------------------------------------------------} 2618function TCDWidgetSet.GetCurrentObject(DC: HDC; uObjectType: UINT): HGDIOBJ; 2619var 2620 LazDC: TLazCanvas; 2621begin 2622 {$ifdef VerboseCDWinAPI} 2623 DebugLn(Format('[TCDWidgetSet.GetCurrentObject uObjectType=%d', [uObjectType])); 2624 {$endif} 2625 2626 Result := 0; 2627 if not IsValidDC(DC) then exit; 2628 LazDC := TLazCanvas(DC); 2629 2630 case uObjectType of 2631 OBJ_BITMAP: Result := HGDIOBJ(LazDC.SelectedBitmap); 2632 OBJ_BRUSH: Result := HGDIOBJ(LazDC.AssignedBrush); 2633 OBJ_FONT: Result := HGDIOBJ(LazDC.AssignedFont); 2634 OBJ_PEN: Result := HGDIOBJ(LazDC.AssignedPen); 2635 end; 2636end; 2637 2638(*{------------------------------------------------------------------------------ 2639 Function: GetCursorPos 2640 Params: lpPoint: The cursorposition 2641 Returns: True if succesful 2642 2643 ------------------------------------------------------------------------------} 2644function TQtWidgetSet.GetCursorPos(var lpPoint: TPoint ): Boolean; 2645var 2646 vPoint: TQtPoint; 2647begin 2648 QCursor_pos(@vPoint); 2649 2650 lpPoint.x := vPoint.x; 2651 lpPoint.y := vPoint.y; 2652 2653 Result := True; 2654end;*) 2655 2656{------------------------------------------------------------------------------ 2657 Function: GetDC 2658 Params: hWnd is any widget. 2659 Returns: Nothing 2660 2661 This function is Called: 2662 - Once on app startup with hWnd = 0 2663 - Twice for every TLabel on the TCustomLabel.CalcSize function 2664 ------------------------------------------------------------------------------} 2665function TCDWidgetSet.GetDC(hWnd: HWND): HDC; 2666var 2667 lObject: TObject; 2668 lWinControl: TWinControl; 2669 lFormHandle: TCDForm; 2670begin 2671 {$ifdef VerboseCDDrawing} 2672 DebugLn(':>[WinAPI GetDC] hWnd: ', dbghex(hWnd)); 2673 {$endif} 2674 2675 Result := 0; 2676 2677 // Screen DC 2678 if HWnd = 0 then Result := HDC(CDWidgetset.ScreenDC); 2679 2680 // Invalid DC 2681 if not IsValidDC(HWnd) then Exit; 2682 2683 lObject := TObject(HWnd); 2684 2685 // Control DC -> Search for the corresponding form 2686 if lObject is TCDWinControl then 2687 begin 2688 lWinControl := TCDWinControl(lObject).WinControl; 2689 lWinControl := Forms.GetParentForm(lWinControl); 2690 lFormHandle := TCDForm(lWinControl.Handle); 2691 end 2692 // Form DC 2693 else if lObject is TCDForm then 2694 lFormHandle := TCDForm(hWnd) 2695 else 2696 raise Exception.Create('Invalid handle for GetDC'); 2697 2698 // Now get Form DC 2699 Result := HDC(lFormHandle.Canvas); 2700 2701 // If the Form DC doesn't yet exist, just give the ScreenDC 2702 // Anyone asking for a DC outside the Paint event can't expect 2703 // to receive something which can be drawn to anyway 2704 if Result = 0 then Result := HDC(CDWidgetset.ScreenDC); 2705 2706 {$ifdef VerboseCDDrawing} 2707 DebugLn(':<[WinAPI GetDC] Result: ', dbghex(Result)); 2708 {$endif} 2709end; 2710 2711(*function TQtWidgetSet.GetDCOriginRelativeToWindow(PaintDC: HDC; 2712 WindowHandle: HWND; var OriginDiff: TPoint): boolean; 2713var 2714 QtDC: TQtDeviceContext absolute PaintDC; 2715 Matrix: QTransformH; 2716 P: TPoint; 2717begin 2718 {$ifdef VerboseQtWinAPI} 2719 WriteLn('[WinAPI GetDCOriginRelativeToWindow] PaintDC ' + dbghex(PaintDC)); 2720 {$endif} 2721 Result := IsValidDC(PaintDC); 2722 if not Result then 2723 exit; 2724 Matrix := QPainter_transform(QtDC.Widget); 2725 OriginDiff := Point(0, 0); 2726 P := Point(0, 0); 2727 if WindowHandle <> 0 then 2728 P := TQtWidget(WindowHandle).getClientOffset; 2729 if Matrix <> nil then 2730 begin 2731 OriginDiff.X := Round(QTransform_Dx(Matrix)) - P.X; 2732 OriginDiff.Y := Round(QTransform_Dy(Matrix)) - P.Y; 2733 end; 2734end; 2735 2736{------------------------------------------------------------------------------ 2737 Function: GetDeviceCaps 2738 Params: DC: HDC; Index: Integer 2739 Returns: Integer 2740 2741 ------------------------------------------------------------------------------} 2742function TQtWidgetSet.GetDeviceCaps(DC: HDC; Index: Integer): Integer; 2743var 2744 QtDC: TQtDeviceContext; 2745 PaintDevice: QPaintDeviceH; 2746 PaintEngine: QPaintEngineH; 2747begin 2748 {$ifdef VerboseQtWinAPI} 2749 WriteLn('[WinAPI GetDeviceCaps] DC ' + dbghex(DC)); 2750 {$endif} 2751 2752 Result := 0; 2753 if DC = 0 then 2754 DC := HDC(QtScreenContext); 2755 2756 if not IsValidDC(DC) then exit; 2757 2758 QtDC := TQtDeviceContext(DC); 2759 2760 PaintEngine := QtDC.PaintEngine; 2761 if PaintEngine = nil then 2762 exit; 2763 PaintDevice := QPaintEngine_paintDevice(PaintEngine); 2764 2765 case Index of 2766 HORZSIZE: 2767 Result := QPaintDevice_widthMM(PaintDevice); 2768 VERTSIZE: 2769 Result := QPaintDevice_heightMM(PaintDevice); 2770 HORZRES: 2771 Result := QPaintDevice_width(PaintDevice); 2772 BITSPIXEL: 2773 Result := QPaintDevice_depth(PaintDevice); 2774 PLANES: 2775 Result := 1; 2776 SIZEPALETTE: 2777 Result := QPaintDevice_numColors(PaintDevice); 2778 LOGPIXELSX: 2779 Result := QPaintDevice_logicalDpiX(PaintDevice); 2780 LOGPIXELSY: 2781 Result := QPaintDevice_logicalDpiY(PaintDevice); 2782 VERTRES: 2783 Result := QPaintDevice_height(PaintDevice); 2784 NUMRESERVED: 2785 Result := 0; 2786 else 2787 Result := 0; 2788 end; 2789end;*) 2790 2791function TCDWidgetSet.GetDeviceSize(DC: HDC; var P: TPoint): Boolean; 2792Var 2793 ScrSize: TPoint; 2794 LazDC: TLazCanvas; 2795begin 2796 Result:= False; 2797 2798 // Screen size 2799 if IsScreenDC(DC) or (DC = 0) then 2800 begin 2801 P.X:= GetSystemMetrics(SM_CXSCREEN); 2802 P.Y:= GetSystemMetrics(SM_CYSCREEN); 2803 Exit(True); 2804 end; 2805 2806 if not IsValidDC(DC) then exit; 2807 LazDC := TLazCanvas(DC); 2808 2809 P.X := LazDC.Width; 2810 P.Y := LazDC.Height; 2811 2812 Result := True; 2813end; 2814 2815(*function TQtWidgetSet.GetDIBits(DC: HDC; Bitmap: HBitmap; StartScan, NumScans: UINT; Bits: Pointer; var BitInfo: BitmapInfo; Usage: UINT): Integer; 2816begin 2817 Result := 0; 2818 {$ifdef VerboseQtWinAPI_MISSING_IMPLEMENTATION} 2819 WriteLn('***** [WinAPI TQtWidgetSet.GetDIBits] missing implementation '); 2820 {$endif} 2821end; 2822 2823{------------------------------------------------------------------------------ 2824 Function: GetDoubleClickTime 2825 Params: none 2826 Returns: 2827 2828 ------------------------------------------------------------------------------} 2829function TQtWidgetSet.GetDoubleClickTime: UINT; 2830begin 2831 Result := QApplication_doubleClickInterval; 2832end;*) 2833 2834{------------------------------------------------------------------------------ 2835 Function: GetFocus 2836 Params: None 2837 Returns: Nothing 2838 ------------------------------------------------------------------------------} 2839function TCDWidgetSet.GetFocus: HWND; 2840begin 2841 Result := 0; 2842 // Don't return the intfcontrol, we try to pretend it doesn't exist 2843 {if FocusedIntfControl <> nil then Result := FocusedIntfControl.Handle 2844 else} 2845 if FocusedControl <> nil then Result := FocusedControl.Handle; 2846end; 2847 2848(*function TQtWidgetSet.GetKeyState(nVirtKey: Integer): Smallint; 2849const 2850 StateDown = SmallInt($FF80); 2851 {StateToggled = SmallInt($0001);} 2852begin 2853 Result := 0; 2854 2855 case nVirtKey of 2856 VK_LSHIFT: nVirtKey := VK_SHIFT; 2857 VK_LCONTROL: nVirtKey := VK_CONTROL; 2858 VK_LMENU: nVirtKey := VK_MENU; 2859 end; 2860 2861 // where to track toggle state? 2862 2863 case nVirtKey of 2864 VK_LBUTTON: 2865 if (QApplication_mouseButtons and QtLeftButton) > 0 then 2866 Result := Result or StateDown; 2867 VK_RBUTTON: 2868 if (QApplication_mouseButtons and QtRightButton) > 0 then 2869 Result := Result or StateDown; 2870 VK_MBUTTON: 2871 if (QApplication_mouseButtons and QtMidButton) > 0 then 2872 Result := Result or StateDown; 2873 VK_XBUTTON1: 2874 if (QApplication_mouseButtons and QtXButton1) > 0 then 2875 Result := Result or StateDown; 2876 VK_XBUTTON2: 2877 if (QApplication_mouseButtons and QtXButton2) > 0 then 2878 Result := Result or StateDown; 2879 VK_MENU: 2880 if (QApplication_keyboardModifiers and QtAltModifier) > 0 then 2881 Result := Result or StateDown; 2882 VK_SHIFT: 2883 if (QApplication_keyboardModifiers and QtShiftModifier) > 0 then 2884 Result := Result or StateDown; 2885 VK_CONTROL: 2886 if (QApplication_keyboardModifiers and QtControlModifier) > 0 then 2887 Result := Result or StateDown; 2888 VK_LWIN, VK_RWIN: 2889 if (QApplication_keyboardModifiers and QtMetaModifier) > 0 then 2890 Result := Result or StateDown; 2891 {$ifdef VerboseQtWinAPI} 2892 else 2893 DebugLn('TQtWidgetSet.GetKeyState TODO ', DbgSVKCode(Word(nVirtkey))); 2894 {$endif} 2895 end; 2896end; 2897 2898function TQtWidgetSet.GetMapMode(DC: HDC): Integer; 2899begin 2900 if IsValidDC(DC) then 2901 Result := TQtDeviceContext(DC).vMapMode 2902 else 2903 Result := 0; 2904end; 2905*) 2906 2907{$ifndef CD_UseNativeMonitors} 2908function TCDWidgetSet.GetMonitorInfo(Monitor: HMONITOR; lpmi: PMonitorInfo): Boolean; 2909begin 2910 Result := (lpmi <> nil) and (lpmi^.cbSize >= SizeOf(TMonitorInfo)) and (Monitor = 1); 2911 if not Result then Exit; 2912 lpmi^.rcMonitor:=Types.Rect(0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); 2913 lpmi^.rcWork:=lpmi^.rcMonitor; 2914 lpmi^.dwFlags := MONITORINFOF_PRIMARY 2915end; 2916{$endif} 2917(* 2918{------------------------------------------------------------------------------ 2919 Method: TQtWidgetSet.GetDeviceSize 2920 Params: none 2921 Returns: True if successful 2922 2923 Return the size of a device 2924 ------------------------------------------------------------------------------} 2925function TQtWidgetSet.GetDeviceSize(DC: HDC; var P: TPoint): Boolean; 2926begin 2927 {$ifdef VerboseQtWinAPI} 2928 WriteLn('[WinAPI GetDeviceSize]'); 2929 {$endif} 2930 2931 Result := False; 2932 2933 P.X := 0; 2934 P.Y := 0; 2935 2936 if not IsValidDC(DC) then Exit; 2937 2938 if (TObject(DC) is TQtDeviceContext) then 2939 P := TQtDeviceContext(DC).getDeviceSize; 2940 2941 Result := True; 2942end; 2943 2944{------------------------------------------------------------------------------ 2945 Method: TQtWidgetSet.GetObject 2946 Params: none 2947 Returns: The size written to the buffer 2948 2949 Necessary for TBitmap support 2950 ------------------------------------------------------------------------------} 2951function TQtWidgetSet.GetObject(GDIObj: HGDIOBJ; BufSize: Integer; Buf: Pointer): Integer; 2952const 2953 QtPenStyleToWinStyleMap: array[QtPenStyle] of UINT = 2954 ( 2955 { QtNoPen } PS_NULL, 2956 { QtSolidLine } PS_SOLID, 2957 { QtDashLine } PS_DASH, 2958 { QtDotLine } PS_DOT, 2959 { QtDashDotLine } PS_DASHDOT, 2960 { QtDashDotDotLine } PS_DASHDOTDOT, 2961 { QtCustomDashLine } PS_USERSTYLE 2962 ); 2963var 2964 aObject: TObject; 2965 AFont: TQtFont absolute aObject; 2966 APen: TQtPen absolute aObject; 2967 ABrush: TQtBrush absolute aObject; 2968 BitmapSection : TDIBSECTION; 2969 ALogFont: PLogFont absolute Buf; 2970 ALogPen: PLogPen absolute Buf; 2971 AExtLogPen: PExtLogPen absolute Buf; 2972 ALogBrush: PLogBrush absolute Buf; 2973 Dashes: TQRealArray; 2974 i: integer; 2975 {$ifdef VerboseQtWinAPI} 2976 ObjType: string; 2977 {$endif} 2978begin 2979 {$ifdef VerboseQtWinAPI} 2980 WriteLn('Trace:> [WinAPI GetObject] GDIObj: ' + dbghex(GDIObj)); 2981 ObjType := ''; 2982 {$endif} 2983 2984 Result := 0; 2985 2986 if not IsValidGDIObject(GDIObj) then 2987 begin 2988 {$ifdef VerboseQtWinAPI} 2989 WriteLn('Trace:< [WinAPI GetObject] Invalid GDI Object'); 2990 {$endif} 2991 2992 Exit; 2993 end; 2994 2995 aObject := TObject(GDIObj); 2996 2997 {------------------------------------------------------------------------------ 2998 Font 2999 ------------------------------------------------------------------------------} 3000 if aObject is TQtFont then 3001 begin 3002 if Buf = nil then 3003 Result := SizeOf(TLogFont) 3004 else 3005 if BufSize >= SizeOf(TLogFont) then 3006 begin 3007 Result := SizeOf(TLogFont); 3008 3009 FillChar(ALogFont^, SizeOf(ALogFont^), 0); 3010 ALogFont^.lfHeight := AFont.getPixelSize; 3011 ALogFont^.lfEscapement := AFont.Angle; 3012 case AFont.getWeight of 3013 10: ALogFont^.lfWeight := FW_THIN; 3014 15: ALogFont^.lfWeight := FW_EXTRALIGHT; 3015 25: ALogFont^.lfWeight := FW_LIGHT; 3016 50: ALogFont^.lfWeight := FW_NORMAL; 3017 55: ALogFont^.lfWeight := FW_MEDIUM; 3018 63: ALogFont^.lfWeight := FW_SEMIBOLD; 3019 75: ALogFont^.lfWeight := FW_BOLD; 3020 80: ALogFont^.lfWeight := FW_EXTRABOLD; 3021 87: ALogFont^.lfWeight := FW_HEAVY; 3022 end; 3023 3024 ALogFont^.lfItalic := Ord(AFont.getItalic) * High(Byte); 3025 ALogFont^.lfUnderline := Ord(AFont.getUnderline) * High(Byte); 3026 ALogFont^.lfStrikeOut := Ord(AFont.getStrikeOut) * High(Byte); 3027 ALogFont^.lfCharSet := DEFAULT_CHARSET; 3028 case AFont.getStyleStategy of 3029 QFontPreferMatch: ALogFont^.lfQuality := DRAFT_QUALITY; 3030 QFontPreferQuality: ALogFont^.lfQuality := PROOF_QUALITY; 3031 QFontNoAntialias: ALogFont^.lfQuality := NONANTIALIASED_QUALITY; 3032 QFontPreferAntialias: ALogFont^.lfQuality := ANTIALIASED_QUALITY; 3033 else 3034 ALogFont^.lfQuality := DEFAULT_QUALITY; 3035 end; 3036 ALogFont^.lfFaceName := UTF16ToUTF8(AFont.getFamily); 3037 end; 3038 end 3039 {------------------------------------------------------------------------------ 3040 Pen 3041 ------------------------------------------------------------------------------} 3042 else 3043 if aObject is TQtPen then 3044 begin 3045 if not APen.IsExtPen then 3046 begin 3047 if Buf = nil then 3048 Result := SizeOf(TLogPen) 3049 else 3050 if BufSize >= SizeOf(TLogPen) then 3051 begin 3052 Result := SizeOf(TLogPen); 3053 TQColorToColorRef(APen.getColor, ALogPen^.lopnColor); 3054 if APen.getCosmetic then 3055 ALogPen^.lopnWidth := Point(1, 0) 3056 else 3057 ALogPen^.lopnWidth := Point(APen.getWidth, 0); 3058 ALogPen^.lopnStyle := QtPenStyleToWinStyleMap[APen.getStyle]; 3059 end; 3060 end 3061 else 3062 begin 3063 i := SizeOf(TExtLogPen); 3064 if APen.getStyle = QtCustomDashLine then 3065 begin 3066 Dashes := APen.getDashPattern; 3067 inc(i, (Length(Dashes) - 1) * SizeOf(DWord)); 3068 end 3069 else 3070 Dashes := nil; 3071 if Buf = nil then 3072 Result := i 3073 else 3074 if BufSize >= i then 3075 begin 3076 Result := i; 3077 AExtLogPen^.elpPenStyle := QtPenStyleToWinStyleMap[APen.getStyle]; 3078 3079 if not APen.getCosmetic then 3080 begin 3081 AExtLogPen^.elpPenStyle := AExtLogPen^.elpPenStyle or PS_GEOMETRIC; 3082 3083 case APen.getJoinStyle of 3084 QtMiterJoin: AExtLogPen^.elpPenStyle := AExtLogPen^.elpPenStyle or PS_JOIN_MITER; 3085 QtBevelJoin: AExtLogPen^.elpPenStyle := AExtLogPen^.elpPenStyle or PS_JOIN_BEVEL; 3086 QtRoundJoin: AExtLogPen^.elpPenStyle := AExtLogPen^.elpPenStyle or PS_JOIN_ROUND; 3087 end; 3088 3089 case APen.getCapStyle of 3090 QtFlatCap: AExtLogPen^.elpPenStyle := AExtLogPen^.elpPenStyle or PS_ENDCAP_FLAT; 3091 QtSquareCap: AExtLogPen^.elpPenStyle := AExtLogPen^.elpPenStyle or PS_ENDCAP_SQUARE; 3092 QtRoundCap: AExtLogPen^.elpPenStyle := AExtLogPen^.elpPenStyle or PS_ENDCAP_ROUND; 3093 end; 3094 3095 AExtLogPen^.elpWidth := APen.getWidth; 3096 end 3097 else 3098 AExtLogPen^.elpWidth := 1; 3099 3100 AExtLogPen^.elpBrushStyle := BS_SOLID; 3101 TQColorToColorRef(APen.getColor, AExtLogPen^.elpColor); 3102 AExtLogPen^.elpHatch := 0; 3103 3104 AExtLogPen^.elpNumEntries := Length(Dashes); 3105 if AExtLogPen^.elpNumEntries > 0 then 3106 begin 3107 for i := 0 to AExtLogPen^.elpNumEntries - 1 do 3108 PDword(@AExtLogPen^.elpStyleEntry)[i] := Trunc(Dashes[i]); 3109 end 3110 else 3111 AExtLogPen^.elpStyleEntry[0] := 0; 3112 end; 3113 end; 3114 end 3115 {------------------------------------------------------------------------------ 3116 Region 3117 ------------------------------------------------------------------------------} 3118 else 3119 if aObject is TQtRegion then 3120 begin 3121 {TODO: implement Region} 3122 {$ifdef VerboseQtWinAPI} 3123 ObjType := 'Region'; 3124 {$endif} 3125 end else 3126 {------------------------------------------------------------------------------ 3127 Brush 3128 ------------------------------------------------------------------------------} 3129 if aObject is TQtBrush then 3130 begin 3131 if Buf = nil then 3132 Result := SizeOf(TLogBrush) 3133 else 3134 if BufSize >= SizeOf(TLogBrush) then 3135 begin 3136 Result := SizeOf(TLogBrush); 3137 TQColorToColorRef(ABrush.getColor^, ALogBrush^.lbColor); 3138 ABrush.GetLbStyle(ALogBrush^.lbStyle, ALogBrush^.lbHatch); 3139 end; 3140 end 3141 {------------------------------------------------------------------------------ 3142 Image 3143 ------------------------------------------------------------------------------} 3144 else 3145 if aObject is TQtImage then 3146 begin 3147 {$ifdef VerboseQtWinAPI} 3148 ObjType := 'Image'; 3149 {$endif} 3150 3151 if Buf = nil then 3152 Result := SizeOf(TDIBSECTION) 3153 else 3154 begin 3155 BitmapSection.dsOffset := 0; 3156 FillChar(BitmapSection, SizeOf(TDIBSECTION), 0); 3157 3158 with TQtImage(aObject) do 3159 begin 3160 {dsBM - BITMAP} 3161 BitmapSection.dsBm.bmType := $4D42; 3162 BitmapSection.dsBm.bmWidth := width; 3163 BitmapSection.dsBm.bmHeight := height; 3164 BitmapSection.dsBm.bmWidthBytes := bytesPerLine; 3165 BitmapSection.dsBm.bmPlanes := 1;//Does Bitmap Format support more? 3166 BitmapSection.dsBm.bmBitsPixel := depth; 3167 BitmapSection.dsBm.bmBits := bits; 3168 3169 {dsBmih - BITMAPINFOHEADER} 3170 BitmapSection.dsBmih.biSize := 40; 3171 BitmapSection.dsBmih.biWidth := BitmapSection.dsBm.bmWidth; 3172 BitmapSection.dsBmih.biHeight := BitmapSection.dsBm.bmHeight; 3173 BitmapSection.dsBmih.biPlanes := BitmapSection.dsBm.bmPlanes; 3174 BitmapSection.dsBmih.biBitCount := BitmapSection.dsBm.bmBitsPixel; 3175 3176 BitmapSection.dsBmih.biCompression := 0; 3177 3178 BitmapSection.dsBmih.biSizeImage := numBytes; 3179 BitmapSection.dsBmih.biXPelsPerMeter := dotsPerMeterX; 3180 BitmapSection.dsBmih.biYPelsPerMeter := dotsPerMeterY; 3181 3182 BitmapSection.dsBmih.biClrUsed := 0; 3183 BitmapSection.dsBmih.biClrImportant := 0; 3184 end; 3185 3186 if BufSize >= SizeOf(BitmapSection) then 3187 begin 3188 PDIBSECTION(Buf)^ := BitmapSection; 3189 Result := SizeOf(TDIBSECTION); 3190 end 3191 else if BufSize > 0 then 3192 begin 3193 Move(BitmapSection, Buf^, BufSize); 3194 Result := BufSize; 3195 end; 3196 end; 3197 end; 3198 3199 {$ifdef VerboseQtWinAPI} 3200 WriteLn('Trace:< [WinAPI GetObject] Result=', dbgs(Result), ' ObjectType=', ObjType); 3201 {$endif} 3202end;*) 3203 3204function TCDWidgetSet.GetParent(Handle : HWND): HWND; 3205var 3206 lHandle: TCDWinControl absolute Handle; 3207 lWinControl: TWinControl; 3208begin 3209 {$ifdef VerboseCDDrawing} 3210 DebugLn(Format('[TCDWidgetSet.GetParent] Handle: ', [Handle])); 3211 {$endif} 3212 3213 Result := 0; 3214 3215 // Invalid DC 3216 if Handle = 0 then Exit; 3217 if not IsValidDC(Handle) then Exit; 3218 3219 lWinControl := lHandle.GetWinControl(); 3220 if lWinControl = nil then Exit; 3221 lWinControl := lWinControl.Parent; 3222 if lWinControl = nil then Exit; 3223 Result := lWinControl.Handle; 3224end; 3225 3226function TCDWidgetSet.GetProp(Handle: hwnd; Str: PChar): Pointer; 3227begin 3228 if Handle<>0 then 3229 result := TCDWinControl(Handle).Props[str] 3230 else 3231 result := nil; 3232end; 3233 3234function TCDWidgetSet.GetRgnBox(RGN : HRGN; lpRect : PRect) : Longint; 3235var 3236 lLazRegion: TLazRegion absolute RGN; 3237begin 3238 if RGN = 0 then 3239 begin 3240 Result := ERROR; 3241 if lpRect <> nil then lpRect^ := Types.Rect(0,0,0,0); 3242 Exit(); 3243 end; 3244 3245 //Result := lLazRegion.IsSimpleRectRegion(); TQtRegion(RGN).GetRegionType; 3246 Result := SIMPLEREGION; 3247 if lpRect <> nil then lpRect^ := lLazRegion.GetBoundingRect(); 3248 3249 {$ifdef VerboseCDWinAPI} 3250 Debugln('Trace:> [WinAPI GetRgnBox] Handle: ' + dbghex(RGN)); 3251 {$endif} 3252end; 3253 3254(*function TQtWidgetSet.GetROP2(DC: HDC): Integer; 3255var 3256 QtDC: TQtDeviceContext absolute DC; 3257begin 3258 {$ifdef VerboseQtWinAPI} 3259 writeln('> TQtWidgetSet.GetROP2() DC ',dbghex(DC)); 3260 {$endif} 3261 Result := R2_COPYPEN; 3262 if not IsValidDC(DC) then 3263 exit; 3264 Result := QtDC.Rop2; 3265 {$ifdef VerboseQtWinAPI} 3266 writeln('< TQtWidgetSet.GetROP2() DC ',dbghex(DC),' Result ',Result); 3267 {$endif} 3268end; 3269 3270function TQtWidgetSet.GetScrollBarSize(Handle: HWND; BarKind: Integer): integer; 3271var 3272 w: TQtWidget; 3273 ScrollBar: TQtScrollBar; 3274begin 3275 {$ifdef VerboseQtWinAPI} 3276 writeln('Trace:> [WinAPI GetScrollBarSize] Handle: ' + dbghex(Handle),' BarKind: ',BarKind); 3277 {$endif} 3278 Result := 0; 3279 if Handle = 0 then exit; 3280 3281 w := TQtWidget(Handle); 3282 3283 {TODO: find out what to do with TCustomForm descendants } 3284 if w is TQtAbstractScrollArea then 3285 begin 3286 if BarKind in [SM_CXVSCROLL, SM_CYVSCROLL] then 3287 ScrollBar := TQtAbstractScrollArea(w).verticalScrollBar 3288 else 3289 ScrollBar := TQtAbstractScrollArea(w).horizontalScrollBar; 3290 end else 3291 if w is TQtScrollBar then 3292 ScrollBar := TQtScrollBar(w) 3293 else 3294 ScrollBar := nil; 3295 if ScrollBar <> nil then 3296 begin 3297 if BarKind in [SM_CXHSCROLL, SM_CYVSCROLL] then 3298 Result := ScrollBar.getWidth 3299 else 3300 Result := ScrollBar.getHeight; 3301 end; 3302end; 3303 3304function TQtWidgetSet.GetScrollbarVisible(Handle: HWND; SBStyle: Integer): boolean; 3305var 3306 w: TQtWidget; 3307 ScrollBar: TQtScrollBar; 3308begin 3309 {$ifdef VerboseQtWinAPI} 3310 writeln('Trace:> [WinAPI GetScrollBarVisible] Handle: ' + dbghex(Handle),' SBStyle: ',SBStyle); 3311 {$endif} 3312 Result := False; 3313 if Handle = 0 then exit; 3314 3315 w := TQtWidget(Handle); 3316 3317 {TODO: find out what to do with TCustomForm descendants } 3318 if w is TQtAbstractScrollArea then 3319 begin 3320 if SBStyle = SB_VERT then 3321 ScrollBar := TQtAbstractScrollArea(w).verticalScrollBar 3322 else 3323 ScrollBar := TQtAbstractScrollArea(w).horizontalScrollBar; 3324 end else 3325 if w is TQtScrollBar then 3326 ScrollBar := TQtScrollBar(w) 3327 else 3328 ScrollBar := nil; 3329 3330 if ScrollBar <> nil then 3331 Result := ScrollBar.getVisible; 3332end; 3333 3334{------------------------------------------------------------------------------ 3335 Function: GetScrollInfo 3336 Params: BarFlag 3337 SB_CTL Retrieves the parameters for a scroll bar control. The hwnd 3338 parameter must be the handle to the scroll bar control. 3339 SB_HORZ Retrieves the parameters for the window's standard horizontal 3340 scroll bar. 3341 SB_VERT Retrieves the parameters for the window's standard vertical 3342 scroll bar. 3343 3344 ScrollInfo returns TScrollInfo structure. 3345 3346 Returns: boolean 3347 3348 ------------------------------------------------------------------------------} 3349function TQtWidgetSet.GetScrollInfo(Handle: HWND; BarFlag: Integer; Var ScrollInfo: TScrollInfo): Boolean; 3350var 3351 QtScrollBar: TQtScrollBar; 3352begin 3353 Result := False; 3354 3355 if Handle = 0 then exit; 3356 3357 if (csDestroying in TQtWidget(Handle).LCLObject.ComponentState) or 3358 (csFreeNotification in TQtWidget(Handle).LCLObject.ComponentState) then 3359 exit; 3360 3361 QtScrollBar := nil; 3362 3363 if not TQtWidget(Handle).LCLObject.InheritsFrom(TCustomScrollBar) then 3364 begin 3365 if (TQtWidget(Handle) is TQtAbstractScrollArea) then 3366 begin 3367 case BarFlag of 3368 SB_HORZ: QtScrollBar := TQtAbstractScrollArea(Handle).horizontalScrollBar; 3369 SB_VERT: QtScrollBar := TQtAbstractScrollArea(Handle).verticalScrollBar; 3370 end; 3371 end else 3372 Result := False; 3373 end 3374 else 3375 QtScrollBar := TQtScrollBar(TScrollBar(TQtWidget(Handle).LCLObject).Handle); 3376 3377 if Assigned(QtScrollBar) then 3378 begin 3379 // POS 3380 if (ScrollInfo.fMask and SIF_POS) <> 0 then 3381 begin 3382 if QtScrollBar.ChildOfComplexWidget = ccwAbstractScrollArea then 3383 ScrollInfo.nPos := QtScrollBar.getSliderPosition 3384 else 3385 ScrollInfo.nPos := QtScrollBar.getValue; 3386 end; 3387 3388 // RANGE 3389 if (ScrollInfo.fMask and SIF_RANGE) <> 0 then 3390 begin 3391 ScrollInfo.nMin:= QtScrollBar.getMin; 3392 ScrollInfo.nMax:= QtScrollBar.getMax + QtScrollBar.getPageStep; 3393 end; 3394 // PAGE 3395 if (ScrollInfo.fMask and SIF_PAGE) <> 0 then 3396 ScrollInfo.nPage := QtScrollBar.getPageStep; 3397 3398 // TRACKPOS 3399 if (ScrollInfo.fMask and SIF_TRACKPOS) <> 0 then 3400 ScrollInfo.nTrackPos := QtScrollBar.getSliderPosition; 3401 3402 Result := True; 3403 end; 3404end;*) 3405 3406function TCDWidgetSet.GetStockObject(Value: Integer): THandle; 3407begin 3408 {$ifdef VerboseCDWinAPI} 3409 DebugLn(Format('Trace:> [WinAPI GetStockObject] Value: %d', [Value])); 3410 {$endif} 3411 3412 Result := 0; 3413 3414 case Value of 3415 BLACK_BRUSH: // Black brush. 3416 Result := THandle(FStockBlackBrush); 3417 DKGRAY_BRUSH: // Dark gray brush. 3418 Result := THandle(FStockDKGrayBrush); 3419 GRAY_BRUSH: // Gray brush. 3420 Result := THandle(FStockGrayBrush); 3421 LTGRAY_BRUSH: // Light gray brush. 3422 Result := THandle(FStockLtGrayBrush); 3423 NULL_BRUSH: // Null brush (equivalent to HOLLOW_BRUSH). 3424 Result := THandle(FStockNullBrush); 3425 WHITE_BRUSH: // White brush. 3426 Result := THandle(FStockWhiteBrush); 3427 3428 BLACK_PEN: // Black pen. 3429 Result := THandle(FStockBlackPen); 3430 NULL_PEN: // Null pen. 3431 Result := THandle(FStockNullPen); 3432 WHITE_PEN: // White pen. 3433 Result := THandle(FStockWhitePen); 3434 3435 {System font. By default, Windows uses the system font to draw menus, 3436 dialog box controls, and text. In Windows versions 3.0 and later, 3437 the system font is a proportionally spaced font; earlier versions of 3438 Windows used a monospace system font.} 3439 DEFAULT_GUI_FONT, SYSTEM_FONT: 3440 Result := THandle(FDefaultGUIFont); 3441 3442 {$ifdef VerboseCDWinAPI} 3443 else 3444 DebugLn(Format('[WinAPI GetStockObject] UNHANDLED Value: %d', [Value])); 3445 {$endif} 3446 end; 3447end; 3448 3449{------------------------------------------------------------------------------ 3450 Function: TCDWidgetSet.GetSysColor 3451 Params: index to the syscolors array 3452 Returns: RGB value 3453 3454 ------------------------------------------------------------------------------} 3455function TCDWidgetSet.GetSysColor(nIndex: Integer): DWORD; 3456begin 3457 if (nIndex < 0) or (nIndex > MAX_SYS_COLORS) then 3458 begin 3459 DebugLn('[TCDWidgetSet.GetSysColor] Unknown lcl system color: '); 3460 Result := 0; 3461 Exit; 3462 end; 3463 3464 case nIndex of 3465 COLOR_SCROLLBAR : Result:=GetDefaultDrawer().FallbackPalette.ScrollBar; 3466 COLOR_BACKGROUND : Result:=GetDefaultDrawer().FallbackPalette.Background; 3467 COLOR_ACTIVECAPTION : Result:=GetDefaultDrawer().FallbackPalette.ActiveCaption; 3468 COLOR_INACTIVECAPTION : Result:=GetDefaultDrawer().FallbackPalette.InactiveCaption; 3469 COLOR_MENU : Result:=GetDefaultDrawer().FallbackPalette.Menu; 3470 COLOR_WINDOW : Result:=GetDefaultDrawer().FallbackPalette.Window; 3471 COLOR_WINDOWFRAME : Result:=GetDefaultDrawer().FallbackPalette.WindowFrame; 3472 COLOR_MENUTEXT : Result:=GetDefaultDrawer().FallbackPalette.MenuText; 3473 COLOR_WINDOWTEXT : Result:=GetDefaultDrawer().FallbackPalette.WindowText; 3474 COLOR_CAPTIONTEXT : Result:=GetDefaultDrawer().FallbackPalette.CaptionText; 3475 COLOR_ACTIVEBORDER : Result:=GetDefaultDrawer().FallbackPalette.ActiveBorder; 3476 COLOR_INACTIVEBORDER : Result:=GetDefaultDrawer().FallbackPalette.InactiveBorder; 3477 COLOR_APPWORKSPACE : Result:=GetDefaultDrawer().FallbackPalette.AppWorkspace; 3478 COLOR_HIGHLIGHT : Result:=GetDefaultDrawer().FallbackPalette.Highlight; 3479 COLOR_HIGHLIGHTTEXT : Result:=GetDefaultDrawer().FallbackPalette.HighlightText; 3480 COLOR_BTNFACE : Result:=GetDefaultDrawer().FallbackPalette.BtnFace; 3481 COLOR_BTNSHADOW : Result:=GetDefaultDrawer().FallbackPalette.BtnShadow; 3482 COLOR_GRAYTEXT : Result:=GetDefaultDrawer().FallbackPalette.GrayText; 3483 COLOR_BTNTEXT : Result:=GetDefaultDrawer().FallbackPalette.BtnText; 3484 COLOR_INACTIVECAPTIONTEXT : Result:=GetDefaultDrawer().FallbackPalette.InactiveCaptionText; 3485 COLOR_BTNHIGHLIGHT : Result:=GetDefaultDrawer().FallbackPalette.BtnHighlight; 3486 COLOR_3DDKSHADOW : Result:=GetDefaultDrawer().FallbackPalette.color3DDkShadow; 3487 COLOR_3DLIGHT : Result:=GetDefaultDrawer().FallbackPalette.color3DLight; 3488 COLOR_INFOTEXT : Result:=GetDefaultDrawer().FallbackPalette.InfoText; 3489 COLOR_INFOBK : Result:=GetDefaultDrawer().FallbackPalette.InfoBk; 3490 // 3491 COLOR_HOTLIGHT : Result:=GetDefaultDrawer().FallbackPalette.HotLight; 3492 COLOR_GRADIENTACTIVECAPTION : Result:=GetDefaultDrawer().FallbackPalette.GradientActiveCaption; 3493 COLOR_GRADIENTINACTIVECAPTION : Result:=GetDefaultDrawer().FallbackPalette.GradientInactiveCaption; 3494 COLOR_MENUHILIGHT : Result:=GetDefaultDrawer().FallbackPalette.MenuHighlight; 3495 COLOR_MENUBAR : Result:=GetDefaultDrawer().FallbackPalette.MenuBar; 3496 // 3497 COLOR_FORM : Result:=GetDefaultDrawer().FallbackPalette.Form; 3498 else 3499 Result:=0; 3500 end; 3501end; 3502 3503(*function TQtWidgetSet.GetSysColorBrush(nIndex: Integer): HBrush; 3504 3505 function GetBrush(Group: QPaletteColorGroup; Role: QPaletteColorRole; ClassName: PAnsiChar = nil): HBrush; 3506 var 3507 Handle: QPaletteH; 3508 begin 3509 Handle := QPalette_create; 3510 if ClassName = nil then 3511 QApplication_palette(Handle) 3512 else 3513 QApplication_palette(Handle, ClassName); 3514 if FSysColorBrushes[nIndex] = 0 then 3515 Result := HBrush(TQtBrush.Create(False)) 3516 else 3517 Result := FSysColorBrushes[nIndex]; 3518 TQtBrush(Result).FHandle := QBrush_create(QPalette_brush(Handle, Group, Role)); 3519 TQtBrush(Result).FShared := True; 3520 3521 QPalette_destroy(Handle); 3522 end; 3523 3524 function GetSolidBrush(AColor: TColor): HBrush; 3525 var 3526 Color: TQColor; 3527 begin 3528 if FSysColorBrushes[nIndex] = 0 then 3529 Result := HBrush(TQtBrush.Create(True)) 3530 else 3531 Result := FSysColorBrushes[nIndex]; 3532 Color := QBrush_Color(TQtBrush(Result).FHandle)^; 3533 ColorRefToTQColor(ColorToRGB(AColor), Color); 3534 QBrush_setColor(TQtBrush(Result).FHandle, @Color); 3535 TQtBrush(Result).FShared := True; 3536 end; 3537 3538begin 3539 if (nIndex < 0) or (nIndex > MAX_SYS_COLORS) then 3540 begin 3541 Result := 0; 3542 Exit; 3543 end; 3544 3545 if (FSysColorBrushes[nIndex] = 0) or 3546 ( 3547 (FSysColorBrushes[nIndex] <> 0) and 3548 (TQtBrush(FSysColorBrushes[nIndex]).FHandle = nil) 3549 ) then 3550 begin 3551 case nIndex of 3552 COLOR_SCROLLBAR : Result:=GetBrush(QPaletteActive, QPaletteButton); 3553 COLOR_BACKGROUND : Result:=GetBrush(QPaletteActive, QPaletteWindow); 3554 COLOR_WINDOW : Result:=GetBrush(QPaletteInActive, QPaletteBase); 3555 COLOR_WINDOWFRAME : Result:=GetBrush(QPaletteActive, QPaletteShadow); 3556 COLOR_WINDOWTEXT : Result:=GetBrush(QPaletteActive, QPaletteWindowText); 3557 COLOR_ACTIVEBORDER : Result:=GetBrush(QPaletteActive, QPaletteWindow); 3558 COLOR_INACTIVEBORDER : Result:=GetBrush(QPaletteInactive, QPaletteWindow); 3559 COLOR_APPWORKSPACE : Result:=GetBrush(QPaletteActive, QPaletteWindow); 3560 COLOR_HIGHLIGHT : Result:=GetBrush(QPaletteActive, QPaletteHighlight); 3561 COLOR_HIGHLIGHTTEXT : Result:=GetBrush(QPaletteActive, QPaletteHighlightedText); 3562 COLOR_BTNFACE : Result:=GetBrush(QPaletteActive, QPaletteButton); 3563 COLOR_BTNSHADOW : Result:=GetBrush(QPaletteActive, QPaletteDark); 3564 COLOR_GRAYTEXT : Result:=GetBrush(QPaletteActive, QPaletteText); 3565 COLOR_BTNTEXT : Result:=GetBrush(QPaletteActive, QPaletteButtonText); 3566 COLOR_BTNHIGHLIGHT : Result:=GetBrush(QPaletteActive, QPaletteLight); 3567 COLOR_3DDKSHADOW : Result:=GetBrush(QPaletteActive, QPaletteShadow); 3568 COLOR_3DLIGHT : Result:=GetBrush(QPaletteActive, QPaletteMidlight); 3569 COLOR_INFOTEXT : Result:=GetBrush(QPaletteInActive, QPaletteToolTipText); 3570 COLOR_INFOBK : Result:=GetBrush(QPaletteInActive, QPaletteToolTipBase); 3571 COLOR_HOTLIGHT : Result:=GetBrush(QPaletteActive, QPaletteLight); 3572 3573 // qt does not provide any methods to retrieve titlebar colors 3574 {$IFNDEF MSWINDOWS} 3575 COLOR_ACTIVECAPTION : Result:=GetBrush(QPaletteActive, QPaletteHighlight); 3576 COLOR_INACTIVECAPTION : Result:=GetBrush(QPaletteInActive, QPaletteHighlight); 3577 COLOR_CAPTIONTEXT : Result:=GetBrush(QPaletteActive, QPaletteHighlightedText); 3578 COLOR_INACTIVECAPTIONTEXT : Result:=GetBrush(QPaletteInactive, QPaletteHighlightedText); 3579 COLOR_GRADIENTACTIVECAPTION : Result:=GetBrush(QPaletteActive, QPaletteBase); 3580 COLOR_GRADIENTINACTIVECAPTION : Result:=GetBrush(QPaletteInactive, QPaletteBase); 3581 {$ELSE} 3582 COLOR_ACTIVECAPTION : Result:=GetSolidBrush(Windows.GetSysColor(COLOR_ACTIVECAPTION)); 3583 COLOR_INACTIVECAPTION : Result:=GetSolidBrush(Windows.GetSysColor(COLOR_INACTIVECAPTION)); 3584 COLOR_CAPTIONTEXT : Result:=GetSolidBrush(Windows.GetSysColor(COLOR_CAPTIONTEXT)); 3585 COLOR_INACTIVECAPTIONTEXT : Result:=GetSolidBrush(Windows.GetSysColor(COLOR_INACTIVECAPTIONTEXT)); 3586 COLOR_GRADIENTACTIVECAPTION : Result:=GetSolidBrush(Windows.GetSysColor(COLOR_GRADIENTACTIVECAPTION)); 3587 COLOR_GRADIENTINACTIVECAPTION : Result:=GetSolidBrush(Windows.GetSysColor(COLOR_GRADIENTINACTIVECAPTION)); 3588 {$ENDIF} 3589 COLOR_MENU : Result:=GetBrush(QPaletteActive, QPaletteButton, 'QMenu'); 3590 COLOR_MENUTEXT : Result:=GetBrush(QPaletteActive, QPaletteButtonText, 'QMenu'); 3591 COLOR_MENUHILIGHT : Result:=GetBrush(QPaletteDisabled, QPaletteHighlight, 'QMenu'); 3592 COLOR_MENUBAR : Result:=GetBrush(QPaletteActive, QPaletteButton, 'QMenu'); 3593 COLOR_FORM : Result:=GetBrush(QPaletteActive, QPaletteWindow); 3594 else 3595 Result:=0; 3596 end; 3597 FSysColorBrushes[nIndex] := Result; 3598 end 3599 else 3600 Result := FSysColorBrushes[nIndex]; 3601end; 3602 3603{------------------------------------------------------------------------------ 3604 Function: GetSystemMetrics 3605 Params: 3606 Returns: Nothing 3607 3608 3609 ------------------------------------------------------------------------------} 3610function TQtWidgetSet.GetSystemMetrics(nIndex: Integer): Integer; 3611var 3612 R: TRect; 3613begin 3614 {$ifdef VerboseQtWinAPI} 3615 WriteLn(Format('Trace:> [TQtWidgetSet.GetSystemMetrics] %d', [nIndex])); 3616 {$endif} 3617 Result := 0; 3618 case nIndex of 3619 SM_ARRANGE: 3620 begin 3621 {$ifdef VerboseQtWinAPI} 3622 WriteLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_ARRANGE '); 3623 {$endif} 3624 end; 3625 SM_CLEANBOOT: 3626 begin 3627 {$ifdef VerboseQtWinAPI} 3628 WriteLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_CLEANBOOT '); 3629 {$endif} 3630 end; 3631 SM_CMONITORS: 3632 Result := QDesktopWidget_numScreens(QApplication_desktop()); 3633 SM_CMOUSEBUTTONS: 3634 begin 3635 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_CMOUSEBUTTONS '); 3636 end; 3637 SM_CXBORDER, SM_CYBORDER: 3638 begin 3639 // size of frame around controls 3640 Result := QStyle_pixelMetric(QApplication_style(), 3641 QStylePM_DefaultFrameWidth, nil, nil); 3642 end; 3643 SM_CXCURSOR: 3644 begin 3645 Result := 32; // recomended in docs 3646 end; 3647 SM_CYCURSOR: 3648 begin 3649 Result := 32; // recomended in docs 3650 end; 3651 SM_CXDOUBLECLK: 3652 begin 3653 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_CXDOUBLECLK '); 3654 end; 3655 SM_CYDOUBLECLK: 3656 begin 3657 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_CYDOUBLECLK '); 3658 end; 3659 SM_CXDRAG: 3660 begin 3661 Result := 2; 3662 end; 3663 SM_CYDRAG: 3664 begin 3665 Result := 2; 3666 end; 3667 SM_CXEDGE: 3668 begin 3669 Result := 2; 3670 end; 3671 SM_CYEDGE: 3672 begin 3673 Result := 2; 3674 end; 3675 SM_CXFIXEDFRAME: 3676 begin 3677 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_CXFIXEDFRAME '); 3678 end; 3679 SM_CYFIXEDFRAME: 3680 begin 3681 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_CYFIXEDFRAME '); 3682 end; 3683 SM_CXFULLSCREEN: 3684 begin 3685 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_CXFULLSCREEN '); 3686 end; 3687 SM_CYFULLSCREEN: 3688 begin 3689 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_CYFULLSCREEN '); 3690 end; 3691 SM_CXHTHUMB: 3692 begin 3693 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_CXHTHUMB '); 3694 end; 3695 SM_CXICON, 3696 SM_CYICON: 3697 begin 3698 Result := 32; 3699 end; 3700 SM_CXICONSPACING: 3701 begin 3702 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_CXICONSPACING '); 3703 end; 3704 SM_CYICONSPACING: 3705 begin 3706 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_CYICONSPACING '); 3707 end; 3708 SM_CXMAXIMIZED: 3709 begin 3710 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_CXMAXIMIZED '); 3711 end; 3712 SM_CYMAXIMIZED: 3713 begin 3714 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_CYMAXIMIZED '); 3715 end; 3716 SM_CXMAXTRACK: 3717 begin 3718 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_CXMAXTRACK '); 3719 end; 3720 SM_CYMAXTRACK: 3721 begin 3722 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_CYMAXTRACK '); 3723 end; 3724 SM_CXMENUCHECK: 3725 begin 3726 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_CXMENUCHECK '); 3727 end; 3728 SM_CYMENUCHECK: 3729 begin 3730 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_CYMENUCHECK '); 3731 end; 3732 SM_CXMENUSIZE: 3733 begin 3734 Result := QStyle_pixelMetric(QApplication_style(), QStylePM_IndicatorWidth, nil, nil); 3735 end; 3736 SM_CYMENUSIZE: 3737 begin 3738 Result := QStyle_pixelMetric(QApplication_style(), QStylePM_IndicatorHeight, nil, nil); 3739 end; 3740 SM_CXMIN: 3741 begin 3742 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_CXMIN '); 3743 end; 3744 SM_CYMIN: 3745 begin 3746 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_CYMIN '); 3747 end; 3748 SM_CXMINIMIZED: 3749 begin 3750 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_CXMINIMIZED '); 3751 end; 3752 SM_CYMINIMIZED: 3753 begin 3754 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_CYMINIMIZED '); 3755 end; 3756 SM_CXMINSPACING: 3757 begin 3758 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_CXMINSPACING '); 3759 end; 3760 SM_CYMINSPACING: 3761 begin 3762 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_CYMINSPACING '); 3763 end; 3764 SM_CXMINTRACK: 3765 begin 3766 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_CXMINTRACK '); 3767 end; 3768 SM_CYMINTRACK: 3769 begin 3770 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_CYMINTRACK '); 3771 end; 3772 SM_CXSCREEN: 3773 begin 3774 QDesktopWidget_screenGeometry(QApplication_desktop(), @R, QDesktopWidget_primaryScreen(QApplication_desktop())); 3775 Result := R.Right - R.Left; 3776 end; 3777 SM_CYSCREEN: 3778 begin 3779 QDesktopWidget_screenGeometry(QApplication_desktop(), @R, QDesktopWidget_primaryScreen(QApplication_desktop())); 3780 Result := R.Bottom - R.Top; 3781 end; 3782 SM_CXSIZE: 3783 begin 3784 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_CXSIZE '); 3785 end; 3786 SM_CYSIZE: 3787 begin 3788 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_CYSIZE '); 3789 end; 3790 SM_CXSIZEFRAME, 3791 SM_CYSIZEFRAME: 3792 begin 3793 Result := QStyle_pixelMetric(QApplication_style(), QStylePM_MDIFrameWidth, nil, nil); 3794 end; 3795 SM_CXSMICON, 3796 SM_CYSMICON: 3797 begin 3798 Result := 16 3799 end; 3800 SM_CXSMSIZE: 3801 begin 3802 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_CXSMSIZE '); 3803 end; 3804 SM_CYSMSIZE: 3805 begin 3806 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_CYSMSIZE '); 3807 end; 3808 SM_CXVIRTUALSCREEN: 3809 begin 3810 Result := QWidget_width(QApplication_desktop); 3811 end; 3812 SM_CYVIRTUALSCREEN: 3813 begin 3814 Result := QWidget_height(QApplication_desktop); 3815 end; 3816 SM_CXVSCROLL, 3817 SM_CYVSCROLL, 3818 SM_CXHSCROLL, 3819 SM_CYHSCROLL: 3820 begin 3821 Result := QStyle_pixelMetric(QApplication_Style, QStylePM_ScrollBarExtent, nil, nil); 3822 end; 3823 SM_CYCAPTION: 3824 begin 3825 Result := QStyle_pixelMetric(QApplication_Style, QStylePM_TitleBarHeight, nil, nil); 3826 end; 3827 SM_CYKANJIWINDOW: 3828 begin 3829 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_CYKANJIWINDOW '); 3830 end; 3831 SM_CYMENU: 3832 begin 3833 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_CYMENU '); 3834 end; 3835 SM_CYSMCAPTION: 3836 begin 3837 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_CYSMCAPTION '); 3838 end; 3839 SM_CYVTHUMB: 3840 begin 3841 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_CYVTHUMB '); 3842 end; 3843 SM_DBCSENABLED: 3844 begin 3845 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_DBCSENABLED '); 3846 end; 3847 SM_DEBUG: 3848 begin 3849 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_DEBUG '); 3850 end; 3851 SM_MENUDROPALIGNMENT: 3852 begin 3853 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_MENUDROPALIGNMENT'); 3854 end; 3855 SM_MIDEASTENABLED: 3856 begin 3857 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_MIDEASTENABLED '); 3858 end; 3859 SM_MOUSEPRESENT: 3860 begin 3861 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_MOUSEPRESENT '); 3862 end; 3863 SM_MOUSEWHEELPRESENT: 3864 begin 3865 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_MOUSEWHEELPRESENT'); 3866 end; 3867 SM_NETWORK: 3868 begin 3869 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_NETWORK '); 3870 end; 3871 SM_PENWINDOWS: 3872 begin 3873 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_PENWINDOWS '); 3874 end; 3875 SM_SECURE: 3876 begin 3877 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_SECURE '); 3878 end; 3879 SM_SHOWSOUNDS: 3880 begin 3881 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_SHOWSOUNDS '); 3882 end; 3883 SM_SLOWMACHINE: 3884 begin 3885 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_SLOWMACHINE '); 3886 end; 3887 SM_SWAPBUTTON: 3888 begin 3889 //DebugLn('Trace:TODO: [TQtWidgetSet.GetSystemMetrics] --> SM_SWAPBUTTON '); 3890 end; 3891 end; 3892end; *) 3893 3894{------------------------------------------------------------------------------ 3895 Function: GetTextColor 3896 Params: DC - A device context 3897 Returns: TColorRef 3898 3899 Gets the Font Color currently assigned to the Device Context 3900 ------------------------------------------------------------------------------} 3901function TCDWidgetSet.GetTextColor(DC: HDC) : TColorRef; 3902var 3903 lFont: TFPCustomFont; 3904 LazDC: TLazCanvas; 3905begin 3906 {$ifdef VerboseCDDrawing} 3907 DebugLn(Format('[TCDWidgetSet.SetTextColor] DC: %x', [DC])); 3908 {$endif} 3909 3910 Result := 0; 3911 if not IsValidDC(DC) then Exit; 3912 LazDC := TLazCanvas(DC); 3913 3914 if LazDC.Font <> nil then 3915 Result := FPColorToTColor(LazDC.Font.FPColor); 3916end; 3917 3918{$ifndef CD_UseNativeText} 3919{------------------------------------------------------------------------------ 3920 Function: GetTextExtentExPoint 3921 Params: http://msdn.microsoft.com/en-us/library/dd144935%28VS.85%29.aspx 3922 Returns: True on success 3923 ------------------------------------------------------------------------------} 3924function TCDWidgetSet.GetTextExtentExPoint(DC: HDC; Str: PChar; Count, 3925 MaxWidth: Integer; MaxCount, PartialWidths: PInteger; var Size: Types.TSize 3926 ): Boolean; 3927{var 3928 i: Integer; 3929 w: Integer; 3930 AStr: WideString; 3931 Accu: Integer; } 3932begin 3933// Result := False; 3934 Result := inherited GetTextExtentExPoint(DC, Str, Count, MaxWidth, 3935 MaxCount, PartialWidths, Size); 3936 {if not IsValidDC(DC) then Exit; 3937 with TQtDeviceContext(DC) do 3938 begin 3939 AStr := GetUtf8String(Str); 3940 Size.cx := 0; 3941 Size.cY := Font.Metrics.Height; 3942 if PartialWidths = nil then 3943 begin 3944 if MaxCount <> nil then 3945 begin 3946 Size.cx := Font.Metrics.width(@AStr); 3947 Accu := 0; 3948 if MaxWidth <= 0 then 3949 MaxCount^ := 0 3950 else 3951 for i := 0 to Count - 1 do 3952 begin 3953 W := QFontMetrics_charWidth(Font.Metrics.FHandle, @AStr, i); 3954 Accu := Accu + W; 3955 if Accu <= MaxWidth then 3956 MaxCount^ := i + 1 3957 else 3958 break; 3959 end; 3960 end; 3961 end else 3962 begin 3963 if MaxCount <> nil then 3964 MaxCount^ := 0; 3965 for i := 0 to Count - 1 do 3966 begin 3967 w := QFontMetrics_charWidth(Font.Metrics.FHandle, @AStr, i); 3968 Inc(Size.cx, w); 3969 if MaxCount <> nil then 3970 begin 3971 if Size.cx <= MaxWidth then 3972 begin 3973 inc(MaxCount^); 3974 PartialWidths[i] := Size.cx; 3975 end else 3976 begin 3977 Dec(Size.cx, w); 3978 break; 3979 end; 3980 end else 3981 PartialWidths[i] := Size.cx; 3982 end; 3983 end; 3984 end; 3985 Result := True;} 3986end; 3987 3988{------------------------------------------------------------------------------ 3989 Function: GetTextExtentPoint 3990 Params: none 3991 Returns: Nothing 3992 ------------------------------------------------------------------------------} 3993function TCDWidgetSet.GetTextExtentPoint(DC: HDC; Str: PChar; Count: Integer; var Size: Types.TSize): Boolean; 3994var 3995 LazDC: TLazCanvas absolute DC; 3996 ftFont: TFreeTypeFont; 3997begin 3998 {$ifdef VerboseCDWinAPI} 3999 DebugLn('[WinAPI GetTextExtentPoint]'); 4000 {$endif} 4001 4002 Result := False; 4003 4004 if not IsValidDC(DC) then Exit; 4005 4006 ftFont := TFreeTypeFont(LazDC.ExtraFontData); 4007 if ftFont = nil then 4008 begin 4009 DebugLn('[TCDWidgetSet.GetTextExtentPoint] Error: ExtraFontData not yet created'); 4010 Exit; 4011 end; 4012 Size.cx := Round(ftFont.TextWidth(Str)); 4013 Size.cy := Round(ftFont.TextHeight(Str)); 4014 if Size.cy = 0 then Size.cy := LazDC.AssignedFont.Size; // crude aproximation 4015 if Size.cy = 0 then Size.cy := DefaultFontSize; 4016 4017 Result := True; 4018end; 4019 4020{------------------------------------------------------------------------------ 4021 Function: GetTextMetrics 4022 Params: DC - A device context with a font selected 4023 TM - The structure to receive the font information 4024 Returns: If successfull 4025 ------------------------------------------------------------------------------} 4026function TCDWidgetSet.GetTextMetrics(DC: HDC; var TM: TTextMetric): Boolean; 4027var 4028 LazDC: TLazCanvas absolute DC; 4029 lTestText: string; 4030 lTestSize: Types.TSize; 4031 lFont: TFPCustomFont; 4032 lFTFont: TFreeTypeFont; 4033 FreeFTFont: Boolean = False; 4034begin 4035 {$ifdef VerboseCDWinAPI} 4036 DebugLn('[WinAPI GetTextMetrics]'); 4037 {$endif} 4038 4039 Result := False; 4040 4041 if not IsValidDC(DC) then Exit; 4042 4043 FillChar(TM, SizeOf(TM), 0); 4044 4045 lFont := LazDC.Font; 4046 lFTFont := TFreeTypeFont(LazDC.ExtraFontData); 4047 if lFTFont = nil then 4048 begin 4049 DebugLn('[TCDWidgetSet.GetTextMetrics] Error: ExtraFontData not yet created'); 4050 Exit; 4051 end; 4052 4053 //QtFontMetrics := QtDC.Metrics; 4054 TM.tmHeight := Round(lFTFont.TextHeight('ŹÇ')); 4055 TM.tmAscent := Round(lFTFont.Ascent); 4056 TM.tmDescent := Round(lFTFont.Descent); 4057 TM.tmInternalLeading := 0; 4058 TM.tmExternalLeading := 0;// ToDo 4059 TM.tmAveCharWidth := Round(lFTFont.TextWidth('x')); 4060 TM.tmMaxCharWidth := Round(lFTFont.TextWidth('M')); 4061 4062 if lFont.Bold then TM.tmWeight := FW_BOLD 4063 else TM.tmWeight := FW_NORMAL; 4064 4065 TM.tmOverhang := 0; 4066 TM.tmDigitizedAspectX := 0; 4067 TM.tmDigitizedAspectY := 0; 4068 TM.tmFirstChar := 'a'; 4069 TM.tmLastChar := 'z'; 4070 TM.tmDefaultChar := 'x'; 4071 TM.tmBreakChar := '?'; 4072 TM.tmItalic := Ord(lFont.Italic); 4073 TM.tmUnderlined := Ord(lFont.Underline); 4074 {$IF (FPC_FULLVERSION<=20600) or (FPC_FULLVERSION=20602)} 4075 TM.tmStruckOut := Ord(lFont.StrikeTrough); //old version with typo 4076 {$ELSE} 4077 TM.tmStruckOut := Ord(lFont.StrikeThrough); 4078 {$ENDIF} 4079 4080 { Defaults to a TrueType font. 4081 Note that the meaning of the FIXED_PITCH constant is the opposite of 4082 the name implies, according to MSDN docs. Just a small inconsistency 4083 on Windows API that we have to mimic. } 4084{ if QtDC.font.fixedPitch then 4085 TM.tmPitchAndFamily := TRUETYPE_FONTTYPE 4086 else} 4087 TM.tmPitchAndFamily := FIXED_PITCH or TRUETYPE_FONTTYPE; 4088 4089 TM.tmCharSet := DEFAULT_CHARSET; 4090 4091 Result := True; 4092 4093 if FreeFTFont then lFTFont.Free; 4094end; 4095{$endif} 4096 4097(*function TQtWidgetSet.GetViewPortExtEx(DC: HDC; Size: PSize): Integer; 4098var 4099 R: TRect; 4100begin 4101 if IsValidDC(DC) and (Size <> nil) then 4102 begin 4103 QPainter_ViewPort(TQtDeviceContext(DC).Widget, @R); 4104 Size^.cx := R.Right - R.Left; 4105 Size^.cy := R.Bottom - R.Top; 4106 Result := Integer(True); 4107 end else 4108 Result := Integer(False); 4109end; 4110 4111function TQtWidgetSet.GetViewPortOrgEx(DC: HDC; P: PPoint): Integer; 4112var 4113 R: TRect; 4114begin 4115 if IsValidDC(DC) and (P <> nil) then 4116 begin 4117 QPainter_ViewPort(TQtDeviceContext(DC).Widget, @R); 4118 P^ := R.TopLeft; 4119 Result := Integer(True); 4120 end else 4121 Result := Integer(False); 4122end; 4123 4124function TQtWidgetSet.GetWindowExtEx(DC: HDC; Size: PSize): Integer; 4125var 4126 R: TRect; 4127begin 4128 if IsValidDC(DC) and (Size <> nil) then 4129 begin 4130 QPainter_Window(TQtDeviceContext(DC).Widget, @R); 4131 Size^.cx := R.Right - R.Left; 4132 Size^.cy := R.Bottom - R.Top; 4133 Result := Integer(True); 4134 end else 4135 Result := Integer(False); 4136end; 4137 4138function TQtWidgetSet.GetWindowLong(Handle : hwnd; int: Integer): PtrInt; 4139begin 4140 Result := 0; 4141 {$ifdef VerboseQtWinAPI_MISSING_IMPLEMENTATION} 4142 WriteLn('***** [WinAPI TQtWidgetSet.GetWindowLong] missing implementation '); 4143 {$endif} 4144end;*) 4145 4146{------------------------------------------------------------------------------ 4147 Method: GetWindowOrgEx 4148 Params: DC - 4149 Returns: 4150 ------------------------------------------------------------------------------} 4151function TCDWidgetSet.GetWindowOrgEx(dc: hdc; P: PPoint): Integer; 4152var 4153 LazDC: TLazCanvas absolute DC; 4154begin 4155 {$ifdef VerboseCDDrawing} 4156 DebugLn(Format(':>[WinAPI GetWindowOrgEx] DC=%s', [dbghex(DC)])); 4157 {$endif} 4158 Result := 0; 4159 if not IsValidDC(DC) then Exit; 4160 if P = nil then Exit; 4161 4162 P^.X := LazDC.WindowOrg.X - LazDC.BaseWindowOrg.X; 4163 P^.Y := LazDC.WindowOrg.Y - LazDC.BaseWindowOrg.Y; 4164 Result := 1; // any non-zero will do according to MSDN 4165 {$ifdef VerboseCDDrawing} 4166 DebugLn(':<[WinAPI GetWindowOrgEx] Result='+dbgs(p^)); 4167 {$endif} 4168end; 4169 4170 4171(*{------------------------------------------------------------------------------ 4172 Method: GetWindowRect 4173 Params: Handle - handle of window 4174 Rect - record for window coordinates 4175 Returns: if the function succeeds, the return value is nonzero; if the 4176 function fails, the return value is zero 4177 4178 Retrieves the dimensions of the bounding rectangle of the specified window. 4179 ------------------------------------------------------------------------------} 4180function TCDWidgetSet.GetWindowRect(Handle: HWND; var ARect: TRect): Integer; 4181var 4182 APos: TQtPoint; 4183 R: TRect; 4184begin 4185 {$ifdef VerboseQtWinAPI} 4186 WriteLn('[WinAPI GetWindowRect]'); 4187 {$endif} 4188 4189 Result := 0; 4190 if not IsValidHandle(Handle) then 4191 exit; 4192 APos := QtPoint(0,0); 4193 QWidget_mapToGlobal(TQtWidget(Handle).Widget, @APos, @APos); 4194 4195 R := TQtWidget(Handle).getFrameGeometry; 4196 ARect := Bounds(APos.X,APos.Y,R.Right-R.Left,R.Bottom-R.Top); 4197 4198 Result := -1; 4199end;*) 4200 4201{------------------------------------------------------------------------------ 4202 Function: GetWindowRelativePosition 4203 Params: Handle : HWND; 4204 Returns: true on success 4205 4206 returns the current widget Left, Top, relative to the client origin of its 4207 parent 4208 ------------------------------------------------------------------------------} 4209function TCDWidgetSet.GetWindowRelativePosition(Handle: HWND; var Left, Top: integer): boolean; 4210var 4211 lObject: TObject; 4212begin 4213 {$ifdef VerboseCDWinAPI} 4214 DebugLn('[WinAPI GetWindowRelativePosition]'); 4215 {$endif} 4216 if Handle = 0 then Exit(False); 4217 lObject := TObject(Handle); 4218 if lObject is TCDForm then 4219 begin 4220 Result := BackendGetWindowRelativePosition(Handle, Left, Top); 4221 Exit; 4222 end 4223 else 4224 Result := inherited GetWindowRelativePosition(Handle, Left, Top); 4225end; 4226 4227{------------------------------------------------------------------------------ 4228 Function: GetWindowSize 4229 Params: Handle : hwnd; 4230 Returns: true on success 4231 4232 Returns the current widget Width and Height 4233 ------------------------------------------------------------------------------} 4234function TCDWidgetSet.GetWindowSize(Handle: hwnd; var Width, Height: integer): boolean; 4235var 4236 lObject: TObject; 4237 lCDWinControl: TCDWinControl; 4238begin 4239 {$ifdef VerboseCDWinAPI} 4240 DebugLn(':>[WinAPI GetWindowSize]'); 4241 {$endif} 4242 if Handle = 0 then Exit(False); 4243 lObject := TObject(Handle); 4244 if lObject is TCDForm then 4245 begin 4246 // Initial size guessed 4247 if TCDForm(lObject).Image <> nil then 4248 begin 4249 Width := TCDForm(lObject).Image.Width; 4250 Height := TCDForm(lObject).Image.Height; 4251 end 4252 else 4253 begin 4254 Width := 0; 4255 Height := 0; 4256 end; 4257 4258 // Now ask the backend 4259 Result := BackendGetWindowSize(Handle, Width, Height); 4260 end 4261 else if lObject is TCDWinControl then 4262 begin 4263 lCDWinControl := lObject as TCDWinControl; 4264 Width := lCDWinControl.WinControl.Width; 4265 Height := lCDWinControl.WinControl.Height; 4266 Result := True; 4267 {$ifdef VerboseCDWinAPI} 4268 DebugLn(Format(':[WinAPI GetWindowSize] WinControl %s:%s', 4269 [lCDWinControl.WinControl.Name, lCDWinControl.WinControl.ClassName])); 4270 {$endif} 4271 end 4272 else 4273 Result := False; 4274 4275 {$ifdef VerboseCDWinAPI} 4276 DebugLn(Format(':<[WinAPI GetWindowSize] Result=%d Width=%d Height=%d', 4277 [PtrInt(Result), Width, Height])); 4278 {$endif} 4279end; 4280 4281(*{------------------------------------------------------------------------------ 4282 Function: GradientFill 4283 Params: DC - DeviceContext to perform on 4284 Vertices - array of Points W/Color & Alpha 4285 NumVertices - Number of Vertices 4286 Meshes - array of Triangle or Rectangle Meshes, 4287 each mesh representing one Gradient Fill 4288 NumMeshes - Number of Meshes 4289 Mode - Gradient Type, either Triangle, 4290 Vertical Rect, Horizontal Rect 4291 4292 Returns: true on success 4293 4294 Performs multiple Gradient Fills, either a Three way Triangle Gradient, 4295 or a two way Rectangle Gradient, each Vertex point also supports optional 4296 Alpha/Transparency for more advanced Gradients. 4297 ------------------------------------------------------------------------------} 4298function TQtWidgetSet.GradientFill(DC: HDC; Vertices: PTriVertex; 4299 NumVertices : Longint; 4300 Meshes: Pointer; NumMeshes : Longint; Mode : Longint): boolean; 4301 4302 function DoFillTriangle: Boolean; inline; 4303 begin 4304 Result := (Mode and GRADIENT_FILL_TRIANGLE) = GRADIENT_FILL_TRIANGLE; 4305 end; 4306 4307 function DoFillVRect: Boolean; inline; 4308 begin 4309 Result := (Mode and GRADIENT_FILL_RECT_V) = GRADIENT_FILL_RECT_V; 4310 end; 4311 4312 function VertexToColor(AVertex: tagTRIVERTEX): TQColor; 4313 var 4314 TheAlpha: Byte; 4315 begin 4316 TheAlpha := AVertex.Alpha shr 8; 4317 if TheAlpha = 0 then 4318 TheAlpha := 255; 4319 with AVertex do 4320 QColor_fromRgb(@Result, Red shr 8, Green shr 8, Blue shr 8, TheAlpha); 4321 end; 4322 4323 function FillTriMesh(Mesh: tagGradientTriangle) : Boolean; 4324 var 4325 V1, V2, V3: tagTRIVERTEX; 4326 C1, C2, C3: TQColor; 4327 Grad: QConicalGradientH; 4328 Brush: QBrushH; 4329 Triangle: QPolygonH; 4330 R: TRect; 4331 Painter: QPainterH; 4332 Rgn: QRegionH; 4333 begin 4334 with Mesh do 4335 begin 4336 Result := 4337 (Vertex1 < Cardinal(NumVertices)) and (Vertex2 >= 0) and 4338 (Vertex2 < Cardinal(NumVertices)) and (Vertex2 >= 0) and 4339 (Vertex3 < Cardinal(NumVertices)) and (Vertex3 >= 0); 4340 4341 if (Vertex1 = Vertex2) or 4342 (Vertex1 = Vertex3) or 4343 (Vertex2 = Vertex3) or not Result then 4344 Exit; 4345 4346 V1 := Vertices[Vertex1]; 4347 V2 := Vertices[Vertex2]; 4348 V3 := Vertices[Vertex3]; 4349 4350 Painter := TQtDeviceContext(DC).Widget; 4351 QPainter_save(Painter); 4352 Triangle := QPolygon_create(3); 4353 QPolygon_setPoint(Triangle, 0, V1.X, V1.Y); 4354 QPolygon_setPoint(Triangle, 1, V2.X, V2.Y); 4355 QPolygon_setPoint(Triangle, 2, V3.X, V3.Y); 4356 QPolygon_boundingRect(Triangle, @R); 4357 4358 Dec(R.Bottom); 4359 Dec(R.Right); 4360 4361 Rgn := QRegion_create(@R); 4362 4363 // make our poly clip region , so gradient center is at real center 4364 QPainter_setClipRegion(Painter, Rgn, QtIntersectClip); 4365 4366 Grad := QConicalGradient_create(R.Right div 2, R.Bottom div 2, 90); 4367 C1 := VertexToColor(V1); 4368 C2 := VertexToColor(V2); 4369 C3 := VertexToColor(V3); 4370 4371 QGradient_setColorAt(Grad, 0.0, @C1); // open 4372 QGradient_setColorAt(Grad, 0.33, @C2); // left corner 4373 QGradient_setColorAt(Grad, 0.66, @C3); // right corner 4374 QGradient_setColorAt(Grad, 1.0, @C1); // close 4375 4376 4377 Brush := QBrush_create(Grad); 4378 QPainter_setPen(Painter, QtNoPen); 4379 QPainter_setBrush(Painter, Brush); 4380 4381 // move center point down, so we remove reflections of C2 and C3 4382 // TODO: C1 reflection is still visible 4383 QPainter_setBrushOrigin(Painter, 0, R.Bottom div 5); 4384 QPainter_drawPolygon(Painter, Triangle); 4385 4386 //TODO: now me must make it look "softer" because reflection look of 4387 // first color is ugly. 4388 4389 QBrush_destroy(Brush); 4390 QPolygon_destroy(Triangle); 4391 QGradient_destroy(Grad); 4392 QRegion_destroy(Rgn); 4393 QPainter_restore(Painter); 4394 4395 end; 4396 end; 4397 4398 function FillRectMesh(Mesh: tagGradientRect) : boolean; 4399 var 4400 TL,BR: tagTRIVERTEX; 4401 StartColor, EndColor, SwapColor: TQColor; 4402 Swap: Longint; 4403 SwapColors: Boolean; 4404 Grad: QGradientH; 4405 Brush: QBrushH; 4406 begin 4407 with Mesh do 4408 begin 4409 Result := 4410 (UpperLeft < Cardinal(NumVertices)) and (UpperLeft >= 0) and 4411 (LowerRight < Cardinal(NumVertices)) and (LowerRight >= 0); 4412 if (LowerRight = UpperLeft) or not Result then 4413 Exit; 4414 4415 TL := Vertices[UpperLeft]; 4416 BR := Vertices[LowerRight]; 4417 SwapColors := (BR.Y < TL.Y) and (BR.X < TL.X); 4418 if BR.X < TL.X then 4419 begin 4420 Swap := BR.X; 4421 BR.X := TL.X; 4422 TL.X := Swap; 4423 end; 4424 if BR.Y < TL.Y then 4425 begin 4426 Swap := BR.Y; 4427 BR.Y := TL.Y; 4428 TL.Y := Swap; 4429 end; 4430 StartColor := VertexToColor(TL); 4431 EndColor := VertexToColor(BR); 4432 if SwapColors then 4433 begin 4434 SwapColor := StartColor; 4435 StartColor := EndColor; 4436 EndColor := SwapColor; 4437 end; 4438 if DoFillVRect then 4439 Grad := QLinearGradient_create(TL.X, TL.Y, TL.X, BR.Y) 4440 else 4441 Grad := QLinearGradient_create(TL.X, TL.Y, BR.X, TL.Y); 4442 QGradient_setColorAt(Grad, 0, @StartColor); 4443 QGradient_setColorAt(Grad, 1, @EndColor); 4444 Brush := QBrush_create(Grad); 4445 TQtDeviceContext(DC).fillRect(TL.X, TL.Y, BR.X - TL.X, BR.Y - TL.Y, Brush); 4446 QGradient_destroy(Grad); 4447 QBrush_destroy(Brush); 4448 end; 4449 end; 4450 4451const 4452 MeshSize: Array[Boolean] of Integer = ( 4453 SizeOf(tagGradientRect), SizeOf(tagGradientTriangle)); 4454var 4455 i : Integer; 4456begin 4457 {$ifdef VerboseQtWinAPI} 4458 WriteLn('***** [WinAPI TQtWidgetSet.GradientFill] '); 4459 {$endif} 4460 4461 //Currently Alpha blending is ignored... Ideas anyone? 4462 Result := (Meshes <> nil) and (NumMeshes >= 1) and (NumVertices >= 2) 4463 and (Vertices <> nil); 4464 if Result and DoFillTriangle then 4465 Result := NumVertices >= 3; 4466 if Result then 4467 begin 4468 Result := False; 4469 4470 //Sanity Checks For Vertices Size vs. Count 4471 if MemSize(Vertices) < PtrUInt(SizeOf(tagTRIVERTEX)*NumVertices) then 4472 exit; 4473 4474 //Sanity Checks For Meshes Size vs. Count 4475 if MemSize(Meshes) < PtrUInt(MeshSize[DoFillTriangle]*NumMeshes) then 4476 exit; 4477 4478 for I := 0 to NumMeshes - 1 do 4479 begin 4480 if DoFillTriangle then 4481 begin 4482 if not FillTriMesh(PGradientTriangle(Meshes)[I]) then 4483 exit; 4484 end 4485 else 4486 begin 4487 if not FillRectMesh(PGradientRect(Meshes)[I]) then 4488 exit; 4489 end; 4490 end; 4491 Result := True; 4492 end; 4493end; 4494 4495function TQtWidgetSet.HideCaret(hWnd: HWND): Boolean; 4496begin 4497 Result := (hWnd <> 0) and QtCaret.HideCaret(TQtWidget(hWnd)); 4498end;*) 4499 4500{------------------------------------------------------------------------------ 4501 Procedure: InitializeCriticalSection 4502 Params: var CritSection: TCriticalSection 4503 Returns: 4504 ------------------------------------------------------------------------------} 4505procedure TCDWidgetSet.InitializeCriticalSection(var CritSection: TCriticalSection); 4506var 4507 ACritSec: System.PRTLCriticalSection; 4508begin 4509 New(ACritSec); 4510 System.InitCriticalSection(ACritSec^); 4511 CritSection:=TCriticalSection(ACritSec); 4512end; 4513 4514(*function TQtWidgetSet.IntersectClipRect(dc: hdc; Left, Top, Right, Bottom: Integer): Integer; 4515var 4516 QtDC: TQtDeviceContext absolute dc; 4517 IntersectRgn, Rgn: QRegionH; 4518begin 4519 {$ifdef VerboseQtWinAPI} 4520 WriteLn('[WinAPI TQtWidgetSet.IntersectClipRect] L ',Left,' T ',Top,' R ',Right,' B ',Bottom); 4521 {$endif} 4522 Result := ERROR; 4523 if not IsValidDC(DC) then exit; 4524 4525 IntersectRgn := QRegion_create(Left, Top, Right - Left, Bottom - Top); 4526 try 4527 if QtDC.getClipping then 4528 begin 4529 Rgn := QRegion_create; 4530 try 4531 QPainter_clipRegion(QtDC.Widget, Rgn); 4532 if QRegion_isEmpty(Rgn) then 4533 QtDC.setClipRegion(IntersectRgn) 4534 else 4535 QtDC.setClipRegion(IntersectRgn, QtIntersectClip); 4536 QtDC.setClipping(True); 4537 // recreate Rgn 4538 QRegion_destroy(Rgn); 4539 Rgn := QRegion_create; 4540 QPainter_clipRegion(QtDC.Widget, Rgn); 4541 Result := QtDC.GetRegionType(Rgn); 4542 finally 4543 QRegion_destroy(Rgn); 4544 end; 4545 end else 4546 begin 4547 QtDC.setClipRegion(InterSectRgn); 4548 QtDC.setClipping(True); 4549 Result := QtDC.GetRegionType(InterSectRgn); 4550 end; 4551 finally 4552 QRegion_destroy(IntersectRgn); 4553 end; 4554end;*) 4555 4556(*function TCDWidgetSet.IsIconic(Handle: HWND): boolean; 4557begin 4558 Result := TCDForm(Handle).LCLForm.FormState = fsMinimized; 4559end;*) 4560 4561function TCDWidgetSet.IsWindow(handle: HWND): boolean; 4562begin 4563 Result := TObject(Handle) is TCDForm; 4564end; 4565 4566function TCDWidgetSet.IsWindowEnabled(Handle: HWND): boolean; 4567begin 4568 Result := TCDForm(Handle).LCLForm.Enabled; 4569end; 4570 4571function TCDWidgetSet.IsWindowVisible(Handle: HWND): boolean; 4572begin 4573 Result := TCDForm(Handle).LCLForm.Visible; 4574end; 4575 4576(*function TQtWidgetSet.IsZoomed(Handle: HWND): boolean; 4577begin 4578 Result := TQtWidget(Handle).isMaximized; 4579end;*) 4580 4581{------------------------------------------------------------------------------ 4582 Function: InvalidateRect 4583 Params: aHandle: 4584 Rect: 4585 bErase: 4586 Returns: 4587 4588 ------------------------------------------------------------------------------} 4589function TCDWidgetSet.InvalidateRect(aHandle: HWND; Rect: pRect; bErase: Boolean): Boolean; 4590var 4591 lHandle: TObject; 4592 lControlHandle: TCDWinControl; 4593 lControl: TWinControl; 4594begin 4595 {$ifdef VerboseCDDrawing} 4596 DebugLn('[WinAPI InvalidateRect]'); 4597 {$endif} 4598 if AHandle = 0 then exit(False); 4599 4600 lHandle := TObject(AHandle); 4601 4602 // Invalidate on a child control 4603 if lHandle is TCDWinControl then 4604 begin 4605 lControlHandle := TCDWinControl(lHandle); 4606 lControlHandle.IncInvalidateCount(); 4607 if lControlHandle.CDControlInjected and (lControlHandle.CDControl <> nil) then 4608 TCDWinControl(lControlHandle.CDControl.Handle).IncInvalidateCount(); 4609 lControl := lControlHandle.WinControl; 4610 lControl := Forms.GetParentForm(lControl); 4611 // Don't use Rect in BackendInvalidateRect unless we really make the full 4612 // conversion of coordinates to window coordinates. Better invalidate everything 4613 // then too few. And anyway on each draw we send everything. 4614 // This fixes changing the selection in TCustomGrid 4615 Result := BackendInvalidateRect(lControl.Handle, nil, BErase); 4616 end 4617 // Invalidate on a form 4618 else 4619 begin 4620 Result := BackendInvalidateRect(AHandle, Rect, BErase); 4621 end; 4622 4623 Result := True; 4624end; 4625 4626{------------------------------------------------------------------------------ 4627 Function: InvalidateRgn 4628 Params: aHandle: 4629 Rect: 4630 bErase: 4631 Returns: True if invalidate is successfull. 4632 Invalidates region of widget. 4633 4634 Felipe: Invalidating a non-rectangular region is unusual and complicated, 4635 so for now lets just get the bounding rect and invalidate that instead. 4636 ------------------------------------------------------------------------------} 4637function TCDWidgetSet.InvalidateRgn(aHandle: HWND; Rgn: HRGN; Erase: Boolean): Boolean; 4638var 4639 lLazRegion: TLazRegion absolute Rgn; 4640 localRect: TRect; 4641begin 4642 {$ifdef VerboseCDWinAPI} 4643 DebugLn('[WinAPI InvalidateRgn]'); 4644 {$endif} 4645 if aHandle = 0 then Exit(False); 4646 if Rgn <> 0 then 4647 begin 4648 localRect := lLazRegion.GetBoundingRect(); 4649 Result := InvalidateRect(aHandle, @localRect, Erase); 4650 end 4651 else 4652 Result := InvalidateRect(aHandle, nil, Erase); 4653end; 4654 4655{------------------------------------------------------------------------------ 4656 Procedure: LeaveCriticalSection 4657 Params: var CritSection: TCriticalSection 4658 Returns: Nothing 4659 ------------------------------------------------------------------------------} 4660procedure TCDWidgetSet.LeaveCriticalSection(var CritSection: TCriticalSection); 4661var 4662 ACritSec: System.PRTLCriticalSection; 4663begin 4664 ACritSec:=System.PRTLCriticalSection(CritSection); 4665 System.LeaveCriticalsection(ACritSec^); 4666end; 4667 4668{------------------------------------------------------------------------------ 4669 Function: LineTo 4670 Params: none 4671 Returns: Nothing 4672 4673 4674 ------------------------------------------------------------------------------} 4675function TCDWidgetSet.LineTo(DC: HDC; X, Y: Integer): Boolean; 4676var 4677 PenPos, LastPos: TPoint; 4678 LazDC: TLazCanvas absolute DC; 4679begin 4680 {$ifdef VerboseCDDrawing} 4681 DebugLn(Format('[TCDWidgetSet.LineTo] DC=%x X=%d Y=%d', [DC, X, Y])); 4682 {$endif} 4683 4684 Result := False; 4685 4686 if not IsValidDC(DC) then 4687 begin 4688 DebugLn('[TCDWidgetSet.LineTo] Invalid DC'); 4689 Exit; 4690 end; 4691 4692(* TQtDeviceContext(DC).getPenPos(@PenPos); 4693 LastPos := Point(X, Y); 4694 if TQtDeviceContext(DC).pen.getCosmetic then 4695 LastPos := TQtDeviceContext(DC).GetLineLastPixelPos(PenPos, LastPos); 4696 TQtDeviceContext(DC).drawLine(PenPos.X, PenPos.Y, LastPos.X, LastPos.Y); 4697 MoveToEx(DC, X, Y, nil);*) 4698 4699 LazDC.LineTo(X, Y); 4700 4701 Result := True; 4702end; 4703(* 4704function TQtWidgetSet.LPtoDP(DC: HDC; var Points; Count: Integer): BOOL; 4705var 4706 P: PPoint; 4707 QtPoint: TQtPoint; 4708 Matrix: QTransformH; 4709 QtDC: TQtDeviceContext; 4710begin 4711 Result := False; 4712 4713 if not IsValidDC(DC) then 4714 Exit; 4715 4716 QtDC := TQtDeviceContext(DC); 4717 4718 Matrix := QPainter_transform(QtDC.Widget); 4719 P := @Points; 4720 while Count > 0 do 4721 begin 4722 Dec(Count); 4723 QtPoint.X := P^.X; 4724 QtPoint.Y := P^.Y; 4725 QTransform_map(Matrix, PQtPoint(@QtPoint), PQtPoint(@QtPoint)); 4726 P^.X := QtPoint.X; 4727 P^.Y := QtPoint.Y; 4728 Inc(P); 4729 end; 4730 4731 Result := True; 4732end;*) 4733 4734{------------------------------------------------------------------------------ 4735 Function: MoveToEx 4736 Params: none 4737 Returns: Nothing 4738 ------------------------------------------------------------------------------} 4739function TCDWidgetSet.MoveToEx(DC: HDC; X, Y: Integer; OldPoint: PPoint): Boolean; 4740var 4741 LazDC: TLazCanvas absolute DC; 4742begin 4743 {$ifdef VerboseCDDrawing} 4744 DebugLn('[WinAPI MoveToEx]', 4745 ' DC:', dbghex(DC), 4746 ' X:', dbgs(X), 4747 ' Y:', dbgs(Y)); 4748 {$endif} 4749 4750 Result := False; 4751 4752 if not IsValidDC(DC) then Exit; 4753 4754 if (OldPoint <> nil) then OldPoint^ := LazDC.PenPos; 4755 4756 LazDC.PenPos := Types.Point(X, Y); 4757 4758 Result := True; 4759end; 4760 4761(*function TQtWidgetSet.OffsetRgn(RGN: HRGN; nXOffset, nYOffset: Integer): Integer; 4762var 4763 QtRgn: QRegionH; 4764begin 4765 Result := ERROR; 4766 4767 if not IsValidGDIObject(RGN) then 4768 Exit 4769 else 4770 QtRgn := TQtRegion(RGN).FHandle; 4771 4772 QRegion_translate(QtRgn, nXOffset, nYOffset); 4773 4774 if QRegion_isEmpty(QtRgn) then 4775 Result := NULLREGION 4776 else 4777 begin 4778 if TQtRegion(RGN).IsPolyRegion or (TQtRegion(RGN).numRects > 0) then 4779 Result := COMPLEXREGION 4780 else 4781 Result := SIMPLEREGION; 4782 end; 4783end; 4784 4785function TQtWidgetSet.PeekMessage(var lpMsg : TMsg; Handle : HWND; wMsgFilterMin, wMsgFilterMax,wRemoveMsg : UINT): Boolean; 4786begin 4787 Result := False; 4788 {$ifdef VerboseQtWinAPI_MISSING_IMPLEMENTATION} 4789 WriteLn('***** [WinAPI TQtWidgetSet.PeekMessage] missing implementation '); 4790 {$endif} 4791end;*) 4792 4793{------------------------------------------------------------------------------ 4794 Function: PolyBezier 4795 Params: DC: HDC; Points: PPoint; NumPts: Integer; Filled: Boolean; 4796 Continuous: Boolean 4797 Returns: Nothing 4798 ------------------------------------------------------------------------------} 4799function TCDWidgetSet.PolyBezier(DC: HDC; Points: PPoint; NumPts: Integer; 4800 Filled, Continuous: Boolean): Boolean; 4801begin 4802 {$ifdef VerboseCDDrawing} 4803 WriteLn('[WinAPI PolyBezier] DC: ', dbghex(DC)); 4804 {$endif} 4805 Result := inherited PolyBezier(DC, Points, NumPts, Filled, Continuous); 4806end; 4807 4808{------------------------------------------------------------------------------ 4809 Function: Polygon 4810 Params: DC: HDC; Points: PPoint; NumPts: Integer; Winding: Boolean 4811 Returns: Nothing 4812 ------------------------------------------------------------------------------} 4813function TCDWidgetSet.Polygon(DC: HDC; Points: PPoint; NumPts: Integer; 4814 Winding: Boolean): boolean; 4815var 4816 LazDC: TLazCanvas absolute DC; 4817 lPoints: array of TPoint; 4818 i: Integer; 4819begin 4820 {$ifdef VerboseCDDrawing} 4821 DebugLn(Format(':>[WinAPI Polygon] DC=%s', [dbghex(DC)])); 4822 {$endif} 4823 4824 if not IsValidDC(DC) then Exit(False); 4825 4826 SetLength(lPoints, NumPts); 4827 for i := 0 to NumPts-1 do 4828 begin 4829 {$ifdef VerboseCDDrawing} 4830 LCLProc.DbgOut(Format(' P=%d,%d', [Points[i].X, Points[i].Y])); 4831 {$endif} 4832 lPoints[i] := Points[i]; 4833 end; 4834 4835 LazDC.Polygon(lPoints); 4836 Result := True; 4837 4838 {$ifdef VerboseCDDrawing} 4839 DebugLn(''); 4840 {$endif} 4841end; 4842 4843{------------------------------------------------------------------------------ 4844 Function: Polyline 4845 Params: DC: HDC; Points: PPoint; NumPts: Integer 4846 Returns: Nothing 4847 ------------------------------------------------------------------------------} 4848function TCDWidgetSet.Polyline(DC: HDC; Points: PPoint; NumPts: Integer): boolean; 4849var 4850 LazDC: TLazCanvas absolute DC; 4851 lPoints: array of TPoint; 4852 i: Integer; 4853begin 4854 {$ifdef VerboseCDDrawing} 4855 DebugLn(Format(':>[WinAPI Polygon] DC=%s', [dbghex(DC)])); 4856 {$endif} 4857 4858 if not IsValidDC(DC) then Exit(False); 4859 4860 SetLength(lPoints, NumPts); 4861 for i := 0 to NumPts-1 do 4862 lPoints[i] := Points[i]; 4863 4864 LazDC.Polyline(lPoints); 4865 Result := True; 4866end; 4867 4868(*function TQtWidgetSet.PostMessage(Handle: HWND; Msg: Cardinal; wParam: WParam; lParam: LParam): Boolean; 4869var 4870 Widget: TQtWidget absolute Handle; 4871 Event: QLCLMessageEventH; 4872begin 4873 Result := False; 4874 if Handle <> 0 then 4875 begin 4876 Event := QLCLMessageEvent_create(QEventLCLMessage, Msg, wParam, lParam, 0); 4877 QCoreApplication_postEvent(Widget.Widget, Event, 1 {high priority}); 4878 Result := True; 4879 end; 4880end;*) 4881 4882function TCDWidgetSet.PtInRegion(RGN: HRGN; X, Y: Integer): Boolean; 4883var 4884 lRegion: TLazRegion absolute RGN; 4885begin 4886 Result := False; 4887 4888 if not IsValidGDIObject(RGN) then Exit; 4889 4890 Result := lRegion.IsPointInRegion(X, Y); 4891end; 4892 4893{------------------------------------------------------------------------------ 4894 Function: Rectangle 4895 Params: DC: HDC; X1, Y1, X2, Y2: Integer 4896 Returns: Nothing 4897 4898 The Rectangle function draws a rectangle. The rectangle is outlined by using 4899 the current pen and filled by using the current brush. 4900 ------------------------------------------------------------------------------} 4901function TCDWidgetSet.Rectangle(DC: HDC; X1, Y1, X2, Y2: Integer): Boolean; 4902var 4903 LazDC: TLazCanvas absolute DC; 4904begin 4905 {$ifdef VerboseCDDrawing} 4906 DebugLn(Format(':>[WinAPI Rectangle] DC=%s', [dbghex(DC)])); 4907 {$endif} 4908 4909 if not IsValidDC(DC) then 4910 begin 4911 {$ifdef VerboseCDDrawing} 4912 DebugLn(':<[WinAPI Rectangle] Invalid DC!'); 4913 {$endif} 4914 Exit(False); 4915 end; 4916 4917 // ToDo: We can normalize the rectangle, but this is not necessary as 4918 // TLazCanvas ignores invalid coordinates 4919{ R := NormalizeRect(Rect(X1, Y1, X2, Y2)); 4920 if IsRectEmpty(R) then Exit(True);} 4921 4922 LazDC.Rectangle(X1, Y1, X2, Y2); 4923 4924 Result := True; 4925end; 4926 4927function TCDWidgetSet.RectVisible(dc : hdc; const ARect: TRect) : Boolean; 4928var 4929 LazDC: TLazCanvas; 4930begin 4931 {$ifdef VerboseCDDrawing} 4932 Debugln('[WinAPI RectVisible]'); 4933 {$endif} 4934 Result := True; 4935 if not IsValidDC(DC) then Exit; 4936 LazDC := TLazCanvas(DC); 4937 // as MSDN says only clipping region can play here 4938{ if QtDC.getClipping then 4939 Result := QtDC.getClipRegion.containsRect(ARect);} 4940end; 4941 4942(*{------------------------------------------------------------------------------ 4943 Function: RedrawWindow 4944 Params: Wnd: 4945 lprcUpdate: 4946 hrgnUpdate: 4947 flags: 4948 Returns: 4949 4950 ------------------------------------------------------------------------------} 4951function TQtWidgetSet.RedrawWindow(Wnd: HWND; lprcUpdate: PRECT; hrgnUpdate: HRGN; flags: UINT): Boolean; 4952var 4953 QtWidget: TQtWidget; 4954 Region: TQtRegion; 4955begin 4956 if not IsValidHandle(Wnd) then 4957 Exit(False); 4958 4959 QtWidget := TQtWidget(Wnd); 4960 if IsValidGDIObject(hrgnUpdate) then 4961 Region := TQtRegion(hrgnUpdate) 4962 else 4963 Region := nil; 4964 if (lprcUpdate = nil) and (hrgnUpdate = 0) then 4965 begin 4966 QtWidget.Update(nil); 4967 Exit(True); 4968 end; 4969 4970 if Region = nil then 4971 Result := InvalidateRect(Wnd, lprcUpdate, False) 4972 else 4973 QtWidget.UpdateRegion(Region.FHandle); 4974 4975 Result := True; 4976end; 4977 4978function TQtWidgetSet.ReleaseCapture: Boolean; 4979var 4980 w: TQtWidget; 4981begin 4982 w := TQtWidget(GetCapture); 4983 Result := w <> nil; 4984 if Result then 4985 begin 4986 {$IFDEF MSWINDOWS} 4987 if w is TQtMainWindow then 4988 w.releaseMouse() 4989 else 4990 windows.ReleaseCapture; 4991 {$ELSE} 4992 w.releaseMouse(); 4993 {$ENDIF} 4994 end; 4995 {$ifdef VerboseQtWinAPI} 4996 WriteLn('[WinAPI ReleaseCapture] Capture = ', THandle(w)); 4997 {$endif} 4998end; 4999 5000{------------------------------------------------------------------------------ 5001 Function: ReleaseDC 5002 Params: hWnd: Handle to the window whose DC is to be released. 5003 hDC: Handle to the DC to be released. 5004 Returns: 5005 ------------------------------------------------------------------------------} 5006function TQtWidgetSet.ReleaseDC(hWnd: HWND; DC: HDC): Integer; 5007begin 5008 {$ifdef VerboseQtWinAPI} 5009 WriteLn('[WinAPI ReleaseDC]', 5010 ' hWnd: ', dbghex(hWnd), 5011 ' DC: ', dbghex(DC)); 5012 {$endif} 5013 5014 Result := 0; 5015 5016 if IsValidDC(DC) then Exit; 5017 5018 Result := 1; 5019end;*) 5020 5021{------------------------------------------------------------------------------ 5022 Function: RestoreDC: Restore a previously saved DC state 5023 Params: 5024 DC: Handle to a DeviceContext 5025 SavedDC: Index of saved state that needs to be restored 5026 Returns: True if state was successfuly restored. 5027-------------------------------------------------------------------------------} 5028function TCDWidgetSet.RestoreDC(DC: HDC; SavedDC: Integer): Boolean; 5029var 5030 LazDC: TLazCanvas absolute DC; 5031begin 5032 {$ifdef VerboseQTWinAPI} 5033 WriteLn('Trace:> [WinAPI RestoreDC] DC=', dbghex(DC),' SavedDC=',SavedDC); 5034 {$Endif} 5035 Result := False; 5036 if not IsValidDC(DC) then Exit; 5037 5038 LazDC.RestoreState(SavedDC); 5039 Result := True; 5040 {$ifdef VerboseQTWinAPI} 5041 WriteLn('Trace:< [WinAPI RestoreDC]'); 5042 {$Endif} 5043end; 5044 5045(*function TQtWidgetSet.RoundRect(DC: hDC; X1, Y1, X2, Y2: Integer; RX,RY : Integer): Boolean; 5046begin 5047 Result := False; 5048 if not IsValidDC(DC) then 5049 begin 5050 {$ifdef VerboseQTWinAPI} 5051 WriteLn('Trace:< [WinAPI RoundRect] DC Invalid, result=', result); 5052 {$Endif} 5053 Exit; 5054 end; 5055 Result := inherited RoundRect(DC, X1, Y1, X2, Y2, RX, RY); 5056end;*) 5057 5058{------------------------------------------------------------------------------ 5059 Function: SaveDC: save DC state information to a stack 5060 Params: DC 5061 Returns: The index assigned to the or 0 if DC is not valid 5062-------------------------------------------------------------------------------} 5063function TCDWidgetSet.SaveDC(DC: HDC): Integer; 5064var 5065 LazDC: TLazCanvas absolute DC; 5066begin 5067 {$ifdef VerboseQTWinAPI} 5068 WriteLn('Trace:> [WinAPI SaveDC] DC=', dbghex(DC)); 5069 {$Endif} 5070 5071 result:=0; 5072 5073 if not IsValidDC(DC) then 5074 begin 5075 {$ifdef VerboseQTWinAPI} 5076 WriteLn('Trace:< [WinAPI SaveDC] DC Invalid, result=', result); 5077 {$Endif} 5078 exit; 5079 end; 5080 5081 Result := LazDC.SaveState(); 5082 5083 {$ifdef VerboseQTWinAPI} 5084 WriteLn('Trace:< [WinAPI SaveDC] result=', Result); 5085 {$Endif} 5086end; 5087 5088(*{------------------------------------------------------------------------------ 5089 Function: ScreenToClient 5090 Params: Handle: HWND; var P: TPoint 5091 Returns: 5092-------------------------------------------------------------------------------} 5093function TQtWidgetSet.ScreenToClient(Handle : HWND; var P : TPoint) : Integer; 5094var 5095 APoint: TQtPoint; 5096begin 5097 Result := 0; 5098 if IsValidHandle(Handle) then 5099 begin 5100 APoint := QtPoint(P.X, P.Y); 5101 QWidget_mapFromGlobal(TQtWidget(Handle).GetContainerWidget, @APoint, @APoint); 5102 P := Point(APoint.x, APoint.y); 5103 Result := 1; 5104 end; 5105end; 5106 5107{------------------------------------------------------------------------------ 5108 Method: ScrollWindowEx 5109 Params: HWnd - handle of window to scroll 5110 DX - horizontal amount to scroll 5111 DY - vertical amount to scroll 5112 PRcScroll - pointer to scroll rectangle 5113 PRcClip - pointer to clip rectangle 5114 HRgnUpdate - handle of update region 5115 PRcUpdate - pointer to update rectangle 5116 Flags - scrolling flags 5117 5118 Returns: True if succesfull 5119 5120 The ScrollWindowEx function scrolls the content of the specified window's 5121 client area 5122 ------------------------------------------------------------------------------} 5123function TQtWidgetSet.ScrollWindowEx(HWnd: HWND; DX, DY: Integer; PRcScroll, 5124 PRcClip: PRect; HRgnUpdate: HRGN; PRcUpdate: PRect; Flags: UINT): Boolean; 5125var 5126 R: TRect; 5127 W: TQtWidget; 5128begin 5129 Result := False; 5130 if (HWND = 0) then exit; 5131 5132 W := TQtWidget(HWND); 5133 if ((Flags and SW_SCROLLCHILDREN) <> 0) then 5134 W.scroll(dx, dy, nil) 5135 else 5136 if (PrcScroll = nil) then 5137 begin 5138 R := W.getClientBounds; 5139 W.scroll(dx, dy, @R); 5140 end 5141 else 5142 W.scroll(dx, dy, PRcScroll); 5143 5144 if ((Flags and SW_INVALIDATE) <> 0) then 5145 begin 5146 if IsValidGDIObject(HRgnUpdate) then 5147 begin 5148 R := TQtRegion(HRgnUpdate).getBoundingRect; 5149 PRcUpdate := @R; 5150 W.Update(@R); 5151 end else 5152 if PRcClip <> nil then 5153 begin 5154 PRcUpdate := PRcClip; 5155 W.Update(PrcClip); 5156 end; 5157 end; 5158 5159 Result := True; 5160end;*) 5161 5162{------------------------------------------------------------------------------ 5163 Function: SelectClipRGN 5164 Params: DC, RGN 5165 Returns: longint 5166 5167 Sets the DeviceContext's ClipRegion. The Return value 5168 is the new clip regions type, or ERROR. 5169 5170 The result can be one of the following constants 5171 Error 5172 NullRegion 5173 SimpleRegion 5174 ComplexRegion 5175 ------------------------------------------------------------------------------} 5176function TCDWidgetSet.SelectClipRGN(DC: hDC; RGN: HRGN): Longint; 5177begin 5178 Result := ExtSelectClipRgn(DC, RGN, RGN_COPY); 5179end; 5180 5181{------------------------------------------------------------------------------ 5182 Function: SelectObject 5183 Params: none 5184 Returns: The GDI object of the same type previously associated with the DC 5185 5186 Changes one of the GDI objects (Font, Brush, etc) of a Device Context; 5187 ------------------------------------------------------------------------------} 5188function TCDWidgetSet.SelectObject(DC: HDC; GDIObj: HGDIOBJ): HGDIOBJ; 5189var 5190 aObject: TObject; 5191 lFont: TFPCustomFont absolute AObject; 5192 lPen: TFPCustomPen absolute AObject; 5193 lBrush: TFPCustomBrush absolute AObject; 5194 lOrigBrush: TFPCustomBrush; 5195 {$ifdef VerboseCDDrawing} 5196 ObjType: string; 5197 {$endif} 5198begin 5199 {$ifdef VerboseCDDrawing} 5200 DebugLn(Format(':>[TCDWidgetSet.SelectObject] DC=%s GDIObj=%s', 5201 [dbghex(DC), dbghex(GDIObj)])); 5202 {$endif} 5203 5204 Result := 0; 5205 5206 if not IsValidDC(DC) then 5207 begin 5208 {$ifdef VerboseCDDrawing} 5209 DebugLn(':<[TCDWidgetSet.SelectObject] Invalid DC'); 5210 {$endif} 5211 5212 Exit; 5213 end; 5214 5215 if not IsValidGDIObject(GDIObj) then 5216 begin 5217 {$ifdef VerboseCDDrawing} 5218 DebugLn(':<[TCDWidgetSet.SelectObject] Invalid GDI Object'); 5219 {$endif} 5220 5221 Exit; 5222 end; 5223 5224 aObject := TObject(GDIObj); 5225 5226 if aObject is TFPCustomFont then 5227 begin 5228 {$ifdef VerboseCDDrawing}ObjType := 'Font';{$endif} 5229 5230 Result := HGDIOBJ(TLazCanvas(DC).AssignedFont); 5231 TLazCanvas(DC).AssignFontData(lFont); // := doesn't work and Assign() raises exceptions 5232 TLazCanvas(DC).AssignedFont := lFont; 5233 {$ifndef CD_UseNativeText} 5234 TLazCanvas(DC).ExtraFontData := TLazCDCustomFont(lFont).FTFont; 5235 {$endif} 5236 end 5237 else if aObject is TFPCustomPen then 5238 begin 5239 {$ifdef VerboseCDDrawing}ObjType := 'Pen';{$endif} 5240 5241 Result := HGDIOBJ(TLazCanvas(DC).AssignedPen); 5242 TLazCanvas(DC).AssignPenData(lPen); // := doesn't work and Assign() raises exceptions 5243 TLazCanvas(DC).AssignedPen := lPen; 5244 end 5245 else if aObject is TFPCustomBrush then 5246 begin 5247 {$ifdef VerboseCDDrawing}ObjType := 'Brush';{$endif} 5248 5249 Result := HGDIOBJ(TLazCanvas(DC).AssignedBrush); 5250 TLazCanvas(DC).AssignBrushData(lBrush); // := doesn't work and Assign() raises exceptions 5251 TLazCanvas(DC).AssignedBrush := lBrush; 5252 end 5253 else if aObject is TCDBitmap then 5254 begin 5255 {$ifdef VerboseCDDrawing}ObjType := 'Bitmap';{$endif} 5256 5257 Result := HGDIOBJ(TLazCanvas(DC).Image); 5258 5259 TLazCanvas(DC).Image := TCDBitmap(aObject).Image; 5260 TLazCanvas(DC).SelectedBitmap := aObject; 5261 end; (*else 5262 if AObject is TQtRegion then 5263 begin 5264 Result := HGDIOBJ(TQtDeviceContext(DC).getClipRegion); 5265 SelectClipRGN(DC, HRGN(GDIObj)); 5266 end*); 5267 5268 {$ifdef VerboseCDDrawing} 5269 DebugLn(':<[TCDWidgetSet.SelectObject] Result=', dbghex(Result), ' ObjectType=', ObjType); 5270 {$endif} 5271end; 5272 5273(*function TQtWidgetSet.SendMessage(HandleWnd: HWND; Msg: Cardinal; 5274 WParam: WParam; LParam: LParam): LResult; 5275var 5276 Widget: TQtWidget absolute HandleWnd; 5277 Event: QLCLMessageEventH; 5278begin 5279 Result := 0; 5280 if (HandleWnd <> 0) and (Widget.Widget <> nil) then 5281 begin 5282 Event := QLCLMessageEvent_create(QEventLCLMessage, Msg, wParam, lParam, 0); 5283 try 5284 QCoreApplication_sendEvent(Widget.Widget, Event); 5285 Result := QLCLMessageEvent_getMsgResult(Event); 5286 finally 5287 QLCLMessageEvent_destroy(Event); 5288 end; 5289 end; 5290end; 5291 5292function TQtWidgetSet.SetActiveWindow(Handle: HWND): HWND; 5293begin 5294 Result := GetActiveWindow; 5295 5296 if Handle <> 0 then 5297 TQtWidget(Handle).Activate 5298 else 5299 Result := 0; // error 5300end; 5301 5302{------------------------------------------------------------------------------ 5303 Function: SetBKColor 5304 Params: X: 5305 Y: 5306 Returns: 5307 5308 ------------------------------------------------------------------------------} 5309function TQtWidgetSet.SetBKColor(DC: HDC; Color: TColorRef): TColorRef; 5310begin 5311 {$ifdef VerboseQtWinAPI} 5312 WriteLn('Trace:> [WinAPI SetBkColor]', 5313 ' DC: ', dbghex(DC), 5314 ' Color: ', dbgs(Color)); 5315 {$endif} 5316 5317 Result := 0; 5318 5319 if not IsValidDC(DC) then 5320 begin 5321 {$ifdef VerboseQtWinAPI} 5322 WriteLn('Trace:< [WinAPI SetBkColor] Invalid DC'); 5323 {$endif} 5324 5325 Exit; 5326 end; 5327 5328 Result := TQtDeviceContext(DC).SetBkColor(TColorRef(Color)); 5329end; 5330 5331{------------------------------------------------------------------------------ 5332 Method: SetBkMode 5333 Params: DC - 5334 Returns: 5335 ------------------------------------------------------------------------------} 5336function TQtWidgetSet.SetBkMode(DC: HDC; bkMode: Integer): Integer; 5337begin 5338 {$ifdef VerboseQtWinAPI} 5339 WriteLn('Trace:> [WinAPI SetBkMode] DC=', dbghex(DC), ' BkMode=', dbgs(bkMode)); 5340 {$endif} 5341 5342 Result := 0; 5343 5344 if not IsValidDC(DC) then 5345 begin 5346 {$ifdef VerboseQtWinAPI} 5347 WriteLn('Trace:< [WinAPI SetBkMode] Invalid DC'); 5348 {$endif} 5349 5350 Exit; 5351 end; 5352 5353 Result := TQtDeviceContext(DC).SetBkMode(bkMode); 5354end; 5355 5356function TQtWidgetSet.SetCapture(AHandle: HWND): HWND; 5357var 5358 Message: TLMessage; 5359begin 5360 Result := GetCapture; 5361 if Result <> AHandle then 5362 begin 5363 if Result <> 0 then 5364 ReleaseCapture; 5365 if AHandle <> 0 then 5366 {$IFDEF MSWINDOWS} 5367 Windows.SetCapture(AHandle); 5368 {$ELSE} 5369 TQtWidget(AHandle).grabMouse(); 5370 {$ENDIF} 5371 {$ifdef VerboseQtWinAPI} 5372 WriteLn('[WinAPI SetCapture] Capture = ', Result, ' New capture = ', AHandle); 5373 {$endif} 5374 if Result <> 0 then 5375 begin 5376 Message.Msg := 0; 5377 FillChar(Message, SizeOf(Message), 0); 5378 Message.msg := LM_CAPTURECHANGED; 5379 Message.wParam := 0; 5380 Message.lParam := Result; 5381 LCLMessageGlue.DeliverMessage(TQtWidget(AHandle).LCLObject, Message); 5382 end; 5383 end; 5384end; 5385 5386function TQtWidgetSet.SetCaretPos(X, Y: Integer): Boolean; 5387begin 5388 Result := QtCaret.SetCaretPos(X, Y); 5389end; 5390 5391function TQtWidgetSet.SetCaretPosEx(Handle: HWnd; X, Y: Integer): Boolean; 5392begin 5393 Result := QtCaret.SetCaretPos(X, Y); 5394end; 5395 5396function TQtWidgetSet.SetCaretRespondToFocus(handle: HWND; 5397 ShowHideOnFocus: boolean): Boolean; 5398begin 5399 Result := True; 5400 QtCaret.SetQtCaretRespondToFocus(ShowHideOnFocus); 5401end; 5402 5403{------------------------------------------------------------------------------ 5404 Function: SetCursor 5405 Params: ACursor - HCursor (TQtCursor) 5406 Returns: 5407 previous global cursor 5408 ------------------------------------------------------------------------------} 5409function TQtWidgetSet.SetCursor(ACursor: HCURSOR): HCURSOR; 5410begin 5411 Result := HCURSOR(OverrideCursor); 5412 5413 if Result = ACursor then 5414 Exit; 5415 5416 if Screen.Cursors[crDefault] = ACursor then 5417 OverrideCursor := nil 5418 else 5419 OverrideCursor := TQtCursor(ACursor); 5420end; 5421 5422{------------------------------------------------------------------------------ 5423 Function: SetCursorPos 5424 Params: X: 5425 Y: 5426 Returns: 5427 5428 ------------------------------------------------------------------------------} 5429function TQtWidgetSet.SetCursorPos(X, Y: Integer): Boolean; 5430begin 5431 {$ifdef VerboseQtWinAPI} 5432 WriteLn('[WinAPI SetCursorPos]'); 5433 {$endif} 5434 5435 QCursor_setPos(X, Y); 5436 5437 Result := True; 5438end;*) 5439 5440{------------------------------------------------------------------------------ 5441 Function: SetFocus 5442 Params: hWnd - Window handle to be focused 5443 Returns: 5444 5445 ------------------------------------------------------------------------------} 5446function TCDWidgetSet.SetFocus(hWnd: HWND): HWND; 5447var 5448 lObject, lOldObject: TCDBaseControl; 5449 lOldControl: TWinControl; 5450 lHandle: TCDWinControl; 5451begin 5452 {$ifdef VerboseCDFocus} 5453 DebugLn(Format('[TCDWidgetSet.SetFocus] Handle=%x', [hWnd])); 5454 {$endif} 5455 Result := 0; 5456 // Strangly this breaks the Android Virtual Keyboard =( 5457 // Remove the ifdef only when we can guarantee that this doesn't break Android Virtual Keyboard 5458 {$ifndef CD_Android} 5459 if hwnd = 0 then 5460 begin 5461 Result := GetFocus(); 5462 Exit; 5463 end; 5464 lObject := TCDBaseControl(hWnd); 5465 5466 // SetFocus on a child control 5467 if lObject is TCDWinControl then 5468 begin 5469 lHandle := TCDWinControl(lObject); 5470 5471 // Set focus in the parent window 5472 //Result := BackendSetFocus(hWnd); 5473 5474 if lHandle.WinControl = nil then Exit; 5475 CDSetFocusToControl(lHandle.WinControl, lHandle.CDControl); 5476 5477 {$ifdef VerboseCDFocus} 5478 DebugLn(Format(':[TCDWidgetSet.SetFocus] NewFocusedControl=%s NewFocusedIntfControl=%x', [FocusedControl.Name, PtrUInt(FocusedIntfControl)])); 5479 {$endif} 5480 end 5481 // SetFocus on a form 5482 else 5483 begin 5484 Result := BackendSetFocus(hWnd); 5485 end; 5486 {$endif} 5487end; 5488 5489(*function TQtWidgetSet.GetForegroundWindow: HWND; 5490var 5491 W: QWidgetH; 5492begin 5493 {$IFDEF HASX11} 5494 if WindowManagerName = 'metacity' then 5495 W := X11GetActivewindow 5496 else 5497 W := QApplication_activeWindow(); 5498 {$ELSE} 5499 W := QApplication_activeWindow(); 5500 {$ENDIF} 5501 Result := HwndFromWidgetH(W); 5502end; 5503 5504function TQtWidgetSet.SetForegroundWindow(HWnd: HWND): boolean; 5505begin 5506 Result := False; 5507 if HWND <> 0 then 5508 begin 5509 Result := TQtWidget(HWND).IsActiveWindow; 5510 TQtWidget(HWnd).Activate; 5511 end; 5512end; 5513 5514function TQtWidgetSet.SetMenu(AWindowHandle: HWND; AMenuHandle: HMENU): Boolean; 5515var 5516 AWidget, AMenuWidget: TQtWidget; 5517 QtMainWindow: TQtMainWindow absolute AWidget; 5518 QtMenuBar: TQtMenuBar absolute AMenuWidget; 5519 R, R1: TRect; 5520begin 5521 AWidget := TQtWidget(AWindowHandle); 5522 Result := AWidget is TQtMainWindow; 5523 if Result then 5524 begin 5525 AMenuWidget := TQtWidget(AMenuHandle); 5526 if AMenuWidget is TQtMenuBar then 5527 begin 5528 R := AWidget.LCLObject.ClientRect; 5529 R1 := QtMainWindow.MenuBar.getGeometry; 5530 R1.Right := R.Right; 5531 QtMenuBar.setGeometry(R1); 5532 QtMainWindow.setMenuBar(QMenuBarH(QtMenuBar.Widget)); 5533 end 5534 else 5535 QtMainWindow.setMenuBar(QMenuBarH(QtMainWindow.MenuBar.Widget)); 5536 end; 5537end; 5538 5539function TQtWidgetSet.SetParent(hWndChild: HWND; hWndParent: HWND): HWND; 5540var 5541 OldVisible: Boolean; 5542 Flags: QtWindowFlags; 5543 W: TQtWidget; 5544begin 5545 {$ifdef VerboseQtWinAPI} 5546 writeln('[WinApi SetParent] child: ',dbgHex(PtrUInt(hwndChild)), 5547 ' parent: ',dbgHex(PtrUInt(hWndParent))); 5548 {$endif} 5549 Result := 0; 5550 if not IsValidHandle(hwndChild) then 5551 exit; 5552 Result := GetParent(hWndChild); 5553 if (Result = hwndParent) then 5554 exit; 5555 W := TQtWidget(hWndChild); 5556 OldVisible := W.getVisible; 5557 Flags := W.windowFlags; 5558 if IsValidHandle(hWndParent) then 5559 W.setParent(TQtWidget(hWndParent).GetContainerWidget) 5560 else 5561 begin 5562 W.setParent(nil); 5563 W.setWindowFlags(Flags); 5564 end; 5565 W.setVisible(OldVisible); 5566end; 5567 5568function TQtWidgetSet.SetMapMode(DC: HDC; fnMapMode : Integer): Integer; 5569var 5570 AWindowExt: TPoint; 5571 R: TRect; 5572begin 5573 if IsValidDC(DC) then 5574 begin 5575 if fnMapMode <> TQtDeviceContext(DC).vMapMode then 5576 begin 5577 case fnMapMode of 5578 MM_ANISOTROPIC:; // user's choice 5579 MM_ISOTROPIC:; // adjusted after each SetViewPortExtEx call (see MSDN for details) 5580 MM_HIENGLISH: AWindowExt := Point(1000, -1000); 5581 MM_HIMETRIC: AWindowExt := Point(2540, -2540); 5582 MM_LOENGLISH: AWindowExt := Point(100, -100); 5583 MM_LOMETRIC: AWindowExt := Point(254, -254); 5584 MM_TWIPS: AWindowExt := Point(1440, -1440); 5585 else 5586 fnMapMode := MM_TEXT; 5587 end; 5588 TQtDeviceContext(DC).vMapMode := fnMapMode; 5589 QPainter_setViewTransformEnabled(TQtDeviceContext(DC).Widget, fnMapMode <> MM_TEXT); 5590 if not (fnMapMode in [MM_TEXT, MM_ANISOTROPIC, MM_ISOTROPIC]) then 5591 begin 5592 QPainter_Window(TQtDeviceContext(DC).Widget, @R); 5593 R.BottomRight := AWindowExt; 5594 QPainter_setWindow(TQtDeviceContext(DC).Widget, @R); 5595 QPainter_ViewPort(TQtDeviceContext(DC).Widget, @R); 5596 R.Right := QtWidgetSet.GetDeviceCaps(DC, LOGPIXELSX); 5597 R.Bottom := QtWidgetSet.GetDeviceCaps(DC, LOGPIXELSX); 5598 QPainter_setViewPort(TQtDeviceContext(DC).Widget, @R); 5599 end; 5600 end; 5601 Result := Integer(True); 5602 end else 5603 Result := Integer(False); 5604end; 5605 5606function TQtWidgetSet.ShowCaret(hWnd: HWND): Boolean; 5607begin 5608 Result := (hWnd <> 0) and (QtCaret.ShowCaret(TQtWidget(hWnd))); 5609end;*) 5610 5611{------------------------------------------------------------------------------ 5612 Method: SetProp 5613 Params: Handle - 5614 Returns: 5615 ------------------------------------------------------------------------------} 5616function TCDWidgetSet.SetProp(Handle: hwnd; Str: PChar; Data: Pointer): Boolean; 5617begin 5618 if Handle<>0 then 5619 begin 5620 TCDBaseControl(Handle).Props[str] := Data; 5621 Result := (TCDBaseControl(Handle).Props[str]=Data); 5622 {$ifdef VerboseCDWinApi} 5623 DebugLn('[WinAPI SetProp win=%s str=%s data=%x',[dbgsname(TCDWinControl(Handle)), str, ptrint(data)]); 5624 {$endif} 5625 end else 5626 Result := False; 5627end; 5628 5629(*{------------------------------------------------------------------------------ 5630 Function: SetROP2 5631 Params: HDC, Raster OP mode 5632 Returns: Old Raster OP mode 5633 5634 Please note that the bitwise raster operation modes, denoted with a 5635 RasterOp prefix, are only natively supported in the X11 and 5636 raster paint engines. 5637 This means that the only way to utilize these modes on the Mac is 5638 via a QImage. 5639 The RasterOp denoted blend modes are not supported for pens and brushes 5640 with alpha components. Also, turning on the QPainter::Antialiasing render 5641 hint will effectively disable the RasterOp modes. 5642 ------------------------------------------------------------------------------} 5643function TQtWidgetSet.SetROP2(DC: HDC; Mode: Integer): Integer; 5644var 5645 QtDC: TQtDeviceContext absolute DC; 5646begin 5647 {$ifdef VerboseQtWinAPI} 5648 writeln('TQtWidgetSet.SetROP2() DC ',dbghex(DC),' Mode ',Mode); 5649 {$endif} 5650 Result := R2_COPYPEN; 5651 if not IsValidDC(DC) then 5652 exit; 5653 Result := QtDC.Rop2; 5654 QtDC.Rop2 := Mode; 5655end; 5656 5657{------------------------------------------------------------------------------ 5658 Function: SetScrollInfo 5659 Params: none 5660 Returns: The new position value 5661 5662 ------------------------------------------------------------------------------} 5663function TQtWidgetSet.SetScrollInfo(Handle : HWND; SBStyle : Integer; 5664 ScrollInfo: TScrollInfo; bRedraw : Boolean): Integer; 5665var 5666 Control: TWinControl; 5667 ScrollBar: TQtScrollBar; 5668 5669 function UpdateScrollInfo: Integer; 5670 var 5671 iReCountMax: Integer; 5672 SBUpdatesCount: Integer; 5673 i: Integer; 5674 WheelLines: Integer; 5675 begin 5676 Result := 0; 5677 SBUpdatesCount := 0; 5678 5679 if (ScrollInfo.FMask and SIF_RANGE) <> 0 then 5680 begin 5681 inc(SBUpdatesCount); 5682 ScrollBar.setMinimum(ScrollInfo.nMin); 5683 5684 // we must recount ScrollBar.Max since invalid value raises AV 5685 iRecountMax := ScrollInfo.nMax - ScrollInfo.nPage; 5686 if iRecountMax < ScrollInfo.nMin then 5687 iRecountMax := ScrollInfo.nMin; 5688 5689 ScrollBar.setMaximum(iRecountMax); 5690 end; 5691 5692 if (ScrollInfo.FMask and SIF_PAGE) <> 0 then 5693 begin 5694 // segfaults if we don't check Enabled property 5695 if ScrollBar.getEnabled then 5696 begin 5697 inc(SBUpdatesCount); 5698 ScrollBar.setPageStep(ScrollInfo.nPage); 5699 WheelLines := QApplication_wheelScrollLines(); 5700 with Scrollbar do 5701 begin 5702 i := Max(1, floor((GetPageStep / WheelLines) / 6)); 5703 setSingleStep(i); 5704 end; 5705 end; 5706 end; 5707 5708 if (ScrollInfo.FMask and SIF_UPDATEPOLICY) <> 0 then 5709 ScrollBar.setTracking(ScrollInfo.nTrackPos <> SB_POLICY_DISCONTINUOUS); 5710 5711 if (ScrollInfo.FMask and SIF_POS) <> 0 then 5712 begin 5713 inc(SBUpdatesCount); 5714 5715 if SBUpdatesCount = 1 then 5716 ScrollBar.BeginUpdate; 5717 try 5718 if not (ScrollBar.getTracking and ScrollBar.getSliderDown) then 5719 begin 5720 {do not setValue() if values are equal, since it calls 5721 signalValueChanged() which sends unneeded LM_SCROLL msgs } 5722 if (ScrollBar.getValue = ScrollInfo.nPos) then 5723 SBUpdatesCount := 0; 5724 5725 if (ScrollInfo.nPos < ScrollBar.getMin) then 5726 ScrollInfo.nPos := ScrollBar.getMin 5727 else 5728 if (ScrollInfo.nPos > ScrollBar.getMax) then 5729 ScrollInfo.nPos := ScrollBar.getMax; 5730 5731 if (SBUpdatesCount > 0) then 5732 ScrollBar.setValue(ScrollInfo.nPos); 5733 end; 5734 finally 5735 if ScrollBar.InUpdate then 5736 ScrollBar.EndUpdate; 5737 end; 5738 end; 5739 5740 if (ScrollInfo.FMask and SIF_TRACKPOS) <> 0 then 5741 begin 5742 ScrollBar.TrackPos := ScrollInfo.nTrackPos; 5743 // from MSDN: the SetScrollInfo function ignores this member 5744 // ScrollBar.setSliderPosition(ScrollInfo.nTrackPos); 5745 end; 5746 5747 Result := ScrollBar.getValue; 5748 end; 5749 5750begin 5751 // bRedraw is useles with qt 5752 5753 Result := 0; 5754 5755 if (Handle = 0) then exit; 5756 5757 ScrollBar := nil; 5758 case SBStyle of 5759 SB_BOTH: 5760 begin 5761 {TODO: SB_BOTH fixme } 5762 //writeln('TODO: ############## SB_BOTH CALLED HERE .... #################'); 5763 end; {SB_BOTH} 5764 5765 SB_CTL: 5766 begin 5767 {HWND is always TScrollBar, but seem that Create ScrollBar should be called here } 5768 if (csReading in TQtWidget(Handle).LCLObject.ComponentState) or 5769 (csDestroying in TQtWidget(Handle).LCLObject.ComponentState) then exit; 5770 5771 ScrollBar := TQtScrollBar(Handle); 5772 5773 if not Assigned(ScrollBar) then exit; 5774 end; {SB_CTL} 5775 5776 SB_HORZ: 5777 begin 5778 if (csReading in TQtWidget(Handle).LCLObject.ComponentState) or 5779 (csDestroying in TQtWidget(Handle).LCLObject.ComponentState) then 5780 exit; 5781 5782 if TQtWidget(Handle) is TQtAbstractScrollArea then 5783 begin 5784 ScrollBar := TQtAbstractScrollArea(Handle).horizontalScrollBar; 5785 end else 5786 begin 5787 {do not localize !} 5788 Control := TWinControl(TQtWidget(Handle).LCLObject.FindChildControl(TQtWidget(Handle).LCLObject.Name+'_HSCROLLBAR')); 5789 if (Control <> nil) and (Control.HandleAllocated) then 5790 ScrollBar := TQtScrollBar(Control.Handle) 5791 end; 5792 end; {SB_HORZ} 5793 5794 SB_VERT: 5795 begin 5796 if (csReading in TQtWidget(Handle).LCLObject.ComponentState) or 5797 (csDestroying in TQtWidget(Handle).LCLObject.ComponentState) then 5798 exit; 5799 5800 if TQtWidget(Handle) is TQtAbstractScrollArea then 5801 begin 5802 ScrollBar := TQtAbstractScrollArea(Handle).verticalScrollBar; 5803 end else 5804 begin 5805 {do not localize !} 5806 Control := TWinControl(TQtWidget(Handle).LCLObject.FindChildControl(TQtWidget(Handle).LCLObject.Name+'_VSCROLLBAR')); 5807 if (Control <> nil) and (Control.HandleAllocated) then 5808 ScrollBar := TQtScrollBar(Control.Handle) 5809 end; 5810 end; {SB_VERT} 5811 5812 end; 5813 5814 if Assigned(ScrollBar) then 5815 Result := UpdateScrollInfo; 5816end;*) 5817 5818{------------------------------------------------------------------------------ 5819 Method: SetTextColor 5820 Params: Handle - 5821 Returns: 5822 ------------------------------------------------------------------------------} 5823function TCDWidgetSet.SetTextColor(DC: HDC; Color: TColorRef): TColorRef; 5824var 5825 lFont: TFPCustomFont; 5826 LazDC: TLazCanvas; 5827begin 5828 {$ifdef VerboseCDDrawing} 5829 DebugLn(Format('[TCDWidgetSet.SetTextColor] DC: %x Color: %8x', [DC, Color])); 5830 {$endif} 5831 5832 Result := CLR_INVALID; 5833 if not IsValidDC(DC) then Exit; 5834 LazDC := TLazCanvas(DC); 5835 5836 if LazDC.Font <> nil then 5837 LazDC.Font.FPColor := TColorToFPColor(Color); 5838end; 5839 5840(*{------------------------------------------------------------------------------ 5841 function ShowScrollBar(Handle: HWND; wBar: Integer; bShow: Boolean): Boolean; 5842 Params Handle: HWND; wBar: Integer; bShow: Boolean 5843 Result 5844------------------------------------------------------------------------------} 5845function TQtWidgetSet.ShowScrollBar(Handle: HWND; wBar: Integer; bShow: Boolean): Boolean; 5846var 5847 w: TQtWidget; 5848 ScrollArea: TQtAbstractScrollArea; 5849begin 5850 {$ifdef VerboseQtWinAPI} 5851 WriteLn('[WinAPI ShowScrollBar] Handle: ', dbghex(Handle),' wBar: ',wBar); 5852 {$endif} 5853 5854 Result := (Handle <> 0); 5855 5856 if not Result then exit; 5857 5858 w := TQtWidget(Handle); 5859 5860 if w is TQtAbstractScrollArea then 5861 begin 5862 ScrollArea := TQtAbstractScrollArea(w); 5863 case wBar of 5864 SB_BOTH: 5865 begin 5866 if bShow then 5867 ScrollArea.setScrollStyle(ssBoth) 5868 else 5869 ScrollArea.setScrollStyle(ssNone); 5870 end; 5871 5872 SB_HORZ: 5873 begin 5874 if bShow then 5875 ScrollArea.setScrollStyle(ssHorizontal) 5876 else 5877 ScrollArea.ScrollBarPolicy[False] := QtScrollBarAlwaysOff; 5878 end; 5879 5880 SB_VERT: 5881 begin 5882 if bShow then 5883 ScrollArea.setScrollStyle(ssVertical) 5884 else 5885 ScrollArea.ScrollBarPolicy[True] := QtScrollBarAlwaysOff; 5886 end; 5887 5888 SB_CTL: 5889 begin 5890 if bShow then 5891 ScrollArea.Show 5892 else 5893 ScrollArea.Hide; 5894 end; 5895 end; 5896 5897 end else 5898 Result := False; 5899end; 5900 5901function TQtWidgetSet.SetViewPortExtEx(DC: HDC; XExtent, YExtent : Integer; OldSize: PSize): Boolean; 5902var 5903 R, RW: TRect; 5904 Ratio: Single; 5905begin 5906 Result := False; 5907 if IsValidDC(DC) then 5908 begin 5909 QPainter_ViewPort(TQtDeviceContext(DC).Widget, @R); 5910 if OldSize <> nil then 5911 begin 5912 OldSize^.cx := R.Right - R.Left; 5913 OldSize^.cy := R.Bottom - R.Top; 5914 end; 5915 if (XExtent <> R.Right) or (YExtent <> R.Bottom) then 5916 begin 5917 case TQtDeviceContext(DC).vMapMode of 5918 MM_ANISOTROPIC, MM_ISOTROPIC: 5919 begin 5920 if TQtDeviceContext(DC).vMapMode = MM_ISOTROPIC then 5921 begin 5922 // TK: Is here also an adjustment on Windows if DPIX and DPIY are different? 5923 QPainter_Window(TQtDeviceContext(DC).Widget, @RW); 5924 Ratio := RW.Right / RW.Bottom; // no check, programmer cannot put nonsense 5925 if YExtent * Ratio > XExtent then 5926 YExtent := RoundToInt(XExtent / Ratio) 5927 else if YExtent * Ratio < XExtent then 5928 XExtent := RoundToInt(YExtent * Ratio) 5929 end; 5930 QPainter_setViewPort(TQtDeviceContext(DC).Widget, R.Left, R.Top, XExtent, YExtent); 5931 Result := True; 5932 end; 5933 end; 5934 end; 5935 end; 5936end; 5937 5938function TQtWidgetSet.SetViewPortOrgEx(DC: HDC; NewX, NewY: Integer; OldPoint: PPoint): Boolean; 5939var 5940 R: TRect; 5941begin 5942 Result := False; 5943 if IsValidDC(DC) then 5944 begin 5945 QPainter_ViewPort(TQtDeviceContext(DC).Widget, @R); 5946 if OldPoint <> nil then 5947 OldPoint^ := R.TopLeft; 5948 if (TQtDeviceContext(DC).vMapMode <> MM_TEXT) and (NewX <> R.Left) or (NewY <> R.Top) then 5949 begin 5950 QPainter_setViewPort(TQtDeviceContext(DC).Widget, NewX, NewY, R.Right - R.Left, R.Bottom - R.Top); 5951 Result := True; 5952 end; 5953 end; 5954end; 5955 5956function TQtWidgetSet.SetWindowExtEx(DC: HDC; XExtent, YExtent: Integer; OldSize: PSize): Boolean; 5957var 5958 R: TRect; 5959begin 5960 Result := False; 5961 if IsValidDC(DC) then 5962 begin 5963 QPainter_Window(TQtDeviceContext(DC).Widget, @R); 5964 if OldSize <> nil then 5965 begin 5966 OldSize^.cx := R.Right - R.Left; 5967 OldSize^.cy := R.Bottom - R.Top; 5968 end; 5969 if (XExtent <> R.Right) or (YExtent <> R.Bottom) then 5970 begin 5971 case TQtDeviceContext(DC).vMapMode of 5972 MM_ANISOTROPIC, MM_ISOTROPIC: 5973 begin 5974 QPainter_setWindow(TQtDeviceContext(DC).Widget, R.Left, R.Top, XExtent, YExtent); 5975 Result := True; 5976 end; 5977 end; 5978 end; 5979 end; 5980end;*) 5981 5982{------------------------------------------------------------------------------ 5983 Method: SetWindowOrgEx 5984 Params: DC - handle of device context 5985 NewX - new x-coordinate of window origin 5986 NewY - new y-coordinate of window origin 5987 Point - record receiving original origin 5988 Returns: Whether the call was successful 5989 5990 Sets the window origin of the device context by using the specified coordinates. 5991 ------------------------------------------------------------------------------} 5992function TCDWidgetSet.SetWindowOrgEx(DC : HDC; NewX, NewY : Integer; OldPoint: PPoint) : Boolean; 5993var 5994 P: TPoint; 5995 LazDC: TLazCanvas absolute DC; 5996begin 5997 {$ifdef VerboseCDDrawing} 5998 DebugLn(Format('[WinAPI SetWindowOrgEx] DC=%x NewX=%d NewY=%d', 5999 [DC, NewX, NewY])); 6000 {$endif} 6001 6002 Result := False; 6003 if not IsValidDC(DC) then Exit; 6004 6005 GetWindowOrgEx(DC, @P); 6006 if OldPoint <> nil then OldPoint^ := P; 6007 6008 LazDC.WindowOrg := Types.Point(-NewX, -NewY); 6009 Result := True; 6010end; 6011 6012(*{------------------------------------------------------------------------------ 6013 Method: SetWindowPos 6014 Params: HWnd - handle of window 6015 HWndInsertAfter - placement-order handle 6016 X - horizontal position 6017 Y - vertical position 6018 CX - width 6019 CY - height 6020 UFlags - window-positioning flags 6021 Returns: If the function succeeds 6022 6023 Changes the size, position, and Z order of a child, pop-up, or top-level 6024 window. 6025 ------------------------------------------------------------------------------} 6026function TQtWidgetSet.SetWindowPos(hWnd: HWND; hWndInsertAfter: HWND; X, Y, cx, 6027 cy: Integer; uFlags: UINT): Boolean; 6028var 6029 DisableUpdates: boolean; 6030begin 6031 {$ifdef VerboseQtWinAPI} 6032 WriteLn('[WinAPI SetWindowPos] Handle: ', dbghex(hWnd), 6033 ' hWndInsertAfter: ',dbghex(hWnd)); 6034 {$endif} 6035 Result := hWnd <> 0; 6036 if not Result then 6037 exit; 6038 6039 DisableUpdates := (SWP_NOREDRAW and uFlags) <> 0; 6040 if DisableUpdates then 6041 TQtWidget(Hwnd).setUpdatesEnabled(False); 6042 try 6043 if (SWP_NOMOVE and uFlags) = 0 then 6044 TQtWidget(Hwnd).move(X, Y); 6045 6046 if (SWP_NOSIZE and uFlags) = 0 then 6047 TQtWidget(Hwnd).resize(CX, CY); 6048 6049 if (SWP_NOZORDER and uFlags) = 0 then 6050 begin 6051 case hWndInsertAfter of 6052 HWND_TOP: 6053 begin 6054 TQtWidget(hWnd).raiseWidget; 6055 if (SWP_NOACTIVATE and uFlags) = 0 then 6056 TQtWidget(hWnd).Activate; 6057 end; 6058 HWND_BOTTOM: TQtWidget(hWnd).lowerWidget; 6059 {TODO: HWND_TOPMOST ,HWND_NOTOPMOST} 6060 end; 6061 end; 6062 finally 6063 if DisableUpdates then 6064 TQtWidget(Hwnd).setUpdatesEnabled(True); 6065 end; 6066end; 6067 6068{------------------------------------------------------------------------------ 6069 Method: SetWindowRgn 6070 Params: hWnd - handle of the widget 6071 hRgn - handle of the region 6072 bRedraw - ? 6073 Returns: 0 if the call failed, any other value if it was successful 6074 6075 Makes the region specifyed in hRgn be the only part of the window which is 6076 visible. 6077 ------------------------------------------------------------------------------} 6078function TQtWidgetSet.SetWindowRgn(hWnd: HWND; 6079 hRgn: HRGN; bRedraw: Boolean):longint; 6080var 6081 w: TQtWidget; 6082 r: TQtRegion; 6083begin 6084 Result := 0; 6085 6086 {$ifdef VerboseQtWinAPI} 6087 WriteLn('[WinAPI SetWindowRgn] Handle: ', dbghex(hWnd)); 6088 {$endif} 6089 6090 // Basic checks 6091 if (hWnd = 0) or (hRgn = 0) then Exit; 6092 6093 w := TQtWidget(hWnd); 6094 r := TQtRegion(hRgn); 6095 6096 // Now set the mask in the widget 6097 w.setMask(r.FHandle); 6098 6099 Result := 1; 6100end; 6101 6102{------------------------------------------------------------------------------ 6103 function ShowWindow(hWnd: HWND; nCmdShow: Integer): Boolean; 6104 6105 nCmdShow: 6106 SW_SHOWNORMAL, SW_MINIMIZE, SW_SHOWMAXIMIZED 6107------------------------------------------------------------------------------} 6108function TQtWidgetSet.ShowWindow(hWnd: HWND; nCmdShow: Integer): Boolean; 6109var 6110 Widget: TQtWidget; 6111begin 6112 {$ifdef VerboseQtWinAPI} 6113 WriteLn('[WinAPI ShowWindow] hwnd ',dbgHex(PtrUInt(hWnd)),' nCmdShow ',nCmdShow); 6114 {$endif} 6115 6116 Result := False; 6117 6118 Widget := TQtWidget(hWnd); 6119 6120 if Widget <> nil then 6121 begin 6122 case nCmdShow of 6123 SW_SHOW: Widget.setVisible(True); 6124 SW_SHOWNORMAL: Widget.ShowNormal; 6125 SW_MINIMIZE: Widget.setWindowState(QtWindowMinimized); 6126 SW_SHOWMINIMIZED: Widget.ShowMinimized; 6127 SW_SHOWMAXIMIZED: Widget.ShowMaximized; 6128 SW_SHOWFULLSCREEN: Widget.ShowFullScreen; 6129 SW_HIDE: Widget.setVisible(False); 6130 end; 6131 Result := True; 6132 end; 6133end;*) 6134 6135{------------------------------------------------------------------------------ 6136 Function: StretchBlt 6137 Params: DestDC: The destination devicecontext 6138 X, Y: The left/top corner of the destination rectangle 6139 Width, Height: The size of the destination rectangle 6140 SrcDC: The source devicecontext 6141 XSrc, YSrc: The left/top corner of the source rectangle 6142 SrcWidth, SrcHeight: The size of the source rectangle 6143 ROp: The raster operation to be performed 6144 Returns: True if succesful 6145 6146 The StretchBlt function copies a bitmap from a source rectangle into a 6147 destination rectangle using the specified raster operation. If needed it 6148 resizes the bitmap to fit the dimensions of the destination rectangle. 6149 Sizing is done according to the stretching mode currently set in the 6150 destination device context. 6151 If SrcDC contains a mask the pixmap will be copied with this transparency. 6152 ------------------------------------------------------------------------------} 6153function TCDWidgetSet.StretchBlt(DestDC: HDC; X, Y, Width, Height: Integer; 6154 SrcDC: HDC; XSrc, YSrc, SrcWidth, SrcHeight: Integer; ROp: Cardinal): Boolean; 6155begin 6156 Result := StretchMaskBlt(DestDC,X,Y,Width,Height, 6157 SrcDC,XSrc,YSrc,SrcWidth,SrcHeight, 6158 0,0,0, 6159 ROp); 6160end; 6161 6162{------------------------------------------------------------------------------ 6163 Function: StretchMaskBlt 6164 Params: DestDC: The destination devicecontext 6165 X, Y: The left/top corner of the destination rectangle 6166 Width, Height: The size of the destination rectangle 6167 SrcDC: The source devicecontext 6168 XSrc, YSrc: The left/top corner of the source rectangle 6169 SrcWidth, SrcHeight: The size of the source rectangle 6170 Mask: The handle of a monochrome bitmap 6171 XMask, YMask: The left/top corner of the mask rectangle 6172 ROp: The raster operation to be performed 6173 Returns: True if succesful 6174 6175 The StretchMaskBlt function copies a bitmap from a source rectangle into a 6176 destination rectangle using the specified mask and raster operation. If needed 6177 it resizes the bitmap to fit the dimensions of the destination rectangle. 6178 Sizing is done according to the stretching mode currently set in the 6179 destination device context. 6180 ------------------------------------------------------------------------------} 6181function TCDWidgetSet.StretchMaskBlt(DestDC: HDC; X, Y, Width, Height: Integer; 6182 SrcDC: HDC; XSrc, YSrc, SrcWidth, SrcHeight: Integer; Mask: HBITMAP; 6183 XMask, YMask: Integer; Rop: DWORD): Boolean; 6184var 6185 SrcLazDC: TLazCanvas absolute SrcDC; 6186 DstLazDC: TLazCanvas absolute DestDC; 6187 BufferImage: TLazIntfImage = nil; 6188 BufferDC: TLazCanvas = nil; 6189 FreeBuffer: Boolean; 6190 SrcRect, DstRect, MaskRect: TRect; 6191begin 6192 {$ifdef VerboseCDDrawing} 6193 DebugLn('[WinAPI StretchMaskBlt]' + 6194 ' DestDC:' + dbghex(DestDC) + 6195 ' SrcDC:' + dbghex(SrcDC) + 6196 ' X:' + dbgs(X) + ' Y:' + dbgs(Y) + 6197 ' W:' + dbgs(Width) + ' H:', dbgs(Height) + 6198 ' XSrc:' + dbgs(XSrc) + ' YSrc:' + dbgs(YSrc) + 6199 ' WSrc:' + dbgs(SrcWidth) + ' HSrc:' + dbgs(SrcHeight)); 6200 {$endif} 6201 6202 Result := False; 6203 6204 // Optimization if no stretch is desired 6205 if (SrcWidth = Width) and (SrcHeight = Height) then 6206 begin 6207 DstLazDC.CanvasCopyRect(SrcLazDC, X, Y, XSrc, YSrc, SrcWidth, SrcHeight); 6208 Exit; 6209 end; 6210 6211 // Otherwise do the real stretch 6212 6213 // Get an interpolation acording to the anti-aliasing option 6214 {if DstLazDC. .AntiAliasing then 6215 DstLazDC.Interpolation := TMitchelInterpolation.Create 6216 else} 6217 DstLazDC.Interpolation := TFPSharpInterpolation.Create; 6218 6219 // Copy the source rectangle to a temporary buffer if it is not the entire source 6220 if (XSrc = 0) and (YSrc = 0) and (SrcWidth = SrcLazDC.Width) and (SrcHeight = SrcLazDC.Height) then 6221 begin 6222 BufferDC := SrcLazDC; 6223 BufferImage := TLazIntfImage(SrcLazDC.Image); 6224 FreeBuffer := False; 6225 end 6226 else 6227 begin 6228 UpdateControlLazImageAndCanvas(BufferImage, BufferDC, 6229 SrcWidth, SrcHeight, clfARGB32); 6230 BufferDC.CanvasCopyRect(SrcLazDC, 0, 0, XSrc, YSrc, SrcWidth, SrcHeight); 6231 FreeBuffer := True; 6232 end; 6233 6234 // Execute the stretch 6235 DstLazDC.StretchDraw(X, Y, Width, Height, BufferImage); 6236 6237 // Free the interpolation 6238 DstLazDC.Interpolation.Free; 6239 DstLazDC.Interpolation := nil; 6240 6241 // Free the buffer 6242 if FreeBuffer then 6243 begin 6244 BufferDC.Free; 6245 BufferImage.Free; 6246 end; 6247 6248 Result := True; 6249end; 6250 6251(*{------------------------------------------------------------------------------ 6252 Function: SystemParametersInfo 6253 Params: uiAction: System-wide parameter to be retrieved or set 6254 uiParam: Depends on the system parameter being queried or set 6255 pvParam: Depends on the system parameter being queried or set 6256 fWinIni: 6257 Returns: True if the function succeeds 6258 retrieves or sets the value of one of the system-wide parameters 6259 ------------------------------------------------------------------------------} 6260function TQtWidgetSet.SystemParametersInfo(uiAction: DWord; uiParam: DWord; pvParam: Pointer; fWinIni: DWord): LongBool; 6261begin 6262 case uiAction of 6263 SPI_GETWHEELSCROLLLINES: PDword(pvPAram)^ := QApplication_wheelScrollLines; 6264 SPI_GETWORKAREA: begin 6265 TRect(pvParam^):=Bounds(GetSystemMetrics(SM_XVIRTUALSCREEN), 6266 GetSystemMetrics(SM_YVIRTUALSCREEN), 6267 GetSystemMetrics(SM_CXVIRTUALSCREEN), 6268 GetSystemMetrics(SM_CYVIRTUALSCREEN)); 6269 Result:=True; 6270 end; 6271 else 6272 Result := False; 6273 end 6274end;*) 6275 6276{------------------------------------------------------------------------------ 6277 Function: TextOut 6278 Params: DC: 6279 X: 6280 Y: 6281 Str: 6282 Count: 6283 Returns: 6284 6285 ------------------------------------------------------------------------------} 6286function TCDWidgetSet.TextOut(DC: HDC; X,Y : Integer; Str : Pchar; Count: Integer) : Boolean; 6287begin 6288 Result:=ExtTextOut(DC, X, Y, 0, nil, Str, Count, nil); 6289end; 6290 6291(*{------------------------------------------------------------------------------ 6292 Method: UpdateWindow 6293 Params: Handle 6294 Returns: 6295 ------------------------------------------------------------------------------} 6296function TQtWidgetSet.UpdateWindow(Handle: HWND): Boolean; 6297begin 6298 {$ifdef VerboseQtWinAPI} 6299 WriteLn('[WinAPI UpdateWindow]'); 6300 {$endif} 6301 Result := False; 6302 if Handle <> 0 then 6303 begin 6304 TQtWidget(Handle).Update; 6305 Result := True; 6306 end; 6307end; 6308 6309{------------------------------------------------------------------------------ 6310 Method: WindowFromPoint 6311 Params: TPoint 6312 Returns: The return value is a handle to the window that contains the param 6313 point. 6314 If no window exists at the given point, the return value is 0. 6315 If the point is over a static text control, 6316 the return value is a handle to the window under the static text control. 6317 ------------------------------------------------------------------------------} 6318function TQtWidgetSet.WindowFromPoint(APoint: TPoint): HWND; 6319var 6320 Widget: QWidgetH; 6321begin 6322 // we use cachedresults instead of calling very expensive widgetAt 6323 if (FLastWFPResult <> 0) then 6324 begin 6325 if not IsValidWidgetAtCachePointer then 6326 FLastWFPResult := 0 6327 else 6328 if (APoint.X = FLastWFPMousePos.X) and (APoint.Y = FLastWFPMousePos.Y) and 6329 TQtWidget(FLastWFPResult).getVisible and 6330 TQtWidget(FLastWFPResult).getEnabled then 6331 begin 6332 // return from cache 6333 exit(FLastWFPResult); 6334 end; 6335 end; 6336 6337 Result := 0; 6338 Widget := QApplication_widgetAt(APoint.x, APoint.y); 6339 6340 if (Widget = nil) then 6341 begin 6342 if (APoint.X = FLastWFPMousePos.X) and (APoint.Y = FLastWFPMousePos.Y) then 6343 begin 6344 FLastWFPMousePos := Point(MaxInt, MaxInt); 6345 FLastWFPResult := 0; 6346 end; 6347 exit; 6348 end; 6349 6350 // according to MSDN disabled widget shouldn't be in result 6351 // but win32 returns first enabled and visible parent ! 6352 if not QWidget_isEnabled(Widget) or not QWidget_isVisible(Widget) then 6353 begin 6354 while Widget <> nil do 6355 begin 6356 Widget := QWidget_parentWidget(Widget); 6357 if (Widget <> nil) and QWidget_IsVisible(Widget) and 6358 QWidget_isEnabled(Widget) then 6359 break; 6360 end; 6361 if Widget = nil then 6362 exit; 6363 end; 6364 6365 Result := HwndFromWidgetH(Widget); 6366 6367 // return from cache if we are same TQtWidget, just update point 6368 if IsValidWidgetAtCachePointer and (Result = FLastWFPResult) then 6369 begin 6370 FLastWFPMousePos := APoint; 6371 exit(FLastWFPResult); 6372 end; 6373 6374 // maybe we are viewport of native QAbstractScrollArea (eg. QTextEdit). 6375 if (Result = 0) then 6376 begin 6377 if QWidget_parentWidget(Widget) <> nil then 6378 begin 6379 while (Widget <> nil) do 6380 begin 6381 Widget := QWidget_parentWidget(Widget); 6382 if Widget <> nil then 6383 Result := HwndFromWidgetH(Widget); 6384 if Result <> 0 then 6385 break; 6386 end; 6387 end; 6388 end; 6389 6390 if (Result <> 0) and 6391 not (TQtWidget(Result) is TQtMainWindow) then 6392 begin 6393 if TQtWidget(Result).getOwner <> nil then 6394 Result := HWND(TQtWidget(Result).getOwner); 6395 end else 6396 begin 6397 Widget := QApplication_topLevelAt(APoint.x, APoint.y); 6398 if (Widget <> nil) and QWidget_isEnabled(Widget) then 6399 Result := HwndFromWidgetH(Widget) 6400 else 6401 Result := 0; 6402 end; 6403 6404 // add to cache 6405 FLastWFPResult := Result; 6406 FLastWFPMousePos := APoint; 6407end;*) 6408 6409//##apiwiz##eps## // Do not remove, no wizard declaration after this line 6410