Forms positioning behavior. Bug? - Forum - OpenEdge General - Progress Community

Forms positioning behavior. Bug?

 Forum

Forms positioning behavior. Bug?

  • I've got a Progress window (.w) & a .Net form (.cls). Both very simple. I open the cls from the .w. No problems so far.

    Now, when I click on the .w, my .Net form gets positioned behind the procedure editor (or application menu). It should be positioned behind the .w. The second time I launch the .w in the same session, the .Net form gets indeed positioned behind the .w

    Does anybody why this happens? Basically it means in our full application (classic .W) the .Net form seems to disappear. It's not: it's behind the menu. But you can see this is not user friendly.

    Below are the 2 windows (well, form & window). If you run these from a simple prowin32, you'll see what I mean. Hopefully. Big Smile

    EDIT: I've tested both on 10.2A & 11.3. On 10.2A, it's seems to work correctly

    .w:

    &ANALYZE-SUSPEND _VERSION-NUMBER AB_v10r12 GUI
    &ANALYZE-RESUME
    &Scoped-define WINDOW-NAME C-Win
    &ANALYZE-SUSPEND _UIB-CODE-BLOCK _CUSTOM _DEFINITIONS C-Win
    CREATE WIDGET-POOL.
    /* *************************** Definitions ************************** */
    /* Parameters Definitions --- */
    /* Local Variable Definitions --- */
    def var frm as class testform no-undo.
    /* _UIB-CODE-BLOCK-END */
    &ANALYZE-RESUME

    &ANALYZE-SUSPEND _UIB-PREPROCESSOR-BLOCK
    /* ******************** Preprocessor Definitions ******************** */
    &Scoped-define PROCEDURE-TYPE Window
    &Scoped-define DB-AWARE no
    /* Name of designated FRAME-NAME and/or first browse and/or first query */
    &Scoped-define FRAME-NAME DEFAULT-FRAME
    /* Standard List Definitions */
    &Scoped-Define ENABLED-OBJECTS BUTTON-1
    &Scoped-Define DISPLAYED-OBJECTS
    /* Custom List Definitions */
    /* List-1,List-2,List-3,List-4,List-5,List-6 */
    /* _UIB-PREPROCESSOR-BLOCK-END */
    &ANALYZE-RESUME
    
    
    /* *********************** Control Definitions ********************** */
    /* Define the widget handle for the window */
    DEFINE VAR C-Win AS WIDGET-HANDLE NO-UNDO.
    /* Definitions of the field level widgets */
    DEFINE BUTTON BUTTON-1
    LABEL "Button 1"
    SIZE 15 BY 1.14.

    /* ************************ Frame Definitions *********************** */
    DEFINE FRAME DEFAULT-FRAME
    BUTTON-1 AT ROW 2.43 COL 9 WIDGET-ID 2
    WITH 1 DOWN NO-BOX KEEP-TAB-ORDER OVERLAY
    SIDE-LABELS NO-UNDERLINE THREE-D
    AT COL 1 ROW 1
    SIZE 80 BY 16 WIDGET-ID 100.

    /* *********************** Procedure Settings ************************ */
    &ANALYZE-SUSPEND _PROCEDURE-SETTINGS
    /* Settings for THIS-PROCEDURE
    Type: Window
    Allow: Basic,Browse,DB-Fields,Window,Query
    Other Settings: COMPILE
    */
    &ANALYZE-RESUME _END-PROCEDURE-SETTINGS
    /* ************************* Create Window ************************** */
    &ANALYZE-SUSPEND _CREATE-WINDOW
    IF SESSION:DISPLAY-TYPE = "GUI":U THEN
    CREATE WINDOW C-Win ASSIGN
    HIDDEN = YES
    TITLE = "<insert window title>"
    HEIGHT = 16
    WIDTH = 80
    MAX-HEIGHT = 16
    MAX-WIDTH = 80
    VIRTUAL-HEIGHT = 16
    VIRTUAL-WIDTH = 80
    RESIZE = yes
    SCROLL-BARS = no
    STATUS-AREA = no
    BGCOLOR = ?
    FGCOLOR = ?
    KEEP-FRAME-Z-ORDER = yes
    THREE-D = yes
    MESSAGE-AREA = no
    SENSITIVE = yes.
    ELSE {&WINDOW-NAME} = CURRENT-WINDOW.
    /* END WINDOW DEFINITION */
    &ANALYZE-RESUME
    
    
    /* *********** Runtime Attributes and AppBuilder Settings *********** */
    &ANALYZE-SUSPEND _RUN-TIME-ATTRIBUTES
    /* SETTINGS FOR WINDOW C-Win
    VISIBLE,,RUN-PERSISTENT */
    /* SETTINGS FOR FRAME DEFAULT-FRAME
    FRAME-NAME */
    IF SESSION:DISPLAY-TYPE = "GUI":U AND VALID-HANDLE(C-Win)
    THEN C-Win:HIDDEN = no.
    /* _RUN-TIME-ATTRIBUTES-END */
    &ANALYZE-RESUME
    
    
    
    
    /* ************************ Control Triggers ************************ */
    &Scoped-define SELF-NAME C-Win
    &ANALYZE-SUSPEND _UIB-CODE-BLOCK _CONTROL C-Win C-Win
    ON END-ERROR OF C-Win /* <insert window title> */
    OR ENDKEY OF {&WINDOW-NAME} ANYWHERE DO:
    /* This case occurs when the user presses the "Esc" key.
    In a persistently run window, just ignore this. If we did not, the
    application would exit. */
    IF THIS-PROCEDURE:PERSISTENT THEN RETURN NO-APPLY.
    END.
    /* _UIB-CODE-BLOCK-END */
    &ANALYZE-RESUME

    &ANALYZE-SUSPEND _UIB-CODE-BLOCK _CONTROL C-Win C-Win
    ON WINDOW-CLOSE OF C-Win /* <insert window title> */
    DO:
    /* This event will close the window and terminate the procedure. */
    APPLY "CLOSE":U TO THIS-PROCEDURE.
    RETURN NO-APPLY.
    END.
    /* _UIB-CODE-BLOCK-END */
    &ANALYZE-RESUME

    &Scoped-define SELF-NAME BUTTON-1
    &ANALYZE-SUSPEND _UIB-CODE-BLOCK _CONTROL BUTTON-1 C-Win
    ON CHOOSE OF BUTTON-1 IN FRAME DEFAULT-FRAME /* Button 1 */
    DO:
    frm:show().
    END.
    /* _UIB-CODE-BLOCK-END */
    &ANALYZE-RESUME

    &UNDEFINE SELF-NAME
    &ANALYZE-SUSPEND _UIB-CODE-BLOCK _CUSTOM _MAIN-BLOCK C-Win

    /* *************************** Main Block *************************** */
    /* Set CURRENT-WINDOW: this will parent dialog-boxes and frames. */
    ASSIGN CURRENT-WINDOW = {&WINDOW-NAME}
    THIS-PROCEDURE:CURRENT-WINDOW = {&WINDOW-NAME}.
    /* The CLOSE event can be used from inside or outside the procedure to */
    /* terminate it. */
    ON CLOSE OF THIS-PROCEDURE
    RUN disable_UI.
    /* Best default for GUI applications is... */
    PAUSE 0 BEFORE-HIDE.
    /* Now enable the interface and wait for the exit condition. */
    /* (NOTE: handle ERROR and END-KEY so cleanup code will always fire. */
    MAIN-BLOCK:
    DO ON ERROR UNDO MAIN-BLOCK, LEAVE MAIN-BLOCK
    ON END-KEY UNDO MAIN-BLOCK, LEAVE MAIN-BLOCK:
    RUN enable_UI.

    frm = new testform().
    frm:ProWinHandle:parent = CURRENT-WINDOW.
    WAIT-FOR System.Windows.Forms.Application:Run().
    System.Windows.Forms.Application:Exit().
    END.
    /* _UIB-CODE-BLOCK-END */
    &ANALYZE-RESUME

    /* ********************** Internal Procedures *********************** */
    &ANALYZE-SUSPEND _UIB-CODE-BLOCK _PROCEDURE disable_UI C-Win _DEFAULT-DISABLE
    PROCEDURE disable_UI :
    /*------------------------------------------------------------------------------
    Purpose: DISABLE the User Interface
    Parameters: <none>
    Notes: Here we clean-up the user-interface by deleting
    dynamic widgets we have created and/or hide
    frames. This procedure is usually called when
    we are ready to "clean-up" after running.
    ------------------------------------------------------------------------------*/
    /* Delete the WINDOW we created */
    IF SESSION:DISPLAY-TYPE = "GUI":U AND VALID-HANDLE(C-Win)
    THEN DELETE WIDGET C-Win.
    IF THIS-PROCEDURE:PERSISTENT THEN DELETE PROCEDURE THIS-PROCEDURE.
    quit.
    END PROCEDURE.
    /* _UIB-CODE-BLOCK-END */
    &ANALYZE-RESUME
    &ANALYZE-SUSPEND _UIB-CODE-BLOCK _PROCEDURE enable_UI C-Win _DEFAULT-ENABLE
    PROCEDURE enable_UI :
    /*------------------------------------------------------------------------------
    Purpose: ENABLE the User Interface
    Parameters: <none>
    Notes: Here we display/view/enable the widgets in the
    user-interface. In addition, OPEN all queries
    associated with each FRAME and BROWSE.
    These statements here are based on the "Other
    Settings" section of the widget Property Sheets.
    ------------------------------------------------------------------------------*/
    ENABLE BUTTON-1
    WITH FRAME DEFAULT-FRAME IN WINDOW C-Win.
    {&OPEN-BROWSERS-IN-QUERY-DEFAULT-FRAME}
    VIEW C-Win.
    END PROCEDURE.
    /* _UIB-CODE-BLOCK-END */
    &ANALYZE-RESUME

    .cls:

    USING Progress.Lang.*.
    USING Progress.Windows.Form.
    ROUTINE-LEVEL ON ERROR UNDO, THROW.
    CLASS testform INHERITS Form: 

    DEFINE PRIVATE VARIABLE components AS System.ComponentModel.IContainer NO-UNDO.

    CONSTRUCTOR PUBLIC testform ( ):


    SUPER().
    InitializeComponent().
    /*THIS-OBJECT:ComponentsCollection:ADD(THIS-OBJECT:components).*/
    CATCH e AS Progress.Lang.Error:
    UNDO, THROW e.
    END CATCH.
    END CONSTRUCTOR.
    METHOD PRIVATE VOID InitializeComponent( ):

    /* NOTE: The following method is automatically generated.

    We strongly suggest that the contents of this method only be modified using the
    Visual Designer to avoid any incompatible modifications.

    Modifying the contents of this method using a code editor will invalidate any support for this file. */
    THIS-OBJECT:SuspendLayout().
    THIS-OBJECT:Name = "testform".
    THIS-OBJECT:Text = "testform".
    THIS-OBJECT:ResumeLayout(FALSE).
    CATCH e AS Progress.Lang.Error:
    UNDO, THROW e.
    END CATCH.
    END METHOD.
    DESTRUCTOR PUBLIC testform ( ):
    END DESTRUCTOR.
    END CLASS.
  • First I'll tell you how to fix it - either start the client with -nozgrouping or add NoZGrouping=yes to the Startup section of the registry or your ini file.

    Now for the explanation: Before 10.2A, OpenEdge parented all windows to a special invisible "owner" window. The owner window kept the windows together in a group so that they all came to the foreground when you clicked on any one of them. When we added forms in 10.2A we also parented them to the owner window. It turned out that forms don't behave well when they have an owner window so in a 10.2B service pack we changed the behavior - now forms are not parented to the owner window so they don't all come to the foreground as a group. And once you've displayed a form we also stop grouping windows together too.

    The first time you run your example, the Procedure Editor is displayed and is parented to the owner window. When you run the code and create the window, the new window is also parented to the owner window. This makes the Procedure Editor window and the new window move together as a group. Then you click the button and display the form. The form is not parented to the owner window so it's not part of the group. We also turn off the grouping because a form has been displayed. Clicking on the new window brings it and everything in its group (the Procedure Editor window) to the foreground, covering the form.

    When you run the window the second time it doesn't get added to the group with the Procedure Editor because we turned off the grouping when you displayed the form the first time. It is on its own. So is the form. None of the windows or forms are grouped so they move independently.

    The -nozgrouping startup parameter and NoZGrouping=yes registry setting disable the grouping at startup so that the windows and forms are never grouped.

  • Thanks for your reply. That explains a lot.

    I looked it up & found an entry in the knowledge base. Apparently, using the startup parameter or as you explained, starting the window a second time, also causes other applications (ie chrome, word, notepad, ...) to mix with the Progress windows.

    Basically: if I'm going to use .Net forms this means other windows can be positioned in between my Progress Windows.

    Not sure if the users will accept that. Is there a workaround for this?

  • I don't know of any workaround. I think you'll find that all .NET applications work this way.

  • Indeed, did a small test in C#.

    I guess a solution could be an mdi-style approach.

    Again, thanks for your quick reply. Wish I had posted this a day earlier...