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!

SYS(1500) Toolbar functionality coordination 3

Status
Not open for further replies.

tamayok

Programmer
Sep 4, 2001
99
PR
Hello to all,

I have written a simple TOOLBAR to provide the most basic editing functions (Cut/Copy/Paste).It works as expected, nonetheless...

How can these buttons on the toolbar automatically DISABLE or ENABLE according to applicability? How do I make them respond as SYS(1500) _MEDIT menu?

I have no problem enabling/disabling toolbar options for application-specific functions... What am I missing?

Sample code:
Code:
PUBLIC oTbr
oTbr = CreateObject("MyToolBar")
oTbr.Visible = .t.

DEFINE CLASS MyToolBar as ToolBar
  	CAPTION = "My ToolBar"

    ADD OBJECT cmdEditCut AS CommandButton WITH ;
    CAPTION = "Cut"

    ADD OBJECT cmdEditCopy AS CommandButton WITH ;
	CAPTION = "Copy"

    ADD OBJECT cmdEditPaste AS CommandButton WITH ;
    CAPTION = "Paste"

	***********************

	PROCEDURE cmdEditCut.CLICK
		SYS(1500, '_MED_CUT', '_MEDIT')

	PROCEDURE cmdEditCopy.CLICK
		SYS(1500, '_MED_COPY', '_MEDIT')

	PROCEDURE cmdEditPaste.CLICK
		SYS(1500, '_MED_PASTE', '_MEDIT')
		* KEYBOARD '{CTRL+V}' && This also works!
ENDDEFINE
 
Create some functions that will return .T. or .F. and then use those for the skip on the menu items...

For CUT or COPY it would be whether the current control on the active form has a sellength property and is > 0

For PASTE it would be whether the _cliptext variable is not empty

...the reason you would need a function, at least for the CUT and COPY skips would be because you'll need to use PEMSTATUS to find out whether the current control is even one with a sellength, such as a textbox or editbox.

boyd.gif

SweetPotato Software Website
My Blog
 
CraigsBoyd,

Many thanks for your prompt reply and direction...

How does the main VFP menu know to enable/disable these edit functions? Isin't there a way to intercept the native handling of this?... Since one does not indicate SKIP FOR conditions on a menu (_MEDIT), I would hope there is some other way of doing this...

I thought of writing code that would verify _CLIPTEXT, etc. but then realized, how am I going to fire it?... Calling it at every InteractiveChange, adding a Timer...

I still need help with this!!!

Thanks for your time and expertise,

Kenneth
San Juan, Puerto Rico - USA

---

PD: I am hoping very much to be able to attend the SouthWest DevCon... It be great to meet you and other VFP greats there!!!
 
You don't need to fire it, the menu will check its elements at the moment that it is invoked (dropped down) and will disable items based on your skip for settings. In your function you could check the _screen.activeform.activecontrol. So, the check would go something like this... (untested, written here only):

Function SkipCutCopy()
if Type("_screen.ActiveForm.ActiveControl.name") = "C"
if PEMSTATUS(_screen.ActiveForm.ActiveControl,"Sellength",5)
return _screen.ActiveForm.ActiveControl.Sellength = 0
endif
endif
return .T.
endfunc

...and then for the paste skip for it would just be whether the _cliptext is empty...

Empty(_cliptext)

...as far as I know there is no easy way to hook into whatever mechanism/routine the _medit is using in order to facilitate what you want, but the Skip for options as outlined above will give you what you need I believe.

I sure hope you are able to make it to Southwest Fox. It will be the Fox conference of the year for sure. I look forward to meeting you if you can make it.


boyd.gif

SweetPotato Software Website
My Blog
 

Kenneth,

I've often faced exactly the same problem. As Craig points out, it is easy enough to deal with for menus, but not for toolbars. The trouble with toolbars is that there is no event that you can trap to test the status of the clipboard.

My solution is to add a timer to the toolbar. Let it fire, say, every 500 ms. In the Timer event, test _Cliptext, etc., and then enable / disable the buttons accordingly.

For the paste button, you need to enable it if _Cliptext is not empty. For cut and copy, find the active control in the active form; if it has a SelLength property, and if that property is greater than 0, enable cut and copy, otherwise disable them.

This is not an ideal solution, and I have never been sure what the best timer interval is. With 500 ms, you will get a delay of up to half a second before the toolbar appears to react, but with a smaller interval I would worry about the effect on overall performance.

I'd be interested in hearing what solution you eventually adopt.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

My sites:
Visual FoxPro (www.ml-consult.demon.co.uk)
Crystal Reports (www.ml-crystal.com)
 
Mike said:
As Craig points out, it is easy enough to deal with for menus, but not for toolbars...

LOL! Well, perhaps I need to wear my glasses when replying to threads. I failed to notice until Mike just replied that your original post was asking about a toolbar. The basic code for to use as criteria remains the same, but the rest of what I said is now rubbish.

Mike's suggestion of a timer is a viable solution, but as he pointed out it can suffer from performance issues or issues of timeliness.

Interesting problem to be sure. If you have subclassed the base classes appropriately, you could add code to the textbox and editbox subclasses your project uses so that they would monitor changes to the sellength (and appropriately disable the toolbar buttons when their lostfocus fires). However, this doesn't solve the problem of the _cliptext which could be getting its data from an outside source.

My only thought on the _cliptext is that it is either getting the value from one of your subclassed textboxes or editboxes and thus the subclasses could handle it, or in the case of the user switching to another application and copying/cutting some text, you would have the opportunity to appropriately enable the paste button when your application receives focus again... such as in the activate event.

Using these two techniques should cover the bases (unless I am missing something again) and also preclude the use of a timer class and the issues that it brings with it.

boyd.gif

SweetPotato Software Website
My Blog
 
Thank you both!!!

I will work with this and evaluate how to implement the solution... but with your help, I am almost there!

Resorting to timers does come with a price, so I will need to worry about turning it off in data-loops (SQLs, scans...) for it not to degrade performance. I imagine any brief interval in interactive forms should be ok (as your adopted practice of 500 ms).

_ClipText will need to be checked not only for being empty but for being suitable to the target object... Luckily, FoxTools.FLL has a function dealing with this concern ISCLIPFMT().

At least there are ways to do it, no doubt.

I am constantly impressed with the Fox, particularly this last version... I often think VFP is the best Microsoft product... Best ReturnOnInvestment for sure!!

Thanks again.

--------

PD: Mike, I always read your articles in FoxPro Advisor... Keep them coming! Craig, I have in my to-do list, the testing/implementation of your Encrypting functions.
 

Kenneth,

As I mentioned earlier, I've never been really happy to use a timer in that way. In fact, in my latest application, I simply ignore the issue and don't bother to grey out inactive buttons. So far, the users haven't complained, but this too is not an ideal solution.

I'd be interested to hear what you eventually decide. (And thanks for the kind words about my articles.)

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

My sites:
Visual FoxPro (www.ml-consult.demon.co.uk)
Crystal Reports (www.ml-crystal.com)
 
I published an article on this topic in the November '97 issue of FoxPro advisor. To be honest, I no longer remember my solution, but it's in the article.

Tamar
 
Tamar,

Big fan of your work as well! Thanks for helping me out... Indeed, I looked for my "Complete 1997 FoxPro Advisor CD" and found your article entitled "Smart Toolbar Techniques"...

I just browsed through your article and will eagerly work with your solution tonight... The approach seems to be to create a timer referenced by a property of the toolbar, adding a method to it that evaluates all of its buttons to store a logical cSkipFor value... Apparently SKPBAR() is at the center of the solution...

Will try to do all of this... THANKS!!!

 
... The 1997 Advisor CD does not seem to have the correct "Resource Disk"... It has a couple of .PRGs "GENRATES.PRG" and "TESTRATE.PRG" under the folder "\ADV_CRD\FA9711\GRANR23"...

Wonder if all the source code needed is featured on the article and I can simply type it.
 
Tamar,

The source code appears under "\ADV_CRD\FA9711\GRANT57"...

VERY HAPPY!! Will test tonight and will report...

THANKS AGAIN!
 
Well, it's beauty!

The toolbar defined by Tamar's 1997 ClassLib (documented in Advisor Magazine) works beautifully while consuming acceptable resources. I used the class in the Resource CD since their where many places where code snippets would have had to have been keyed.

To update the appearance of the 1997 toolbar, I just updated the icon/picture property and the SpecialEffect property to HotTracking. I temporarily removed the Open and Save buttons from Tamar's class since my forms would need some re-working to comply.

I agree with Tamar's remark in the article that the key to this solution is the reference to the SKPBAR() function. Each command button in the toolbar maintains a custom property that in turn calls skpbar("_medit",_med_???). The button's Click event would have the expected instruction SYS(1500,"_MED_???","_MEDIT"). Therefore _MEDIT options must be available in the menu for this to work.

I am now just looking to see if there is an easy/clean way to suspend the timer at the start of long data procedures and resume it's functionality when they are finished, in order to optimize performance.

Stars to all involved!!!
 

Tamar,

I published an article on this topic in the November '97 issue of FoxPro advisor. To be honest, I no longer remember my solution

I find it interesting that you don't remember the solution, but you do recall the data of the issue. Some kind of selective memory at work here? <g>

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

My sites:
Visual FoxPro (www.ml-consult.demon.co.uk)
Crystal Reports (www.ml-crystal.com)
 
Nah, I have a list of my articles on my website, so I could find it by title, but I couldn't remember how I'd done it.

Tamar
 
Just wanted to comment on the files on the Advisor CD. GRANR23 is the file for the Q&A column in that issue: GRANR translates to "Granor and Roche". GRANT is the code for my articles alone.

Tamar
 
Hi!

Just wanted to report that fine-tuning the resource consumption of Tamar's toolbar is extremely easy... There's a variable on the toolbar class (nUpdateTimer? - not at the office!), that is read by the timer.

My appl. has a combination of data-entry/interactive forms, as well as, some extended procedures (SQLs, loops, etc). I have two basic ON SHUTDOWN procedures to handle these differences. Taking advantage of that, I simply placed a IIF statement to keep the interval at 1000* m during "regular" application unless the ON("SHUTDOWN") call is to the alternate procedure. In that case, the timer is set to 60000 (1 min.) since the toolbar serves no purpose at that non-interactive time.

I highly recommend looking for that '97 Advisor Mag. resouce disk. Tamar was hitting homeruns even back then!

Kenneth,
San Juan, Puerto Rico - USA

----

*1 sec seems fine - 1/2 a second is perhaps too much, besides few type and get the mouse that fast!
 

I just re-read Tamar's article.

Tamar, it was reassuring to see that you described the same technique that I have adopted myself (although you described it much better than I could have done).

However, I note you didn't recommend a value for the timer. I've been using 500 ms, but it looks a bit odd -- the toolbar seems to react sluggishly to the user's actions. I could try a smaller interval but I would worry about the effect on overall performance. Maybe that's not an issue -- I don't know.

Kenneth's using 1 second. Anyone else got any thoughts?

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

My sites:
Visual FoxPro (www.ml-consult.demon.co.uk)
Crystal Reports (www.ml-crystal.com)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top