Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Position OpenDialog in the center of main form (not screen)?

1,231 views
Skip to first unread message

Martin B

unread,
Sep 7, 2005, 11:27:19 AM9/7/05
to
Hello,

How to control the position of OpenDialog?
(I know you can position the BrowseForFolder, but the method does not apply
to OpenDialog)


I have investigated for some time how to position an OpenDialog in the
center
of the main form (or any other position for that matter).

The dialog is always placed in the center of the screen. This is not very
nice
when all your message popups in the program appear in the center of the
active window.

I have a field definition window for defining the fields in a data file.
This window pops up in the center of the main form, because this is most
natural.


Regards,
Martin


Peter Below (TeamB)

unread,
Sep 7, 2005, 1:59:43 PM9/7/05
to
In article <431f071d$1...@newsgroups.borland.com>, Martin B wrote:
> How to control the position of OpenDialog?
> (I know you can position the BrowseForFolder, but the method does not apply
> to OpenDialog)

Here is an older post that should be what you need.

Moving a common dialog, preventing the standard centering.

> I am developing a custom dialog component from TOpenDialog and I would like
> to be able to position the dialog anywhere on screen. Unfortunately, I have
> had no success in using either SetWindowPos or MoveWindow. Although
> MoveWindow will change the dimensions of the dialog so adding custom
> controls is no problem, the parameters int X and int Y are completely
> ignored. The dialog always shows centered in the screen (BTW, I don't have
> the "Center dialogs" option checked in my display settings). Does anyone
> know how to control positioning of common dialogs.

The problem here is that the VCL code responsible for centering the
dialog is executed after the DoShow method (which fires the OnShow
event). You did not mention where you have placed the code to change the
window dimensions, but with a standard TOpenDialog the following works
in the OnShow event:

procedure TForm1.OpenDialog1Show(Sender: TObject);
var
r: TRect;
begin
with sender as topendialog do begin
GetWIndowRect( GetParent( handle ), r );
MOveWindow( GetParent( handle ),
10, 10, r.right-r.left,
r.bottom-r.top, true );
Abort;
end;
end;

The Abort prevents the WM_NOTIFY message that triggered the OnShow event
from reaching the dialogs original window proc, which would pass it to
the ExplorerHook function in dialogs.pas, which does the centering if
the notification is CBN_INITDONE.


--
Peter Below (TeamB)
Use the newsgroup archives :
http://www.mers.com/searchsite.html
http://www.tamaracka.com/search.htm
http://groups.google.com
http://www.prolix.be


Heinrich Wolf

unread,
Sep 7, 2005, 2:51:38 PM9/7/05
to
Hi,

while you posted, I have been trying exactly that way.
But I did not find out, that I have to use Abort.
Then I read your post and tried it.
I noticed that it only works on the first execution of the dialog.
If I move the dialog, close it and open it again,
it remembers the position, where it was moved to.
How can I control the position in repeated executions?

Regards
Heiner


Martin B

unread,
Sep 7, 2005, 5:54:26 PM9/7/05
to
Excellent, but strange things happen when I try to put variables in place of
the constants.
When I replace the first 10 with variable X, everything works.
But when I also replace the next 10 with Y, I get an Access Violation.
This is very stange, since the values are ok, and x,y are declared as
integer.

Also, why not use SetWindowsPos instead of MoveWindow?
Then you can avoid setting the width and height propoerty.
(Same Access violation occurs with SetWindowPos)

Martin B

unread,
Sep 7, 2005, 6:25:37 PM9/7/05
to
How about this:
First use the onShow event to position the dialog box out of screen (out of
sight).
The use a timer to center the dialog on the main form (set the interval to
50 msec):

procedure TMainWindow.fopenShow(Sender: TObject);
var r: TRect;
begin
fopentimer.Enabled:=true;


with sender as topendialog do
begin

GetWindowRect( GetParent( handle ), r );
SetWindowPos(getparent(handle), 0,
-(r.Right-r.Left),-(r.Bottom-r.Top),
0, 0, SWP_NOSIZE);
Abort;
end;
end;

procedure TMainWindow.fopentimerTimer(Sender: TObject);
var dlgWnd : HWND;
dlgX,dlgY : Integer;
dlgRect : TRect;
begin
fopentimer.Enabled:=false;
dlgWnd := FindWindow('#32770', Pansichar(fopen.Title)); {Find the
dialog window}
if dlgWnd <> 0 then
begin
GetWindowRect(dlgWnd, dlgRect);
dlgX := application.MainForm.Left +
(application.MainForm.Width-(dlgRect.Right - dlgRect.Left)) div 2;
dlgY := application.MainForm.Top +
(application.MainForm.Height-(dlgRect.Bottom - dlgRect.Top)) div 2;
SetWindowPos(dlgWnd, 0, dlgX, dlgY, 0, 0, SWP_NOSIZE);
end;
end;


Peter Below (TeamB)

unread,
Sep 8, 2005, 2:10:45 PM9/8/05
to
In article <431f...@newsgroups.borland.com>, Martin B wrote:
> Excellent, but strange things happen when I try to put variables in place of
> the constants.
> When I replace the first 10 with variable X, everything works.
> But when I also replace the next 10 with Y, I get an Access Violation.
> This is very stange, since the values are ok, and x,y are declared as
> integer.

Without seeing the actual code you use there is no chance to make a diagnosis.

> Also, why not use SetWindowsPos instead of MoveWindow?

Certainly an option.

0 new messages