Как закрыть окно UIFrame из самого объекта? (Разница в поведении GMS 1.x и GMS 2.x)

В GMS2.x закрытие окна UIFrame с кодом, показанным ниже, приведет к сбою DM (при нажатии кнопки close).

Однако тот же код отлично работает с GMS 1.x.

Есть ли способ обойти эту проблему в 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);

person KEVIVI    schedule 22.01.2015    source источник


Ответы (2)


Это расширение этого вопроса для GMS 3.X:

По сути, ответ ниже верен и для GMS 3, но только начиная с его версии 3.2 (возможно, GMS 3.1.2 также).

В более ранних версиях GMS 3 есть ошибка, как указал KEVIVI в комментарии к ответу.

Однако для этого есть обходное решение, которое немного сложно:

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:

  • Для GMS 3.2 и более поздних версий: используйте self.close();

  • Для GMS 3.0 и 3.1 (с ошибкой): используйте обходной путь.

  • Для GMS 2.x: используйте self.close();

  • Для GMS 1.x: используйте self.GetFrameWindow().WindowClose(0);

person BmyGuest    schedule 31.01.2017

Да, в GMS 2.x вы должны использовать

self.close();

вместо

self.GetFrameWindow().WindowClose(0);

person BmyGuest    schedule 22.01.2015
comment
Как насчет GMS 3.x? само.закрыть(); больше не закрывает UIFrame в GMS 3.x, и сообщение об ошибке не выдается. - person KEVIVI; 10.06.2016
comment
@KEVIVI GMS 3.0 содержит ошибку, которая уже исправлена ​​в последней версии GMS 3.1. Эту проблему можно обойти с помощью немного сложной идеи: создайте отдельный поток, чтобы просто закрыть окно. Я могу опубликовать это в качестве примера здесь через мгновение .... - person BmyGuest; 31.01.2017