Solved

Dealing with screen resolutions

Posted on 2002-06-29
29
436 Views
Last Modified: 2010-04-04
Hi
The age old question, what is the best way to handle different screen resolutions, I've read many articles on this subject but I'm hoping some expert out there has the answer I'm looking for.

I use the following which works:

procedure TfrmMainForm.FormCreate(Sender: TObject);
const
     SCREEN_WIDTH_DEV = 800; {screen designed at 800X600}
     PIXEL_PER_INCH_DEV = 96;

begin
        if Screen.PixelsPerInch<>PIXEL_PER_INCH_DEV then
        frmMainForm.ScaleBy
PIXEL_PER_INCH_DEV,Screen.PixelsPerInch);
        if (Screen.Width<>SCREEN_WIDTH_DEV) then
        frmMainForm.ScaleBy(screen.width,SCREEN_WIDTH_DEV);
end;

This does work but I dislike the fact that all the fonts and text components size up giving it that "just not right" look, I'm sure I'm missing something simple, I need help.

I would like to achieve the 1024 X 768 look overall when the desktop is at that setting, so do I design my forms at 1024 X 768 and hope that it scales OK when the desktop is at 800 X 600 or do I design at  800 X 600 or just give up and become a train driver!

Excuse my ravings,please help, thanks in advance
0
Comment
Question by:palin2000
  • 8
  • 7
  • 5
  • +5
29 Comments
 
LVL 3

Expert Comment

by:SteveWaite
ID: 7119286
just some input
I do similar but use a scale factor to scale everything that doesnt automatically scale

  SF := Screen.PixelsPerInch / CompilePixelsPerInch;

but this is only for if the user changes to large fonts etc

i dont zoom my apps just because the user selects larger screen res
Regards
Steve
ps train driving sounds fun!
0
 

Author Comment

by:palin2000
ID: 7119326
Thanks Steve

I'm not really looking at the small/large fonts issue although now you have given me something to consider.

All the books say design at 800 X 600 which makes sense and if the target machine runs at 1024 X 768 the application forms are re-positioned around the screen alright, but for this to happen the labels and text input boxes look too big, I'm looking for a small routine that would re-position the components but not re-size them.

Any ideas?

And train drivers get paid a lot of money over here!
0
 
LVL 3

Expert Comment

by:Slavak
ID: 7119641
listening...
0
 
LVL 3

Expert Comment

by:Slavak
ID: 7119647
There is constants for starndard resources:


RT_ACCELERATOR     Accelerator table
RT_ANICURSOR     Animated cursor
RT_ANIICON     Animated icon
RT_BITMAP     Bitmap resource
RT_CURSOR     Hardware-dependent cursor resource
RT_DIALOG     Dialog box
RT_FONT             Font resource
RT_FONTDIR     Font directory resource
RT_GROUP_CURSOR     Hardware-independent cursor resource
RT_GROUP_ICON     Hardware-independent icon resource
RT_ICON             Hardware-dependent icon resource
RT_MENU             Menu resource
RT_MESSAGETABLE     Message-table entry
RT_RCDATA     Application-defined resource (raw data)
RT_STRING     String-table entry
RT_VERSION     Version resource


0
 
LVL 3

Expert Comment

by:Slavak
ID: 7119648
sorry, mistake :)
0
 
LVL 45

Accepted Solution

by:
aikimark earned 350 total points
ID: 7119782
When your form is loaded, adjust the controls' .TOP property relative to the current screen height and adjust the controls' .LEFT property relative to the current screen width.

control.TOP := control.TOP * (Screen.Height / 600)
control.LEFT := control.LEFT * (Screen.Width / 800)

As the screen size increases, so does the multiplication factor.  Nothing moves if the screen size is 600x800.
0
 

Author Comment

by:palin2000
ID: 7119949
Thanks for replys

Slavak, no problem

aikimark, I'm not sure what you mean, could you expand on your suggestion, I did have a look at your code but there seems to be a conflict between Incompatible types: 'Integer' and 'Extended'.

Would this re-position all the components on the screen without actually re-sizing them when the user changes their desktop settings from 800 X 600 to 1024 X 768?

Thanks in advance
0
 
LVL 7

Expert Comment

by:Cynna
ID: 7120309
palin2000,

aikimark gave you the correct procedure for what you want.

Assuming you want to reposition all visible components on Form1:


1. Copy/Paste:
--------------------

procedure TForm1.RepositionControls(DefaultWidth, DefaultHight: Integer);
// Arguments represent design-time screen dimensions
var i: Integer;
begin
 for i := ControlCount - 1 downto 0 do
     with Controls[i] do begin
          Top  := Round(Top*Screen.Height / DefaultHight);
          Left := Round(Left*Screen.Width / DefaultWidth);
     end;
end;


2. Place this in OnCreate event:
----------------------------------------------------------
procedure TForm1.FormCreate(Sender: TObject);
begin
  // Assuming you design at 800x600 resultion:
  RepositionControls(800, 600);
end;



Above code will keep actual distance between upper left corners of
all components the same. By actual I mean real physical distance
(you can change your display settings, and measure it by ruler,
if you want...).

You must copy above procedure for all forms in your project.

0
 
LVL 45

Expert Comment

by:aikimark
ID: 7120314
Did you remember to terminate the statements with semi-colons (;)?
0
 
LVL 7

Expert Comment

by:Cynna
ID: 7120390
aikimark,  your perception and insightfulness is impressive....
I'm truly sorry I dared helping palin2000 in 'Incompatible
types' problem.
And I'm truly, truly sorry I didn't mention you enough in my previous post.

So..

palin2000, if this does what you want please give your points to aikimark.



0
 
LVL 3

Expert Comment

by:VSF
ID: 7120674
BRAZIL 5 times WorldCup Champion!

Congratulations too to all Brazilian Experts and those that beleived we would be world's number one (one more time).

Victory Fernandes, a proud Brazilian!
www.victory.hpg.com.br
0
 
LVL 3

Expert Comment

by:SteveWaite
ID: 7120701
i just found this in some old cut and pasted stuff..

Auto Scaling routine...

From: tekhed@charm.net.spam (Randy)
This routine has made life very very easy. This routine will insure that your application will look scaled at ANY resolution. Notice the 640 reference. This is because I develop apps in 640x480. You can adjust the routine to work from what YOU develop in so you dont have to worry about the odd and big screen resolutions that your users may have. Place, in the OnCreate event of the form you want auto-scaled:

AdjustResolution(Self);


{ AdjustResolution ******************************************************* }
{ This procedure scales all the children on a given form to conform to the }
{ current screen resolution                                                }
{ ************************************************************************ }
procedure AdjustResolution(oForm:TForm);
var
iPercentage:integer;
begin
if Screen.Width > 640 then
  begin
    iPercentage:=Round(((Screen.Width-640)/640)*100)+100;
    oForm.ScaleBy(iPercentage,100);
  end;
end;

0
 
LVL 1

Expert Comment

by:thanes
ID: 7120859
Something I've seen, but don't have the code for yet (may get my hands on a common class for doing this soon) but what I've seen is the following:

1. Decide what real estate your application needs, i.e. 640, 800, 1024, or ?

2. When your application initializes determine if the video card and monitor support what you've decided in question 1.

3. If the card and monitor don't support #1's requirements then shutdown with appropriate message.  Otherwise, save what the current settings are and make appropriate API calls to set video to what you decided in #1.

4. Finish firing up your app.  Let users do their thing.

5. When users close your app, set video back to saved settings.

That is the approach I've seen some guys using lately.  I'm looking forward to trying it myself soon.  When I get the example I'll post it somewhere.  Or if you'd like send me your email address(es) and I will make an effort to forward you the code to do it.

Regards, Thane Schaffer
0
 
LVL 3

Expert Comment

by:VSF
ID: 7121481
AdjustResolution(Self);

Wont work with DBGrid fields that keep the same size!
With other components it word fine!

VSF
www.victory.hpg.com.br
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Author Comment

by:palin2000
ID: 7123220
Thanks once again for replys.

I've just came in and would like to have a good look at the various solutions, I'll get back ASAP.

VFS Well done to your team, this comes from a Scotsman, guess who we were cheering for when they played England!, only kidding England played well in their games.

Excuse my lack of understanding with regards to aikimark's first solution, but I am no expert and require help from you guys.

Speak to you soon, thanks again.

Palin
0
 
LVL 2

Expert Comment

by:mikepj
ID: 7123629
Here's another point of view.  I use panels quite a bit and let their Align property manage the way it looks.  As for the font sizes, I set Scaled=false.  Occasionally I have a component which needs special sizing and when that happens, I put a line in OnResize but that is only rarely needed.  I'm happy with the controls always being the same size regardless of the screen resolution.  That choice also avoids many "bad things".
0
 

Author Comment

by:palin2000
ID: 7125505
Yet again thank you all for your contributions.

Cynna and aikimark's solution seems to fit my requirements best, if you guys can sort this last requirement out I'll happly up the points to 500.

Your RepositionControls solution works great when dealing with components on the base form, I forgot that several of my forms contain a framework of panels for which I have various components in each.

For example pnlMenuPanel, pnlNotificationPanel, remembering I am not an expert like yourselves I had trouble getting this solution to work with the panel components.

If you can bear with this a bit longer and provide a solution, it would help me a lot and I feel would be of great value to other basic Delphi programmers.

With regards to the other solutions I will need to work at them for a bit longer to assess their use, but thanks for suggesting them.

Best regards
Palin
0
 

Author Comment

by:palin2000
ID: 7125509
Yet again thank you all for your contributions.

Cynna and aikimark's solution seems to fit my requirements best, if you guys can sort this last requirement out I'll happly up the points to 500.

Your RepositionControls solution works great when dealing with components on the base form, I forgot that several of my forms contain a framework of panels for which I have various components in each.

For example pnlMenuPanel, pnlNotificationPanel, remembering I am not an expert like yourselves I had trouble getting this solution to work with the panel components.

If you can bear with this a bit longer and provide a solution, it would help me a lot and I feel would be of great value to other basic Delphi programmers.

With regards to the other solutions I will need to work at them for a bit longer to assess their use, but thanks for suggesting them.

Best regards
Palin
0
 
LVL 45

Expert Comment

by:aikimark
ID: 7125725
My gut feeling on this problem would be to base the action (reposition or resize) on whether the control is a container control and the value of the align property.
Example:
Dim ctlX As Control
Dim sngH As Single
Dim sngW As Single

sngH = Screen.Height / 600      'height multiplier
sngW = Screen.Width / 800       'width multiplier

For Each ctlX In Me.Controls
    Select Case TypeName(ctlX)
        Case "Picturebox", "Panel"
            Select Case ctlX.Align
                Case vbAlignNone
                    ctlX.Move ctlX.Left * sngW, ctlX.Top * sngH, ctlX.Width * sngW, ctlX.Height * sngH
                Case vbAlignTop
                    ctlX.Move ctlX.Left, ctlX.Top, ctlX.Width, ctlX.Height * sngH
                Case vbAlignBottom
                    ctlX.Move ctlX.Left, ctlX.Top * -sngH, ctlX.Width, ctlX.Height * sngH
                Case vbAlignLeft
                    ctlX.Move ctlX.Left, ctlX.Top, ctlX.Width * sngW, ctlX.Height
                Case vbAlignRight
                    ctlX.Move ctlX.Left * -sngW, ctlX.Top, ctlX.Width * sngW, ctlX.Height
            End Select
        Case "Frame"
            ctlX.Move ctlX.Left * sngW, ctlX.Top * sngH, ctlX.Width * sngW, ctlX.Height * sngH
        Case Else
            ctlX.Move ctlX.Left * sngW, ctlX.Top * sngH, ctlX.Width, ctlX.Height
    End Select
Next
0
 
LVL 45

Expert Comment

by:aikimark
ID: 7125735
Warning: the height and width multiplier needs tweaking.

sngH = ScaleY(Screen.Height, vbTwips, vbPixels) / 600   'height multiplier
sngW = ScaleX(Screen.Width, vbTwips, vbPixels) / 800      'width multiplier
0
 

Author Comment

by:palin2000
ID: 7126274
Hi aikimark

I've that feeling I'm going to make a twit of myself by saying this, but your last solution appears to me as if it is Visual Basic, am I right?

Would it be possible to show me in "Copy/Paste" form how your code fits into a basic Delphi form, please.

I think I can see where you are going with this, I was wondering however if there was any way of referencing a panel's components, for instance pnlMainPanel.Button1?

Thanks in advance.

Palin
0
 
LVL 45

Expert Comment

by:aikimark
ID: 7126844
Palin,

Oops.  I forgot what area I was in when I answered the question.  You are most perceptive.  This was a VB example and not a Delphi example.  There are several people in my Delphi user group who would be laughing heartily at my expense if they were to hear about this.

I'm not sure what you mean by a "copy/paste" form.  Please elaborate.

Why do you want to iterate through the controls just in a panel (or some container)?  I thought you wanted to move controls, based on the size of the screen relative to the 800x600 design-time screen size.  You will need to iterate through the Controls collection (see the Cynna example code) and base your actions upon whether the Controls[i].Parent is the panel in which you are interested.

What my example tried to convey is the need to enlarge some container objects to accomodate the movement of the objects they contain.  Those container objects that are aligned to some side of the form must be treated differently than containers that aren't aligned.
0
 
LVL 7

Expert Comment

by:Cynna
ID: 7126963
Palin,

I think this will do what you need. Principle is the same,
but this code works for nested panels (repositions controls
inside panel, relative to panel position, but using the same ratio).

procedure TForm1.RepositionPanelControls(Panel: TPanel; DefaultWidth, DefaultHight: Integer);
var i: Integer;
begin
  for i := Panel.ControlCount - 1 downto 0 do begin
      if Panel.Controls[i] is TPanel then
        RepositionPanelControls((Panel.Controls[i] as TPanel), DefaultWidth, DefaultHight);
      with Panel.Controls[i] do begin
           Top  := Round(Top*Screen.Height / DefaultHight);
           Left := Round(Left*Screen.Width / DefaultWidth);
      end;
  end;

end;

procedure TForm1.RepositionControls(DefaultWidth, DefaultHight: Integer);
// Arguments represent design-time screen dimensions
var i,j: Integer;
begin
 for i := ControlCount - 1 downto 0 do
    with Controls[i] do begin
         Top  := Round(Top*Screen.Height / DefaultHight);
         Left := Round(Left*Screen.Width / DefaultWidth);
         if Controls[i] is TPanel then
            RepositionPanelControls((Controls[i] as TPanel), DefaultWidth, DefaultHight);
    end;
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
  RepositionControls(800,600);
end;
0
 
LVL 45

Expert Comment

by:aikimark
ID: 7127094
Cynna,

1. Won't we need to increase the size of Tpanel to accomodate the movement of its contained controls?
2. Does the Tpanel's align property affect our code action?
3. What should we do about Delphi Frames?  They provide some of the auto-resize functionality without code.

I defer to your code examples.
0
 
LVL 7

Expert Comment

by:Cynna
ID: 7127259
aikimark,

> 1. Won't we need to increase the size of Tpanel to accomodate the movement of its contained controls?

I'm quoting palin2000 inital request:

>  ...I'm looking for a small routine that would re-position the components but not re-size them.





> 2. Does the Tpanel's align property affect our code action?

Of course, but this is irrelevant. Using alignment is contrary to inital request.





> 3. What should we do about Delphi Frames?

Nothing - we shouldn't use them with this code.




I didn't tried posting a Magic Bullet that solves any resolution-change related problem for any scenario. If you think you can, by all means do, I'll be interested to see it.
I simply attempted to solve palin2000 problem (as I saw it) in example, copy/paste fashion, so that  he could use it as a template for more elaborate situations and adjust it to his specific needs.


By the way,

>I'm not sure what you mean by a "copy/paste" form. Please elaborate.

When you post complete example, that works right away, so that reader can simply Copy it and then Paste it to Delphi.
He presses F9 and then he can quickly judge if it yields the results he needs. If it does, he can than spend time learning how it was done, knowing that that code is worth it.
IMHO, palin2000 was reffering to this.








0
 
LVL 45

Expert Comment

by:aikimark
ID: 7127335
thanks, Cynna.

===============
Palin,

I think you now have your repositioning-but-not-resizing solution.  Please be aware of the following:
1. Since you asked for a move-but-don't-resize solution, be aware that some Tpanel-contained controls might be repositioned beyond the edge of some Tpanels, because the Tpanels aren't being resized.
2. If any of your Tpanel controls are aligned, you will need to accomodate this condition in your code or remove their aligned property.
3. The use of Frame controls won't work well with this scheme.
0
 

Author Comment

by:palin2000
ID: 7127541
Hi

I've got to say you guys are brilliant!, I just got home and within 2 minutes my (total) problem was resolved, I can't thank both of you enough.

I will now study the code to see how it all hangs together and learn from that, and as I said before this will help other programmers like myself, you should post it elsewhere.

If you both agree I would like to increase the overall points on this question to 500 and share it between the both of you.

If so I'll drop it back to 250 and accept aikimark's solution then post another "for cynna only" question for 250 points.

Once again thanks for all your help.

Best regards
Palin
0
 
LVL 45

Expert Comment

by:aikimark
ID: 7127566
Thanks for the points, Palin.

Thanks to Cynna for the quick code examples in the appropriate language for this forum. :-)
0
 
LVL 7

Expert Comment

by:Cynna
ID: 7127645
palin2000,

Thank you - for points and kind words, hope you finish your project OK.



aikimark,

No problem, I post more or less just in Delphi, so I guess it's a bit easier for me to speak only Delphi... ;}

0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now