Sunday, August 14, 2005

The day before yesterday I was surfing my blogroll and came across an interesting post by Calvin Hsia -- "Enable crop and zooming in on your digital photograph display form". It was using GDI+ in a Visual FoxPro form and, since I am writing a series of articles for FoxTalk on the subject, it caught my eye. One of the things I liked the most about Calvin's entry was the idea of using a shape in order to create a rubberband selection area; basically a rectangle with a dotted line border that you may have noticed once or twice in various Windows applications (still don't know what I'm talking about? Go to your desktop and left click and drag a rubberband selection area around some icons -- or just look at the screen shot below). I came away from Calvin's entry thinking he had a great idea, so I've implemented my own and expanded on it.

I created a class called "rubberband" that can be added through code to any form during runtime. It facilitates a rubberband selector when the user drags their mouse over the surface of the form. This class has several features that I thought would be useful to a developer.

  • The rubberband is reversible, meaning it can follow the mouse no matter which way the user maybe dragging their selection area.
  • It provides feedback when the selection is started, when the selection area is changed, and also when the selection has been completed.
  • It has an optional feature that will allow you to get a collection of the selected objects as well as a collection of objects that aren't selected based on the selection area. This is turned on or off via a property of the class named "selectobjects"
  • Left or right mouse button can be specified as the active mouse button that creates the rubberband selection areas.
  • Optional keys (shift, alt, or ctrl) can also be specified as required during the selection (such as, the user must hold the alt key down while dragging with the left mouse button depressed).

The class makes liberal use of Visual FoxPro's Bindevent function to monitor the user's activity on the form's surface. And, the example form I'm including in the download uses bindevents as well to receive feedback from the rubberband class. All-in-all, it turned out to be a pretty workable solution and implementation of Calvin Hsia's idea.

One of the problems I ran into however, was when the mouse was over a particular object on the form, the form obviously didn't receive the mouse events... so the rubberband just stops. The solution for this example was to send the mouse events up the chain to the parent form. However, in perhaps a future blog entry I will use the vfpex.fll with its BindEventEx/UnBindEventEx functions (if interested you can read my earlier blog post regarding vfpex.fll) in order to create a mouse hook and keyboard hook in order to facilitate this without having to send mouseevents up to the parent object. I'm not sure if BindEventEx would be needed or not, perhaps Visual FoxPro 9.0's BindEvent would be enough... never hit something with a sledgehammer when a simple tap will do.

Before I go, I just want to say that I highly recommend Calvin Hsia's WebLog, there's a lot of great content there... especially in the archives. Who knows, if enough people take an interest in his blog, he might give us more secrets. :) Now, without any further ado here's the usual screen shot and download link. (oh, and by the way, that weird thing with the fonts getting bolder as the form repaints definitely needs to be fixed in Visual FoxPro 9.0 -- I've left it in this example to maybe draw some more attention to it, see the checkboxes as you play with the example).

Download Rubberband Selector Class and Example Form (9 KB approx.)

Sunday, August 14, 2005 11:35:01 AM (Central Daylight Time, UTC-05:00)  #    Comments [3]
Sunday, August 14, 2005 1:53:10 PM (Central Daylight Time, UTC-05:00)
Craig,

Regarding the "that weird thing with the fonts getting bolder as the form repaints definitely needs to be fixed" ... this has been a constant source of irritation for me because, IMO, it compromises the "fit and finish" of the applications that we deliver with VFP 9.

I've posted about this behavior on Tek-Tips, Profox and the UT with various theories and workarounds. One solution that works in my development environment (not yet tested in other environments) is to turn off VFP's off-screen bitmaps via sys( 602, 0 ).

I've been reluctant to use this technique in production code because of my "sense" that disabling off-screen bitmaps may be buggy. By "sense" I am refering to the comments of others (Tek-Tips, Profox, UT, Wiki) regarding this function as it relates to using VFP with Terminal Services or Citrix. The un-scientific concencus appears to be to NOT turn-off off-screen bitmaps, even in TS/Citrix environments, if you are running VFP 7 or later. My conclusion is that disabling off-screen bitmaps is really a hack for VFP 6 apps running under TS/Citrix.

As an aside, would turning off off-screen bitmaps have an impact (negative performance or incompatibilities) on the double buffering techniques you are writing about in FoxTalk?

Thanks again for your contributions to the VFP community.

Malcolm
Sunday, August 14, 2005 2:45:09 PM (Central Daylight Time, UTC-05:00)
Craig,

Some ideas:

1. Re: "when the mouse was over a particular object on the form, the form obviously didn't receive the mouse events... so the rubberband just stops. The solution for this example was to send the mouse events up the chain to the parent form."

Rather than having each object in a rubberband's region pass its mouse events up to its parent, could you place a transparent shape over the entire rubberband region and use that to capture mouse events? This transparent shape could be "visible" in rubberband mode and hidden when the rubberband event finishes.

2. When in rubberband mode, it might be nice to constrain the mouse to the rubberband region itself. Anatoliy has documented how to do this via the ClipCursor() Win32 API.

Clipping mouse cursor area
http://www.news2news.com/vfp/?example=80&function=118

I'm enjoying your code. Very fun!

Malcolm
Monday, August 15, 2005 2:42:58 AM (Central Daylight Time, UTC-05:00)
Yes, the code that is repainting those labels is off by just a smidgeon, so the labels appear to become bold, only worse. I expect this will be fixed in Visual FoxPro 9.0 (the Fox Team usually does a good job of listening to problems developers are encountering and this is definitely a problem).

As for your idea of creating a transparent shape just during the selection... that's a good one. I'll explore it.

I'll also look into that solution out on news2news, that sounds like an excellent addition to the class. I'll check this out as well. Thanks for the comments and the useful ideas Malcolm, they're appreciated.
Name
E-mail
(will show your gravatar icon)
Home page

Comment (Some html is allowed: a@href@title, b, blockquote@cite, em, i, strike, strong, sub, super, u)  

Enter the code shown (prevents robots):


 

Archive

<October 2008>
SunMonTueWedThuFriSat
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678