如何从对象本身关闭 UIFrame window? (行为差异 GMS 1.x 到 GMS 2.x)
How to close a UIFrame window from the object itself? (Behavioral difference GMS 1.x to GMS 2.x)
在 GMS2.x 中,使用下面显示的代码关闭 UIFrame window 将导致 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);
是的,
在 GMS 2.x 中你必须使用
self.close();
而不是
self.GetFrameWindow().WindowClose(0);
这是 GMS 问题的扩展 3.X:
从本质上讲, 对于 GMS 3 也是正确的,但仅限于其版本 3.2(可能还有 GMS 3.1.2)。
早期版本的 GMS 3 有一个错误,正如 KEVIVI 在对答案的评论中指出的那样。
不过,对此有一个work-around解决方案,稍微复杂一点:
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();
对于 GMS 3.0 和 3.1(有错误):使用解决方法。
对于 GMS 2.x:使用 self.close();
对于 GMS 1.x:使用 self.GetFrameWindow().WindowClose(0);
在 GMS2.x 中,使用下面显示的代码关闭 UIFrame window 将导致 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);
是的, 在 GMS 2.x 中你必须使用
self.close();
而不是
self.GetFrameWindow().WindowClose(0);
这是 GMS 问题的扩展 3.X:
从本质上讲,
早期版本的 GMS 3 有一个错误,正如 KEVIVI 在对答案的评论中指出的那样。
不过,对此有一个work-around解决方案,稍微复杂一点:
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();
对于 GMS 3.0 和 3.1(有错误):使用解决方法。
对于 GMS 2.x:使用
self.close();
对于 GMS 1.x:使用
self.GetFrameWindow().WindowClose(0);