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

How to avoid the waiting cursor while timer event runs

Status
Not open for further replies.

Irwin1985

Programmer
Feb 2, 2017
44
ES
Hi everybody,

I have a control Timer running each second in my form but when it runs the form shows a wait icon as pointer. How can i avoid or hide that mouse Pointer?

I tried this:

Procedure Timer
This.Enabled = .F.
Thisform.MousePointer = 0
ThisForm.Lockscreen = .T.
&& Here goes my Proccess
Thisform.LockScreen = .F.
This.Enabled = .T.
EndProc

Thanks...!
 
Put the mouse pinter back to normal after unlocking the screen:

Code:
[highlight #FCE94F]Local lnOldMousePointer[/highlight]
This.Enabled = .F.
[highlight #FCE94F]lnOldMousePointer = Thisform.MousePointer[/highlight]
Thisform.MousePointer = 0
ThisForm.Lockscreen = .T.
&& Here goes my Proccess
Thisform.LockScreen = .F.
[highlight #FCE94F]Thisform.MousePointer = lnOldMousePointer[/highlight]
This.Enabled = .T.

There may be a good reason to change the mouse pointer. It's not only visual sugar in case the timer process takes a little longer, it also prevents any interaction with the locked form, which may cause unwanted interruptions and interferences with the now priority process before unlocking the form again. So you do keep the setting of the mouse pointer to 0, but simply set it back to whatever it was beforehand.

Bye, Olaf.
 
Hi Olaf, I tried your sample but the problem continues.

I've tried severals samples like:

Declare Integer ShowCursor in User32 Long lShow
ShowCursor(.F.)
...

SET CURSOR OFF
...

MousePointer = 13
...
MousePointer = 99
...
MouseIcon = "myIcon.cur"
...
Application.AutoYield = .F.
...
SYS(2002)
...

Any suggestion?
 
If you really just want to AVOID a wait icon as cursor icon, there is nothing to do. Neither lock the screen nor change the mousepointer.

Would it be that easy? I think you want something else, but you still haven't told us, what exactly do you want to avoid, or better yet:

What do you want to happen?

If you use a timer class from a framework, this might itself already affect LockScreen and/or MousePointer and your code overlaps with the inherited behaviour in an unwanted manner.

As you tried AutoYield: Is OLE involved with this? How?

You have to reveal more about your problem, it seems if you want a qualified solution.

Looking up the reference on MousePointer 0 is the default anyway, and means the real mouse pointer is up to the control you hover. What is that forms MousePointer value to start with? Is that 11? That would explain an hours glass/wrist watch or in modern UI circle icon.

Bye, Olaf.
 
Thanks Olaf,

Here is my situation, I have a custom button based on a container. I've created a property called "SkipFor" and I want the control gets enabled or disabled automatically without writting any code.

In the "Refresh" method I put this:

If !Empty(This.SkipFor)
Local lcMacro
lcMacro = This.SkipFor
This.Enabled = &lcMacro
Else &&!Empty(This.SkipFor)
Endif &&!Empty(This.SkipFor)

In my form I have 6 Buttons: (Create, Delete, Edit, Save, Cancel, Exit) and I call the Refresh methods on my control timer.

Any better idea?
 
Your code will only ever set This.Enabled = .T., because .F. is empty and .t. is not empty (!Empty).

It also is just a very complicated form of wanting to do:

Code:
This.Enabled = This.SkipFor

And that in itself points out you don't need a SkipFor property, you could simply use the Enabled property itself.

Furthermore, you don't need a timer, you could simply set enabled as necessary in whatever situation and then call Thisform.Refrresh().

Bye, Olaf

 
I recommend you do this without a timer. Instead, set up your form so that changes you make cause your code that sets Enabled status to run.

If you're putting this code in the Refresh method of the individual controls, then you just need to make sure that the form-level Refresh is called after changes that could affect enabled status.

Incidentally, you don't need to use a macro. Use EVAL() instead; it'll be a little faster:

Code:
IF NOT EMPTY(This.SkipFor)
   This.Enabled = EVAL(This.SkipFor)
ENDIF

(Olaf, his SkipFor property contains an expression to be evaluated when things change.)

Tamar
 
Thanks Tamar,

I am migrating the native buttons of a form to my custom buttons but I do not want to touch the code to put enabled = .T. Or .F. Depending on the original button

What I'm doing is hiding the original buttons and leaving the new buttons in place, so I want my new buttons to be enabled or not depending on the original buttons and that is automatically.

I thought about doing it with a timer but it is not the best thing.

An example of what I want are the buttons of a ribbon type menu that are activated or deactivated depending on the actions that are performed on a form.

Another example is the context menu of editing (Copy, Paste, Undo, etc) that is activated or not depending on the mouse action.

Thank you...!
 
Thanks Tamar, I don't see where SkipFor came from, but an expression in it makes more sense.

Irwin said:
What I'm doing is hiding the original buttons
Well, if you hide controls, they automatically are disabled. Setting their Enabled property has no influence whatsoever.

As far as I understand you want all previous code acting on the old buttons to stay as is and let that be reflected to your new buttons. One part of the problem is you're using containers instead of buttons. They don't have the overall same properties and behaviour as buttons.

Your best friend will be BINDEVENT to bind to the events of code acting on the old buttons enabled or other properties, but there is no general binding to all properties. Defining a THIS_Access methods in the old buttons could help, but it's hard to explain in just a few words in a post. Maybe read up on it here and come back with questions:
The nice thing is, you know the accessed member and have its name as a parameter. In the simplest case, you can redirect all access to old button properties by returning THISFORM.yournewbutton1,2,3, instead of THIS within the old button THIS_ACCESS method. It's hardly doable, if the buttons are the native base button class and have no class, then a first step would be exchanging the buttons with button classes, to be able to ad a THIS_ACCESS method, it does not exist by default.

And to let your new button click cause the old button click code, you need a reverse binding.

It really is simpler to keep it at buttons and do whatever cosmetic changes via the button.picture property and not new containers.

Bye, Olaf.
 
Okay, so the new buttons may not be on the form itself, right? Then, you need the form's Refresh method to call the Refresh method of whatever contains the new buttons.

In my applications, I have the ability to connect a toolbar with a form (not put it on the form, but have a relationship). The form class's custom UpdateEnabled method, which is called from Refresh, calls the custom UpdateEnabled method of the toolbar, to ensure the buttons get properly updated.
The toolbar's UpdateEnabled method loops through all its buttons and checks whether to enable or disable.

Tamar
 
I was able to solve my trouble by adding BINDEVENT() on each commandbutton instead timer control.

Thanks for the advices...!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top