We help IT Professionals succeed at work.

Delphi TFileOpenDialog.ClientGUID

plumothy
plumothy asked
on
Embarcadero documentation says TFileOpenDialog.ClientGUID "holds a GUID associated with a dialog's persisted state".

But where does it store this persisted state? Does it persist between session of the application or just throughout one session?
Comment
Watch Question

Lukasz Zielinskisoftware developer
Top Expert 2008

Commented:
Hi,

It is normal property of type string. So it will stay as long as TFileOpenDialog exists or until you re-set it to different value.
Only difference between other string properties is that when .Execute() is called - StringToGUID() will be called on value you set.

ziolko.
Lukasz Zielinskisoftware developer
Top Expert 2008

Commented:
…"persistent" means also that if you drop TFileOpenDialog on your form/datamodule in design time and assign value to ClientGuid property - this value will be saved to your .dfm file.

ziolko.

Author

Commented:
I have done some more testing and have discovered that Size and Position of the dialog persist between application sessions. This means that Size and Postion are being stored somewhere other than in the application itself.

I have searched the Registry and my hard disks for the GUID that I have been using and cannot find it anywhere. But it must be somewhere!

The MS documentation says "A dialog's state can include factors such as the last visited folder and the position and size of the dialog".

This is not explicit: "...can include.." implies it may include or may not include and "...factors such as..." just gives some examples.

I would like to know what is stored so that I can know what I have to do myself and what I can leave to the automated system. I asked WHERE it is stored so I can go there and see WHAT is stored
Lukasz Zielinskisoftware developer
Top Expert 2008

Commented:
TFileOpenDialog calls windows shell to invoke dialog so Size and Position are properties of windows object, and it's OS that saves those values, along with last opened folder and probably some others.
ClientGuid is Delphi's object property and windows is not aware of it's existence and as result not saved by Windows.


ClientGuid is defined as "published" property:

...
  TFileOpenDialog = class(TCustomFileOpenDialog)
  published
    property ClientGuid;


which causes it's value to be stored in .dfm of your form/datamodule.

This property is used only by Delphi object and never passed to any Windows call.
You will not find it anywhere in registry unles you store it yourself (or use 3rd party components to store component properties).

It will act same as Caption property of your form except that ClientGuid will be checked for proper GUID value.


ziolko.

Author

Commented:
I am not asking about where TFileOpenDialog.ClientGUID is stored. I am asking where the persisted information is stored (so I can see what that information is). My dialog is created at runtime so I don't think the DFM has anything to do with it.

I can do this:
  • run my application
  • open the dialog
  • change its size and position
  • close the application
  • run it again
  • open the dialog - it has remembered its pervious size and position.

So, doesn't this mean that the OS must be remembering those attributes (and, therefore, the associated GUID) somehow?

If I have got that wrong and it is my application that is storing the information between sessions then where is it storing it?

TCustomFileOpenDialog descends from TCustomFileDialog, which implements IFileDialog:

  TCustomFileDialog = class(TComponent)
  strict protected
    function CreateFileDialog: IFileDialog; virtual; abstract;

Open in new window


IFileDialog is partly documented here
Lukasz Zielinskisoftware developer
Top Expert 2008

Commented:
I am asking where the persisted information is stored
"persisted" in Delphi means "published" properties, and they are stored in .dfm


My dialog is created at runtime so I don't think the DFM has anything to do with it
if you create object in run-time then indeed .dfm has nothing to do with it.

In your case this info is not stored anywhere except object's memory. So as soon as your object is destroyed - information is gone.

Again "size" and "position" are not properties of TFileOpenDialog.

If you want to know where OS is storing info about last position of opened windows look somewhere in here:
Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\bam\State\UserSettings
just search that node of registry and look for your exe name (like Project1.exe).
But what you will find will be Binary value - so it's going to be difficult to retrieve anything from it - and for sure ClientGuid will not be there

ziolko.

Author

Commented:
"persisted" in Delphi means "published" properties, and they are stored in .dfm
In this instance, I believe the word "persisted" in the Delphi documentation comes directly from the MS documentation (the wording is almost identical).

Again "size" and "position" are not properties of TFileOpenDialog.
I realize this - they are just two examples of what (according to MS) "can" be persisted. I would like to know what actually IS persisted (not just a couple of examples).

If you want to know where OS is storing info about last position of opened windows look somewhere in here:
Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\bam\State\UserSettings
just search that node of registry and look for your exe name (like Project1.exe).
But what you will find will be Binary value - so it's going to be difficult to retrieve anything from it - and for sure ClientGuid will not be there.

Thank you - yes I do see an entry there and as you said, it is binary. So, that changes my question from WHERE is it stored to WHAT is stored (in addition to size and position).
Lukasz Zielinskisoftware developer
Top Expert 2008

Commented:
In this instance, I believe the word "persisted" in the Delphi documentation comes directly from the MS documentation (the wording is almost identical).

if I look at sourcecode of TFileOpenDialog it's clear that ClientGuid is nothing more than "published" object property - not used in calls to windows shell.

So, that changes my question from WHERE is it stored to WHAT is stored (in addition to size and position).
That's more of Windows question than Delphi/programming question. Windows does to all apps regardless of prog. language.
I would be surprised if Microsoft published details of this reg entry. I can imagine that there is much more that just size and position, my bet is not only on last opened folder but also some kind of monitor/display ID. And probably some others

ziolko.

Author

Commented:
I have done some more investigation.

I used Delphi to create two different applications (Test1.exe and Test2.exe). Both of these create a FileOpenDialog at runtime and set its GUID to the SAME value.

I ran Test1.exe, displayed the dialog and changed its size and position.

I checked HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\bam\State\UserSettings.
Test1.exe was in one of the keys there, but not Test2.exe.

I ran Test2.exe and it displayed the dialog with the same size and position as Test1.exe. This suggests to me that Test2.exe did NOT obtain the dialog size and position from a key under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\bam\State\UserSettings.
So, I think it must have used the GUID that was given - because that is the only thing that is common to the two test applications.

So, I guess the original question actually still stands - where is this information stored?
Lukasz Zielinskisoftware developer
Top Expert 2008

Commented:
did you create new Delphi project or just renamed existing Test1.exe?
because when I create separate project - size and position of open dialog is different for each exe

ziolko
Lukasz Zielinskisoftware developer
Top Expert 2008

Commented:
… it was my mistake, indeed it opens in same location.
that's a puzzle, i will get back to it tomorrow.

ziolko.
software developer
Top Expert 2008
Commented:
ok, I admit  - I was to quick with my earlier comments. Indeed ClientGuid is passed to shell and is used to store info about dialogs.
I did some investigation and found out that everytime I use new random guid for ClientGuid property there is a item created in registry:

Computer\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\CIDSizeMRU

See attached pic, it's quite clear. You'll also understand why your registry search failed.
EE.jpg

Author

Commented:
ziolko,

Fantastic!

Looking in my registry I can see a large number of entries in that key. They have very unhelpful Names (just a number!), each with a binary Value (so text searching not possible, as you say).

Each Value begins with either the GUID supplied or the name of the EXE, then it is empty except for the last few bytes which, presumably, is where the  size & position are stored.

If there is anything else stored there I guess we will never know!

However, you have answered my question 100% so thank you very much for that.

Author

Commented:
Great work ziolko. Thank you!
Lukasz Zielinskisoftware developer
Top Expert 2008

Commented:
Glad I could help you:)

This binary value... my guess is that it is some kind of struct (Delphi's record) that just gets stored.
So technically it should be possible to reverse engineer it by simply moving dialog window and observing which bytes are changed.
But then you never know when Microsoft decides to change it.

I tried to find some more details about it but came up empty, I guess data structure of this binary is not officially published by Microsoft.

ziolko.