Opening a wxFileDialog from within a wxDialog

BlitzMax Modules Forums/Brucey's Modules/Opening a wxFileDialog from within a wxDialog

I'm trying to get a wxFileDialog to open in response to a button click within a modal wxDialog.

In OSX, the code below seems to work, although the wxDialogs need to be wxSTAY_ON_TOP for some reason.

But in XP and Vista, I can't get it to work at all. Any help/ideas really, really appreciated :-)

Code below opens a test file dialog. Then, in response to both dialog's button clicks, another file dialog should open .

SuperStrict

Framework wx.wxApp
Import wx.wxFrame
Import wx.wxDialog
Import wx.wxButton
Import wx.wxFileDialog

New MyApp.run()

Type MyApp Extends wxApp

	Field Window:TTestWindow
	
	Method OnInit:Int()
					
		Window = New TTestWindow
		Window.Create(, , "Window", -1, -1, 550, 550)
		Window.Center()
		Window.Show()
		Window.Refresh(True)
				
		Return True
		
	End Method

End Type

Type TTestWindow Extends wxFrame
	
	Field Dialog:TTestDialog
		
	Method OnInit()
		
		'	Open up a file requester 
		Local file_dialog:wxFileDialog = New wxFileDialog.Create(Self, "File dialog 1: Parent is the wxFrame",Null,Null, "*.*", wxFD_OPEN|wxFD_DEFAULT_STYLE)
	
		If file_dialog.ShowModal() <>  wxID_OK Then DebugLog "User selected cancel from the file dialog"
		
		Dialog = TTestDialog(New TTestDialog.Create_(Self, wxID_ANY,"1st dialog"))',,,,, wxDEFAULT_DIALOG_STYLE | wxSTAY_ON_TOP))
		Dialog.ShowModal()
							
	End Method

End Type

Type TTestDialog Extends wxDialog

	Field Button:TTestButton
	Field Dialog2:TTestDialog2
	
	Method OnInit()
		Button = TTestButton(New TTestButton.Create(Self, wxID_OK, "OK"))
		Button.ConnectAny(wxEVT_COMMAND_BUTTON_CLICKED, _OnClick, Null, Self)
	End Method

	Method OnClick(_event:wxCommandEvent)
	
		DebugLog "Dialog 1 Clicked! - attempting to open a dialog"
		
		'	Open up a file requester 
		Local file_dialog:wxFileDialog = New wxFileDialog.Create(Self, "File dialog 2: Parent is Dialog 1",Null,Null, "*.*", wxFD_OPEN|wxFD_DEFAULT_STYLE)
		
		If file_dialog.ShowModal() <>  wxID_OK Then DebugLog "User selected cancel from the file dialog"
		
		Dialog2 =TTestDialog2( New TTestDialog2.Create_(Self, wxID_ANY,"2nd dialog"))',,,,, wxDEFAULT_DIALOG_STYLE | wxSTAY_ON_TOP) )
		Dialog2.ShowModal()
		
	End Method		
	
	Function _OnClick(_event:wxEvent)
	
		'	parent is the Object of the click, sink is the Object that handles the event.
	
		TTestDialog(_event.sink).OnClick(wxCommandEvent(_event))
	End Function
	
End Type

Type TTestDialog2 Extends wxDialog

	Field Button:TTestButton
		
	Method OnInit()
		Button = TTestButton(New TTestButton.Create(Self, wxID_OK, "2nd OK"))
		Button.ConnectAny(wxEVT_COMMAND_BUTTON_CLICKED, _OnClick, Null, Self)
	End Method

	Method OnClick(_event:wxCommandEvent)
	
		DebugLog "Clicked! Dialog 2 - attempting to open a file dialog"
	
		'	Open up a file requester 
		Local file_dialog:wxFileDialog = New wxFileDialog.Create(Self, "File dialog 3: Choose a file",Null,Null, "*.*", wxFD_OPEN|wxFD_DEFAULT_STYLE)
	
		If file_dialog.ShowModal() <>  wxID_OK Then DebugLog "User selected cancel from the file dialog"
		
	
	End Method		
	
	Function _OnClick(_event:wxEvent)
		'	parent is the Object of the click, sink is the Object that handles the event.
		TTestDialog2(_event.sink).OnClick(wxCommandEvent(_event))
	End Function
	
End Type


Type TTestButton Extends wxButton
End Type


You might find this thread quite interesting :

http://groups.google.com/group/comp.soft-sys.wxwindows/browse_thread/thread/1a11027b13a41fcb/176bf086fd1ce389?lnk=raot

Specifically the very long post from April 16.

Hey Brucey :-)

Mmmm thanks for this - but I'm not sure what to make of it all I confess...

It seems to be saying that I can fix the wxSTAY_ON_TOP issue with OSX modal dialogs by performing the equivalent of:

 OSStatus err = ChangeWindowAttributes((WindowRef)m_macWindow,  
kWindowHideOnSuspendAttribute, 0); 


Trouble is a) I don't know how to do this in wxMax (I can't find a ChangeWindowAttributes() Method?) and b) My issue in this instance is actually regarding Win32 rather than OS X, which seemed to be what the linked thread was all about.

Simply put - still stuck! :-)

Hang on - this is interesting... bordering on amusing. Wrapping the wxFileDialog within a wxDialog seems to circumvent the issue! ie

Type TDummyFileDialog Extends wxDialog

	Field FileDialog:wxFileDialog

	Method OnInit()

		'	Open up a file requester 
		FileDialog = New wxFileDialog.Create(Self, "File dialog 1: Parent is the wxFrame",Null,Null, "*.*", wxFD_OPEN|wxFD_DEFAULT_STYLE)
	
		If FileDialog.ShowModal() <>  wxID_OK Then DebugLog "User selected cancel from the file dialog"	

	End Method
End Type


see following code for demo:

SuperStrict

Framework wx.wxApp
Import wx.wxFrame
Import wx.wxDialog
Import wx.wxButton
Import wx.wxFileDialog

New MyApp.run()



Type MyApp Extends wxApp

	Field Window:TTestWindow
	
	Method OnInit:Int()
					
		Window = New TTestWindow
		Window.Create(, , "Window", -1, -1, 550, 550)
		Window.Center()
		Window.Show()
		Window.Refresh(True)
				
		Return True
		
	End Method

End Type

Type TTestWindow Extends wxFrame
	
	Field Dialog:TTestDialog
		
	Method OnInit()
	
'		ChangeWindowAttributes(1 Shl 24)
		
		
		Dialog = TTestDialog(New TTestDialog.Create_(Self, wxID_ANY,"1st dialog"))',,,,, wxDEFAULT_DIALOG_STYLE | wxSTAY_ON_TOP))
		Dialog.ShowModal()
							
	End Method

End Type

Type TTestDialog Extends wxDialog

	Field Button:TTestButton
	Field Dialog2:TTestDialog2
	
	Method OnInit()
	
		Button = TTestButton(New TTestButton.Create(Self, wxID_OK, "OK"))
		Button.ConnectAny(wxEVT_COMMAND_BUTTON_CLICKED, _OnClick, Null, Self)
	End Method

	Method OnClick(_event:wxCommandEvent)
	
		DebugLog "Dialog 1 Clicked! - attempting to open a dialog"
		
		New TDummyFileDialog.Create_(Self, wxID_ANY,"Dummy dialog")
		
		Dialog2 =TTestDialog2( New TTestDialog2.Create_(Self, wxID_ANY,"2nd dialog"))',,,,, wxDEFAULT_DIALOG_STYLE | wxSTAY_ON_TOP) )
		Dialog2.ShowModal()
		
	End Method		
	
	Function _OnClick(_event:wxEvent)
	
		'	parent is the Object of the click, sink is the Object that handles the event.
	
		TTestDialog(_event.sink).OnClick(wxCommandEvent(_event))
	End Function
	
End Type

Type TTestDialog2 Extends wxDialog

	Field Button:TTestButton
		
	Method OnInit()
		Button = TTestButton(New TTestButton.Create(Self, wxID_OK, "2nd OK"))
		Button.ConnectAny(wxEVT_COMMAND_BUTTON_CLICKED, _OnClick, Null, Self)
	End Method

	Method OnClick(_event:wxCommandEvent)
	
		DebugLog "Clicked! Dialog 2 - attempting to open a file dialog"
	
		'	Open up a file requester 
		'Local file_dialog:wxFileDialog = New wxFileDialog.Create(Self, "File dialog 3: Choose a file",Null,Null, "*.*", wxFD_OPEN|wxFD_DEFAULT_STYLE)
		'If file_dialog.ShowModal() <>  wxID_OK Then DebugLog "User selected cancel from the file dialog"
		New TDummyFileDialog.Create_(Self, wxID_ANY,"Dummy dialog 2")

	
	End Method		
	
	Function _OnClick(_event:wxEvent)
		'	parent is the Object of the click, sink is the Object that handles the event.
		TTestDialog2(_event.sink).OnClick(wxCommandEvent(_event))
	End Function
	
End Type


Type TTestButton Extends wxButton
End Type


Type TDummyFileDialog Extends wxDialog

	Field FileDialog:wxFileDialog

	Method OnInit()

		'	Open up a file requester 
		FileDialog = New wxFileDialog.Create(Self, "File dialog 1: Parent is the wxFrame",Null,Null, "*.*", wxFD_OPEN|wxFD_DEFAULT_STYLE)
	
		If FileDialog.ShowModal() <>  wxID_OK Then DebugLog "User selected cancel from the file dialog"	

	End Method
End Type


Surprise, surprise - the above hack is unreliable (to put it politely).

Righty...

You'll need to update to the latest wxMax for this stuff...

SuperStrict

Framework wx.wxApp
Import wx.wxFrame
Import wx.wxDialog
Import wx.wxButton
Import wx.wxFileDialog

New MyApp.run()

Type MyApp Extends wxApp

	Field Window:TTestWindow
	
	Method OnInit:Int()
					
		Window = New TTestWindow
		Window.Create(, , "Window", -1, -1, 550, 550)
		Window.Center()
		Window.Show()
		Window.Refresh(True)
				
		Return True
		
	End Method

End Type

Type TTestWindow Extends wxFrame
	
	Field Dialog:TTestDialog
		
	Method OnInit()
		
		'	Open up a file requester 
		Local file_dialog:wxFileDialog = New wxFileDialog.Create(Self, "File dialog 1: Parent is the wxFrame",Null,Null, "*.*", wxFD_OPEN|wxFD_DEFAULT_STYLE)
	
		If file_dialog.ShowModal() <>  wxID_OK Then DebugLog "User selected cancel from the file dialog"
		
		Dialog = TTestDialog(New TTestDialog.Create_(Self, wxID_ANY,"1st dialog"))',,,,, wxDEFAULT_DIALOG_STYLE | wxSTAY_ON_TOP))
		Dialog.ShowModal()
							
	End Method

End Type

Type TTestDialog Extends wxDialog

	Field Button:TTestButton
	Field Dialog2:TTestDialog2
	
	Method OnInit()
		Button = TTestButton(New TTestButton.Create(Self, wxID_OK, "OK"))
		Button.ConnectAny(wxEVT_COMMAND_BUTTON_CLICKED, _OnClick, Null, Self)
	End Method

	Method OnClick(_event:wxCommandEvent)
	
		DebugLog "Dialog 1 Clicked! - attempting to open a dialog"
		
		'	Open up a file requester 
		Local file_dialog:wxFileDialog = New wxFileDialog.Create(Self, "File dialog 2: Parent is Dialog 1",Null,Null, "*.*", wxFD_OPEN|wxFD_DEFAULT_STYLE)
		
		If file_dialog.ShowModal() <>  wxID_OK Then DebugLog "User selected cancel from the file dialog"
		
		Dialog2 =TTestDialog2( New TTestDialog2.Create_(Self, wxID_ANY,"2nd dialog"))',,,,, wxDEFAULT_DIALOG_STYLE | wxSTAY_ON_TOP) )
		Dialog2.ShowModal()
		
	End Method		
	
	Function _OnClick(_event:wxEvent)
	
		'	parent is the Object of the click, sink is the Object that handles the event.
	
		TTestDialog(_event.sink).OnClick(wxCommandEvent(_event))
	End Function
	
	Method ShowModal()
		HIWindowChangeClass(MacGetWindowRef(), 4);
		Super.ShowModal()
	End Method
	
End Type

Extern
	Function HIWindowChangeClass:Int(handle:Byte Ptr, style:Int)
End Extern

Type TTestDialog2 Extends wxDialog

	Field Button:TTestButton
		
	Method OnInit()
		Button = TTestButton(New TTestButton.Create(Self, wxID_OK, "2nd OK"))
		Button.ConnectAny(wxEVT_COMMAND_BUTTON_CLICKED, _OnClick, Null, Self)
	End Method

	Method OnClick(_event:wxCommandEvent)
	
		DebugLog "Clicked! Dialog 2 - attempting to open a file dialog"
	
		'	Open up a file requester 
		Local file_dialog:wxFileDialog = New wxFileDialog.Create(Self, "File dialog 3: Choose a file",Null,Null, "*.*", wxFD_OPEN|wxFD_DEFAULT_STYLE)
	
		If file_dialog.ShowModal() <>  wxID_OK Then DebugLog "User selected cancel from the file dialog"
		
	
	End Method		
	
	Function _OnClick(_event:wxEvent)
		'	parent is the Object of the click, sink is the Object that handles the event.
		TTestDialog2(_event.sink).OnClick(wxCommandEvent(_event))
	End Function

	Method ShowModal()
		HIWindowChangeClass(MacGetWindowRef(), 4);
		Super.ShowModal()
	End Method

End Type


Type TTestButton Extends wxButton
End Type


This is your original code as posted at the top with some additions, based on the thread I linked to previously.
Notably, the dialogs now override ShowModal :
	Method ShowModal()
		HIWindowChangeClass(MacGetWindowRef(), 4);
		Super.ShowModal()
	End Method

"4" is kMovableModalWindowClass.

And for HIWindowChange you need to add :
Extern
	Function HIWindowChangeClass:Int(handle:Byte Ptr, style:Int)
End Extern


Now the windows appear to handle modality in a more expected way.
However, the close/min/max buttons are now disabled. But then, a Modal dialog tends to work a bit differently to a normal document window, so this may not be a problem. (there may well be a way to re-enable those in flags).

See how you get on with that...

:o)

Well here's a big yay! from me as you've managed to solve a different os x bug that's been bothering me for ages. Your new ShowModal() override means I no longer have to use wxSTAY_ON_TOP on osx wxDialogs.

The sharky fin of the win32 wxFileDialog issue is however, still out there. Circling...