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