Add additional Components to a TOpenDialog lazarus / 67-Windows ---------------------------------------------------------------------- dangersgromit · 2025-01-15 23:26 Hello everyone! I'm kind of stuck trying to add a combobox to a TFileDialog (in this case a TOpenDialog). I tried to adapt an old Delphi example I found on StackOverflow to Lazarus. Everythings seems fine, but i get an "Error: identifier idents no member "QueryInferace" while compiling on lines 57 and 68 It looks fine to me when i follow the function back to TComponent. Even the IDE presents these help lines: Quoteprotected function TComponent. QueryInterface(constref IID: TGUID; out Obj): Hresult; C:\lazarus40\fpc\3.2.2\source\rtl\objpas\classes\classesh.inc(1941,14) unit Classes Any ideas? Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unit Unit1; {$mode objfpc}{$H+} interface uses  Windows, Messages, Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, Variants, win32Extra; type   { TForm1 }   TForm1 = class(TForm)    btnOpenFile: TButton;    ListBox1: TListBox;    ExampleDialog: TOpenDialog;    procedure btnOpenFileClick(Sender: TObject);    procedure ExampleDialogCanClose(Sender: TObject; var CanClose: Boolean);    procedure ExampleDialogShow(Sender: TObject);  private   public   end; var  Form1: TForm1; const  CUSTOM_CONTROL_ID = 1; implementation uses  shlobj; {$R *.lfm} { TForm1 } procedure TForm1.btnOpenFileClick(Sender: TObject);begin  ExampleDialog.Tag := 0;  if ExampleDialog.Execute then  begin    ShowMessage (Format ('Selected Custom Item %d'#13#10+'File: %s', [ExampleDialog.Tag, ExampleDialog.Filename]));  end;end; procedure TForm1.ExampleDialogCanClose(Sender: TObject; var CanClose: Boolean);var  ICustomize : IFileDialogCustomize;  vSelectedIndex : DWORD;begin  vSelectedIndex:= 0;  if ExampleDialog.QueryInterface(IFileDialogCustomize, ICustomize) = S_OK then    ICustomize.GetSelectedControlItem(CUSTOM_CONTROL_ID, vSelectedIndex);  ExampleDialog.Tag := vSelectedIndex -1;end; procedure TForm1.ExampleDialogShow(Sender: TObject);var  ICustomize : IFileDialogCustomize;  vItem : String;  i: Integer;begin  if ExampleDialog.QueryInterface(IFileDialogCustomize, ICustomize) = S_OK then  begin    ICustomize.StartVisualGroup(0, 'Custom Items: ');    try      ICustomize.AddComboBox(CUSTOM_CONTROL_ID);       for i := 0 to ListBox1.Count -1 do      begin        vItem := ListBox1.Items[i];        ICustomize.AddControlItem(CUSTOM_CONTROL_ID, i+1, PWideChar(vItem));      end;      if ListBox1.ItemIndex > -1 then    ICustomize.SetSelectedControlItem(CUSTOM_CONTROL_ID, ListBox1.ItemIndex+1);    finally      ICustomize.EndVisualGroup;    end;  end;end; end. ---------------------------------------------------------------------- Remy Lebeau · 2025-01-16 02:52 Quote from: dangersgromit on January 16, 2025, 12:26:58 amI'm kind of stuck trying to add a combobox to a TFileDialog (in this case a TOpenDialog). I tried to adapt an old Delphi example I found on StackOverflow to Lazarus. Everythings seems fine, but i get an "Error: identifier idents no member "QueryInferace" while compiling on lines 57 and 68 QueryInterface() is protected in TComponent, in both Delphi and FreePascal.  So, you can't call it directly from outside of the class.  However, TComponent inherits a public GetInterface() method from TObject, and TComponent.QueryInterface() uses TObject.GetInterface() internally. However, you should use SysUtils.Supports() instead.  Even in Delphi, this is the preferred way to query objects for interfaces. However, TOpenDialog itself does not implement IFileDialogCustomize, so I would expect any of these query methods to fail.  It is the IFileDialog object that is wrapped inside of the TOpenDialog which implements IFileDialogCustomize.  So, you would need to query that IFileDialog object instead. But, I don't think TOpenDialog in FreePascal/Lazarus exposes access to the wrapped IFileDialog.  TOpenDialog in Delphi certainly doesn't. Delphi has a whole separate TFileOpenDialog component which does expose access to IFileDialog, but FreePascal/Lazarus does not have that component. I don't know which StackOverflow example you based your code on, but I don't see how it could ever have worked in Delphi, let alone in FreePascal/Lazarus. ---------------------------------------------------------------------- dangersgromit · 2025-01-16 03:26 Thanks Remy. The original example used TFileOpenDialog indeed. So there is no "easy" way to do this in lazarus. For this project I'll have to do another way. Instead of adding a Combobox do the dialog i'll have to do a second dialog afterwards asking for the additional information. Greetings Klaus. ---------------------------------------------------------------------- Remy Lebeau · 2025-01-16 04:08 Quote from: dangersgromit on January 16, 2025, 04:26:41 amSo there is no "easy" way to do this in lazarus. For this project I'll have to do another way. Instead of adding a Combobox do the dialog i'll have to do a second dialog afterwards asking for the additional information. Or, you could simply use IFileOpenDialog directly. https://learn.microsoft.com/en-us/windows/win32/shell/common-file- dialog ---------------------------------------------------------------------- Thaddy · 2025-01-16 05:39 And https://learn.microsoft.com/en-us/windows/win32/api/shobjidl_core/nn- shobjidl_core-ifiledialogcustomize and family. Note all Windows only. I am not sure these API's have already a Pascal equivalent, not in Windows nor in jwaWindows. ---------------------------------------------------------------------- cdbc · 2025-01-16 06:03 Hi Hmmmm, MeThinks that will take some doing to get right... Not just bolted together in a hurry... That method-list is worthy of a /dang/ Michelin-star  "Dialog on the fly" ...that's an idea  Regards Benny ---------------------------------------------------------------------- anse · 2025-08-16 13:31 I also like to add a combo box to the TOpenDialog, so the user can select an encoding of the textfile he's opening. In Delphi I was using the same as mentioned above (Dialog.QueryInterface(IFileDialogCustomize, iCustomize) = S_OK). Now in Lazarus, with TOpenDialog, I just see some workarounds, all leaving some bitter taste: * show a second dialog after the open-dialog, asking for the encoding * or extend the file extension filter in the open-dialog: "Textfile, UTF-8|*.txt|Textfile, Unicode Big Endian|*.txt|...". Downside: a looong list of file types if you support multiple file extensions. * remove support for non-UTF-8 files ---------------------------------------------------------------------- Thaddy · 2025-08-16 13:50 Well, you can also write your own... that may be the best option. ---------------------------------------------------------------------- anse · 2025-08-16 14:12 Yeah, probably. But that feels like reinventing the wheel. ---------------------------------------------------------------------- Remy Lebeau · 2025-08-16 17:08 As I mentioned earlier this year, you could simpy use the IFileOpenDialog API directly. You don't really need a component wrapper for it. https://learn.microsoft.com/en-us/windows/win32/shell/common-file- dialog ---------------------------------------------------------------------- wp · 2025-08-16 18:30 Quote from: anse on August 16, 2025, 04:12:38 pmBut that feels like reinventing the wheel. Not much to reinvent - all the building blocks are available. Find in the attachment a simple "home-made" TOpenDialog, not 100% complete, and certainly some bugs here and there. But it shows you than it does not take much to build a pure-Pascal TOpenDialog. And starting from here, you can extended it with whatever you like. ---------------------------------------------------------------------- anse · 2025-08-17 19:16 Agreed, quite easy with the TShellTreeView on the left and TShellListView on the right. Both are working nicely on Windows and Linux/gtk2. Some "sugar features" like bookmarks and recently used places are missing. But definitely worth it for adding custom controls on the dialog. Thanks for the inspiration!