andru
asked on
multiple monitors
hi ppl
i have a easidock dockin station that allows me to add a 2nd monitor to my laptop.
in the screen object there is an array of the monitors on the system.
i can't specifically put a form on a particular monitor, but i would at least like to allow all child forms to appear on the same monitor as the main form.
i have set
defaultmonitor:=dmMainForm ;
at the start of each onshow event for each child form.
i have to show/hide a form 3 times for the child form to remain on the same monitor as the main form.
is there a fix for this problem? or at least a workaround.
tia
andrew sprott
i have a easidock dockin station that allows me to add a 2nd monitor to my laptop.
in the screen object there is an array of the monitors on the system.
i can't specifically put a form on a particular monitor, but i would at least like to allow all child forms to appear on the same monitor as the main form.
i have set
defaultmonitor:=dmMainForm
at the start of each onshow event for each child form.
i have to show/hide a form 3 times for the child form to remain on the same monitor as the main form.
is there a fix for this problem? or at least a workaround.
tia
andrew sprott
Another ideea. The second monitor left point is:
Form2.Left:=Screen.Width+W hereIWishT oBeOnForm2 .
Set the childs left to Screen.Width+....
Form2.Left:=Screen.Width+W
Set the childs left to Screen.Width+....
Have you looked at TCustomForm.Position? You could try poMainFormCenter.
Represents the size and placement of the form.
type TPosition = (poDesigned, poDefault, poDefaultPosOnly, poDefaultSizeOnly, poScreenCenter, poDesktopCenter, poMainFormCenter, poOwnerFormCenter);
property Position: TPosition;
Description
Use Position to get or set the size and placement of the form. Position can have one of the following TPosition values:
Value Meaning
poDesigned The form appears positioned on the screen and with the same height and width as it had at design time.
poDefault The form appears in a position on the screen and with a height and width determined by the operating system. Each time you run the application, the form moves slightly down and to the right. The right side of the form is always near the far right side of the screen, and the bottom of the form is always near the bottom of the screen, regardless of the screen's resolution.
poDefaultPosOnly The form displays with the size you created it at design time, but the operating system chooses its position on the screen. Each time you run the application, the form moves slightly down and to the right. When the form can no longer move down and to the right and keep the same size while remaining entirely visible on the screen, the form displays at the top-left corner of the screen.
poDefaultSizeOnly The form appears in the position you left it at design time, but the operating system chooses its size. The right side of the form is always near the far right side of the screen, and the bottom of the form is always near the bottom of the screen, regardless of the screen's resolution.
poScreenCenter The form remains the size you left it at design time, but is positioned in the center of the screen. In multi-monitor applications, the form may be moved from this center position so that it falls entirely on one monitor, as specified by the DefaultMonitor property.
poDesktopCenter The form remains the size you left it at design time, but is positioned in the center of the screen. No adjustments are made for multi-monitor applications.
poMainFormCenter The form remains the size you left it at design time, but is positioned in the center of the application’s main form. No adjustments are made for multi-monitor applications. This position should only be used with secondary forms. If set for a main form, it acts like
poScreenCenter.
poOwnerFormCenter The form remains the size you left it at design time, but is positioned in the center of the form specified by the Owner property. If the Owner property does not specify a form, this position acts like poMainFormCenter.
Represents the size and placement of the form.
type TPosition = (poDesigned, poDefault, poDefaultPosOnly, poDefaultSizeOnly, poScreenCenter, poDesktopCenter, poMainFormCenter, poOwnerFormCenter);
property Position: TPosition;
Description
Use Position to get or set the size and placement of the form. Position can have one of the following TPosition values:
Value Meaning
poDesigned The form appears positioned on the screen and with the same height and width as it had at design time.
poDefault The form appears in a position on the screen and with a height and width determined by the operating system. Each time you run the application, the form moves slightly down and to the right. The right side of the form is always near the far right side of the screen, and the bottom of the form is always near the bottom of the screen, regardless of the screen's resolution.
poDefaultPosOnly The form displays with the size you created it at design time, but the operating system chooses its position on the screen. Each time you run the application, the form moves slightly down and to the right. When the form can no longer move down and to the right and keep the same size while remaining entirely visible on the screen, the form displays at the top-left corner of the screen.
poDefaultSizeOnly The form appears in the position you left it at design time, but the operating system chooses its size. The right side of the form is always near the far right side of the screen, and the bottom of the form is always near the bottom of the screen, regardless of the screen's resolution.
poScreenCenter The form remains the size you left it at design time, but is positioned in the center of the screen. In multi-monitor applications, the form may be moved from this center position so that it falls entirely on one monitor, as specified by the DefaultMonitor property.
poDesktopCenter The form remains the size you left it at design time, but is positioned in the center of the screen. No adjustments are made for multi-monitor applications.
poMainFormCenter The form remains the size you left it at design time, but is positioned in the center of the application’s main form. No adjustments are made for multi-monitor applications. This position should only be used with secondary forms. If set for a main form, it acts like
poScreenCenter.
poOwnerFormCenter The form remains the size you left it at design time, but is positioned in the center of the form specified by the Owner property. If the Owner property does not specify a form, this position acts like poMainFormCenter.
ASKER
yesh, yesh.
i dont want to place each form in the center, i already place em where they were placed before.
the form appears on the 2nd monitor fine, but it then relocates itself on the primary display.
and i have to move it to the 2nd monitor 3 times before it'll stick on it.
tia
i dont want to place each form in the center, i already place em where they were placed before.
the form appears on the 2nd monitor fine, but it then relocates itself on the primary display.
and i have to move it to the 2nd monitor 3 times before it'll stick on it.
tia
My only tip would be to use the ClientToScreen function to obtain the location of the main form and then to position the child forms accordingly.
However, since you say that you have to move your forms several times before they stick, it sounds like you have some other code (or setting) causing them to move (btw. Position should be set to poDesigned - otherwise the form may be moved by the VCL or Windows).
Also check your driver. Mine expands the desktop so that Windows sees all the monitors as one large desktop. Check this with the Screen variables DesktopWidth/Height properties (they should return the size of the entire desktop across monitors). You can also take a look at the GetSystemMetrics API call.
Good luck,
runebj
However, since you say that you have to move your forms several times before they stick, it sounds like you have some other code (or setting) causing them to move (btw. Position should be set to poDesigned - otherwise the form may be moved by the VCL or Windows).
Also check your driver. Mine expands the desktop so that Windows sees all the monitors as one large desktop. Check this with the Screen variables DesktopWidth/Height properties (they should return the size of the entire desktop across monitors). You can also take a look at the GetSystemMetrics API call.
Good luck,
runebj
Have you test :
Form1.Left:=Screen.Width+2 0; // 20 left on second monitor.
Form1.Left:=Screen.Width+2
ASKER
yesh but how will i gnow the 2nd monitor is to the right of the primary display?
tia
tia
:(
ASKER
k, i've tried your suggestions. even when the main panel is visible on the secondary display, the control panels still switch to the primary display when they are made visible.
tia
tia
ASKER
Well, I solved the problem myself, so would you delete this question?
TIA
TIA
It would be nice if you told us how you solved it.
ASKER
I'll explain how I did it and will post some example code next week.
Andrew
Andrew
Thanks.
ASKER
OK, here is some code...
<snip>
type
p_dimensions_record=^dimen sions_reco rd;
dimensions_record=record
vdu_index,
old_vdu_index,
screen_left,
screen_top,
last_screen_height,
last_screen_width,
current_height,
current_width,
form_top,
form_left:integer;
end;
procedure Tscope.find_vdu(
form:tform;
dimensions:p_dimensions_re cord);
var
i,lw,lh:integer;
done,vdu_changed:boolean;
procedure switch_monitor;
begin
with dimensions^,screen.monitor s[vdu_inde x] do
begin
if screen_left<0 then
begin
if form_left>=0 then
form_left:=form_left+scree n_left+lef t
else
form_left:=abs(form_left-s creen_left )+left;
end
else
form_left:=form_left-scree n_left+lef t;
if screen_top<0 then
begin
if form_top>=0 then
form_top:=form_top+screen_ top+top
else
form_top:=abs(form_top-scr een_top)+t op;
end
else
form_top:=form_top-screen_ top+top;
screen_left:=left;
screen_top:=top;
end;
end;
begin
with screen,dimensions^ do
begin
vdu_changed:=false;
if vdu_index>=0 then
begin
i:=0;
if (old_vdu_index>=0) and (old_vdu_index<monitorcoun t) then
begin
if old_vdu_index<>vdu_index then
begin
vdu_index:=old_vdu_index;
switch_monitor;
end;
old_vdu_index:=-1;
end;
done:=false;
while not done do
if i<monitorcount then
with monitors[i] do
begin
if (form_left<left) or
(form_left>left+width) or
(form_top<top) or
(form_top>top+height) then
inc(i)
else
begin
if i<>vdu_index then
vdu_index:=i;
done:=true;
end;
end
else
begin
done:=true;
vdu_changed:=true;
vdu_index:=-1;
end;
end;
if vdu_index<0 then
begin
i:=0;
while (i<monitorcount) and not monitors[i].Primary do
inc(i);
if i<monitorcount then
vdu_index:=i
else
vdu_index:=0;
vdu_changed:=true;
end;
with monitors[vdu_index] do
begin
if vdu_changed then
begin
lw:=current_width;
lh:=current_height;
switch_monitor;
if (lw<>width) or (lh<>height) then
begin
last_screen_width:=current _width;
last_screen_height:=curren t_height;
current_width:=width;
current_height:=height;
form_left:=trunc(form_left /last_scre en_width*c urrent_wid th);
if form_left+form.width>left+ current_wi dth then
form_left:=left+current_wi dth-form.W idth;
if form_left<left then
form_left:=left;
form_top:=trunc(form_top/l ast_screen _height*cu rrent_heig ht);
if form_top+form.height>top+c urrent_hei ght then
form_top:=top+current_heig ht-form.he ight;
if form_top<top then
form_top:=top;
end;
end
else
begin
current_width:=width;
current_height:=height;
end;
end;
end;
end;
procedure tscope.get_dimensions(
form:tform;
dimensions:p_dimensions_re cord;
section:string;
ini_file:tinifile);
begin
with ini_file,dimensions^ do
begin
vdu_index:=readinteger(sec tion,'moni tor',-1);
old_vdu_index:=readinteger (section,' another_mo nitor',-1) ;
form_top:=readinteger(sect ion,'top', top);
form_left:=readinteger(sec tion,'left ',left);
screen_left:=readinteger(s ection,'sc reen_left' ,0);
screen_top:=readinteger(se ction,'scr een_top',0 );
last_screen_width:=readint eger(secti on,'screen _width',-1 );
current_width:=last_screen _width;
last_screen_height:=readin teger(sect ion,'scree n_height', -1);
current_height:=last_scree n_height;
find_vdu(form,dimensions);
end;
end;
procedure tscope.write_dimensions(
dimensions:p_dimensions_re cord;
left,
top:integer;
section:string;
ini_file:tinifile);
var
i:integer;
begin
with ini_file,screen,dimensions ^ do
begin
for i:=0 to monitorcount-1 do
if monitors[i].primary and (vdu_index<>i) then
old_vdu_index:=vdu_index;
writeinteger(section,'anot her_monito r',old_vdu _index);
writeinteger(section,'moni tor',vdu_i ndex);
writeinteger(section,'left ',left);
writeinteger(section,'top' ,top);
writeinteger(section,'scre en_width', current_wi dth);
writeinteger(section,'scre en_height' ,current_h eight);
writeinteger(section,'scre en_left',m onitors[vd u_index].l eft);
writeinteger(section,'scre en_top',mo nitors[vdu _index].to p);
end;
end;
</snip>
Andrew
<snip>
type
p_dimensions_record=^dimen
dimensions_record=record
vdu_index,
old_vdu_index,
screen_left,
screen_top,
last_screen_height,
last_screen_width,
current_height,
current_width,
form_top,
form_left:integer;
end;
procedure Tscope.find_vdu(
form:tform;
dimensions:p_dimensions_re
var
i,lw,lh:integer;
done,vdu_changed:boolean;
procedure switch_monitor;
begin
with dimensions^,screen.monitor
begin
if screen_left<0 then
begin
if form_left>=0 then
form_left:=form_left+scree
else
form_left:=abs(form_left-s
end
else
form_left:=form_left-scree
if screen_top<0 then
begin
if form_top>=0 then
form_top:=form_top+screen_
else
form_top:=abs(form_top-scr
end
else
form_top:=form_top-screen_
screen_left:=left;
screen_top:=top;
end;
end;
begin
with screen,dimensions^ do
begin
vdu_changed:=false;
if vdu_index>=0 then
begin
i:=0;
if (old_vdu_index>=0) and (old_vdu_index<monitorcoun
begin
if old_vdu_index<>vdu_index then
begin
vdu_index:=old_vdu_index;
switch_monitor;
end;
old_vdu_index:=-1;
end;
done:=false;
while not done do
if i<monitorcount then
with monitors[i] do
begin
if (form_left<left) or
(form_left>left+width) or
(form_top<top) or
(form_top>top+height) then
inc(i)
else
begin
if i<>vdu_index then
vdu_index:=i;
done:=true;
end;
end
else
begin
done:=true;
vdu_changed:=true;
vdu_index:=-1;
end;
end;
if vdu_index<0 then
begin
i:=0;
while (i<monitorcount) and not monitors[i].Primary do
inc(i);
if i<monitorcount then
vdu_index:=i
else
vdu_index:=0;
vdu_changed:=true;
end;
with monitors[vdu_index] do
begin
if vdu_changed then
begin
lw:=current_width;
lh:=current_height;
switch_monitor;
if (lw<>width) or (lh<>height) then
begin
last_screen_width:=current
last_screen_height:=curren
current_width:=width;
current_height:=height;
form_left:=trunc(form_left
if form_left+form.width>left+
form_left:=left+current_wi
if form_left<left then
form_left:=left;
form_top:=trunc(form_top/l
if form_top+form.height>top+c
form_top:=top+current_heig
if form_top<top then
form_top:=top;
end;
end
else
begin
current_width:=width;
current_height:=height;
end;
end;
end;
end;
procedure tscope.get_dimensions(
form:tform;
dimensions:p_dimensions_re
section:string;
ini_file:tinifile);
begin
with ini_file,dimensions^ do
begin
vdu_index:=readinteger(sec
old_vdu_index:=readinteger
form_top:=readinteger(sect
form_left:=readinteger(sec
screen_left:=readinteger(s
screen_top:=readinteger(se
last_screen_width:=readint
current_width:=last_screen
last_screen_height:=readin
current_height:=last_scree
find_vdu(form,dimensions);
end;
end;
procedure tscope.write_dimensions(
dimensions:p_dimensions_re
left,
top:integer;
section:string;
ini_file:tinifile);
var
i:integer;
begin
with ini_file,screen,dimensions
begin
for i:=0 to monitorcount-1 do
if monitors[i].primary and (vdu_index<>i) then
old_vdu_index:=vdu_index;
writeinteger(section,'anot
writeinteger(section,'moni
writeinteger(section,'left
writeinteger(section,'top'
writeinteger(section,'scre
writeinteger(section,'scre
writeinteger(section,'scre
writeinteger(section,'scre
end;
end;
</snip>
Andrew
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
MakeFullyVisible(Form1.Mon