Link to home
Start Free TrialLog in
Avatar of andru
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

Avatar of ginsonic
ginsonic
Flag of Romania image

Not sure:

MakeFullyVisible(Form1.Monitor);
Another ideea. The second monitor left point is:

Form2.Left:=Screen.Width+WhereIWishToBeOnForm2.

Set the childs left to Screen.Width+....
Avatar of sftweng
sftweng

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.
Avatar of andru

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
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
Have you test :
  Form1.Left:=Screen.Width+20; // 20 left on second monitor.
Avatar of andru

ASKER

yesh but how will i gnow the 2nd monitor is to the right of the primary display?

tia
Avatar of andru

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
Avatar of andru

ASKER

Well, I solved the problem myself, so would you delete this question?

TIA
It would be nice if you told us how you solved it.
Avatar of andru

ASKER

I'll explain how I did it and will post some example code next week.

Andrew
Thanks.
Avatar of andru

ASKER

OK, here is some code...

<snip>

type
  p_dimensions_record=^dimensions_record;
  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_record);
var
  i,lw,lh:integer;
  done,vdu_changed:boolean;

  procedure switch_monitor;
  begin
    with dimensions^,screen.monitors[vdu_index] do
      begin
        if screen_left<0 then
          begin
            if form_left>=0 then
              form_left:=form_left+screen_left+left
            else
              form_left:=abs(form_left-screen_left)+left;
          end
        else
          form_left:=form_left-screen_left+left;
        if screen_top<0 then
          begin
            if form_top>=0 then
              form_top:=form_top+screen_top+top
            else
              form_top:=abs(form_top-screen_top)+top;
          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<monitorcount) 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:=current_height;
                  current_width:=width;
                  current_height:=height;
                  form_left:=trunc(form_left/last_screen_width*current_width);
                  if form_left+form.width>left+current_width then
                    form_left:=left+current_width-form.Width;
                  if form_left<left then
                    form_left:=left;
                  form_top:=trunc(form_top/last_screen_height*current_height);
                  if form_top+form.height>top+current_height then
                    form_top:=top+current_height-form.height;
                  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_record;
  section:string;
  ini_file:tinifile);
begin
  with ini_file,dimensions^ do
    begin
      vdu_index:=readinteger(section,'monitor',-1);
      old_vdu_index:=readinteger(section,'another_monitor',-1);
      form_top:=readinteger(section,'top',top);
      form_left:=readinteger(section,'left',left);
      screen_left:=readinteger(section,'screen_left',0);
      screen_top:=readinteger(section,'screen_top',0);
      last_screen_width:=readinteger(section,'screen_width',-1);
      current_width:=last_screen_width;
      last_screen_height:=readinteger(section,'screen_height',-1);
      current_height:=last_screen_height;
      find_vdu(form,dimensions);
    end;
end;

procedure tscope.write_dimensions(
  dimensions:p_dimensions_record;
  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,'another_monitor',old_vdu_index);
      writeinteger(section,'monitor',vdu_index);
      writeinteger(section,'left',left);
      writeinteger(section,'top',top);
      writeinteger(section,'screen_width',current_width);
      writeinteger(section,'screen_height',current_height);
      writeinteger(section,'screen_left',monitors[vdu_index].left);
      writeinteger(section,'screen_top',monitors[vdu_index].top);
    end;
end;

</snip>

Andrew
ASKER CERTIFIED SOLUTION
Avatar of PAQ_Man
PAQ_Man
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial