Put an OpenDialog component on a new form and this code in OnCreate
opendialog1.filename:='This is a long filename.txt';
opendialog1.execute;
When the app runs the dialog appears with the filename displayed in the opendialog, but the filename is highlighted and scrolled to the right (even though there is plenty of room to show the full filename).
All it shows is "ng filename.txt" that has been highlighted.
Is there a way I can "unhighlight" the filename and get the text scrolled back to the left so it shows the full name "This is a long filename.txt"?
The problem would be fixed if I could simulate/push a press of the home key into the OpenDialog once it is shown, but none of the following options seem to work.
keybd_event(VK_HOME, 0, 0, 0);
keybd_event(VK_HOME, 0, KEYEVENTF_KEYUP, 0);
or
input.Itype := INPUT_KEYBOARD;
input.ki.wVk := 47;
input.ki.wScan := 47;
input.ki.dwFlags := 0;
input.ki.time := 0;
input.ki.dwExtraInfo := 0;
SendInput(1, input, sizeof(input));
input.ki.dwFlags := KEYEVENTF_KEYUP;
SendInput(1, input, sizeof(input));
or
PostMessage(GetParent(OpenDialog1.Handle), WM_KEYDOWN, VK_HOME, 0);
PostMessage(GetParent(OpenDialog1.Handle), WM_KEYUP, VK_HOME, 0);
If I put those snippets of code before openDialog1.execute it does seem to work on my PC, but is a bad idea as the dialog is not open yet and so may not receive the key press message(s).
Trying all of those methods after the opendialog1.execute call don't seem to do anything.
The suggested solution
is not safe, no matter when you execute it.
What if I press Ctrl+O in the app and switch to a different app while waiting for the dialog to show?
Then this other app will receive the HOME key. Then anything can happen. The other app might be displaying a track bar controlling the rate of flow of a patient's IV drugs, and that HOME key might set the trackbar to 0 cc/min.
More likely: you lose the selection in an Explorer window (possibly containing a thousand images), the caret pos in a document (located at a very particular place), the selected node in a tree view, etc. Or your media player restarts the current track.
And yes, many people (such as myself) really do multitask in that way!
This is a possible (safe) solution. I don't claim that it is the most elegant one, though.
The approach is as follows:
I use the
OnSelectionChange
event to get a chance to run some code after the dialog window has been created. However, I must manually make sure that I only run my "file name fix" the very first time this event is fired. I also make sure only to run this code if the (default) file name is non-empty.The first time the event is fired, I find the edit box inside it. I "know" it is the right control because (1) it is an edit box and (2) its text is equal to the (default) file name (which is not empty).
I then specifically instruct this edit box to move its caret to the first character, and then to (re)select every character.
Full code:
Before:
After:
Update
Upon request, I have made an easily reusable unit and function to apply this fix.
Here is the complete unit:
To use this unit and function in your own unit
X
, just add the unit (OpenDialogUpgrader
) to yourX
unit's implementation sectionuses
clause and change your standardinto
Of course, if your application has 73 open dialogs in 20 different units, you only need a single copy of this
OpenDialogUpgrader
unit, but you need to add it to the implementation sectionuses
clause in each of your 20 units. And you need to callFixOpenDialog
before eachTOpenDialog.Execute
.