Difference between revisions of "Accessing the Interfaces directly"

From Free Pascal wiki
(List of Handles on various LCL classes)
m (See also: Updated)
 
(27 intermediate revisions by 8 users not shown)
Line 1: Line 1:
 
{{Accessing the Interfaces directly}}
 
{{Accessing the Interfaces directly}}
  
This page describes, how to write a new LCL control, using the various LCL interfaces for the platform dependent implementations.
+
This page describes how to write access the underlying [[Widgetset|widgetset]] used by lazarus directly (for example: The Windows API, or Gtk, or Qt, etc). One should always try to avoid relying on widgetset specials. This document is here for both people improving the widgetsets and for people writing components that really need to access the widgets directly.
  
OpenGL is a platform independent language for 3D graphics.
+
== Overview ==
The platform dependent part is to get a OpenGL context. Under linux/freebsd/X you use glx for that, under windows you use WGL and under MacOSX you can use AGL.
 
  
Every TWinControl has a Handle, and the LCL does not need to know, what a Handle is. The meaning of the Handle is totally up to the LCL interface:
+
Every TWinControl has a handle, and the LCL does not need to know, what a Handle is. The meaning of the Handle is totally up to the interface:
  
* under gtk a Handle is often a PGtkWidget
+
* under [[:Category:GTK Widgetsets|GTK]] a handle is often a PGtkWidget
* under windows a Handle is often a HWnd.
+
* under Windows a handle is often a HWnd.
* under carbon a Handle is often a ControlRef
+
* under Carbon a handle is often a object descendant of TCarbonWidget.
* under Qt, a Handle is often a pointer to a object descendent of TQtWidget.
+
* under Qt, a handle is often a pointer to a object descendent of TQtWidget.
 
 
Be aware that you should avoid relying on any widgetset specials. This page is for people improving the widgetsets and for people writing components that need to access the widgets directly.
 
  
 
== Per-Widgetset Details ==
 
== Per-Widgetset Details ==
Line 19: Line 16:
 
=== Qt ===
 
=== Qt ===
  
Handles on Qt are mostly pointers to objects. Every time a control is created, a helper object is also created and both are connected. The helper object is necessary to receive events from Qt. After receiving a event it will send it to the LCL.
+
Handles on [[Qt Interface|Qt]] are mostly pointers to objects. Every time a control is created, a helper object is also created and both are connected. The helper object is necessary to receive events from Qt. After receiving an event it will send it to the LCL.
  
 
Most of those objects are descendents from TQtWidget as declared below:
 
Most of those objects are descendents from TQtWidget as declared below:
  
<pre>
+
<syntaxhighlight lang="pascal">
{ TQtWidget }
+
{ TQtWidget }
  
TQtWidget = class(TObject)
+
TQtWidget = class(TObject)
private
+
private
public
+
  ...
  Widget: QWidgetH;
+
public
  LCLObject: TWinControl;
+
  Widget: QWidgetH;
  end;
+
  LCLObject: TWinControl;
</pre>
+
public
 +
  function GetContainerWidget: QWidgetH; virtual;
 +
  ...
 +
end;
 +
</syntaxhighlight>
  
 
Notice the two variables they all contain:
 
Notice the two variables they all contain:
  
 
* Widget - This is a connect to the Qt object for this Widget
 
* Widget - This is a connect to the Qt object for this Widget
 +
* LCLObject - Is a bridge with the LCL object it is linked to.
 +
 +
And also this method:
 +
 +
* GetContrainerWidget() - When you wish to create a new widget and set it's parent, don't set it to Widget. Set it to GetContrainerWidget() instead. This happens because forms have 2 widgets. The main form widget, and also a container widget, where all child controls should be put to ensure that the size of the menu is handled automatically. Most other controls will have just one widget, but by using this function you avoid surprises in case the implementation of a control changes.
 +
 +
=== Carbon ===
 +
 +
Handles on [[Carbon Interface|Carbon]] are very similar to Qt ones. The helper classes are descended from abstract class TCarbonWidget.
 +
 +
<syntaxhighlight lang="pascal">
 +
{ TCarbonWidget }
 +
 +
TCarbonWidget = class(TObject)
 +
private
 +
public
 +
  Widget: Pointer;
 +
  LCLObject: TWinControl;
 +
end;
 +
</syntaxhighlight>
 +
 +
Notice the two variables they all contain:
 +
 +
* Widget - This is a connect to the Carbon object for this Widget: ControlRef (TCarbonControl descendants) or WindowRef (TCarbonWindow descendants).
 
* LCLObject - Is a bridge with the LCL object it is linked to.
 
* LCLObject - Is a bridge with the LCL object it is linked to.
  
 
=== Windows ===
 
=== Windows ===
  
Handles on Win32 or WinCE are almost always the same as their relative win api handles,For example handle of tmenu is HMENU,handle of TBrush is HBRUSH,so you can easily use them and pass them to windows apis.
+
Handles on [[Win32/64 Interface|Win32]] or [[Windows CE Interface|WinCE]] are almost always the same as their corresponding Win api handles. For example the handle for a TMenu is an HMENU, the handle for a TBrush is an HBRUSH. You simply pass one such handle as a parameter in a Windows api call.
  
 
== List of Handles on various LCL classes ==
 
== List of Handles on various LCL classes ==
Line 49: Line 74:
 
* Win32, WinCE: HFONT
 
* Win32, WinCE: HFONT
 
* Qt: A TQtFont object from qtprivate.pas
 
* Qt: A TQtFont object from qtprivate.pas
* Carbon: A TCarbonFont object from carbondef.pp
+
* Carbon: A TCarbonFont object from carbongdiobjects.pp
  
 
=== TCanvas ===
 
=== TCanvas ===
  
 
* Win32, WinCE: HDC
 
* Win32, WinCE: HDC
 +
* Gtk: A TDeviceContext object from gtkdef.pp
 +
** You can get a drawable, for example with: TDeviceContext(MyCanvas.Handle).Drawable
 
* Qt: A TQtDeviceContext object from qtprivate.pas
 
* Qt: A TQtDeviceContext object from qtprivate.pas
* Carbon: A TCarbonDeviceContext object from carbondef.pp
+
* Carbon: A TCarbonDeviceContext object from carboncanvas.pp
 +
** The native handle can be accessed with TCarbonDeviceContext(MyCanvas.Handle).CGContext of type CGContextRef
  
 
=== TBrush ===
 
=== TBrush ===
Line 61: Line 89:
 
* Win32, WinCE: HBRUSH
 
* Win32, WinCE: HBRUSH
 
* Qt: A TQtBrush object from qtprivate.pas
 
* Qt: A TQtBrush object from qtprivate.pas
* Carbon: A TCarbonBrush object from carbondef.pp
+
* Carbon: A TCarbonBrush object from carbongdiobjects.pp
  
 
=== TBitmap ===
 
=== TBitmap ===
Line 68: Line 96:
 
* Gtk: PGDIObject (defined on unit GtkDef)
 
* Gtk: PGDIObject (defined on unit GtkDef)
 
* Qt: A TQtImage object from qtobjects.pas unit
 
* Qt: A TQtImage object from qtobjects.pas unit
* Carbon: A TCarbonBitmap object from carbondef.pp
+
* Carbon: A TCarbonBitmap object from carbongdiobjects.pp
  
 
You can access this on Gtk using:
 
You can access this on Gtk using:
  
<pre>
+
<syntaxhighlight lang="pascal">
 
var
 
var
 
   GDIObject: PGDIObject;
 
   GDIObject: PGDIObject;
Line 89: Line 117:
 
   gtk_container_add(GTK_CONTAINER(MyForm.Handle), AImage);
 
   gtk_container_add(GTK_CONTAINER(MyForm.Handle), AImage);
 
end;
 
end;
</pre>
+
</syntaxhighlight>
  
 
=== TCustomForm ===
 
=== TCustomForm ===
Line 95: Line 123:
 
* Win32, WinCE: it´s a HWND, a native window handle
 
* Win32, WinCE: it´s a HWND, a native window handle
 
* Gtk: It´s a pointer to a structure.
 
* Gtk: It´s a pointer to a structure.
* Qt: The Handle is a pointer to a object from the TQtMainWindow class declared at qtprivate.pas. To have access to the QMainWindow Qt object it represents do: TQtMainWindow(Handle).Widget
+
* Qt: The Handle is a pointer to a object from the TQtMainWindow class declared at qtwidgets.pas.
* Carbon: WindowRef, Carbon native window handle
+
** To have access to the QMainWindow Qt object it represents do: TQtMainWindow(Handle).Widget
 +
** To have access to the container widget of the form, do: TQtMainWindow(Handle).GetContrainerWidget
 +
* Carbon: TCarbonWindow from carbonprivate.pp
  
 
=== TMenu, TMainMenu, TMenuItem and TPopUpMenu ===
 
=== TMenu, TMainMenu, TMenuItem and TPopUpMenu ===
Line 102: Line 132:
 
* Win32, WinCE : HMENU
 
* Win32, WinCE : HMENU
 
* Qt: TMainMenu is a pointer to a TQtMenuBar object. TPopUpMenu is a TQtMenu object. TMenuItem can either be a TQtAction if it represents a clickable item or a separator or a TQtMenu if it is an item that has submenus.
 
* Qt: TMainMenu is a pointer to a TQtMenuBar object. TPopUpMenu is a TQtMenu object. TMenuItem can either be a TQtAction if it represents a clickable item or a separator or a TQtMenu if it is an item that has submenus.
 +
* Carbon: TMenuItem is a TCarbonMenu object, TMenu (TMainMenu and TPopupMenu) is represented by its root menu item
 +
 +
== See also ==
 +
 +
*[[Interfaces]]
 +
*[[How To Use Interfaces]]
 +
*[[Understanding Interfaces]]

Latest revision as of 01:37, 9 March 2020

English (en) português (pt)

This page describes how to write access the underlying widgetset used by lazarus directly (for example: The Windows API, or Gtk, or Qt, etc). One should always try to avoid relying on widgetset specials. This document is here for both people improving the widgetsets and for people writing components that really need to access the widgets directly.

Overview

Every TWinControl has a handle, and the LCL does not need to know, what a Handle is. The meaning of the Handle is totally up to the interface:

  • under GTK a handle is often a PGtkWidget
  • under Windows a handle is often a HWnd.
  • under Carbon a handle is often a object descendant of TCarbonWidget.
  • under Qt, a handle is often a pointer to a object descendent of TQtWidget.

Per-Widgetset Details

Qt

Handles on Qt are mostly pointers to objects. Every time a control is created, a helper object is also created and both are connected. The helper object is necessary to receive events from Qt. After receiving an event it will send it to the LCL.

Most of those objects are descendents from TQtWidget as declared below:

{ TQtWidget }

TQtWidget = class(TObject)
private
  ...
public
  Widget: QWidgetH;
  LCLObject: TWinControl;
public
  function  GetContainerWidget: QWidgetH; virtual;
  ...
end;

Notice the two variables they all contain:

  • Widget - This is a connect to the Qt object for this Widget
  • LCLObject - Is a bridge with the LCL object it is linked to.

And also this method:

  • GetContrainerWidget() - When you wish to create a new widget and set it's parent, don't set it to Widget. Set it to GetContrainerWidget() instead. This happens because forms have 2 widgets. The main form widget, and also a container widget, where all child controls should be put to ensure that the size of the menu is handled automatically. Most other controls will have just one widget, but by using this function you avoid surprises in case the implementation of a control changes.

Carbon

Handles on Carbon are very similar to Qt ones. The helper classes are descended from abstract class TCarbonWidget.

{ TCarbonWidget }

TCarbonWidget = class(TObject)
private
public
  Widget: Pointer;
  LCLObject: TWinControl;
end;

Notice the two variables they all contain:

  • Widget - This is a connect to the Carbon object for this Widget: ControlRef (TCarbonControl descendants) or WindowRef (TCarbonWindow descendants).
  • LCLObject - Is a bridge with the LCL object it is linked to.

Windows

Handles on Win32 or WinCE are almost always the same as their corresponding Win api handles. For example the handle for a TMenu is an HMENU, the handle for a TBrush is an HBRUSH. You simply pass one such handle as a parameter in a Windows api call.

List of Handles on various LCL classes

TFont

  • Win32, WinCE: HFONT
  • Qt: A TQtFont object from qtprivate.pas
  • Carbon: A TCarbonFont object from carbongdiobjects.pp

TCanvas

  • Win32, WinCE: HDC
  • Gtk: A TDeviceContext object from gtkdef.pp
    • You can get a drawable, for example with: TDeviceContext(MyCanvas.Handle).Drawable
  • Qt: A TQtDeviceContext object from qtprivate.pas
  • Carbon: A TCarbonDeviceContext object from carboncanvas.pp
    • The native handle can be accessed with TCarbonDeviceContext(MyCanvas.Handle).CGContext of type CGContextRef

TBrush

  • Win32, WinCE: HBRUSH
  • Qt: A TQtBrush object from qtprivate.pas
  • Carbon: A TCarbonBrush object from carbongdiobjects.pp

TBitmap

  • Win32, WinCE: HBITMAP
  • Gtk: PGDIObject (defined on unit GtkDef)
  • Qt: A TQtImage object from qtobjects.pas unit
  • Carbon: A TCarbonBitmap object from carbongdiobjects.pp

You can access this on Gtk using:

var
  GDIObject: PGDIObject;
  Bitmap: TBitmap;
  AImage: PGtkWidget;
begin
  ...

  GDIObject := PgdiObject(Bitmap.Handle);

  AImage := gtk_image_new_from_pixmap(GDIObject^.GDIPixmapObject,
   GDIObject^.GDIBitmapMaskObject);

  gtk_widget_show(AImage);

  gtk_container_add(GTK_CONTAINER(MyForm.Handle), AImage);
end;

TCustomForm

  • Win32, WinCE: it´s a HWND, a native window handle
  • Gtk: It´s a pointer to a structure.
  • Qt: The Handle is a pointer to a object from the TQtMainWindow class declared at qtwidgets.pas.
    • To have access to the QMainWindow Qt object it represents do: TQtMainWindow(Handle).Widget
    • To have access to the container widget of the form, do: TQtMainWindow(Handle).GetContrainerWidget
  • Carbon: TCarbonWindow from carbonprivate.pp

TMenu, TMainMenu, TMenuItem and TPopUpMenu

  • Win32, WinCE : HMENU
  • Qt: TMainMenu is a pointer to a TQtMenuBar object. TPopUpMenu is a TQtMenu object. TMenuItem can either be a TQtAction if it represents a clickable item or a separator or a TQtMenu if it is an item that has submenus.
  • Carbon: TMenuItem is a TCarbonMenu object, TMenu (TMainMenu and TPopupMenu) is represented by its root menu item

See also