Round widgets

changing the shape of a widget

based on an example by Sturla Johnsen



The animated gif shows an impression of Rounddemo.w.
Rounddemo, written by Sturla Johnsen, creates a normal Progress dialog box with some widgets on it (a frame, two fill-ins and two buttons) and demonstrates how the default rectangular region of any widget can be replaced by a different shaped region. In this case by elliptic regions.
Rounddemo.w calls procedure Roundwidget.p from within the CHOOSE trigger of the button. Both procedures are attched (see table near end of this topic) and can be downloaded from here to see for yourself.

ON CHOOSE OF BUTTON-1 IN FRAME Dialog-Frame /* Press me (several times) */
DO:
  IF SELF:PRIVATE-DATA = ? THEN 
     ASSIGN SELF:PRIVATE-DATA = "1".
  DEFINE VARIABLE HANDLE AS HANDLE.
  CASE INT(SELF:PRIVATE-DATA):
    WHEN 1 THEN ASSIGN HANDLE = FRAME {&FRAME-NAME}:HANDLE.
    WHEN 2 THEN ASSIGN HANDLE = FILL-IN-1:HANDLE.
    WHEN 3 THEN ASSIGN HANDLE = FILL-IN-2:HANDLE.
    WHEN 4 THEN ASSIGN HANDLE = FRAME FRAME-A:HANDLE.
    WHEN 5 THEN ASSIGN HANDLE = SELF.
    WHEN 6 THEN ASSIGN HANDLE = Btn_Close:HANDLE
                       SELF:SENSITIVE = NO.
    OTHERWISE RETURN NO-APPLY.
  END CASE.
  RUN roundwidget.p (HANDLE).
  ASSIGN SELF:PRIVATE-DATA = STRING(INT(SELF:PRIVATE-DATA) + 1).
END.
/*******************************************
*   roundwidget.p                          *
*   Sturla Johnsen                         *
*******************************************/   
DEFINE INPUT PARAMETER hWidget AS HANDLE.
 
DEFINE VARIABLE hrgn        AS INTEGER NO-UNDO.
DEFINE VARIABLE ReturnValue AS INTEGER NO-UNDO.
 
IF NOT VALID-HANDLE(hWidget) THEN RETURN ERROR.
 
RUN CreateEllipticRgn (1, /* Start Xpos */
                       1, /* Start Ypos */
                       hWidget:WIDTH-PIXELS,
                       hWidget:HEIGHT-PIXELS, 
                       OUTPUT hrgn).
 
RUN SetWindowRgn(hWidget:HWND, 
                 hrgn, 
                 1, /* 1 = Redraw */
                 OUTPUT ReturnValue).
 
PROCEDURE SetWindowRgn EXTERNAL "user32.dll" :
  DEFINE INPUT  PARAMETER HWND        AS LONG.
  DEFINE INPUT  PARAMETER hRgn        AS LONG.
  DEFINE INPUT  PARAMETER bRedraw     AS LONG.
  DEFINE RETURN PARAMETER ReturnValue AS LONG.
END PROCEDURE.
 
PROCEDURE CreateEllipticRgn EXTERNAL "gdi32.dll" :
  DEFINE INPUT  PARAMETER StartX AS LONG.
  DEFINE INPUT  PARAMETER StartY AS LONG.
  DEFINE INPUT  PARAMETER HEIGHT AS LONG.
  DEFINE INPUT  PARAMETER WIDTH  AS LONG.
  DEFINE RETURN PARAMETER hrgn   AS LONG.
END PROCEDURE.  

notes

CreateEllipticRgn creates a region which is a GDI object. A program should delete all the GDI objects it creates (using procedure DeleteObject). But not this time, because it is passed to SetWindowRgn. From now on this region is owned by the operating system and will eventually be deleted automatically.
There are many more API functions for creating regions with different shapes, like CreatePolygonRgn, CreateRectRgn, CreateRoundRectRgn. You can also create several regions and combine them using CombineRgn to create every shape you can imagine.

Attachments

rounddemo.zip : Example code


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
beverlycraig's picture

Great

nice post by the way