Recent

Author Topic: How do I obtain the X11 or MS Windows handle of a QT window object?  (Read 2845 times)

vfclists

  • Hero Member
  • *****
  • Posts: 1045
    • HowTos Considered Harmful?
I'm trying to embed forms and windows of other programs into a QT based panel, and they require the a window ID for the panel.

Lazarus 3.0/FPC 3.2.2

MarkMLl

  • Hero Member
  • *****
  • Posts: 7508
Re: How do I obtain the X11 or MS Windows handle of a QT window object?
« Reply #1 on: January 19, 2024, 04:04:53 pm »
I might be able to provide a partial answer for X11.

I have a monitoring program here which can detect if something that looks like an exception popup is on the screen, and alert a monitoring program to- on rare occasions- wake me up in the middle of the night. Looking at the code, I ran  wmctrl -lp  to get a list of titles, after which I filtered looking for candidate problems. So I suggest that in the X11 case it boils down to working out what API wmctrl is using... which might not be a simple job since I find all of the Window Manager stuff to be pretty impenetrable.

The predecessor program was written for Win-32 in the W2K era but in practice only used NT-era APIs, I've got a very vague recollection that I used the windowstation (?) API to scan multiple desktops and (presumably) filtered on names etc. after that.

HTH in some small way.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

CCRDude

  • Hero Member
  • *****
  • Posts: 608
Re: How do I obtain the X11 or MS Windows handle of a QT window object?
« Reply #2 on: January 19, 2024, 04:11:08 pm »
I must admit I used google... and it looks quite easy:

https://stackoverflow.com/questions/22652592/getting-the-hwnd-of-a-widget-in-qt

Quote
You can use QWidget::winId() to get the HWND associated with a widget.

vfclists

  • Hero Member
  • *****
  • Posts: 1045
    • HowTos Considered Harmful?
Re: How do I obtain the X11 or MS Windows handle of a QT window object?
« Reply #3 on: January 19, 2024, 04:45:45 pm »
I must admit I used google... and it looks quite easy:

https://stackoverflow.com/questions/22652592/getting-the-hwnd-of-a-widget-in-qt

Quote
You can use QWidget::winId() to get the HWND associated with a widget.

Yes, but that leaves how to get the winId of the TWinControl in question within FreePascal.

I am sure I've done it before, I just can't remember the sample program I did it in.
Lazarus 3.0/FPC 3.2.2

zeljko

  • Hero Member
  • *****
  • Posts: 1638
    • http://wiki.lazarus.freepascal.org/User:Zeljan
Re: How do I obtain the X11 or MS Windows handle of a QT window object?
« Reply #4 on: January 19, 2024, 05:18:52 pm »
TWinControl.handle = TQtWidget, if you need QWidget then
  TQtWidget(Handle).Widget.
eg if you want to call Qt directly from your app:
QWidget_setVisible(TQtWidget(Handle).Widget, True);
if you want to directly access QPainter inside paint event then:
TQtDeviceContext(Canvas.Handle).Widget
eg
WideStr := 'MyText';
QPainter_drawText(TQtDeviceContext(Canvas.Handle).Widget, @WideStr);

vfclists

  • Hero Member
  • *****
  • Posts: 1045
    • HowTos Considered Harmful?
Re: How do I obtain the X11 or MS Windows handle of a QT window object?
« Reply #5 on: January 20, 2024, 04:42:04 pm »
TWinControl.handle = TQtWidget, if you need QWidget then
  TQtWidget(Handle).Widget.
eg if you want to call Qt directly from your app:
QWidget_setVisible(TQtWidget(Handle).Widget, True);
if you want to directly access QPainter inside paint event then:
TQtDeviceContext(Canvas.Handle).Widget
eg
WideStr := 'MyText';
QPainter_drawText(TQtDeviceContext(Canvas.Handle).Widget, @WideStr);

Thanks. I managed to get it working.

I embedded an Emacs session into TPanel and got it working.

The problem now is Emacs doesn't get resized when the panel is resized, and I think the way to do that would be to get the window handle of the embedded session and ask X11 or Windows, or perhaps QT the resize.

Is there some way for the TPanel to get the handle of the embedded Emacs?

Maybe there is another type of control that can get any items placed inside to behave like Lazarus own alClient child controls?
Lazarus 3.0/FPC 3.2.2

MarkMLl

  • Hero Member
  • *****
  • Posts: 7508
Re: How do I obtain the X11 or MS Windows handle of a QT window object?
« Reply #6 on: January 20, 2024, 05:43:09 pm »
The problem now is Emacs doesn't get resized when the panel is resized, and I think the way to do that would be to get the window handle of the embedded session and ask X11 or Windows, or perhaps QT the resize.

xref to final para of https://forum.lazarus.freepascal.org/index.php/topic,65913.msg502935.html#msg502935

That sort of thing is specifically why I added resize monitoring to the IDE's console window: I was working on something that wanted an embedded shell. Looking at my notes in pseudoterminaldlg.pp, at least in Linux there's an ioctl() involved which, if sent to a terminal (a pty?) results in the kernel sending the appropriate signal to the app(s) sunning in it.

MarkMLl
« Last Edit: January 20, 2024, 07:30:37 pm by MarkMLl »
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

zeljko

  • Hero Member
  • *****
  • Posts: 1638
    • http://wiki.lazarus.freepascal.org/User:Zeljan
Re: How do I obtain the X11 or MS Windows handle of a QT window object?
« Reply #7 on: January 20, 2024, 10:42:55 pm »
TWinControl.handle = TQtWidget, if you need QWidget then
  TQtWidget(Handle).Widget.
eg if you want to call Qt directly from your app:
QWidget_setVisible(TQtWidget(Handle).Widget, True);
if you want to directly access QPainter inside paint event then:
TQtDeviceContext(Canvas.Handle).Widget
eg
WideStr := 'MyText';
QPainter_drawText(TQtDeviceContext(Canvas.Handle).Widget, @WideStr);

Thanks. I managed to get it working.

I embedded an Emacs session into TPanel and got it working.

The problem now is Emacs doesn't get resized when the panel is resized, and I think the way to do that would be to get the window handle of the embedded session and ask X11 or Windows, or perhaps QT the resize.

Is there some way for the TPanel to get the handle of the embedded Emacs?

Maybe there is another type of control that can get any items placed inside to behave like Lazarus own alClient child controls?

How exactly you embed emacs window into TPanel ? Have you used qt or x11 directly ?

vfclists

  • Hero Member
  • *****
  • Posts: 1045
    • HowTos Considered Harmful?
Re: How do I obtain the X11 or MS Windows handle of a QT window object?
« Reply #8 on: January 20, 2024, 11:33:39 pm »

How exactly you embed emacs window into TPanel ? Have you used qt or x11 directly ?

This is the code for getting the panel's window handle.

Code: Pascal  [Select][+][-]
  1. procedure TForm1.btnPanelHandleClick(Sender: TObject);
  2. begin
  3.   edtWinHandle.Text := IntToStr(QWidget_winId(TQtWidget(pnlEmacsParent.Handle).Widget));
  4. end;
  5.  


This the Emacs command, with window handle 102760473
Code: Bash  [Select][+][-]
  1. emacs  --parent-id 102760473 --with-profile doom01
Lazarus 3.0/FPC 3.2.2

zeljko

  • Hero Member
  • *****
  • Posts: 1638
    • http://wiki.lazarus.freepascal.org/User:Zeljan
Re: How do I obtain the X11 or MS Windows handle of a QT window object?
« Reply #9 on: January 21, 2024, 08:49:32 am »
You have Qt routines to embedd foreign window, maybe that works better. I cannot remember exactly but long time ago way example here on forum howto embedd x11 window via starting it's process via TProcess.
Check this two routines: https://doc.qt.io/qt-6/qwidget.html#createWindowContainer and https://doc.qt.io/qt-6/qwindow.html#fromWinId.

 

TinyPortal © 2005-2018