Dm script 如何从对象本身关闭UIFrame窗口?(行为差异GMS 1.x至GMS 2.x)

Dm script 如何从对象本身关闭UIFrame窗口?(行为差异GMS 1.x至GMS 2.x),dm-script,Dm Script,在GMS2.x中,使用下面显示的代码关闭UIFrame窗口将导致DM崩溃(在按下关闭按钮时) 但是,同样的代码在gms1.x中也可以正常工作 在GMS2.x中有没有解决这个问题的方法 class UIWindowCloseTest : UIFrame { void CloseSelf( object self ) self.GetFrameWindow().WindowClose(0); UIWindowCloseTest( object self ) { T

在GMS2.x中,使用下面显示的代码关闭UIFrame窗口将导致DM崩溃(在按下关闭按钮时)

但是,同样的代码在gms1.x中也可以正常工作

在GMS2.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);
对, 在GMS2.x中,您必须使用

self.close()

而不是

self.GetFrameWindow().WindowClose(0)

这是GMS 3.X中问题的扩展: 在本质上,GMS 3也是正确的,但只有在其版本3.2(也可能是GMS 3.1.2)之后才正确

正如KEVIVI在对答案的评论中指出的,GMS3的早期版本有一个bug

但是,有一种变通解决方案可以解决这一问题,该解决方案有点复杂:

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("")
}

因此:

  • 对于GMS 3.2及更高版本:使用
    self.close()

  • 对于GMS3.0和3.1(有缺陷):使用变通方法

  • 对于GMS2.x:使用
    self.close()

  • 对于GMS1.x:使用
    self.GetFrameWindow().WindowClose(0)


在GMS 3.x中如何?self.close();不再关闭GMS 3.x中的UIFrame,也不会抛出错误消息。@KEVIVI GMS 3.0有一个错误,该错误已在最新的GMS 3.1版本中修复。可以用一个稍微复杂的想法来解决这个问题:创建一个单独的线程来关闭窗口。我可以马上把它作为一个例子贴在这里。。。。