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 biv343 on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

VFP 'unresponsive' for 60 secs when closing MSCOMMLib.MSComm 3

David Higgs

Programmer
May 6, 2012
406
GB
My VFP application connects to my Amateur Radio Transceiver (via Serial COM Port 3) for CAT Control. CAT Control is a generic term used to describe how a PC can control the frequency and various other settings of a transceiver. The CAT commands are bi-directional. My application has run for a number of years without any ‘comms’ issues.

I’ve been looking at sharing the Transceiver (Serial COM Port 3) with VFP and another 3rd Party Application. I decided on using a Virtual Serial Port Emulator (VSPE) by https://eterlogic.com/products.vspe.html

I configured VSPE to allow my VFP application using Virtual Serial Port COM 10 to communicate with my Transceiver Serial Port COM 3. I intend using another 3rd Party Application on Virtual Serial Port COM 11.

When running VSPE, my VFP application (Virtual Serial Port COM 10) connects to my Transceiver (COM 3) and works as expected. However, I have an issue which I’ve not be able to resolve. When I exit my VFP application by clicking the ‘Exit Program’ Command Button VFP becomes ‘unresponsive’ for 60 secs before closing down.

VSPE Test

To eliminate any ‘code’ issues with my VFP application, I created a simple VFP Form with just three Command Buttons ‘Set Frequency 1’, ‘Set Frequency 2’ and ‘Exit Program’

I ran this VFP Form with no other Code, it opened and closed with no issues.

I then added an ‘ActiveX Control OLE Class MSCOMMLib.MSComm.1’ to the form.

I then ran the VFP Form again and when clicking the ‘Exit Program’ Command Button the application became ‘unresponsive’ for 60 Seconds and then closed.

The only time the problem (VFP being un-responsive for 60 Secs) seems to manifest itself is when I run VFP and VSPE together.

My VFP application works ok when connected directly to my Transceiver on Serial Port COM 3.

VSPE works ok with my Transceiver using other 3rd party applications.

Comms settings

Screenshot 2025-02-20 125149.png
Screenshot 2025-02-20 125249.png

Code:
* Command Button 1

thisform.transceiver.output = "FA003760000;"     && Set Transceiver Frequency 

* Command Button 2

thisform.transceiver.output = "FA007160000;"     && Set Transceiver Frequency 

* Command Button 'Exit Program'

thisform.transceiver.PortOpen = .F.    && Release Comm Port

thisform.Release
 
The only suggestion I have is to use the RemoveObject() method of the VSPE's parent control to first remove the control before you close the form.
 
Hi Greg,

Thank you for your reply; I'll take a look at your suggestion.
 
Hi Greg,

Having looked at the Properties of VSPE.SCX (see previous post) I'm not sure how to implement RemoveObject() on the ActiveX (ole control) named Transceiver in my case. It's probably me being a bit thick!
 
It's not an OCX method, it's a VFP method:

Code:
Thisform.RemoveObject("Transceiver")

If you put the ocx in a container or page of a pageframe, use the parent object (the container or the page, whatever) and call the RemoveObject method of that, i.e. the RemoveObject() method always only can remove objects directly on the level of the object, Thisform.RemoveObject() can't remove objects within pageframes, containers, etc, just objects directly on the form. As this is no visual control I assume you just put it directly onto the form.

It's actually holding on to a straw, but so simple that it's still worth trying. Removing the object is also done when releasing the form, as that removes all objects in the form release, from that persepctive there's nothing to expect from directly and explicitly removing the object. But it still may circumvent something that takes the 60 seconds. In the worst case, if this one RemoveObject takes most of the 60 seconds you actually know and could dig deeper about how to close down the COM port to make the object relese/remove faster. So for that matter measure how long the object removal takes:

Code:
lnStarttime = Seconds()
Thisform.RemoveObject("Transceiver")
lnEndTime=Seconds()
Messagebox("Tranceiver object removed in "+Transform(lnEndTime-lnStartTime)+" seconds."

You already are explicitly doing thisform.transceiver.PortOpen = .F. Well, PortOpen might just be a property to read, not to set, there might be a ClosePort method to do, instead. Whatever is causing the delay in release must have to do with closing connections and resources used by the OCX before it can actually finish. But it also might turn out anything else takes long.

If it turns out this does not take long but the form still needs long to release, then you suspected the wrong thing, just because it's the only unusual thing you don't have in other forms. That's would just turn out to be a hasty assumption, but you'll see. Then it would of course be innteresting to find out what takes so long, and SET COVERAGE might tell you that. The only downside is, that it only measures time code takes, so it would summarize all the time the form needs to release on the one line of code THISFORM.Release() and can't give an overview about detail times taken for each form control, unless there is code in destroy events that's also measured. Therefore explicitly removing objects and not letting this be done automatically can point out a bottleneck, as you can measure the time it takes to execute the RemoveObject call.
 
Last edited:
Chris,

Thank you for your reply; I was nearly there, I'd missed the quotes around Transceiver.

When I ran your code it took 60.025 secs to complete.

It's a strange problem because My App runs ok when using a standard Serial Comms Port, the issue only occurs when using a Virtual Serial Port (VSPE).

Code:
lnStarttime = Seconds()

Thisform.RemoveObject("Transceiver")

lnEndTime=Seconds()

Messagebox("Tranceiver object removed in " + Transform(lnEndTime-lnStartTime) + " seconds.")

SET COVERAGE TO

thisform.Release

0.000211,,test.set_freq_7160.click,2,d:\visual fox pro\projects\comms\forms\vspe.sct,1
0.000173,,test.set_freq_3760.click,2,d:\visual fox pro\projects\comms\forms\vspe.sct,1
0.000056,,test.closelogbook.click,2,d:\visual fox pro\projects\comms\forms\vspe.sct,1
60.028075,,test.closelogbook.click,4,d:\visual fox pro\projects\comms\forms\vspe.sct,1
0.000103,,test.closelogbook.click,6,d:\visual fox pro\projects\comms\forms\vspe.sct,1
3.790639,,test.closelogbook.click,8,d:\visual fox pro\projects\comms\forms\vspe.sct,1
0.000042,,test.closelogbook.click,10,d:\visual fox pro\projects\comms\forms\vspe.sct,1
 
Last edited:
So line number 4 in the click code is the RemoveObject, right?
Is there any code in the VSPE COMM port object Destroy event? I don't assume.

Now there's only one thing you can do: Dig into the documentation to find out how you're supposed to close the port and release it as quickly as can be done, i.e. the intended way to tidy up usage of ressources and connections etc. Because that's the only thing that causes that delay, isn't it?

You can do a little experimenting in designing a test form only with that OCX control, then don't open a port and just measure how long it takes to release, if that already takes long, it's nothing to do with closing the port. But if that runs fast, that's the baseline of relase time and you should be able to get near there.

I alkso wonder if you unintentionally create objects while the form runs and releasing them takes time. So you could just look at Thisform.Objects.Count at init of the form and at release of it to check that out.
 
I was nearly there, I'd missed the quotes around Transceiver.
On that, learn how to read intellisense information:
1740314920636.png
The c in front of ObjectName tells you that the parameter is a string of the object name, so "Transceiver" not Transceiver.

Here's a an example in contrast:
1740315000531.png
ADir expects you to write an array name directly, not in quotes. In this case even a name of an array to be created, not one that must alreaddy exist. It can exist and will be overwritten and extended, but that's details off topic. The intellisense has subtle differences, but what oyu need to specify is told to you by, when you know it.
 
Last edited:
So line number 4 in the click code is the RemoveObject, right?

That's correct.
Is there any code in the VSPE COMM port object Destroy event? I don't assume.
There is no code (Default) in the Destroy Event

I alkso wonder if you unintentionally create objects while the form runs and releasing them takes time. So you could just look at Thisform.Objects.Count at init of the form and at release of it to check that out.
I created the Test App to have the bare minimum of Code and Code alterations, but I will do the object counts. I will also carry out some more tests as you suggest.

I will also pay more attention to the 'intellisense information' now you pointed it out. As you say I should have noticed the 'c' .
 
You can do a little experimenting in designing a test form only with that OCX control, then don't open a port and just measure how long it takes to release, if that already takes long, it's nothing to do with closing the port. But if that runs fast, that's the baseline of release time and you should be able to get near there.

I designed a basic form, added an OCX control and a Command Button to close the form. The only thing I changed was the Comm Port to COM 10. I then ran the form and closed it using the Command Button; the Form closed instantaneously. I then ran the form with the Comm Port Open and on closing there was a 60 sec delay.

I'm thinking that the issue (whatever it is) maybe due to the fact that I'm trying to close a Virtual Serial Port and not a Hardware Serial COM Port.
 
I don't see that. But how is the driver configured? If the virtual nature of the port is the reason, does it remove the virtual port when you close it instead of just closing it?
I could see why that takes a minute. So if you open up the Device manager and look into (virtual) COM port devices, does it remove ports when you form closes?

As you can't see inside the process of removing the MSCOMMLib.MSCOMM control your only way of getting more details will be using procmon to look what runs when your form closes. Logging what procmon can monitor is hard, though. Usually, when you know you look for specific things like file related api calls, you can limit the logging, if you don't know what's done you'd have to go through a full logging. And then the problem also is synchronizing the procmon logging with the closing of the VFP form, starting short before closing and ending logging after the minute it takes. And then going through a minute of log data.
 
Could it be you have set the COM port into a mode waiting for incoming data? Then closing the port might be delayed in a timeout that seems to be configured to 60 seconds somewhere or by default. Before closing the port, you might need to set/unset some other properties modes of the COM port to be able to close it.
 
So if you open up the Device manager and look into (virtual) COM port devices, does it remove ports when you form closes?

No, the COM Ports (COM10,COM11) are still showing after VFP Closes.

Could it be you have set the COM port into a mode waiting for incoming data?

No, I don't think so. I placed the OCX control on the Form with minimal changes.

I've just carried a further some further tests using the test form. I now have 4 Command Buttons.
Code:
* Button 1 - check status of Com Port
MESSAGEBOX(thisform.TestComm.portOpen())

* Button 2 -
thisform.testComm.portOpen= .T.

* Button 3 -
thisform.testComm.portOpen= .F.

* Button 4 -
lnStarttime = Seconds()

Thisform.RemoveObject("TestComm")

lnEndTime=Seconds()

Messagebox("Object removed in " + Transform(lnEndTime-lnStartTime) + " seconds.")

thisform.release

I ran the form, check the status of Com Port (Command Button 1), Opened Com Port (Command Button 2) and then Closed Com Port (Command Button 3). When I clicked Command 3 the 60 sec delay occurred. Next, I click on Command 4 and the form closed instantaneously.

So, it would appear that the issue is with changing the status of the Com Port?
 
Well, did you try closing the form without closing the com port? I wouldn't expect a difference, becuase the coverage logging already showed the 60 seconds go into removing the object, which always happens.

So one ide idea circumventing to remove that object would be to add the MSCOMMlib.MsCOMM object to the screen instead of your form and keep it existing until you quit the application. That will then take 60 seconds.

Overall you will need to identify the reason for that timeout of 60 seconds, something is done and not reset that causes a timeout, it seems to me.
 
Well, did you try closing the form without closing the com port?

Yes, I did and still had the delay.

I'm still thinking on the lines that the issue is something to do with Virtual Port sharing. If I use the same Form and Comms setup on Serial Port COM3 there isn't a problem but as soon as I change to Virtual Serial Port COM 10 and use Virtual Port sharing (VSPE) I have the issue. When using Virtual Port sharing with the form open, I'm able to communicate with the Transceiver, it's only when I close the connection that I get the issue.

Thank you for your help, I very much appreciated it as I'm a little out of my depth. The VSPE team appear to be very helpful, so, with the results of the various tests I may well seek their opinion and see if they can offer any advice. None this affects the use of my application it's just that I wanted to include another application sharing the Com Port.
 
Well, the idea to put the MsCommLib.MsComm object to the screen instead of a form still would solve the problem, as this object can stay until you quit the application.
 
Last edited:
Well, the idea to put the MsCommLib.MsComm object to the screen instead of a form still would solve the problem, as this object can stay until you quit the application.

There lies another problem! When I drag the MsCommLib.MsComm object and drop it on the screen, it disappears off the form but doesn't show on the screen. I have removed SCREEN = OFF from config.fpw but still the same.
 
Hello,
I remember that many years ago we replaced mscomm with scomm32 due to problems on virtual ports (>8). Use was exactly the same (no code change)
Later on a friend informed me that its now freeware. Not sure whether its available anymore, we do not need it anymore.
Basically you may try another control.
 
Hello,
I remember that many years ago we replaced mscomm with scomm32 due to problems on virtual ports (>8). Use was exactly the same (no code change)
Later on a friend informed me that its now freeware. Not sure whether its available anymore, we do not need it anymore.
Basically you may try another control.
Hi Tom, Thank you for your reply. My App works ok with the Virtual Port COM 10 with the exception of closing the comm port. I will try using a lower port number and see if that helps.
 
There lies another problem! When I drag the MsCommLib.MsComm object and drop it on the screen, it disappears off the form but doesn't show on the screen. I have removed SCREEN = OFF from config.fpw but still the same.
You can't drop the control on the screen, as you never have the screen in designmode, but you can use _screen.addobject(), just like you can use removeobject.
 

Part and Inventory Search

Sponsor

Back
Top