Can events be added to a New DesktopWindow?

I would like to have a message dialog just like MessageBox:
except that it can close itself when it sees the Deactivate event and
is created from code rather than from an instance of an existing window.

Is this possible with New DesktopWindow?
Can events and accompanying code be added to a window or buttons that have been created this way?

Thanks-

I have seen the examples of creating a window from code ( Making desktopwindow at runtime with controls inside? ), but there seems to be some bugs, like the Close button will not appear.

The missing Close button would not be a show stopper if I could get
Var myNewButton As DesktopButton = New DesktopButton
myNewButton.Cancel=True <—to work.

  1. First, create a window with the objects you want to display in your message.

  2. Add a method to send the data to the new screen.

  3. You can create this window anywhere with this code:



Var MyWindow As New Mensaje
MyWindow.Set_Values("Titulo","Este es el mensaje que quiero dar")
MyWindow.Show



1 Like

Yes, thanks. It looks like an instance of a window created in the IDE has to be used for this purpose. I was looking to see if there is a way to sense events in a window created using a method like the one below.

//Button method to create new window from DestopWindow
Var myWindow As DesktopWindow= New DesktopWindow
myWindow.Type=DesktopWindow.Types.Floating
myWindow.Title = “Testing a Window”
myWindow.Top = 200
myWindow.Left = 400
myWindow.Height = 500
myWindow.Width = 400
myWindow.Visible = True
myWindow.HasCloseButton=True  ’ * The button does not appear *

Var myMessage As New DesktopTextArea
myMessage.Text= “How to get this window to close when it Deactivates” _
+EndOfLine+“or when myNewButton responds to the Enter key” _
+EndOfLine+“or the Escape key, had myNewButton.Cancel been set”
myMessage.Visible=True
myMessage.top=10
myMessage.Left=10
myMessage.Width=380
myMessage.Height=300
myMessage.MultiLine=True
myWindow.AddControl(myMessage)

Var myNewButton As DesktopButton = New DesktopButton
myNewButton.Default=True
myNewButton.top=400
myNewButton.Left=60
myNewButton.Width=60
myNewButton.Height=60
myNewButton.Visible=True
myNewButton.Caption=“Close”
myWindow.AddControl(myNewButton)

myWindow.Show

You’re fighting a battle you can’t win.

Making things more complicated.

It’s better to think in terms of objects.

myWindow
myMessage
myNewButton

The objects above have everything they need to be one object in their own right. From a design perspective, creating a class is also the best approach.

The class’s sole purpose is to be a message window that replaces MessageBox.

My recommendation is to convert everything you’ve done into a class. Then, instantiate it as I explained earlier.

Important note. All events must be handled within the same class.

maybe you look for AddHandler / RemoveHandler if you create objects at runtime

the event always comes with sender object as first method argument.

Step 1



Var myMessage As New DesktopTextArea
myMessage.Text = "How to get this window to close when it Deactivates"+EndOfLine+"or when myNewButton responds to the Enter key"
'myMessage.Text= "How to get this window to close when it Deactivates”+EndOfLine+"or when myNewButton responds to the Enter key" +EndOfLine+"or the Escape key, had myNewButton.Cancel been set."
myMessage.Visible=True
myMessage.top=10
myMessage.Left=10
myMessage.Width=380
myMessage.Height=300
myMessage.MultiLine=True


Var myNewButton As DesktopButton = New DesktopButton
myNewButton.Default=True
myNewButton.top=400
myNewButton.Left=60
myNewButton.Width=60
myNewButton.Caption="Press Me"
AddHandler myNewButton.Pressed, AddressOf MyMethod


//Button method to create new window from DestopWindow
Var myWindow As DesktopWindow= New DesktopWindow
myWindow.Type=DesktopWindow.Types.Floating
myWindow.Title = "Testing a Window"
myWindow.Top = 200
myWindow.Left = 400
myWindow.Height = 500
myWindow.Width = 400
myWindow.Visible = True
myWindow.AddControl(myMessage)
myWindow.AddControl(myNewButton)


Step 2

Public Sub MyMethod(sender As DesktopButton)
  
  MessageBox("Hello !!!  I hit the button")
  
End Sub

What about using a Declare ?

Great ideas. I’m now aware of AddHandler. Declare would work if there is a more suitable OS MessageBox to call?

This code does what I am looking for, in that the window has a message, will close without having to click somewhere inside the window, and all is handled in one short method. (I’m not completely comfortable with the way it gets closed.)

Also, the delegate appears to be the only parameter that can be passed, so the message can’t be changed which defeats the purpose of this being used as a MessageBox replacement. Creating a window in the IDE is still looking to be the best option.

Public Sub MsgWin(optional Sender As DesktopWindow)
If Sender=Nil Then
Var myMessage As New DesktopTextArea
myMessage.Text=“Message still has to be hard coded…”
myMessage.Visible=True
myMessage.top=10
myMessage.Left=10
myMessage.Width=380
myMessage.Height=300
myMessage.MultiLine=True

' Var myNewButton not needed in this case
 
Var myWindow As DesktopWindow= New DesktopWindow
myWindow.Type=DesktopWindow.Types.Floating
myWindow.Title = "Testing a Window"
myWindow.Top = 200
myWindow.Left = 400
myWindow.Height = 500
myWindow.Width = 400
myWindow.Visible = True
myWindow.AddControl(myMessage)
' myWindow.AddControl(myNewButton)
AddHandler myWindow.Deactivated, AddressOf MsgWin 

Else
’ myWindow does not exist here, so taking a chance on window placement
App.WindowAt(app.WindowCount-2).Close

End If

End Sub
1 Like

To do this, just add the Timer object.

Tried adding a timer, but that results in an error since Timer is not a DesktopUIControl.
Also, the timer’s Period, like the message, would have to be hard-coded since parameters can’t be passed to the method MsgWin.

Var myTimer As Timer = New Timer
myTimer.Period=1000
myTimer.Enabled=True
myTimer.RunMode= Timer.RunModes.Single

App.MsgWin, line 26
Parameter “control” expects class DesktopUIControl, but this is class Timer.
myWindow.AddControl(myTimer)

Goodness, this approach has you repeatedly getting stuck, doesn’t it. Let me suggest a different approach.

Design your window in the IDE. Add in all the controls you want and give them meaningful names - in this example, myMessageField is a DesktopTextField and myTimer is a DesktopTimer.

Importantly, set your window’s Visible property to false. That way, when you create the window, it won’t be immediately visible.

Your timer’s Action event will have code to hide the window:

Visible=false

Add a method to your window named InitAndShow:

Method InitAndShow(message as string, durationSeconds as integer)

In this method, you will set up the window’s controls, show it on the screen, and start the timer:

myMessageField.Text = message

Visible=true

myTimer.Period=1000*durationSeconds

To use this window, do this:

myMessageDisplayer = new MessageDisplayWindow

myMessageDisplayer.InitAndShow(“hello world”, 10)

This is a pretty common pattern when dealing with creating windows of all sorts. It’s easy to see how you would add more parameters to the InitAndShow method to enable more functionality, such as setting the title of the window to something meaningful to the user.

try Timer.CallLater

@ Keith Culotta

as a suggestion

this way can be more simplified into a shared method of this class:

MessageDisplayWindow.InitAndShow(“hello world”, 10)

and the new object will be created inside of the shared method and could also returned if needed.

the second argument could be optional too:

InitAndShow(msg As String, Optional t As Integer = 10)

I was wondering how far a single method creating a window “built from nothing” could be taken.

The window and controls can be created, properties can be set, but events appear to be out of reach for the most part. A single event can be made useable with AddHandler. The method (MsgWin) can have no additional parameters. A reference to the window that was created seems unattainable. So, as has been pointed out, this single method approach is not nearly as flexible as employing a (single) window built in the IDE, where all these issues disappear.

A window constructed in code like that seems to me more a curiosity than a generally useful technique. Perhaps I’m just old school - this wasn’t even possible in older versions of Xojo/REALbasic - but the IDE has a pretty good window editor and the resulting window is much more flexible in terms of how you code it up and use it. I just don’t see the appeal.

1 Like

It does look that way. I thought the NewDesktopWindow, AddControl, AddHandler, AddEtc… might be purposed to create lightweight alternatives to some UI windows.

AddControl might be useful in certain dynamic UI situations. And if you pull it all together you might be able to do some interesting loadable-from-file UI stuff. But there wouldn’t be anything lightweight about needing to write all the code to construct a window from scratch. An IDE-designed window is almost certainly going to be the easier path if you aren’t looking at super dynamic user interface elements.

And as for AddHandler - this really should be avoided in any circumstance where it can be avoided. It makes your code much less analyzable because event handlers constructed in this way aren’t visible in the IDE; you have to track down all the places in code where it might be happening, and that could be extremely difficult if they are widespread. You can’t even put a break in the debugger to catch the event before it is handled by the code defined by AddHandler. I understand that there are situations where AddHandler is the most convenient way to go, and that’s a valid decision, but I do think that most mainstream code shouldn’t be using it. It really sidesteps the event model presented by the Xojo IDE.

if you need something modular, you can also use container controls with self defined events.
a form designer is very useful, i will never miss it.

And you’re absolutely right.

This approach is not the best way. Neither are object-oriented designers.

The option that works for both design and code maintenance is using classes or containers.

Are you not interested in continuing to use OOP?

Still interested.

I have a module containing useful methods that I can drop into apps. The hope was to add a method which would supply the message window. Since the window class is better suited, I’ll have two things to drop into apps.

1 Like