Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Changing Form WindowType from Modal to Modeless 1

Status
Not open for further replies.

ScottMcVt

Programmer
Apr 11, 2001
8
US
I am calling Microsoft's monthview activex object from the click event of a button on my modal form. The control seems to work only if the form is modeless, however. So I need to be able to make the form modeless just before popping up the calendar and back to modal after the user selects a date and the calendar closes. I've tried everything and I can't seem to make the form modeless. I have the following properties set on the form: WindowType - Modal(1), WindowState - Normal(0), ShowWindow - In Screen(Default).

Any clues???

Thanks

 
Hi ScottmcVt,

When a form is visible it is impossible to change the mode of a form. This means that the WindowState and WindowType are readonly properties and cannot be changed. If you want to change them the only way to do it is:

form1= CREATEOBJECT("....")

form1.Visible=.F.
form1.WindowState= <anything you want>
form1.Visible=.T.


Hope this helps.

JNC73


 

One workaround would be to make a copy of your modal form and set it to be modeless.

Then:-

DO FORM formA && Modal form

In cmdButton.Click or other event in formA put:-

THISFORM.Release
DO FORM formB WITH parameters && Modeless form

where parameters are .left,.top,.height etc

In cmdButton.Click or other event in formB put:-

THISFORM.Release
DO FORM formA WITH parameters && Modal form

where parameters are .left,.top,.height, date etc

The date is recovered by formB and you return to the modal form formA with the date as a parameter

Chris :)


 
Use the Show method to etermine if it is modal or modeless.

Form1.Show(1) && modal
Form1.Show(2) && modeless

HTH,
Weedz (Wietze Veld)
veld4663@exact.nl
The Netherlands

They cling emotionally to code and fix development rather than choosing practices based on analytical assesments of what works best.

After the GoldRush - Steve McConnell
 
It is possible to change the modality of a form after it has been originally displayed. Changing Modeless-to-Modal is as simple as HIDE(), then SHOW(1). Changing Modal-to-Modeless proves to be a bit more tricky because modality can't be changed until after execution returns to the method that invoked the modal state.

See the FAQ titled How can I make my form Modal/Modeless on the fly at:
Jon Hawkins
 
Appendum:

Just for clarification, JNC73's comment above, in regards to WindowType being read-only while the form is visible, is accurate. Attempting to change it directly will result in a 'property is read-only' error. Attempting to change it with the Show method will result in a 'cannot change modality of visible form' error.

However, the WindowState property is read/write at all times, regardless of the visibility of the form. Paste the following into a prg and run it for an illustration:

Code:
oForm=CreateObject('form')
oForm.visible=.T.
oForm.windowstate=2
wait window 'press any key to minimize'
oForm.windowstate = 1
wait window 'press any key to release'
oForm.release
release oForm
Jon Hawkins
 
Unfortunately, I need to change from Modal to Modeless and back again. I have not seen anyone doing that, so I'm going to assume it's impossible. Thanks anyway.

Scott McWherter
 
Scott

The workaround in the third post in this thread works, allowing you to change the form's status at will without any visual change to the form.

I suggest you try it before surrendering!

:) Chris
 
Chris, this workaround will flash visually.

Another suggestion, related to the ActiveX controls. I did not met yet any ActiveX control that requires modeless forms. I wondered, how modal state of the form is related to the behavior of the ActiveX? Did you tried such things as changing _VFP.AutoYield property and use of sys(2333)?

These are the first things you should try with ActiveX. Than find other workarounds.

Finally, what means &quot;I am calling Microsoft's monthview activex object from the click event of a button on my modal form&quot;.
- Do you create it in run-time and place on the same form where button is located?
- Do you call a separate form with this control?
- Do you have it on the form hidden and show this control when button clicked?

Try different technique also. There are many ways to do similar things in VFP.



Vlad Grynchyshyn
vgryn@softserve.lviv.ua
The professional level of programmer could be determined by level of stupidity of his/her bugs
 
Vlad

Chris, this workaround will flash visually

That is not the case, and if you test it you will see what I mean.

However it is possible to detect a barely perceptible flicker from the controls if there are a number of them.

Testing with a single command button produced no flicker whatsoever.

The alternative to releasing the one form before calling the next form is to place the following code in the .init events of the forms.

FOR n = 1 TO _SCREEN.FormCount
[tab]IF _SCREEN.Forms[n].Name = [FormA] && A or B
[tab][tab]_SCREEN.Forms[n].Release()
[tab]ENDI
ENDFOR

Chris :)
 
Hi
Start a new modeless Form and add 2 buttons, name them Modal and Modeless
In the Valid of Model insert this code
Code:
ThisForm.Hide()
ThisForm.Show(1) && Show Modal
ThisForm.Show(2) && Show Modeless
In the Valid of Modeless insert this code
Code:
ThisForm.Hide()
It may look strange to show modal and modeless in the same valid event of Modal button, but the trick is
When you switch the state of a form from Modeless to Modal at this time you form will be in a wait state meaning
this line of code
Code:
ThisForm.Show(2) && Show Modeless
will never be executed unless you break this wait state and this is what is HIDE() in the other valid doing.
To make this more clear, lets write the first valid like that
Code:
ThisForm.Hide()
ThisForm.Show(1) && Show Modal
WIAT WIND &quot;Hi there&quot;
ThisForm.Show(2) && Show Modeless
When you click this command your form will be Modal and will enter a wait state waiting for your user to communicate with the GUI, but you will never see the wait window unless you click the Modeless button to break the wait state. At this time the rest of you code will be executed which is a wait window and command to FOX to show this form Modeless.
Anyway, one drawback of (of many)for this solution is that your form will flash very quickly according to the Hide().
if you decided to take this as a solution, your problem will be find a method in this ActiveX control suitable to execute the Modal method
and another one for modeless. Although this will work and basically answer your q about switching state but if I were you I will never do that and deliver my form to the users after I spent the last 2000 years developing and debugging with this ugly flashing thing. Beside it doesn’t look like a clean solution to me.
Meaning I will have to repeat the same game over and over every time I want to use this control in any form and clutter your form with a lot of code. IF some day I want to fix a bug or make enhancement, good luck.

Well, the problem is this spoiled ActiveX control needs its container to be modal, [you said so].
Our problem is, we don't want to switch state of our form
we want to keep it as it is.

Ok, let’s cheat and lie -WOW-, I mean God forgive us all.

We will convince this control that its container is modal but at the same time we will keep our form modeless. How?? Very simple
The idea is to define a Visual class library PopCal.VCX and add two classes to it.
1-Class popup_Calendar based on FORM which will contain the ActiveX control contained in a MODAL FROM.
2-Class cmd_date based on command button, which will call popup_Calendar
Start modifying the first class which is the form. Add a Month View control to this form, change the name of this control to OleCalendar, right click this control and select properties, make sure you set the right propertied for your control like the Start Of Week etc…
Set your form to be Modal (technically, you don’t have to). In the Init of your form add this code
Code:
*// Let the form decide its proper size automatically.
THIS.WIDTH=THISFORM.OleCalendar.WIDTH
THIS.HEIGHT=THISFORM.OleCalendar. HEIGHT
In the DateDblClick of the ActiveX control add this code
Code:
*// The Parent object in the next line of code references the container of the ActiveX control
*// Which is your modal form. ReturnSelecteDate() is a method you will add to this form
THIS.PARENT.ReturnSelecteDate()
THIS.PARENT.HIDE()
Now you need to add one method and one property to your form (the container of the ActiveX control)
ReturnSelecteDate method and SelectedDate property
Now open the ReturnSelecteDate and insert this code
Code:
LOCAL lcDate,lcMonth,lcDay,lcYear
lcMonth = ALLTRIM(STR(THIS.OleCalendar.Month,2))
lcDay   = ALLTRIM(STR(THIS.OleCalendar.Day,2)) 
lcYear  = ALLTRIM(STR(THIS.OleCalendar.Year,4)) 
lcDate  = '{^'+  lcYear + '-' + lcMonth + '-' + lcDay + '}'
THIS.SelectedDate = &lcDate
Now this class is done, you can test drive it from your command window
Code:
SET CLASSLIBRARY TO GETFILE()    &&Locate your PopCal.VCX file
OX=CREATEOBJECT(“Popup_Calendar”)
OX.SHOW(1)        && SHOW AS MODAL, THAT IS WHY (technically, you don’t have to)
*// Now Dbl click any date you want, the calendar will disappear 
WAIT WIND DTOC(OX.SelectedDate)
OX=NULL
Very simple, so much fun. Now it is the time for the real work, although you can call this calendar from any form just like what you did from your command window, as a programmer you still want to feel more control over this calendar, right?
Some thing like a command button in my form has a connection with the text box, when I click this button I will have my calendar in the right position and I don’t need to worry about any thing(after I already did).
Well, you can go ahead and add the cmd_Date class to you PopCal.VCX class library
Code:
CREATE CLASS cmd_date OF PopCal AS COMMANDBUTTON
Why is this command button for???
1- Instantiate an instance of the popup_calendar class.
2- Automatically position the calendar properly relative to the associated object (The text box we will update its value with whatever returned date).
3- If any valid date in the associated object, initialize the calendar with this date.
4- When the calendar is closed update the associated object.
5- Destroy the instance of this calendar.
Since this is a lot of code and I want to run to my bed before I collapse. I will leave the implementation of this command button to you or if you want the class library, feel free to send me E-mail and I will send to you.
Hope this will help
Walid Magd
Engwam@Hotmail.com
 
I use this ActiveX without problems!
I think that you have wrong setup for the ShowWindow property of the new form,one tyhat hosts the ActiveX.

This setup depends if you are or not in runtime-exe mode, more exactly on your Application.Visible property's value.

I think ShowWindow = InTopLevel Form will solve your issue!

Liviu
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top