WINAPI & VFP Internals

Neat Solutions HomeFoxtools HomeFoxQuill HomeVFPX Projects HomeMiscellaneous HomeWINAPI & VFP INternals HomeNews HomeBasics HomeTips&Tricks HomeToolbox HomeComplex Controls Home


The Scope Resolution Operator | Into The Void | The Madlen Effect | ADSs, Hard Links & Junctions | How to Tame an Editor | How to Tame a Debugger | Unbreakable Objects Revisited | Corral Your Libraries | Two-Faced Properties | Private Affairs | The Unknown Species

WINAPI And VFP Internals

Calling into the Windows API using 'self-declared' WINAPI calls always was a true adventure … in the early days this seemed reserved for a skilled group of C/C++ programmers, I never belonged to. Today, we have excellent support, for example, through using the VFPX VFP2C32 Project.

Intro

I do believe that there still is a huge number of qualified and fully skilled VFP developers out there that have no idea, and they also don't care, about most WINAPI function calls. They are used to solve all challenges of their business domains writing pure VFP code only. Good Boys!

Do it Your Own Way

It's alright for me not to use WINAPI calls, if you can solve your problems without them in a reasonable time, creating code that runs fast enough to make your boss happy. But within the (problem-) domain of this blog, we would be stranded sooner or later without the assistance of the underlying operation system.

On The Other Hand…

Sometimes, constructing C-structures and passing them to Windows functions using referenced VFP strings, sounds like a mission to mars to me… At least in those precious moments, when I luckily could unearth some unknown/forgotten native VFP feature! Inevitably, an old saying comes to my mind: "Why must we targeting the stars as long as we haven't found all treasures of earth?" hmm, that's a pretty free-style translation.

Content of This Thread

FoxPro's behavior is full of oddities. Luckily, most of us will never stumble upon most of them… But wait, there is another VFP developer 'species'THOSE, who are haunting THEM! This section is especially made for all those VFP-Hackers – Welcome!

We will put the main focus on VFP here, not on how to define and execute WINAPI calls only, at least, to a certain extend. There are enough little treasures buried inside VFP to be raised. Sometimes oddities have to be moved to (or viewed from) another application context first, before they render useful. In other words, you might better think: "What else could I do with this bug?", instead of: "How can I code a work-around?" in the first place! Remember, a bug must not be your enemy, but can be an occasion for you to discover something new and useful, at least sometimes…


The Scope Resolution Operator

Scope Resolution OperatorUsing VFP's Scope Resolution Operator definitely is my least used method invocation strategy. Sounds familiar, right? The only thing that is written about the Scope Resolution Operator is, that it is used to call a method of its parent class. And then, all examples show an almost identical calling scheme: a method named Click() calls another method named Click() on its ancestor class. After that, one is advised to better use the DoDefault() method instead. I'm really no fan of conspiracy theories, but… ;-) Go and read the whole truth by yourself…


Into The Void

Into The Void  link

What if I would have asked you, if it's possible to really return NOTHING from a method? I mean, not that 'little' .NULL. value, but a real .VOID. one!? What would you have answered? Is it possible, and if so, what could it be good for?
Basically, a voided property value in VFP is one without a value AND without a type! Indeed, I found a special way to corrupt the internal type member of a VFP value structure using a native VFP method; let's say, by invoking it "a little bit outside of the recommended implementation guidelines"!


The Madlen Effect

The Madlen Effect link

I worked together with a VFP colleague for two years; her name was Madlen. Madlen discovered a remarkable VFP feature while debugging some weird side effects, that were produced by exact that 'feature'. Thus, it is not my discovery, but let's give honor to whom honor is due. Obviously, Madlen don't find enough time to share here new knowledge with the VFP community beside here daily work, and allowed me liberally to post about her findings. I have to state that this VFP 'feature' was absolutely new to me, and all of my former colleagues, too. That's why I supposed that even today scarcely anybody knows about it.

What's it all about?

Did you ever wondered about why temporary VFP cursors can have long field names? I mean, these guys are common free tables! VFP maintains long field names only for its DBC-bound "database tables", right? If we are able to make use of long field names, maybe it is possible to enable other DBC-only features, too? What's about implementing triggers on temporary tables? If it can it be done, how can we achieve that? And what can we (ab)use it for? …


ADSs, Hard Links & Junctions

ADSs, Hard Links & Junctions

Did you ever heard about the Delorean Copy DeLorean Copy? The link on the left leads you to the very interesting page of Mr. Schinagl from Austria. He is working on his Link Shell Extensions since 1999! Please read his enlightening, very thoroughly written documentation first, before we dive deeper into how we can use theses things from within our VFP code! If you prefer even more technically biased documentation, let me recommend this page FlexHEX Resources: NTFS Hard Links, Directory Junctions, and Window Shortcuts! It is full of detailed technical information, written from the viewpoint of a software developer who had developed the ultimate Hex-Editor, which is able to deal with raw hard drive data!

I will show you how to bootstrap/generate whole sets of classes at any level with the help of some very small PRG-based generators. Chief attraction: All PEMs, class–, and inheritance-definitions, as well as all module compositions are based on simple TXT-files and directory entries of a NTFS-file system. Okay, okay, naturally, they are highly "decorated" with Alternate Data Streams, and most of all files are purest NTFS Hard Links, or Directory Junctions. Therefore, you can move/copy them within your Windows Explorer at will. Only at the end of each design cycle you have to start a short generator run once. Refactoring and bulk modifications of whole feature sets never have been easier!


How to Tame an Editor…

How to Tame an Editor

Many, many years ago we were excited about syntax coloring. There was a company that offered syntax coloring for FoxPro editor sessions even before Microsoft implemented it natively. Today, I'm hoping for some code-folding feature, and other cool stuff we get for free from Visual Studio, would fall out of the sky…

At least, wouldn't it be nice to be able to launch any editor session in a top level window so that it could be dragged to our second screen? No, I don't mean that 'dusty' ACTIVATE WINDOW IN MACDESKTOP trick, that, by the way, ruins your editor session's copy & paste functionality instantly!
Or wouldn't it be nice to share a document between multiple editor sessions, each showing another part of the code? And, of course, code-folding! Is it possible to inject/apply code-folding into a VFP editor session window? That would be a valuable functionality, right?


How to Tame a Debugger…

Doc_Light_116

Do you need programmatic control over your debugger at design-time? Do you know what gets stored in the FoxUser.dbf records and how to unearth and reuse it? Do you know what the undocumented SYS(989,n) function is for? Do you know how to hook on a running VFP session from a Visual Studio debugger? If not, then this section is for you…


Unbreakable Objects Revisited…

Unbreakable Objects Revisited

One of my discoveries was, that it is possible to cancel a CLEAR ALL invoked from VFP's command window by putting a CANCEL command in the .QueryOnload() event of a SCX-based form instance (read more here). Well, canceling a CLEAR ALL is slightly not what we expect to happen when we explicitly type a CLEAR ALL in our VFP command window, right?
Good news: Luckily, there are instances of one distinct, native VFP base class which, if treated right, survive every interactively entered CLEAR ALL!
Another good news: If you treat one of your PRG-based procedure libraries the right way, all defined function in it will also survive an otherwise disastrous SET PROCEDURE TO.
Once more my questions:
Can we create such a class instance using VFP's Createobject() function? Can we then issue a CLEAR ALL that will destroy all instances immediately, but not our special one? Can we achieve this without resorting to the _SHELL trick, or using a CANCEL in one of our SCX-based form's QueryOnload() methods?
The answers are: YES, Yes, and Yes again…


Corral Your Libraries

Corral Your Libraries

This is all about VFP's Class Libraries, the visual, and the non-visual ones. We will discuss amongst other details:

  1. why it sometimes makes sense to add them to a FoxPro DBC.
  2. when and why we should using library alias names.
  3. why it is better to always use CreateObject() instead of Newobject().
  4. how to setup a generic loader mechanism for PRG-based class libraries.
  5. how to setup a reasonable Include File Management that can be dropped later, in cases the new target platform prevents us from using Include Files at all (like C# does).

Some of the above topics might be trivial pursuit for some of you, but wait, there is more to know about class libraries than just that! Many reflection-related VFP functions behave slightly different when used with SCX-, VCX-, or PRG- based objects. There are also subtle behavioral differences between PRG-based class instances that have a VCX-based ancestor somewhere "up" in their inheritance pedigree, and those PRG-based class instances that were build exclusively from flat file libraries (PRG-based ones)!
And, last but not least, we have numerous reflection-related function like AMEMBERS() that share one strange, optional parameter value. Can you describe exactly, how to use the cClassName parameter option of those functions? Tell us, how to use it with VFP's Amembers() function, as an example…
To be honest, for a long time I thought I had to simply pass in the name of the class to fill the Amembers array. I thought that this was some kind of design-time related option while dealing with an instance inside VFP's class designer. But, finally wondered, that non of my assumptions were true at all, obviously…
 


Two-Faced Properties

Two-Faced Properties

Please be honest, do you think it is possible to store more than one single value in a scalar (non-array) VFP property at a time? At design- and runtime? NO! you say? Right you are, I used to share this truism since I started working with Visual FoxPro.
One fine day, I had to muse about VFP's .ResetToDefault() method, because I've had some troubles getting it to do what I expected it to do.
Somewhere down the road I asked myself, how this darn .ResetToDefault() method could work internally. What do you think?
My number one question was: "From where do VFP's
.ResetToDefault() methods get their default values at runtime? Perhaps 'out of the air'?"; believe me, they don't…


Private Affairs

Private Affairs

How many ways do you know to create a private variable in VFP? I mean, beside the common declarations PRIVATE pMyPrivate, PRIVATE ALL, and the forgotten one (assigning a value to a variable not declared LOCAL). Well, let me tell you, there is at least one more non-obvious way, which is a little bit nasty, by the way. It is hard to debug, because VFP isn't complaining even if _VFP.LanguageOptions = 1 (which means: "Strict Memvar declaration required"), and it's hard to replace with another, more obvious, implementation, because the whole operation is a pure side-effect! But this place wouldn't be called The Hackers Corner, if we couldn't find a way to make use of that feature, right?


The Unknown Species (this 'teaser' will be moved into a new post, ASAP! So, do not read this;-)

The Unknown Species

The best has yet to come! Earlier this year (March 2014) it so happened that I stumbled over some source code example in the Regular VFP Help File. I couldn't believe my eyes, it must have been written down there during the outcome of VFP 3.0 – to be buried in oblivion…

I DO Tell The Truth, Believe Me!

I never saw such a piece of code! Nowhere! Neither silently applied, nor explicitly explained, neither published on the internet, nor privately kept by any of the companies I've ever worked for! Sounds weird, I know, as we all believe that we've seen every possible crime committable writing XBASE-Code, don't we?

What I Can Tell You so Far…

Well, the FF (Forgotten Feature)…

  1. is available since VFP version 3.0.
  2. obviously is not related to event binding, or other advanced concepts that were introduced only later.
  3. is a real, native VFP behavior, that radically hooks into the default VFP message handling between container instances and their children.
  4. is almost undocumented other than the short code snippet I was able to find inside VFP's documentation.
  5. allows us to write code once for all classes, even stemming from different base classes(!), and lets that class-agnostic code execute on every message sent to any child instance, independently of its class type!

Okay, I know, that you have to read the last point(5) twice! Take all the time you need, that smokeless tobacco is hard to chew :.)

A Native IoC-Container

Employing this orgotten feature, for me is the first implementation of an Inversion of Control Container in VFP, which has rightfully earned its name, because it's just that, what's going on behind the scenes, if you take that confusing buzzword literally! I've read a lot of bullsh** about how to implement an IoC-Container in VFP. Let me tell you that most of what I've read so far about IoC was even more obfuscating than the term as is! Especially, when it came to explain what the heck is really meant by Inversion of Control, and why, for heavens sake, we should try to apply that pattern within a native VFP runtime environment (without thinking about any future migration options).

What Our IoC-Container Does

Calling any method of any object added to our Native IoC-Container (that's how I'm going to call such a specialized container from now on), at first fires our IoC-Implementation, and not the other way round! We would expect that our code within the child instance would run first. From inside that child implementation then, we normally would decide to run a DODEFAULT() to invoke our parent class' implementation, or just not (in cases we want to override the feature completely with our child object's behavior).

Born into a Native IoC-Container, our child instances have no longer control over their message handling! For example, they cannot overwrite any behavior of a Native IoC-Container, because the Native IoC-Container implementation gets called first by Visual FoxPro – ALWAYS! Within a Native IoC-Container we are able (and have) to decide if we want to execute any child behavior, and when we want to do that.

The best of all (for me) is, that this Native IoC-Container feature gets invoked for all instances natively by VFP, and not by some dirty trick I came up with! VFP behaves totally type-agnostic: If a Native IoC-Container implements Click(), every Click() event raised from any object inside the Native IoC-Container will be intercepted by VFP, and will be redirected to the Native IoC-Container Implementation first, whatever class the child object was created from, and whatever implementation its local click() method has, or is missing.

I LOVE Good Cliffhangers Zwinkerndes Smiley

Whenever code of a Native IoC-Cotainer gets executed by Visual FoxPro natively, that code is run within the memory context of the child control! In other words, we have to (better said, we must) reflect VFP's type-agnostic behavior within the implementation of every Native IoC-Container, because it will be executed in totally different instance contexts at runtime…

Finally, For The Still Unconvinced

If you now ask: "What if there are a lot of buttons, textboxes and labels on my form – how does FoxPro let me know, which object's message it is just interfering?" - let me tell you, that there are two answers to this question:

  • a.) As I've told you, during the Native IoC-Container Call, we only have to query the actual THIS reference, which then is the child reference we are just taking over control.
  • b.) The next observation sounds equally unbelievable, but is also true:
    FoxPro adds another parameter to every signature of all forwarded messages, if their invocations were triggered from one of the controlled IoC-children! The parameter value passed in is an integer index into the IoC-Container's children enumeration. This element index parameter is passed in at the 1st position of any signature, always! For example, if we want to implement a type-agnostic, Native IoC-Container Hook for, let's say, the MouseDown() events of all class instances that implement that feature, we have to define our IoC.MouseDown() like so:
PROCEDURE Object.MouseDown
LPARAMETERS tnIndex, tnButton, tnShift, tnXCoord, tnYCoord
Is that cool, or am I just going to make a total fool out of myself, because this is common sense, and I am the only VFP guy on earth that wasn't aware of the whole story?