October 06, 2022, 12:09:41 PM


IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!

8. Windows vs Dialogs

Started by LarryMc, October 19, 2014, 12:44:25 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.


I probably should have covered this earlier but now is as good a time as any.

When we first set up our tutorial project we made the main form a WINDOW and not a DIALOG.  Why?
Things you can do with a WINDOW that you can't do with a DIALOG(without doing some workarounds):

  • Change the color of the client area of the window
  • Write text directly in the client area of the window
  • Draw lines, circles, and rectangles directly in the client area of the window
  • Display images directly in the client area of the window

So, for just those reasons alone I suggest that a WINDOW is always the parent of your application.
However, if you don't mind not having the features listed above, or, you don't mind dealing with the workaround coding to get some of those features then go ahead and use a DIALOG.

Trust me, go with a WINDOW.

Now, let's talk a little about child windows and dialogs.
In the tutorial so far we have setup up a child dialog with dlg1.
And we are all familiar with dialogs like "Open File", ""Save As", "Create Executable", "FontRequest", ColorRequest", and the list goes on and on.

What do we like about dialogs?

  • All their code is self contained
  • When implemented properly they keep us from having a mess of open windows/dialogs at one time.
  • They are not restricted to the client area of the parent.  They can actually be larger than their parent and cover it entirely while they are open.
  • When open, they do not create an additional icon in the task bar.

Can we use a child window instead of a child dialog, and why would we?

Yes we can; for the various reasons cited above for using a WINDOW as the parent of the application.

You can create its own source file and pattern it exactly like dialog1.iwb;

  • An Init... routine to create the window
  • The handler for the child window
  • And, based upon the specific needs the control id constants can be placed either at the beginning of this file or they can be made Project Global by placing them in the constants section of the globals.iwb file.
  • Placing the window declaration in the 'projectglobal "on"' section of the globals.iwb file
However there are several adjustments that need to be made.
When creating the window in the Init... routine we have to use the @hidden style flag so the child window isn't displayed all the time.
When we are ready to show the window we can't use DOMODAL because that is only for dialogs..
We have to use the SHOWWINDOW command with the @SWSHOW flag.

Since unlike the Dialog, the child window actually exist when the OPENWINDOW command is executed in our Init... routine we can preload the controls in the child window before displaying it with the SHOWWINDOW command.

After showing the child window and doing whatever it was designed to do it is time to quit displaying it.
I purposely didn't say 'close' the window for a reason.

We know that when we close a dialog with CLOSEDIALOG dlg1 that the structure created in the Init... routine is still there but the controls and their contents aren't really there anymore.  So the next time we use DOMODAL we start with a clean slate of control contents that can be preloaded and configured in the @IDINITDIALOG portion of the message handler.

With the child window we have two options, based upon our desired end.
We can simply use SHOWWINDOW with the @SWHIDE flag.
If we choose this option then showing the window again the window contents will appear exactly like they did when we hid it.
Using this technique is not usually used when we are simply trying to duplicate what I call a normal dialog.

We normally use this technique when we have multiple modes of operation, each with its own child window, that has to fit in the same client area. A typical example would be an application where we have a tab control in the client area of the parent. As a tab is selected the child window associated with the previously selected tab is hidden and the child window associated with the newly selected tab is displayed.

Our other option is to use the CLOSEWINDOW command.
We would use this technique when we are trying to make our child window work like a true dialog as closely as possible.
When the CLOSEWINDOW command is issued all the contents of our window are lost(cleared) because the child window no longer exists. If we use this technique we will have to execute our Init... routine and call the SHOWWINDOW function in order to redisplay the child window.

When using child windows in place of dialogs there is one other consideration.
Remember we said that when displaying a dialog with DOMODAL it meant the parent was disabled until the dialog was closed.
DOMODAL doesn't work with child windows but we still need that disabling of the parent.
We do that by using the EnableWindow API to disable the parent right before we use the SHOWWINDOW command to show the child window and when we are ready to hide/close our child window we use the same API to re-enable our parent window.

My advice:
Don't use child windows to replace 'normal' dialogs unless, for some reason, you absolutely have to.  Doing so just makes things needlessly more complicated. Also, it is important to remember that a child window has to fit inside the client area of the parent unlike a dialog.

It is perfectly acceptable for child windows to be used as discussed above with the tab control or similar applications like displaying several child windows at the same time in the parent's client area.

All the techniques described above result in only one icon being displayed on the task bar.
There is something else that can be done though but it can become a real pain to make it work well for the End User of your application.  We know your parent window has no parent.  But there is nothing from keeping you from creating other windows that have no parent in your application.
You can show and hide them as discussed above, put the code in their own source file and do pretty much everything else we described above.
To use these parentless windows will require that you use the EnableWindow API to disable/enable the main parent window as described above.  You'll have to make sure that every possible way to close your non-parent window is covered and forces the main window to be enabled.
Also, when these windows are created you will need to make sure to use the @TOPMOST style flag or they can get buried under other windows on your screen.
The plus of this technique is that these windows can be as big as your screen and placed anywhere on your screen.

The major drawback, besides the extra coding involved, is that every window you create like this in your application will create a new additional icon on your task bar.  I personally hate that.

I STRONGLY suggest you have only one parent level window in your application unless you are a glutton for punishment.

This completes 8. Windows vs Dialogs
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library