I am attempting to call System.Windows.Forms.ColorDialog from within an older ABL screen (though I'm developing within the 10.2B IDE). I am using the ColorDialog object instead of the standard call to "SYSTEM-DIALOG COLOR" because I want to set up the Custom Colors prior to showing the window. My problem is that in order to call the ColorDialog from within the ABL screen I have to include it as part of a WAIT-FOR statement (otherwise I get an error that says, "you can only call showdialog as part of a wait-for statement"). I cannot figure how to then get the System.Windows.Forms.DialogResult object that ColorDialog returns.
Here is my code:
DEFINE VARIABLE dialogObj AS CLASS System.Windows.Forms.ColorDialog NO-UNDO.
DEFINE VARIABLE dialogRes AS System.Windows.Forms.DialogResult NO-UNDO.
DEFINE VARIABLE tmpColor AS System.Drawing.Color NO-UNDO.
DEFINE VARIABLE tmpInt AS INTEGER EXTENT 16 NO-UNDO.
ASSIGN
dialogObj = NEW System.Windows.Forms.ColorDialog()
dialogObj:AllowFullOpen = TRUE
dialogObj:FullOpen = TRUE
dialogObj:ShowHelp = FALSE
tmpInt[1] = 14215660 /* <-- I've cut out code that fills in values for the other 15 array elements...*/
dialogObj:CustomColors = tmpInt.
WAIT-FOR dialogObj:ShowDialog().
ASSIGN tmpColor = dialogObj:Color.
So by the end of that code, I do have the Color that the user has selected but I have no indication of whether the user closed the ColorDialog window by clicking on the OK or the CANCEL button. Normally I would be able to grab that by doing:
ASSIGN dialogRes = dialogObj:ShowDialog().
However, because I need to wrap that into a WAIT-FOR statement, I can't do an ASSIGN statement to get that returning value. Can anyone help me out?
Thanks
Use the SET option of the WAIT-FOR Statement.
That sounds like what I'm looking for but I can't find any mention of a SET option in the help for WAIT-FOR. Can you give me an example of how to use it? Thank you!
fresh schrieb:
That sounds like what I'm looking for but I can't find any mention of a SET option in the help for WAIT-FOR. Can you give me an example of how to use it? Thank you!
In your case this should work:
WAIT-FOR dialogObj:ShowDialog() SET dialogRes .
That should be mentioned in the GUI for .NET developers guide somewhere - the online doc seems not to mention that.
Ah, I was looking at the older ABL help. You're right, the help for the .NET WAIT-FOR has a SET option. So according to the help files there are two WAIT-FOR statements, one that's ABL only (which does not have a SET option) and one that's for .NET and ABL (which does have a SET option).
I tried the following code:
WAIT-FOR dialogObj:ShowDialog( ) SET dialogRes.
It compiles, and the code runs. However the variable dialogRes never gets its value set/updated by the ShowDialog call. If I message out its value after the return from ShowDialog, dialogRes still has its default value of "none," regardless of whether I click on the OK or CANCEL button to close the dialog window:
WAIT-FOR dialogObj:ShowDialog( ) SET dialogRes.
MESSAGE dialogRes:ToString() VIEW-AS ALERT-BOX.
My best guess is that the code is using the older WAIT-FOR which is ignoring the SET option, though at this point I'm unclear on how to force it to recognize it as a .NET WAIT-FOR.
Hmh. This works for me:
DEFINE VARIABLE dialogObj AS CLASS System.Windows.Forms.ColorDialog NO-UNDO.
DEFINE VARIABLE dialogRes AS System.Windows.Forms.DialogResult NO-UNDO.
dialogObj = NEW System.Windows.Forms.ColorDialog () .
WAIT-FOR dialogObj:ShowDialog () SET dialogRes .
MESSAGE dialogRes:ToString()
VIEW-AS ALERT-BOX INFO BUTTONS OK.
Returns OK or Cancel depending on the button I press. Tested this on 10.2B03, Windows 7, x64.
If the above code does not work for you, you should call tech support (or post a full sample).
When I run your code (similar set up as you: Windows 7, x64, though I'm on 10.2B02), the reference to dialogRes:ToString() raises the following error presumably because the SET is being ignored for whatever reason:
Invalid handle. Not initialized or points to a deleted object. (3135)
I'll see if anyone in my office is on 10.2B03 and if so I'll see if that makes any difference. Otherwise I may submit it to tech support.
Thanks again for all of your help.
Just to add to that, if I run that code directly from a Procedure Editor it does work properly and returns the expected value of OK or CANCEL. The problem occurs when I try to run it from a procedure (or trigger block) defined within an ABL .w file.
Tried it from an event handler in a GUI for .NET Form. Works like a charm.
You should definitively get in touch with tech support.
fresh wrote:
Just to add to that, if I run that code directly from a Procedure Editor it does work properly and returns the expected value of OK or CANCEL. The problem occurs when I try to run it from a procedure (or trigger block) defined within an ABL .w file.
What's the WAIT-FOR in the ABL window?
-- peter
What's the WAIT-FOR in the ABL window?
Good point. And I think the right question should be what's the topmost (and hopefully only) WAIT-FOR (that's not related to modal dialogs) in the application.
Should probably be a WAIT-FOR System.Windows.Forms.Application:Run ().
Has been discussed in this forum a couple of times. However if that would be the root cause for the WAIT-FOR dialogRef:ShowDialog () SET dialogResult not working, I'd consider it a bug.
You guys are right, the topmost WAIT-FOR seems to be a contributing factor in the SET not working.
The way that our application is set up, we have a .NET .cls file as the main screen which makes calls out to various ABL .w files. The only WAIT-FOR statement is within the .cls file, which gets called when the .cls is first instantiated:
WAIT-FOR System.Windows.Forms.Application:Run (UIForm).
Each .w is called as a persistent procedure, so the .w's don't have a WAIT-FOR statement within them. We have it set up this way so that we can have multiple .w's open and active at one time.
I did try adding the following line to the .w that is using the color system dialog:
WAIT-FOR "U1" OF {&WINDOW-NAME}.
When I add that in, the statement WAIT-FOR dialogRef:ShowDialog () SET dialogResult does properly make use of the SET option. Unfortunately adding the WAIT-FOR "U1" causes other problems with the .w because we're running it as a persistent procedure. So I may just have to look for a different approach to this color dialog.
WAIT-FOR System.Windows.Forms.Application:Run (UIForm).
...
So I may just have to look for a different approach to this color dialog.
Call tech support. If your one and only WAIT-FOR (with the exception of the modal dialog) is already initiating the .NET message loop there is no excuse for the malfunction that you are experiencing.
Was this ever fixed?
Not sure, but there was a case recently where the dialog itself was deleted in the destructor (delete object this-object) , so the handle became invalid .. something to look out for
I can reproduce the problem if the .w has the following trigger defined;
ON ENTRY OF {&WINDOW-NAME}
DO:
END.