views:

2851

answers:

5

Hi, I am developing a .NET CF based Graphics Application, my project involves a lot of drawing images, We have decided to go for porting the application on different handset resolution.(240 X 240 , 480 X 640) etc.

How would i go onto achieve this within single solution/project?

Is there a need to create different projects based on resolutions? How would i handle common files? and i need the changes in one of the common classes to occur across all devices.

Thank you, Cronos

+1  A: 

This code has worked for me in determining the resolution of the screen dynamically:

[DllImport("coredll.dll", EntryPoint = ("GetSystemMetrics"))]
public static extern int GetSystemMetrics(int nIndex);

private const int SM_CXSCREEN = 0;
private const int SM_CYSCREEN = 1;

private int width = GetSystemMetrics(SM_CXSCREEN);
private int height = GetSystemMetrics(SM_CYSCREEN);

I don't remember it out of the top of my head, but there is also a way to get the Screen Orientation. These would help merge some code in a single Class.

I would strongly recommend to create a single solution for all resolutions. You could have as many projects as you want under these solution. These projects could be Windows Forms Applications, Dll Library projects or Set Up Projects.

I would aim to create a single Windows Forms Application Project. I would use the above technique and read the static images from the File System. If this doesn't work for you and/or you prefer to read your images as resources, then create an 'engine' dll project, containing all the code that is common to all resolutions. Add then the output of this project as reference to as many Windows Forms Applications projects as you need.

kgiannakakis
+4  A: 

Anchoring and Docking is the most common mechanism for handling different resolutions (remember also that many devices can rotate the screen, so you need to handle changes even on a single device). Getting screen size, if needed after that, is as simple as querying the Screen object:

int screenWidth = Screen.PrimaryScreen.Bounds.Width;
int workingHeight = Screen.PrimaryScreen.WorkingArea.Height;
ctacke
+2  A: 

There is no simple answer to this question. Designing forms to handle different screen resolutions is easy to do in Windows where even the smallest screen size is usually 600 x 800. In the CF world, the screen can be as small as 240 x 240 (or smaller for smartphones) or as large as 640 x 480 (or larger). Anchoring and Docking tend to work very poorly over these size ranges.

One option is to use a least-common-denominator approach and design everything to fit on the smallest possible screen. This is guaranteed to work on every device, but obviously will waste useful space on larger screens.

Another option is to design each form to be resolution-aware. For example, if you have a form that displays data in a grid and a filter combobox above it, you can write code in the form's Resize event that adjusts the dimensions of the grid to fill whatever space is available.

An alternative option to resolution-aware code is to create a separate form for each resolution for a particular UI function. This is more work and leads to code duplication, of course, but for some particular functions this is just something you have to do. As long as you abstract out the common logic, you'll be fine.

You have the right idea about wanting to achieve this within a single project. Different screen resolutions can usually be handled with a little bit of work and thought, and are definitely not grounds for splitting your product into different projects.

MusiGenesis
Please see my new answer. I dig a little digging into this problem and found a much better way of dealing with screen resolutions.
MusiGenesis
+2  A: 

Don't listen to that idiot MusiGenesis. A much better way of handling different screen resolutions for Windows Mobile devices is to use forms inheritance, which can be tacked onto an existing CF application with minimal effort.

Basically, you design each form for a standard 240x320 screen. When you need to re-arrange a form for a new resolution (let's say 240x240), you add a new form to your project and have it inherit from your original 240x320 form:

public partial class frmDialog240x240: frmDialog

instead of just Form:

public partial class frmDialog240x240: Form

like usual. On your original form, you need to set the Modifiers property of each control to Protected (instead of the default Private). In the designer for your new form, you will see all of the controls on the form you're inheriting from, and you can move them and resize them as you see fit to accomodate the new screen dimensions (this will not affect the original form's layout).

When your program is running, it's easy for it to check the screen resolution of the device it's running on and create the appropriate form (a factory method is good for this). Your new form inherits everything from the old form, but uses your new custom layout.

This approach allows you to avoid code duplication, because there isn't any.

MusiGenesis
I tried the inheritance approach and did not get very far, mostly due to issues with the designer. I resorted to docking and got decent results.
cdonner
@cdonner: did you set the Modifiers property of each control on the parent form to Protected (instead of Private)? That's the key to getting the designer to work properly.
MusiGenesis
A: 

I gave up on the designer for all but the most basic compact applications. I try to place every control mathematically using the screen dimensions. It sounds painful but once you get going it becomes second nature.

For every form I create a 'regenerate' method which is fired whenever the form is shown or resized. In that method I generally set location, size and, if necessary, font size for each control on the form. When placing the control, my thought process is:

  1. OK for regular portrait device?
  2. OK for regular landscape device?
  3. OK for square device?
  4. OK for VGA (640x480) (high DPI) device?

For font sizes and dealing with high DPI (Dots Per Inch) VGA devices, I use the property -:

CurrentAutoScaleDimensions.Height / 96

...to produce a font-scaling factor. (Regular devices are 96 DPI)

As a last resort, you can use conditional (if) statements in your regenerate code to test for various screen sizes/shapes.

It's still possible to use the designer for basic layout but you'll need to run the forms on various emulators/devices and try switching portrait/landscape to fully test the 'regenerate' methods.

Damien