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.

Leave a Reply

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

Leave the field below empty!

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