How to close a UIFrame window from the object itse

2019-08-03 15:36发布

In GMS2.x, closing UIFrame window with the code shown below will cause DM to crash (at pressing the close button.)

However, the same code works fine with GMS 1.x.

Is there a way to work around this problem in GMS 2.x?

class UIWindowCloseTest : UIFrame {

    void CloseSelf( object self ) self.GetFrameWindow().WindowClose(0);

    UIWindowCloseTest( object self ) {
        TagGroup tgDialog = DLGCreateDialog( "window close test" );
        tgDialog.DLGAddElement( DLGCreatePushButton( "Close", "CloseSelf" ));
        self.super.init(tgDialog);
        self.Display( "test" );
        result( self.ScriptObjectGetID().Hex() + " constructed\n" );
    };

    ~UIWindowCloseTest( object self ) \
        result( self.ScriptObjectGetID().Hex() + " destructed\n\n" );
};

alloc(UIWindowCloseTest);

标签: dm-script
2条回答
对你真心纯属浪费
2楼-- · 2019-08-03 15:57

This is the extension of this questions for GMS 3.X:

In essense, the answer below is correct for GMS 3 as well, but only since its version 3.2 (Maybe GMS 3.1.2 as well).

Earlier versions of GMS 3 have a bug as KEVIVI pointed out in the comment to the answer.

However, there is a work-around solution to this, which is slightly elaborate:

Class myDLG : UIframe
{
    myDLG(object self)  result("\n Create DLG")
    ~myDLG(object self) result("\n Kill DLG")

    void DeferredClose( object self )
    {
        TagGroup tgs = GetPersistentTagGroup()
        number scriptID
        if ( tgs.TagGroupGetTagAsLong( "DummyTag_CloseWindow_ID", scriptID ) )
        {
            object obj = GetScriptObjectFromID( scriptID )
            if ( obj.ScriptObjectIsValid() )
            {
                obj.GetFrameWindow().WindowClose(0)
                return
            }
        }
        Debug( "\n Sorry, but could not close dialog." )
    }

    void CloseButtonAction( object self )    
    {
        // Normally, it would be save to use "self.close()" here,
        // but due to a bug, this is currenlty not possible in GMS 3.1
        // The alternative method of getting the window of the UIframe object
        // and closing it, is okay, but it must not be called directly here,
        // or it will crash DM.
        // As a work-around, one can store the object ID and have a separate
        // thread pick it up, get the object, and close the object's window.
        // This is, what we are doing below.


        // Write ScriptID into tags 
        TagGroup tgs = GetPersistentTagGroup()
        tgs.TagGroupSetTagAsLong( "DummyTag_CloseWindow_ID", self.ScriptObjectGetID() ) 

        // Launch separate thread just to close... (0.1 sec delay for safety)
        AddMainThreadSingleTask( self, "DeferredClose", 0.1 )
    }

    TagGroup CreateDLG(object self)
    {
        TagGroup DLGtg,DLGtgItems
        DLGtg=DLGCreateDialog("my Dialog",DLGtgItems)
        DLGtgItems.DLGAddElement(DLGCreatePushButton("Close","CloseButtonAction"))
        return DLGtg
    }
}

{
    object dialog=Alloc(myDLG)
    dialog.Init( dialog.CreateDLG() )
    dialog.display("")
}

So:

  • For GMS 3.2 and later: Use self.close();

  • For GMS 3.0 and 3.1 (with the bug): Use the workaround.

  • For GMS 2.x: Use self.close();

  • For GMS 1.x: Use self.GetFrameWindow().WindowClose(0);

查看更多
Summer. ? 凉城
3楼-- · 2019-08-03 16:00

Yes, in GMS 2.x you have to use

self.close();

instead of

self.GetFrameWindow().WindowClose(0);

查看更多
登录 后发表回答