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

Want to change position of standard dialogs

12 views
Skip to first unread message

Robert Schimpfle

unread,
Oct 29, 2003, 2:20:49 PM10/29/03
to
Hi!

Can I change the position of standard dialogs in C-Builder?

e. g.:

There is a form with a TOpenDialog OpenInputFile;
if I use the command "OpenInputFile->Show ();", the dialog is placed
right in the middle of my screen.
Can I force C-Builder / Windows to put this dialog at another place, f.
i. top left or at a specified point?

I am using C-Builder 4, NT 4.0

thanks

Robert

Remy Lebeau (TeamB)

unread,
Oct 29, 2003, 3:04:22 PM10/29/03
to

"Robert Schimpfle" <schi...@uni-trier.de> wrote in message
news:3FA01311...@uni-trier.de...

> if I use the command "OpenInputFile->Show ();", the
> dialog is placed right in the middle of my screen.

You shold not be calling Show() directly. Use Execute() instead:

OpenInputFile->Execute()

> Can I force C-Builder / Windows to put this dialog at

> another place, f.i. top left or at a specified point?

The dialog is controlled by the OS itself, not the VCL. You can try using
the OnShow event to manualy move the underlying dialog window itself using
MoveWindow(). TOpenDialog inherits a Handle property that is the HWND for
the dialog.


Gambit

Robert Schimpfle

unread,
Oct 30, 2003, 4:03:54 PM10/30/03
to
I used MoveWindow, but it did not work...

Anybody who has already done it?
I would appreciate a few lines of C++ code for this problem?

Robert

Remy Lebeau (TeamB)

unread,
Oct 30, 2003, 4:17:39 PM10/30/03
to

"Robert Schimpfle" <schi...@uni-trier.de> wrote in message
news:3FA17CBA...@uni-trier.de...

> I used MoveWindow, but it did not work...

Please show your actual code.

You may have to call GetParent() to get the true HWND for the dialog.


Gambit


Rodolfo Frino

unread,
Oct 30, 2003, 6:23:38 PM10/30/03
to
If you don't mind to have a short display in the middle (ugly) followed with
the dialog
in the position that you want, you can do this:
...
TOpenDialog* OpenDialog1;
//--------------------------------------------------------------------------
-
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
//CREATE OPENDIALOG
OpenDialog1 = new TOpenDialog(this);
OpenDialog1->OnSelectionChange = OpenDialog1SelectionChange;
}
//--------------------------------------------------------------------------
-

void __fastcall TForm1::BitBtn1Click(TObject *Sender)
{

OpenDialog1->FileName = "doc.c";

if (OpenDialog1->Execute())
{
// Place your code here
}
}

void __fastcall TForm1::OpenDialog1SelectionChange(TObject *Sender)
{
MoveWindow(
FindWindow(NULL, "Open"), // handle of window
0, // horizontal position
0, // vertical position
800, // width
300, // height
true // rep
);
}


"God not only plays dice with the universe, and sometimes throws them where
they cannot be seen, but also his dice are sometimes loaded" Rodolfo, 2003

"Robert Schimpfle" <schi...@uni-trier.de> wrote in message

news:3FA01311...@uni-trier.de...

Remy Lebeau (TeamB)

unread,
Oct 30, 2003, 6:43:45 PM10/30/03
to

"Rodolfo Frino" <rodolfowrvx...@yahoo.com.jki> wrote in message
news:3fa1...@newsgroups.borland.com...

> FindWindow(NULL, "Open"), // handle of window

That will not work if the TOpenDialog has its Title property set.


Gambit


Rodolfo Frino

unread,
Oct 30, 2003, 8:08:42 PM10/30/03
to
Then define Title as

char DialogTitle[] = "DefineSomeTitleHere";

FindWindow(NULL, DialogTitle ), // handle of window

"Human language is an extraordinary invention, despite of being so old it is
highly undefined" Rodolfo, 2003

"Remy Lebeau (TeamB)" <gambit47...@no.spam.yahoo.com> wrote in message
news:3fa1a188$1...@newsgroups.borland.com...

Remy Lebeau (TeamB)

unread,
Oct 30, 2003, 10:24:54 PM10/30/03
to

"Rodolfo Frino" <rodolfowrvx...@yahoo.com.jki> wrote in message
news:3fa1b607$1...@newsgroups.borland.com...

> FindWindow(NULL, DialogTitle ), // handle of window

Better to just use the actual Title:

if( !OpenDialog1->Title.IsEmpty() )
FindWindow(NULL, OpenDialog1->Title.c_str() )
else
FindWindow(NULL, "Open" )

Now, with that said, using the OnShow event is too soon to move the dialog,
and using the OnSelectionChanged event is too late to prevent the dialog
from noticably flickering from one position to another. The following code
works for me in delaying the moving while also hiding the flickering:

#define APPWM_MOVE_OPENDIALOG (WM_APP + 100)

void __fastcall TForm1::Button1Click(TObject *Sender)
{
OpenDialog1->Execute();
}

void __fastcall TForm1::OpenDialog1Show(TObject *Sender)
{
SendMessage(GetDesktopWindow(), WM_SETREDRAW, FALSE, 0);
PostMessage(Handle, APPWM_MOVE_OPENDIALOG, 0, 0);
}

void __fastcall TForm1::WndProc(TMessage &Message)
{
if( Message.Msg == APPWM_MOVE_OPENDIALOG )
{
SetWindowPos(GetParent(OpenDialog1->Handle), NULL,
Message.WParam, Message.LParam, 0, 0, SWP_NOSIZE|SWP_NOZORDER);

SendMessage(GetDesktopWindow(), WM_SETREDRAW, TRUE, 0);
InvalidateRect(NULL, NULL, TRUE);

Message.Result = TRUE;
}
else
TForm::WndProc(Message);
}


Gambit


Rodolfo Frino

unread,
Oct 31, 2003, 12:33:13 AM10/31/03
to
There is an easier way if you clear the options ;)

TOpenDialog* OpenDialog1;
String DlgTitle;
HWND H;

//--------------------------------------------------------------------------
-
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{

//CREATE OPENDIALOG --------------------------------------------
OpenDialog1 = new TOpenDialog(this);
OpenDialog1->Title = "This is the Title";
DlgTitle = OpenDialog1->Title;
OpenDialog1->OnShow = OpenDialog1Show;
OpenDialog1->OnSelectionChange = OpenDialog1SelectionChange;
OpenDialog1->Options.Clear();
}
//--------------------------------------------------------------------------
-

void __fastcall TForm1::BitBtn1Click(TObject *Sender)
{
OpenDialog1->FileName = "doc.c";

if (OpenDialog1->Execute())
{
// Place your code here
}
}

//--------------------------------------------------------------------------
-

void __fastcall TForm1::OpenDialog1Show(TObject *Sender)
{

H = FindWindow(NULL, DlgTitle.c_str());
MoveWindow(H, 0, 0, 0, 0, false);
}
//--------------------------------------------------------------------------
-

void __fastcall TForm1::OpenDialog1SelectionChange(TObject *Sender)
{
MoveWindow(H, 0, 0, 800, 300, true);
}
//--------------------------------------------------------------------------
-

"Programming is the art of picking a needle out of a hayheap." Rodolfo,
2003


Remy Lebeau (TeamB)

unread,
Oct 31, 2003, 12:46:38 AM10/31/03
to

"Rodolfo Frino" <rodolfowrvx...@yahoo.com.jki> wrote in message
news:3fa1...@newsgroups.borland.com...

> There is an easier way if you clear the options ;)

What do the Options have to do with anything? The option settings that are
enabled by default are ofHideReadOnly and ofEnableSizing, neither of which
effect the dialog's ability to be moved.

> OpenDialog1->Options.Clear();

You cannot clear the Options like that. You are modifying a temporary
value, not the original property value. Just like with other Set
operations, you need to use the '=' assignment operation instead, ie:

OpenDialog1->Options = TOpenOptions();

> void __fastcall TForm1::OpenDialog1Show(TObject *Sender)
> {
> H = FindWindow(NULL, DlgTitle.c_str());
> MoveWindow(H, 0, 0, 0, 0, false);
> }

I have already determined that you cannot move the dialog from the OnShow
event. That is why my earlier example had to delay the movement. OnShow is
triggered during the handling of the WM_INITDIALOG message, however
TOpenDialog internally repositions the dialog during the handling of the
CDN_INITDONE notification later on, thus cancelling out any movements you do
in the OnShow event.

> void __fastcall TForm1::OpenDialog1SelectionChange(TObject *Sender)
> {
> MoveWindow(H, 0, 0, 800, 300, true);
> }

I guess you missed the point of my earlier example - the OnSelectionChange
event is triggered well after the dialog has become visible, so the user
sees the dialog appear in the middle of the screen and then move to the
coordinates seconds later. Which even you said earlier was an ugly effect
:-p Thus my use of disabling the dekstop's ability to update the screen
while the dialog is being moved, so the user won't see it happen.


Gambit


Rodolfo Frino

unread,
Oct 31, 2003, 1:07:51 AM10/31/03
to
I used it because Borland uses too. Haver a look at this example in the
Builder's help:
OpenPictureDialog, TApplication::Icon Example

However, I replaced that line with the one that you posted
OpenDialog1->Options = TOpenOptions(); // Statement 1

The first dialog is not shown because of two things

1- In the OpenDialog1Show event handler the dimensions of the first dialog
are zero

MoveWindow(H, 0, 0, 0, 0, false);

2- If we don't use the Statement 1, we will see the title bar of the first
dialog (with no dialog's client area
because the dimensions are 0). So we clear the options to remove the menu
bar. However, I
did not investigate any further as to see why.

As a result I can only see one dialog box, the one corresponding to the call
in
the OpenDialog1SelectionChange event handler.

MoveWindow(H, 0, 0, 800, 300, true);

The only thing that I noticed is a small flickering of the Parent form (The
one that contaoins the BitBtn)
immediatly before the creation of the Dialog which I think is negligible
(althogh you might think it isn't)

Please, run the program and you will see that there is only one dialog
visible.

TForm1 *Form1;


TOpenDialog* OpenDialog1;
String DlgTitle;
HWND H;

//--------------------------------------------------------------------------
-
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
//CREATE OPENDIALOG --------------------------------------------
OpenDialog1 = new TOpenDialog(this);
OpenDialog1->Title = "This is the Title";
DlgTitle = OpenDialog1->Title;
OpenDialog1->OnShow = OpenDialog1Show;
OpenDialog1->OnSelectionChange = OpenDialog1SelectionChange;

OpenDialog1->Options = TOpenOptions(); //<<================== Replaced

}
//--------------------------------------------------------------------------
-

void __fastcall TForm1::BitBtn1Click(TObject *Sender)
{
OpenDialog1->FileName = "doc.c";

if (OpenDialog1->Execute())
{
// Place your code here
}
}
//--------------------------------------------------------------------------
-

void __fastcall TForm1::OpenDialog1Show(TObject *Sender)
{
H = FindWindow(NULL, DlgTitle.c_str());
MoveWindow(H, 0, 0, 0, 0, false); //<<==== Notice NILL dimensions
}
//--------------------------------------------------------------------------
-

void __fastcall TForm1::OpenDialog1SelectionChange(TObject *Sender)
{

MoveWindow(H, 0, 0, 800, 300, true); //<<==== Wanted dimensions
}
//--------------------------------------------------------------------------
-

void __fastcall TForm1::BitBtn2Click(TObject *Sender)
{
//
OpenDialog2->FileName = "doc.c";

if (OpenDialog2->Execute())


{
// Place your code here
}
}


Rodolfo


Remy Lebeau (TeamB)

unread,
Oct 31, 2003, 2:51:27 AM10/31/03
to

"Rodolfo Frino" <rodolfowrvx...@yahoo.com.jki> wrote in message
news:3fa1fc23$1...@newsgroups.borland.com...

> I used it because Borland uses too.

And how many times have Borland's examples and documentation been proven
wrong? Too many times.

> 1- In the OpenDialog1Show event handler the dimensions
> of the first dialog are zero

I did not notice earlier that you were shrinking the dialog to 0 dimensions.

However, you should not just pick an arbitrary size for the new dimensions
when re-displaying the dialog later. I ran your example, and upon
re-showing the dialog, it took up half my screen, and half of the dialog was
empty. Very ugly.

Also, there's still no need to use FindWindow(), calling GetParent() on the
OpenDialog's Handle returns the same HWND that FindWindow() would have
found, and is a lot less error-prone to find the wrong window by accident
:-)

> Please, run the program and you will see that there is only one dialog
> visible.

My screen still flickers when I run your code. Whatever window is currently
on top (including the desktop itself in case everything is minimized) when
the dialog is displayed, it is repainted in full upon displaying the dialog.

I'm still sticking with my earlier example, for a few extra lines of code it
produced a cleaner effect for the user.

> OpenDialog1 = new TOpenDialog(this);

I am wondering, why do you keep showing examples that dynamically create
everything at runtime instead of using the form designer at designtime?


Gambit


Rodolfo Frino

unread,
Oct 31, 2003, 9:44:43 AM10/31/03
to
> My screen still flickers when I run your code. Whatever window is
currently
> on top (including the desktop itself in case everything is minimized) when
> the dialog is displayed, it is repainted in full upon displaying the
dialog.
> I'm still sticking with my earlier example, for a few extra lines of code
it
> produced a cleaner effect for the user.

I know that there is a little bit a flickering I mentioned it in my previous
post.
I didn't say that the example is perfect :-)

> > OpenDialog1 = new TOpenDialog(this);
>
> I am wondering, why do you keep showing examples that dynamically create
> everything at runtime instead of using the form designer at designtime?

There are several reasons. One of them is that, in general, the user can see
exactly all the components
on the form and their properties without posting extra files. Never develop
any form at design time.
Do everything at runtime is less error-prone. Imagine that you develop a
complex mainform at designtime.
Then, one day you open the project and by mistake you change the value of
some properties in your Object
Inspector without realizing. Then you recompile your project and now your
program has got different values
for one or more properties and your program runs but does not behave the way
you intended to.
If you design each and every form at runtime these type of error will never
take effect, since your
program will set the properties at runtime, overriding any values entered in
the Object Inspector by accident.

"Computers are machines that make us think that they could think one
unthinkable day"
Rodolfo, 2003


Timothy H. Buchman

unread,
Oct 31, 2003, 12:31:21 PM10/31/03
to
"Robert Schimpfle" <schi...@uni-trier.de> wrote in message
news:3FA17CBA...@uni-trier.de...

> I used MoveWindow, but it did not work...
>
> Anybody who has already done it?
> I would appreciate a few lines of C++ code for this problem?

This is more or less an established technology. In fact, the VCL has
to do the centering itself in the earlier versions of Windows and BCB.

Here's a page that simply answers your question:
http://thunder.prohosting.com/~cbdn/cd002.htm

If you derive your own descendant, you can override DoShow. Here's a
more complicated example of that:
http://home.att.net/~secondcut/opdlgvcl.htm

--
Timothy H. Buchman
========================================
City Center Theater, New York NY
mail address tbuchmanPLEASE(at sign)REMOVEcitycenterD O Torg
Search .borland message archive on http://www.mers.com/searchsite.html

Rodolfo Frino

unread,
Nov 1, 2003, 10:06:11 AM11/1/03
to
> Here's a page that simply answers your question:
> http://thunder.prohosting.com/~cbdn/cd002.htm

That won't work. Can I suggest the following modification to the code
shown on the above link:

#include <vcl.h>
#pragma hdrstop

#include "MoveWindow.h"
//--------------------------------------------------------------------------
-
#pragma package(smart_init)
#pragma resource "*.dfm"


TForm1 *Form1;
TOpenDialog* OpenDialog1;
String DlgTitle;

//--------------------------------------------------------------------------


-
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
//CREATE OPENDIALOG --------------------------------------------
OpenDialog1 = new TOpenDialog(this);

OpenDialog1->Title = "Title";


DlgTitle = OpenDialog1->Title;
OpenDialog1->OnShow = OpenDialog1Show;
}

//--------------------------------------------------------------------------
-

void __fastcall TForm1::BitBtn1Click(TObject *Sender)
{
OpenDialog1->FileName = "doc.c";

if (OpenDialog1->Execute())
{
// Place your code here
}
}
//--------------------------------------------------------------------------
-

void __fastcall TForm1::OpenDialog1Show(TObject *Sender)
{

TRect rect;
HWND H = GetParent(dynamic_cast<TOpenDialog*>(Sender)->Handle);

GetWindowRect(H, &rect);

MoveWindow(H,
0, // put your coordinate here as required
0, // put your coordinate here as required
rect.right - rect.left,
rect.bottom - rect.top,
true);

Abort();
}

Ah, by the way a short message for Remy: here there is no flickering
and also this is the simplest solution :-)

Rodolfo


Rodolfo Frino

unread,
Nov 1, 2003, 10:07:08 AM11/1/03
to
Please, see my answer to Timothy

Rodolfo


0 new messages