Scaling of dialogs

Technical progress is certainly nothing new in the IT world. It is taking place in all areas, not only in a wide variety of hardware, but also in screen resolutions. At the beginning of the 1990s, the most widespread resolution was 640×480 pixels. By the end of the decade, this had risen to 800×600 pixels. Over the years, the resolution increased further from 1024×768 to the current 1366×768 pixels. As a result, there have been an increasing number of inquiries from support in the past about how to implement individual scalability of a frame in conzept 16. In the following article, I would like to introduce you to a procedure that offers an easy way to scale existing frames individually.


The fundamental idea:

Most desktop users work with the usual resolutions of 1024 x 768, 1366 x 768, 1280 x 1024 and 1920 x 1080.
Instead of scaling the underlying dialog at runtime, scaled dialogs are generated for the known resolutions and saved with WinSave() in the database. If the dialog is then supposed to be displayed in the application, the screen resolution is first determined and then the pre-generated dialog is loaded. This can be achieved with the standard conzept 16 commands WinInfo() and WinDialog(). This leaves the task of scaling, which is the subject of this article.

Main-Funktion:

The existing frame that is supposed to be scaled is transferred within this function. The next step is to specify the desired size. It is recommended that the aspect ratio of the scaled frame is identical to the original dialog, as otherwise text objects, including fonts, for example, may not be displayed as desired. Once the desired frame size has been entered, the actual scaling function is called up.

main()
  local
  {
    tDHdl               : handle;   // Dialog
    tSizeWish           : point;    // Desired dialog size
  }
{
  // Dialog to be scaled
  tDHdl # WinOpen('DragDropEvents', _WinOpenDialog | _WinOpenEventsOff);
  if (tDHdl > 0)
  {
    tDHdl->wpAreaClientRestore # false;

    // If the new icons are used, then set
    //_App->wpTileTheme # _WinTileThemeEnhanced;

    // Desired size of the dialog
    tSizeWish # PointMake(1024 , 768);

    // Scaling function
    ScaleFrame(tDHdl, tSizeWish:x, tSizeWish:y);

    tDHdl->WinDialogRun(_WinDialogCenterScreen);
    tDHdl->WinClose();
  }
}
Scaling function ‘ScaleFrame’:

The output frame, the desired width and height are transferred to this function. First, the current height and width of the frame and that of the client area are determined. The difference in the client area of the scaled dialog is then calculated. In order to scale the frame, the scaling factor must be determined. To do this, it is essential to determine the percentage deviation of the height and width. This is done using function GetDifferencePercent(). Once the scaling factor has been determined, the current frame is set to the desired size and then all objects and their sub-objects are scaled.

sub ScaleFrame
(
  aFrame                : handle;       // Frame
  aWidth                : int;          // Desired width
  aHeight               : int;          // Desired height
)

  local
  {
    tWidth              : int;          // Width of the frame
    tHeight             : int;          // Height of the frame
    tClientW            : int;          // Client area width
    tClientH            : int;          // Client area height

    tDifW               : int;          // Width difference (dialog border and client area)
    tDifH               : int;          // Height difference (dialog border and client area)

    tScaleClientW       : int;          // Client area of the scaled frame (Width)
    tScaleClientH       : int;          // Client area of the scaled frame (Height)

    tPercentW           : float;        // Width scaling factor in %
    tPercentH           : float;        // Height scaling factor in %
  }

{
  // Width and height of the frame
  tWidth  # aFrame->wpAreaRight  - aFrame->wpAreaLeft;
  tHeight # aFrame->wpAreaBottom - aFrame->wpAreaTop;

  // Client area
  tClientW # WinInfo(aFrame, _WinClientWidth);
  tClientH # WinInfo(aFrame, _WinClientHeight);

  // Difference between frame and client area
  tDifH # tHeight - tClientH;
  tDifW # tWidth - tClientW;

  // Client area of the scaled frame
  tScaleClientW # aWidth  - tDifW;
  tScaleClientH # aHeight - tDifH;

  // Percentage deviation (Width)
  tPercentW # GetDifferencePercent(tClientW, tScaleClientW);
  // Percentage deviation (Height)
  tPercentH # GetDifferencePercent(tClientH, tScaleClientH);

  // Scaling factor
  tPercentW  # tPercentW / 100.0;
  tPercentH  # tPercentH / 100.0;

  // Frame size
  aFrame->wpAreaLeft   # 0;
  aFrame->wpAreaTop    # 0;
  aFrame->wpAreaRight  # aWidth;
  aFrame->wpAreaBottom # aHeight;

  // Scaling objects and sub-objects
  aFrame->ScaleObject(tPercentW, tPercentH, tClientW, aWidth, aHeight);
}
Function ‘ScaleObject’:

After transferring the parent object, the scaling factor of the length and width, the client area and the desired width and length, the scaling factor of the font is determined first. The text of the objects is then resized. In the next step, all sub-objects are determined in a loop and checked to ensure that they are not exceptions. The recursive function is now called for each determined sub-object so that the font can also be resized. The final step at the end of the function is to increase the size of each individual object by the previously determined percentage.

// Scale objects
sub ScaleObject
(
  aParent               : handle;           // Parent object
  aPercentW             : float;            // Width scaling factor
  aPercentH             : float;            // Height scaling factor

  aWidth                : int;              // Client area of the old frame
  aNewWidth             : int;              // Desired dialog width
  aNewHeight            : int;              // Desired dialog height
)

  local
  {
    tObj                : handle;           // Object

    tArea               : rect;             // Size

    tGrouping           : int;              // Grouping property
    tHasGrouping        : logic;            // Grouping set?
    tHasFont            : logic;            // hhas a font?
    tFontParent         : logic;            // FontParent set?
    tFont               : font;             // Font of the object

    tFontPercent        : float;            // FontSize scaling factor
    tPoint              : float;            // FontSize
  }

{
  // Is grouping set?
  if (WinPropGet(aParent, _WinPropGrouping, tGrouping))
    tHasGrouping # tGrouping != _WinGroupingNone;

  // Scaling factor of the font
  tFontPercent # Fnc.CalcPercent(aWidth, aNewWidth, aNewHeight);

  // Scaling text in the objects
  if (WinPropGet(aParent, _WinPropFontParent, tFontParent)) // Eigenschaft vorhanden?
  {
    if (!tFontParent) // false
    {
      tFont  # aParent->wpFont;

      // FontSize is available in tenths of a point
      tPoint # CnvFI(tFont:Size) / 10.0;
      // Scale font
      tPoint # Fnc.CalcPoint(tPoint, tFontPercent);
      tFont:Size # CnvIF(tPoint) * 10;

      aParent->wpFont # tFont;
    }
  }

  // Search object
  for   tObj # WinInfo(aParent, _WinFirst);
  loop  tObj # WinInfo(tObj, _WinNext);
  while (tObj > 0)
  {
    // Exceptions
    if (WinInfo(tObj, _WinType) = _WinTypeListColumn or
        WinInfo(tObj, _WinType) = _WinTypeGroupColumn or
        WinInfo(tObj, _WinType) = _WinTypeTreeNode or
        WinInfo(tObj, _WinType) = _WinTypeToolbarButton or
        WinInfo(tObj, _WinType) = _WinTypeStatusbar)
      cycle;

    // Search for sub-objects
    tObj->ScaleObject(aPercentW, aPercentH, aWidth, aNewWidth, aNewHeight);

    // Exception
    if (WinInfo(tObj, _WinType) = _WinTypeGroupTile)
      cycle;

    // Exception
    if (tHasGrouping)
      if (WinPropGet(tObj, _WinPropAlignGrouping, tGrouping) and tGrouping != _WinAlignGroupingNone)
        cycle;

    // Scaling the objects
    tArea # tObj->wpArea;

    tArea:Left   # CnvIF(CnvFI(tArea:Left)   * aPercentW);
    tArea:Top    # CnvIF(CnvFI(tArea:Top)    * aPercentH);
    tArea:Right  # CnvIF(CnvFI(tArea:Right)  * aPercentW);
    tArea:Bottom # CnvIF(CnvFI(tArea:Bottom) * aPercentH);

    tObj->wpArea # tArea;
  }
}
Exceptions

However, there are also objects within concept 16 that cannot be scaled. For example, the Column header of a list object is not adjustable in size. Checkbox, Radio button objects and Scrollbox objects are also not scalable. There are currently other points that should be taken into account before scaling frames in order to achieve a perfect result:

  • The property wpAreaClientRestore must not be set for the frame.
    After the frame has been scaled and saved, the property can be set again.
  • It must be ensured that the same wpTileTheme property is used throughout.
  • All objects should have a certain distance to the edge of the frame.
  • The property wpShowGrip for Toolbar-Button should be set
    Otherwise it could happen that the Toolbar-Button ‘changes’ its previous position.
  • The text of the labels should not go beyond the margin.
  • The font of the RtfEdit object should not be changed procedurally.

The procedure presented in the article is available for download at the end of the article.

Download

Zum downloaden hier klicken ScaleDialog.zip (1.93 KB)
Sie müssen angemeldet sein, um die Datei herunterladen zu können.

Klicken Sie hier, um die Nutzungsbedingungen für unseren Blog zu lesen.

Leave a Reply

Your email address will not be published. Required fields are marked *

Leave the field below empty!

Requests, questions or feedback are welcome:

Terms of use of the comment function in the blog

1. General information

Vectorsoft AG (‘Provider’) provides a public blog for Internet users (‘Users’) on the vectorsoft.de website. The public blog is intended for the exchange of information and ideas. Users who participate with contributions and comments undertake to comply with the blog terms of use and are responsible for the accuracy, appropriateness and freedom from legal infringements of their contributions. By using the comment function in our blog, you accept these terms of use.

2. Netiquette

We ask you to refrain from personal attacks and provocations based on other opinions. Please argue objectively and maintain a constructive discussion culture. Your comment should always be related to the topic in question in order to avoid digressions into other topics. Posting the same comment or several similar comments more than once is not permitted.

3. Prohibition of illegal content

By submitting your comment, you confirm that you are not violating any copyrights or other rights of third parties. Inciting, racist statements, instructions for criminal offences and their glorification, depictions of violence, pornographic content and statements that violate personal rights are prohibited.

4. No advertising

The use of the comment function is not permitted for commercial or party-political purposes. Advertising contributions of any kind will be deleted immediately.

5. Details of the name

When entering your name, pay attention to the principles mentioned above.

6. Source references

If you intend to publish quotes or contributions from third parties, please indicate the respective sources and explain how they relate to the blog post.

7. Violation of the terms of use

Posts that violate this policy will be deleted immediately. If you notice any violations yourself, please send us the link to the comment in question by e-mail to . We expressly point out that we will exclude individual users in the event of repeated or serious violations of these terms of use.

As of: Sept. 2024

Get your Trial Version now!

Test yeet free of charge

IHRE EVALUIERUNGSLIZENZ - JETZT ANFORDERN!

TESTEN SIE DIE CONZEPT 16 VOLLVERSION - UNVERBINDLICH und KOSTENFREI

Subscribe to our newsletter

[cleverreach_signup]
WordPress Cookie Notice by Real Cookie Banner