tag:blogger.com,1999:blog-261671582024-02-19T11:59:22.754+01:00Burkhard's VFP BlogIdeas, Concepts and Implementations with Visual FoxPro and other (OOP) LanguagesBurkhardhttp://www.blogger.com/profile/11631168041975170500noreply@blogger.comBlogger104125tag:blogger.com,1999:blog-26167158.post-65803847095416333532017-09-12T16:52:00.001+02:002017-09-27T00:07:58.924+02:00Latest News<p><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-foxtools.html"><img title="Foxtools Home" style="border-width: 0px; display: inline;" border="0" alt="Foxtools Home" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgztd-3jktLLMOg9ST2Cf1vzRIXP2Nroxgv6HjE4BouQzG-OQfR2LLZ0EH4Cf539UwGcdeRa7IqSSDJ6mFHM31fXwJwljFRZQ9lP5s7S1cb-2NyLl1DHTCVhi7aOtzR623gkcLb/?imgmax=800" width="32" height="43" /></a><a href="http://myvfpblog.blogspot.com/2009/09/foxquill-more-than-framework-foxquill.html"><img title="FoxQuill Home" style="border-width: 0px; display: inline;" border="0" alt="FoxQuill Home" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1zgkKmj9gQC__ig5t-A7EmcZBdapbVTJmW9jXkyz8wur700nmtDR-zzpgJ0usFZcL8bD6wI4mdeYochIBZNwcK5sLThdD3Ibq8qT4qfxbenUbBtAD6IoEtY0oS5eAjtUFMUO9/?imgmax=800" width="48" height="64" /></a><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-vfpx-projects-this.html"><img title="VFPX Projects Home" style="border-width: 0px; display: inline;" border="0" alt="VFPX Projects Home" src="http://lh4.ggpht.com/_MOmDLu4Rm5Y/SsG7vGV-2cI/AAAAAAAACCg/LnG3L-Zc1d4/Home_64_RGBA%5B1%5D.png?imgmax=800" width="64" height="85" /></a><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-miscellaneous-diverse.html"><img title="Miscellaneous Home" style="border-width: 0px; display: inline;" border="0" alt="Miscellaneous Home" src="http://lh6.ggpht.com/_MOmDLu4Rm5Y/SsG7vWR74gI/AAAAAAAACCk/lkw3az3-eZA/Home_72_RGBA%5B1%5D.png?imgmax=800" width="72" height="96" /></a><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-windows-api-calling.html"><img title="Windows API Home" style="border-width: 0px; display: inline;" border="0" alt="Windows API Home" src="http://lh3.ggpht.com/_MOmDLu4Rm5Y/SsG7vnG_i1I/AAAAAAAACCs/CXrlkWDBfqw/Home_96_RGBA%5B1%5D.png?imgmax=800" width="96" height="128" /></a><img title="News Home" style="border-width: 0px; display: inline;" border="0" alt="News Home" src="http://lh3.ggpht.com/_MOmDLu4Rm5Y/SsG7wTrojkI/AAAAAAAACCw/Ai2538g7Awg/Home_128_RGBA%5B1%5D.png?imgmax=800" width="160" height="160" /><a title="http://myvfpblog.blogspot.com/2009/09/basics-home.html" href="http://myvfpblog.blogspot.com/2009/09/basics-home.html"><img title="Basics Home" style="border-width: 0px; display: inline;" border="0" alt="Basics Home" src="http://lh4.ggpht.com/_MOmDLu4Rm5Y/SsG7w6mLMQI/AAAAAAAABs4/ZMCZlQncCSU/Home_96_RGBA%5B4%5D.png?imgmax=800" width="96" height="128" /></a><a title="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-tips-tricks-in-this.html" href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-tips-tricks-in-this.html"><img title="Tips&Tricks Home" style="border-width: 0px; display: inline;" border="0" alt="Tips&Tricks Home" src="http://lh5.ggpht.com/_MOmDLu4Rm5Y/SsG7xcpCfLI/AAAAAAAABtA/lHwWlG5m9hI/Home_72_RGBA%5B4%5D.png?imgmax=800" width="72" height="96" /></a><a title="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-toolbox-in-this-section.html" href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-toolbox-in-this-section.html"><img title="Toolbox Home" style="border-width: 0px; display: inline;" border="0" alt="Toolbox Home" src="http://lh6.ggpht.com/_MOmDLu4Rm5Y/SsG7xkSynnI/AAAAAAAABtE/t_FSa245s8o/Home_64_RGBA%5B4%5D.png?imgmax=800" width="64" height="85" /></a><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-complex-controls-no.html"><img title="Complex Controls Home" style="border-width: 0px; display: inline;" border="0" alt="Complex Controls Home" src="http://lh3.ggpht.com/_MOmDLu4Rm5Y/SsG7yZVAklI/AAAAAAAACC4/gYXsXhOhQAo/Home_48_RGBA%5B2%5D.png?imgmax=800" width="48" height="64" /></a><a title="http://myvfpblog.blogspot.com/2009/09/neat-solutions-home.html" href="http://myvfpblog.blogspot.com/2009/09/neat-solutions-home.html"><img title="Neat Solutions Home" style="border-width: 0px; display: inline;" border="0" alt="Neat Solutions Home" src="http://lh6.ggpht.com/_MOmDLu4Rm5Y/SsG7yqemKGI/AAAAAAAABtQ/XQgXPDq6Mw8/Home_32_RGBA%5B4%5D.png?imgmax=800" width="32" height="43" /></a> <br /></p> <hr /> <h1 style="color: rgb(68, 68, 68); font-family: verdana,sans-serif; background-color: rgb(204, 204, 204);"><span style="font-size: x-large;"><img title="VogelStrauss" style="border-width: 0px; margin: 43px 10px 0px; display: inline;" border="0" alt="VogelStrauss" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiC64UnSsynX9EtiqoslWeOZCzL0CfJl2gSbA6i0eJwZbw7yOQh2K7Jkug8ysKM267162L-vAK7rMuTXkDexaZl6cM4EveMzViI32MPbAfVL5fbtZX47at5Vsk7ctyQ1NiGFv6T/?imgmax=800" width="131" align="left" height="131" /></span><span style="font-size: small;"></span></h1> <h1><font color="#000080"><strong><span style="font-size: x-large;">Latest News</span><span style="font-size: small;"> </span></strong></font></h1> <span style="font-size: small;"></span> <h4><font color="#000080">This section of my VFP Blog gets filled at random times and with random content. <br /></font><font color="#000080">One could say, this is the remaining most blog-like part of my VFP Blog. <br /></font><font color="#000080">Most of the entries will be dealing with what I’ve added to the other sections of my blog lately. </font><font color="#000080">Thus, it seems to be a good idea to always check <em>The News</em> first…</font></h4> <hr /> <p><strong>Tuesday, September 27<sup>th</sup>, 2017</strong></p> <p><font color="#000000"><font size="4"><strong>More Than Two Years Have Passed by… <br /></strong></font></font>… there is no doubt, I’ve seen better ones. But, and that’s good enough for me, I’m still alive and, even better, I am still creating VisualFoxpro programs, at least sometimes:-) So guys, if you belong to the die-hard VisualFoxpro enthusiasts, just like me, be my guests: "Welcome back my friends to the show that never ends ~ Ladies and Gentlemen..." <a title="Welcome Back My Friends to the Show That Never Ends ~ Ladies and Gentlemen" href="https://www.youtube.com/watch?v=iaPnfke-OVw" target="_blank"><img title="OffSiteLink" style="margin: 6px 0px 0px; border: 0px currentcolor; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" border="0" alt="OffSiteLink" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2-WgFvslv-IKxxLRlQGbuqAAyWhOhMGryE_zilhNH9cjQIPoAa4SCAUnAbS_b7KD6pcHrFY-DmcUAgkXf9yEejbzhw-jeiQT1kvENoIGS1aBlzxxd4ncmjQ_vlxMNz2nXC7a9/?imgmax=800" width="11" height="7" /></a></p> <hr /> <p><strong><font color="#a5a5a5">Saturday, January 24<sup>th</sup>, 2015</font></strong></p> <p><font style="background-color: rgb(255, 255, 0);" size="5"><strong></strong></font><font color="#a5a5a5" size="5"><strong>Important Note</strong></font><font style="background-color: rgb(255, 255, 0);" size="5"><strong></strong></font></p> <p><font color="#a5a5a5">I’m just in the middle of restructuring my domains. I dropped some of them and moved some others from all over the place to one single provider. Now, it is easier for me to handle them. You know, a single provider means: one place to go for all tasks, which is nice. Although I prepared the task pretty well, alas, <strong><em>I forgot to backup my Foxpro files referenced from within this blog</em></strong>. This morning it was too late to do that. My German FoxQuill.de web-space was dropped dead. It was a really small web-space just holding some images and files and: I do have a local copy of all files missing at the moment! But, it will take me some time to upload them all up again… In the meanwhile, there will be no downloads available on my entire VFP-blog, <strong><em>which I’m awfully sorry for</em></strong>!</font></p> <p><font color="#a5a5a5">I’m going to port this whole blog space to my German <em><font style="background-color: rgb(255, 255, 0);"></font></em><em>FoxQuill.de</em> site. Don’t panic it will still be written in English! :-) </font></p> <p><font color="#a5a5a5">Finally, this blog-space will only hold the latest news, the headlines of what I recently added to my German FoxQuill site. It will become a kind of referrer, a handle for those who came and still come here to read the latest, and one fine day the last news about Visual FoxPro…</font></p> <p><font color="#a5a5a5">Stay tuned, I will be up and running FoxQuill.de in a few weeks. </font></p> <font color="#a5a5a5"> <hr /></font> <p><strong><font color="#a5a5a5">Sunday, September 7<sup>th</sup>, 2014</font></strong></p> <p><font color="#a5a5a5"><font size="4"><strong>Added "ADSs, Hard Links & Junctions" under WINAPI And VFP Internals section <br /></strong></font>This post is about Alternate Data Streams, Hard Links and Junctions (it's still under construction) </font><a title="ADSs, Hard Links & Junctions link" href="http://myvfpblog.blogspot.com/2014/09/adss-hard-links-junctions.html" target="_blank"><font color="#a5a5a5"><img title="ADSs, Hard Links & Junctions link" style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" border="0" alt="ADSs, Hard Links & Junctions link" src="http://lh4.ggpht.com/-dedEE5rDc7M/VAyW0Q_OvmI/AAAAAAAAIYs/EdIrEJogPw8/OffSiteLink%25255B14%25255D.png?imgmax=800" width="11" height="7" /></font></a><font color="#a5a5a5"> </font></p> <font color="#a5a5a5"> <hr /></font> <p><strong><font color="#a5a5a5">Sunday, September 7<sup>th</sup>, 2014</font></strong></p> <p><font color="#a5a5a5"><font size="4"><strong>Added "Into The Void" under WINAPI And VFP Internals section  <br /></strong></font>This post is about another "Unknown" – <strong><em>The .VOID.</em></strong> </font><a title="The Missing Type link" href="http://myvfpblog.blogspot.com/2014/09/the-missing-type-void.html" target="_blank"><font color="#a5a5a5"><img title="The Missing Type link" style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" border="0" alt="The Missing Type link" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiR7cYyNkqUsOeH4RI6BG89MY6bJKqKRfN2wxHlxSc0-ssaXi5FSg2JVvO6AT4XlNtKX7W3e6uxkofM54-VOkDVLgstOrEFLrhsSvHxO-p2GrDk90V4IYbDEmAgS_4X4q0G_3w5/?imgmax=800" width="11" height="7" /></font></a><font color="#a5a5a5"> </font></p> <font color="#a5a5a5"> <hr /></font> <p><strong><font color="#a5a5a5">Saturday, September 6<sup>th</sup>, 2014</font></strong></p> <p><font color="#a5a5a5" size="4"><strong>Added "The Madlen Effect" under WINAPI And VFP Internals section <br /></strong></font></p> <p><font color="#a5a5a5">There is some almost unknown behavior that can be applied on any temporary VFP coursor. Madlen was the first VFP developer I know, who to dig that out! Exciting… </font><a title="The Madlen Effect link" href="http://myvfpblog.blogspot.com/2014/09/the-madlen-effect.html" target="_blank"><font color="#a5a5a5"><img title="The Madlen Effect link" style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" border="0" alt="The Madlen Effect link" src="http://lh5.ggpht.com/-zK4D6EZw-XE/VAyGQKQIvqI/AAAAAAAAIX8/ENAJeRWhEMw/OffSiteLink%25255B5%25255D.png?imgmax=800" width="11" height="7" /></font></a><font color="#a5a5a5"> </font></p> <font color="#a5a5a5"> <hr /></font> <p><strong><font color="#a5a5a5">Saturday, September 6<sup>th</sup>, 2014</font></strong></p> <p><font color="#a5a5a5" size="4"><strong>Added "The Scope Resolution Operator" under WINAPI And VFP Internals section <br /></strong></font></p> <p><font color="#a5a5a5">Using VFP's </font><a href="http://msdn.microsoft.com/en-US/library/8ehdyws9(v=vs.80).aspx"><font color="#a5a5a5">Scope Resolution Operator</font></a><font color="#a5a5a5"> definitely is my least used method invocation strategy. Sounds familiar, right? Then, why is that so? Go and get the whole story… </font><a title="The Scope Resolution Operator link" href="http://myvfpblog.blogspot.com/2014/09/how-to-jump-over-hidden-hurdle.html" target="_blank"><font color="#a5a5a5"><img title="The Scope Resolution Operator link" style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" border="0" alt="The Scope Resolution Operator link" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUsJ7tAY9cBRMGSrHqnV4-5KQlZWqRb6os4iMbbmTD0MHD9da92krHydqqgCRgt2qc7ElTMDD7uFFaaI_H4TqYxkKchY5zfbmcxYyNFn3wM-0m0jf_r3dLBWcvTwCCaL0WK9sI/?imgmax=800" width="11" height="7" /></font></a><font color="#a5a5a5"> </font></p> <font color="#a5a5a5"> <hr /></font> <p><strong><font color="#a5a5a5">Saturday, September 6<sup>th</sup>, 2014</font></strong></p> <p><font color="#a5a5a5"><font size="4"><strong>Updated WINAPI And VFP Internals section  <br /></strong></font>There are a lot of new topics there – I'm just busily working on that threads </font><a title="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-windows-api-calling.html" href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-windows-api-calling.html" target="_blank"><font color="#a5a5a5"><img title="WINAPI And VFP Internals" style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" border="0" alt="WINAPI And VFP Internals" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcGIflsW2p-br2lCVfDVaK4jwtm-2JpeUzqJReZAjGI2uy59VZ7sO8OzEqH-wmHvJHxM2ZTIoXLiFWTXhnHEKzsZq28AcOFo7jlBhZpPclEzMgir73431vec6IPR5bYu-HcFDv/?imgmax=800" width="11" height="7" /></font></a><font color="#a5a5a5"> </font></p> <hr /> <p><strong><font color="#a5a5a5">Tuesday, September 2<sup>nd</sup>, 2014</font></strong></p> <p><font color="#a5a5a5"><font size="4"><strong>Updated Visual FoxPro – Toolbox section <br /></strong></font>Curious? Have a peek ;-) </font><a title="http://myvfpblog.blogspot.com/2014/03/preprocessor-and-compile-time-constants.html" href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-toolbox-in-this-section.html" target="_blank"><font color="#a5a5a5"><img title="Visual FoxPro – Toolbox section " style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" border="0" alt="Visual FoxPro – Toolbox section " src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-2Y8wjvnq0BD8nQ9UDVr0BP4lBjeaUGTzHuHBj6afSYeK3vRe5fcLWpfYozN-g9UggYllmvE0XwG6iRMJjYf20hpK1KvkIPmbvG68fgetfJMY3oF67E950uiwgS3rO6PUNUPQ/?imgmax=800" width="11" height="7" /></font></a><font color="#a5a5a5"> </font></p> <font color="#a5a5a5"> <hr /></font> <p><strong><font color="#a5a5a5">Tuesday, September 2<sup>nd</sup>, 2014</font></strong></p> <p><font color="#a5a5a5"><font size="4"><strong>Restructured my Windows API blog section  <br /></strong></font>I changed Windows API section to "WINAPI and VFP Internals" to hold more VFP-related contend. I didn't find the time to post some useful WINAPI examples anyway. This is an invitation to all VFP-Hackers: come in and have a look :-) </font><a title="http://myvfpblog.blogspot.com/2014/03/preprocessor-and-compile-time-constants.html" href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-windows-api-calling.html" target="_blank"><font color="#a5a5a5"><img title="Restructured Windows API Blog Section" style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" border="0" alt="Restructured Windows API Blog Section" src="http://lh4.ggpht.com/-bEOeVRrnqRM/VAUxy6aPxFI/AAAAAAAAIPQ/Uq_ZbrokjTM/OffSiteLink%25255B4%25255D.png?imgmax=800" width="11" height="7" /></font></a><font color="#a5a5a5"> </font></p> <font color="#a5a5a5"> <hr /></font> <p><strong><font color="#a5a5a5">Tuesday, September 2<sup>nd</sup>, 2014</font></strong></p> <p><font color="#a5a5a5"><font size="4"><strong>Added "How to Jump Over the Hidden Hurdle" <br /></strong></font>This is a detailed examination of VFP's <strong><em>Scope Resolution Operator</em></strong> behavior, and what can be done with it beside invocation of some parent class behavior… </font><a title="http://myvfpblog.blogspot.com/2014/03/preprocessor-and-compile-time-constants.html" href="http://myvfpblog.blogspot.com/2014/08/vfp-basics-part-3.html" target="_blank"><font color="#a5a5a5"><img title="How to Jump Over the Hidden Hurdle" style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" border="0" alt="How to Jump Over the Hidden Hurdle" src="http://lh6.ggpht.com/-F_ExKyX9U1c/VAUVR_6FajI/AAAAAAAAIPY/-6zY_W905DI/OffSiteLink%25255B5%25255D.png?imgmax=800" width="11" height="7" /></font></a><font color="#a5a5a5"> </font></p> <font color="#a5a5a5"> <hr /></font> <p><strong><em><font color="#a5a5a5">Monday, September 1<sup>st</sup>, 2014</font></em></strong></p> <p><font color="#a5a5a5"><font size="4"><strong>Added VFP's BASICS (Part 3) <br /></strong></font>This is the <em>entry point</em> into a set of more general discussions like Multiple Inheritance, AOP, Multitasking, Design-b-Contract, and so on  </font><a title="http://myvfpblog.blogspot.com/2014/03/preprocessor-and-compile-time-constants.html" href="http://myvfpblog.blogspot.com/2014/09/how-to-jump-over-hidden-hurdle.html" target="_blank"><font color="#a5a5a5"><img title="VFP's BASICS (Part 3)" style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" border="0" alt="VFP's BASICS (Part 3)" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicELWLHaTewyY0iqssqdtDI6OpIxxkyl6EuUoU1EzylRPp_n_C64jJu5kxuoSaeBjdydlE_3MV-reRQheCdWot2SQBQ2vb69me3mRN4GS4Vnd6agq7nyVu_4AfvhXnsHWhro-Z/?imgmax=800" width="11" height="7" /></font></a><font color="#a5a5a5"> </font></p> <font color="#a5a5a5"> <hr /></font> <p><strong><em><font color="#a5a5a5">Sunday, August 31, 2014</font></em></strong></p> <p><font color="#a5a5a5"><font size="4"><strong>Added VFP's BASICS (Part 2) <br /></strong></font>Go and get your own copy of one of the most fundamental <strong><em>definite book</em></strong> about OOP here </font><a title="http://myvfpblog.blogspot.com/2014/03/preprocessor-and-compile-time-constants.html" href="http://myvfpblog.blogspot.com/2014/08/vfp-basics-part-2.html" target="_blank"><font color="#a5a5a5"><img title="VFP's BASICS (Part 2)" style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" border="0" alt="VFP's BASICS (Part 2)" src="http://lh6.ggpht.com/-JBko1YwfEUU/VANKKQ3BMOI/AAAAAAAAIJc/IHjo2ftjjGA/OffSiteLink%25255B4%25255D.png?imgmax=800" width="11" height="7" /></font></a><font color="#a5a5a5"> </font></p> <font color="#a5a5a5"> <hr /></font> <p><font color="#a5a5a5"><strong><em>Thursday, July 23, 2014, 19:25:00</em></strong> </font></p> <p><font color="#a5a5a5"><font size="4"><strong>Started "VFPX – FoxUnit"  <br /></strong></font>Lets get involved in VFP-based Unit-Testing. I will publish this series of posts under my <strong><em>VFPX Projects</em></strong> section, because of the FoxUnit project which is maintained by the VFPX Community today. Unit-Testing is only one aspect of an overall testing approach which should encompass <strong><em>Integration</em></strong>- and <strong><em>Acceptance-Testing</em></strong> as well. Go and get a first overview here </font><a title="http://myvfpblog.blogspot.com/2014/03/preprocessor-and-compile-time-constants.html" href="http://myvfpblog.blogspot.com/2014/07/vfpxfoxunit.html" target="_blank"><font color="#a5a5a5"><img title="VFPX – FoxUnit" style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" border="0" alt="VFPX – FoxUnit" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4BogLp0AxoHEsIh8GnXVrDB176CHVrrLFiTt_OFEovhKQhH4ROGvemz_TyCR6OMtz1G8namDlvbiECIHZh5SseBDwvd0A-ZFTpPUwDbdfkFXpI5qU8CBNiqfmHj1Nw0bY1Lop/?imgmax=800" width="11" height="7" /></font></a><font color="#a5a5a5"> </font></p> <hr /> <p><font color="#a5a5a5"><strong><em>Friday, March 28, 2014, 15:36:00</em></strong> </font></p> <p><font color="#a5a5a5"><font size="4"><strong>Started "Dynamic Declarations and Value Assignments"  <br /></strong></font>I must admit, the title of this post is a little bit misleading. Primarily, I only wanted to write about the bad habit of using VFP's Macro Substitutions over and over again instead of utilizing faster native commands. But in this context, there still is more to talk about. Thus, I started a more generally blog post dealing with any kind of native optimization, where 'native' means replacing a slow VFP command with another, faster one. I'm looking for your comments an additions! See you there! </font><a title="http://myvfpblog.blogspot.com/2014/03/preprocessor-and-compile-time-constants.html" href="http://myvfpblog.blogspot.com/2014/03/dynamic-declarations-and-value.html"><font color="#a5a5a5"><img title="Dynamic Declarations and Value Assignments" style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" border="0" alt="Dynamic Declarations and Value Assignments" src="http://lh6.ggpht.com/-hne4zeTMkCY/UzWI6oxOlbI/AAAAAAAAIEg/cc9VVC3RpJ4/OffSiteLink%25255B4%25255D.png?imgmax=800" width="11" height="7" /></font></a><font color="#a5a5a5"> </font></p> <font color="#a5a5a5"> <hr /></font> <p><font color="#a5a5a5"><strong><em>Friday, March 28, 2014, 03:25:00</em></strong> </font></p> <p><font color="#a5a5a5"><font size="4"><strong>Added "Write protection for Properties"  <br /></strong></font>It took me a long way to find my favorite implementation for read-only properties in VFP. It had to be a fast one; it had to be a solid one (taking my forgetfulness into account); it had to be a generic one, and it had to support the concept of <em>Friends Classes</em> so that I could Unit test-drive my classes easily… </font><a title="http://myvfpblog.blogspot.com/2014/03/preprocessor-and-compile-time-constants.html" href="http://myvfpblog.blogspot.com/2014/03/write-protection-for-properties.html"><font color="#a5a5a5"><img title="Write protection for Properties" style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" border="0" alt="Write protection for Properties" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTzaV41-tpj3SCTH84CuynlJpKINFo1s3n7AKsriwumzitz-Pkas6uI1VOrF6TUOxlDxozRMZn07Z8w6Ucz9lRGNNXzH5I8fSuqIfFeJTWUzV7UaBnOAx5daYZQuG7U8a3g3_z/?imgmax=800" width="11" height="7" /></font></a><font color="#a5a5a5"> </font></p> <font color="#a5a5a5"> <hr /></font> <p><font color="#a5a5a5"><strong><em>Thursday, March 27, 2014, 22:23:00</em></strong> </font></p> <p><font color="#a5a5a5"><font size="4"><strong>Added some "good to know" facts about VFP's preprocessor <br /></strong></font>Can there be anything cool about include files, #DEFINE statements and the way how VFP's preprocessor heckles them? I think so! Go an form an opinion about it yourself </font><a title="http://myvfpblog.blogspot.com/2014/03/preprocessor-and-compile-time-constants.html" href="http://myvfpblog.blogspot.com/2014/03/preprocessor-and-compile-time-constants.html"><font color="#a5a5a5"><img title="Some "Secrets" of VFP's Preprocessor Revealed" style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" border="0" alt="Some "Secrets" of VFP's Preprocessor Revealed" src="http://lh5.ggpht.com/-R0kH0ZibxKg/UzSWv4VtdRI/AAAAAAAAID4/8FoslSpcKP8/OffSiteLink%25255B4%25255D.png?imgmax=800" width="11" height="7" /></font></a><font color="#a5a5a5"> </font></p> <hr /> <p><font color="#cccccc"><strong><em>Tuesday, March 18, 2014, 10:45:00</em></strong> </font></p> <p><font color="#cccccc"><font size="4"><strong>Added a neat solution – A ProjectHook "On Steroids" <br /></strong></font>Create a VCX ClassLib and code it in under 5 minutes - enjoy all day long </font><a href="http://myvfpblog.blogspot.com/2014/03/a-diet-hook-on-steroids.html"><font color="#cccccc"><img title="A Diet Hook On Steroids" style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" border="0" alt="A Diet Hook On Steroids" src="http://lh3.ggpht.com/-iTEfQWMJDwg/UygYxZrhNRI/AAAAAAAAIEA/TT_JwJ1f4TM/OffSiteLink%25255B5%25255D.png?imgmax=800" width="11" height="7" /></font></a><font color="#cccccc"> </font></p> <font color="#cccccc"> <hr /></font> <p><font color="#cccccc"><strong><em>Saturday, March 8, 2014, 00:10:10</em></strong> </font></p> <p><font color="#cccccc"><font size="4"><strong>Started publishing my FoxQuill Framework <br /></strong></font>Bon Appétit! </font><a href="http://myvfpblog.blogspot.com/2009/09/foxquill-more-than-framework-foxquill.html"><font color="#cccccc"><img title="FoxQuill yet another VFP Framework" style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" border="0" alt="FoxQuill yet another VFP Framework" src="http://lh4.ggpht.com/-tl-GQ5ZoHkg/UxqJqNThypI/AAAAAAAAICc/YixyPOHzG18/OffSiteLink%25255B5%25255D.png?imgmax=800" width="11" height="7" /></font></a><font color="#cccccc"> </font></p> <font color="#cccccc"> <hr /></font> <p><font color="#cccccc"><strong><em>Saturday, March 1, 2014, 00:05:00</em></strong> </font></p> <p><font color="#cccccc"><font size="4"><strong>Updated my Basics <br /></strong></font>There is new content at the end of my VFP's BASICS(Part 1) document. I finally added my rules #19 to #21 there. Enjoy! </font><a href="http://myvfpblog.blogspot.de/2008/04/vfp-editor-code-rtf2html-part-6.html"><font color="#cccccc"><img title="VFP's BASICS (Part 1)" style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" border="0" alt="VFP's BASICS (Part 1)" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7Q0TN98L8n7SY-eRaxQBPVYHAVo6L9RHPLeO1VsB5a9J1iDd4zw2ORnTQyeK1O7iFmduTXIiEbMWxK3am5AoLmpOErhcYCgjWA88gaokwSSD7FKWKbE6tu_G3H6EQB1zkLZWR/?imgmax=800" width="11" height="7" /></font></a></p> <font color="#cccccc"> <hr /></font> <p><font color="#cccccc"><strong><em>Thursday, January 10, 2014, 16:05:00</em></strong> </font></p> <p><font color="#cccccc"><font size="4"><strong>>> Fast Forward >>  <br /></strong></font>Wow, this is awesome! More than two years passed by without giving me enough spare time to write some lines like these! </font><font color="#cccccc">Today is my 55th anniversary. I’m still looking forward to finally complete some of my “never ending stories” here. Therefor, I will reactivate one of my older VFP sites (one will be </font><a href="http://www.foxquill.de"><font color="#cccccc">www.foxquill.de</font></a><font color="#cccccc">), because it seems easier to write and publish longer essays like I do via some dedicated internet site than to use this Google blog like I did in the past. I will only use this blog to announce new additions and updates I’ve made on my FoxQuill site.</font><font color="#cccccc"></font></p> <p><font color="#cccccc"></font></p> <hr /> <p><font color="#cccccc"><font size="1"><strong><em>Wednesday, August 30, 2011, 06:05:00</em></strong> </font></font></p> <p><font color="#cccccc"><font size="4"><strong><font size="3">As time goes by… </font> <br /></strong></font>I finished my C# course and passed the examine. Now, instead of starting using it, I’m facing a new challenge: <br />I need to set up some Apache-based internet sites (with cool interactivity)! Thus, I started learning (renewing) PHP and ALAX. <strong><em>I’m afraid, learning will never end</em></strong> :-)</font></p> <p><font color="#cccccc">I’m still working on my VFP TreeView (but not spending too much time on it at the moment). At least I will make a download link available. <br />I’m going to add more chapters to my FoxTools reference in the future as well as to my OOP-basics chapters, and: I have written an new exhaustive post about cool and unknown(!) </font><a title="http://myvfpblog.blogspot.com/2011/05/cool-vfp-event-binding.html" href="http://myvfpblog.blogspot.com/2011/05/cool-vfp-event-binding.html"><strong><font color="#cccccc">EVENTBINDING features</font></strong></a><font color="#cccccc">! <br /> <br />Finally, I’m afraid, I have to stop posting long “articles” here on this blog because of missing free time. Creating new VFP blog entries using my current blogger template is too time-consuming. I will reset this VFP blog to one of the common/regular layouts, so I can publish my future VFP-related latest news here in minutes, not in hours.</font></p> <p><font color="#cccccc">I won’t drop my VFP-related activities completely – never ever! But there will be another platform for my activities (watch out on </font><a href="http://www.alligora.com" target="_blank"><font color="#cccccc">www.alligora.com</font></a><font color="#cccccc">). </font></p> <font color="#cccccc"> <hr /></font> <p><font color="#a5a5a5"><strong><em>Monday, July 18, 2011, 13:00:00</em></strong> </font></p> <p><font color="#a5a5a5">Some of you found all my download links broken last days. This was caused by a high jacking attack on my CMSystem I was running on my FoxQuill.de website. I missed an important maintenance upgrade and found my CMS site cracked short time later. So, take my advice and never miss any CMS upgrades! I deleted my CMS test-drive installation (containing my blogger-resources as well). Thus, sorry for going offline for some days, now you should be able to download again. <br /> </font></p> <hr /> <p><font color="#a5a5a5"><strong><em>Monday, May 02, 2011, 24:00:00</em></strong> </font></p> <p><font color="#a5a5a5">Another step towards the final release of my native TreeView: I added the first part of hierarchical indexing </font><a title="http://myvfpblog.blogspot.com/2011/05/hierarchical-table-order-part-i.html" href="http://myvfpblog.blogspot.com/2011/05/hierarchical-table-order-part-i.html"><font color="#a5a5a5"><img title="hierarchical indexing for nerds ;-)" style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" border="0" alt="hierarchical indexing for nerds ;-)" src="http://lh5.ggpht.com/_MOmDLu4Rm5Y/Tb9gV7uqJEI/AAAAAAAAHhU/JeqhcEjqJ70/icon_go_up%5B8%5D.gif?imgmax=800" width="15" height="15" /></font></a><font color="#a5a5a5"> <br />Let me introduce to you *Bruno* – my RR </font><a title="http://myvfpblog.blogspot.com/2011/04/bruno-my-rr-rhodesian-ridgeback.html" href="http://myvfpblog.blogspot.com/2011/04/bruno-my-rr-rhodesian-ridgeback.html"><font color="#a5a5a5"><img title="Bruno my RR" style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" border="0" alt="Bruno my RR" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxzQRsReLcWN_7L6quoP628xRXZh3-V2FzxqgYUzttgOp8HOQh1j8sp4i25rdN3NC89ffkweIG7XK5YM2MLEDRSjHOs43SgexV4Spa1DphQXJvfHENQ1gKqU8-5G5sl-Q8G3jE/?imgmax=800" width="15" height="15" /></font></a><font color="#a5a5a5"> </font></p> <font color="#a5a5a5"> <hr /></font> <p><font color="#a5a5a5"><strong><em>Friday, April 29, 2011, 22:25:00</em></strong> </font></p> <p><font color="#a5a5a5">Finally I found some time to start filling some old gaps; I added a first entry under the </font><a title="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-vfpx-projects-this.html" href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-vfpx-projects-this.html"><font color="#a5a5a5">VFPX projects section</font></a><font color="#a5a5a5"> </font><a title="http://myvfpblog.blogspot.com/2011/04/vfpx-help-file-corrected-supported-and.html" href="http://myvfpblog.blogspot.com/2011/04/vfpx-help-file-corrected-supported-and.html"><font color="#a5a5a5"><img title="Go to Post" style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" border="0" alt="Go to Post" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBXYqWjTW73QU_XZ-08jjV2m-v9olh55Fkjf4mN_-gwY_KAZbhS8Sv9Us361MqycN26Obey779qmYmFw0ISetoZ1E1aLPChDWO4lXGRvWotEg6HxWHLvyyPHjd_HKPCQyUROlt/?imgmax=800" width="15" height="15" /></font></a><font color="#a5a5a5"> <br />Next, I restructured my </font><a title="http://myvfpblog.blogspot.com/2009/09/foxquill-more-than-framework-foxquill.html" href="http://myvfpblog.blogspot.com/2009/09/foxquill-more-than-framework-foxquill.html"><font color="#a5a5a5">FoxQuill framework section</font></a><font color="#a5a5a5"> because I am going to post new entries there ASAP. </font><a title="http://myvfpblog.blogspot.com/2011/04/foxquill-becomes-foxquillnet.html" href="http://myvfpblog.blogspot.com/2011/04/foxquill-becomes-foxquillnet.html"><font color="#a5a5a5"><img title="Go to Post" style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" border="0" alt="Go to Post" src="http://lh6.ggpht.com/_MOmDLu4Rm5Y/Tbsh1JfWlJI/AAAAAAAAHb8/1-Holrp-JRU/icon_go_up%5B9%5D.gif?imgmax=800" width="15" height="15" /></font></a><font color="#a5a5a5"> <br />Last but not least, my native TreeView story develops further. There are only two or three post left to describe some needed background.</font></p> <font color="#a5a5a5"> <hr /></font> <p><font color="#a5a5a5"><strong><em>Monday, April 25, 2011, 23:45:00</em></strong> </font></p> <p><font color="#a5a5a5">As announced: I added a new entry under my “Tips & Tricks” section >>> <strong><em>LOADPICTURE() Function – Some Myths Revealed</em></strong>. </font><a title="http://myvfpblog.blogspot.com/2011/04/loadpicture-functionsome-myths-revealed.html" href="http://myvfpblog.blogspot.com/2011/04/loadpicture-functionsome-myths-revealed.html"><font color="#a5a5a5"><img title="Go to Post" style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" border="0" alt="Go to Post" src="http://lh4.ggpht.com/_MOmDLu4Rm5Y/TbXuHrkocpI/AAAAAAAAHZc/bFb-_Bl5PTY/icon_go_up%5B7%5D.gif?imgmax=800" width="15" height="15" /></font></a><font color="#a5a5a5"> <br />Started publishing some thoughts under my framework section “FoxQuill”, too. </font><a title="http://myvfpblog.blogspot.com/2009/09/foxquill-more-than-framework-foxquill.html" href="http://myvfpblog.blogspot.com/2009/09/foxquill-more-than-framework-foxquill.html"><font color="#a5a5a5"></font></a><a title="http://myvfpblog.blogspot.com/2009/09/foxquill-more-than-framework-foxquill.html" href="http://myvfpblog.blogspot.com/2009/09/foxquill-more-than-framework-foxquill.html"><img title="Go to Post" style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" border="0" alt="Go to Post" src="http://lh4.ggpht.com/_MOmDLu4Rm5Y/TbXuH6ETEXI/AAAAAAAAHcA/5i8teUbuXxI/icon_go_up%5B7%5D.gif?imgmax=800" width="15" height="15" /></a></p> <font color="#a5a5a5"> <hr /></font> <p><font color="#a5a5a5"><strong><em>Tuesday, April 12, 2011, 15:15:00</em></strong> </font></p> <p><font color="#a5a5a5">Added a new “How to…” under my Miscellaneous section. </font><a title="http://myvfpblog.blogspot.com/2008/02/got-seek-you-v6-installed.html" href="http://myvfpblog.blogspot.com/2008/02/got-seek-you-v6-installed.html"><font color="#a5a5a5"><img title="Go to Post" style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" border="0" alt="Go to Post" src="http://lh6.ggpht.com/_MOmDLu4Rm5Y/TbXvH0ERiCI/AAAAAAAAHZk/Dqa5kEgr3pQ/icon_go_up%5B13%5D.gif?imgmax=800" width="15" height="15" /></font></a><font color="#a5a5a5"> <br />Busily working on my final native VFP TreeView. See chapter 5 under my Complex Controls section. </font><a title="http://myvfpblog.blogspot.com/2011/04/native-treeview-part-v.html" href="http://myvfpblog.blogspot.com/2011/04/native-treeview-part-v.html"><font color="#a5a5a5"><img title="Go to Post" style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" border="0" alt="Go to Post" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEje1Iw8stL5giI29gJ1D5d6Jys4O6jKULKBnIl8MfYqizvu7rQXyil-2AQu-2ARZfwOiA1chZ6L-McIoc7NbVZ-Vg7XLe5oUE5YGDiLwDHTmbICyfzRUUZqhM3BfyWIvIqum-op/?imgmax=800" width="15" height="15" /></font></a><font color="#a5a5a5"> <br />Just going to release another very interesting entry under my Tips&Tricks section. Be prepared :-)</font></p> <hr /> <p><font color="#a5a5a5"><strong><em>Monday, April 4, 2011, 23:35:00</em></strong> </font></p> <p><font color="#a5a5a5">Gosh, I started a C# learning course end of last year – 6 month intensive fulltime-training:  8 hours a day! Folks I can tell: many new classes and new concepts to learn but after a while one gets used to it. Especially the VS2010 IDE is cool! VFP’s code editor and class/form designers look a little bit shabby after some month working exclusively with VS2010. The only feature I still was missing in VS is VFP’s command window. But then I found a little something called FastSharpForm written by Matthew Manela (see below)</font></p> <p><a title="FastSharpForm - Rapid .NET Scripting Created by Matthew Manela" href="http://matthewmanela.com/projects/fastsharp/" rel="nofollow" target="_blank"><font color="#a5a5a5"><img title="FastSharpForm" style="border-width: 0px; display: inline;" border="0" alt="FastSharpForm" src="http://matthewmanela.com/wp-content/uploads/2009/05/FastSharpForm.png" width="240" height="190" /></font></a><font color="#a5a5a5"> </font></p> <p><font color="#a5a5a5">So, now I can hack in a simple line containing a C# expression or even a whole code block and click [run] – an Voilà! there it is, the result (or an error :-) Just like using VFP’s command window – well, almost. To be honest, still, there are missing a lot of well-known VFP features. But who knows, maybe Matthew will add some of them to his smart little helper in the future!</font></p> <p><font color="#a5a5a5"></font></p> <p><font color="#a5a5a5"></font></p> <font color="#a5a5a5"> <hr /></font> <p><font color="#a5a5a5"><strong><em>Tuesday, February 15, 2011, 23:22:00</em></strong> </font></p> <p><font color="#a5a5a5">Just “recovering” from the second removal within one year (the third within the last two years) - From now on the old saying: “Three removals are as bad as fire” makes much more sense! <br />After more than three month without any stable internet connection, it was good to see my VFP blog today filled with many comments waiting to be accepted/published. I am happy to see that there are many people still out there willing to read my writings. <br />At first glance, Visual FoxPro is getting closer to the binary nirvana year after year? (;-) Hold on! There is life in the old dog yet, and I am going to prove that pretty soon! Thus, stay tuned and be prepared…</font></p> <p><font color="#808080"></font></p> <p><font color="#808080"></font></p> <font color="#808080"> <hr /></font> <div style="color: rgb(68, 68, 68); font-family: verdana,sans-serif; background-color: rgb(204, 204, 204);"><font color="#a5a5a5"><strong><em></em></strong></font><font color="#a5a5a5"><strong><em></em></strong></font><font color="#a5a5a5"><strong><em>Wednesday, September 15, 2010, 09:25:00</em></strong> Finally published an old demo (a VFP exe) you may want to play with while waiting for “the real thing” – the <strong><em>One and Only Native VFP TreeView</em> :-) <a href="http://myvfpblog.blogspot.com/2008/02/native-treeview-part-iv-b.html" target="_blank"><font color="#a5a5a5">http://myvfpblog.blogspot.com/2008/02/native-treeview-part-iv-b.html</font></a></strong> <strong><em>Thursday, August 26, 2010, 16:25:00</em></strong> Since </font><font color="#a5a5a5">my last posting some months went by neither giving me time to write any blog updates nor adding new stuff as expected. Please, don’t blame me for that! Even if I would like to post much more, reality is that driving this blog is only my hobby and not my profession. Beside my VFP work I began learning C# (using VS2010) which is another good exculpation for not fostering these pages during the past months.</font></div> <div style="color: rgb(68, 68, 68); font-family: verdana,sans-serif; background-color: rgb(238, 238, 238);"> <div style="color: rgb(68, 68, 68); background-color: rgb(204, 204, 204);"><strong><u><font color="#000000"></font></u></strong></div> <div style="color: rgb(68, 68, 68); background-color: rgb(204, 204, 204);"><strong><u><font color="#a5a5a5">There are some unfinished “projects” I started here that I definitely will bring to a presentable/usable state!</font></u></strong></div> <div style="color: rgb(68, 68, 68); background-color: rgb(204, 204, 204);"><font color="#a5a5a5"><strong>1.) The “ominous” native VFP tree view</strong>. This still is a “living” work in progress! It was (and still is!) attracting interest! What’s going on “behind the green door” is that I’m busily working on some essential speed improvements, which tend to be much more than simple refactorings!</font></div> <div style="color: rgb(68, 68, 68); background-color: rgb(204, 204, 204);"><font color="#a5a5a5"><strong>2.) The Global Resource Manager</strong>. This also is a work in progress! In fact, I’m actually working on that solution (parallel to writing these lines)!</font></div> <div style="color: rgb(68, 68, 68); background-color: rgb(204, 204, 204);"><font color="#a5a5a5"><strong>3.) The Complete Foxtools Reference</strong>. Again, this isn’t forgotten, but does not have that high priority ATM.</font></div> <div style="color: rgb(68, 68, 68); background-color: rgb(204, 204, 204);"><font color="#a5a5a5"><strong>4.) The RTF2HTML Converter</strong>. I dropped that project because there are enough free plug-ins available that do that job very well.</font></div> <div style="color: rgb(68, 68, 68); background-color: rgb(204, 204, 204);"><font color="#a5a5a5"><strong>5.) VFP’S BASICS</strong>. My initial intension when starting this thread was to have a place where I can pile up my own OOP-related findings and believing so that I’m able to look them up whenever I needed to do so. Still, part II & III have to be written, even part I needs to be polished up, but like my Foxtools reference, this isn’t flagged “urgent” ATM.</font><font color="#a5a5a5"></font></div> </div>Burkhardhttp://www.blogger.com/profile/11631168041975170500noreply@blogger.com0tag:blogger.com,1999:blog-26167158.post-87136287864082476432015-01-24T15:52:00.000+01:002015-01-24T17:44:46.607+01:00Latest News<p><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-foxtools.html"><img title="Foxtools Home" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="Foxtools Home" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgztd-3jktLLMOg9ST2Cf1vzRIXP2Nroxgv6HjE4BouQzG-OQfR2LLZ0EH4Cf539UwGcdeRa7IqSSDJ6mFHM31fXwJwljFRZQ9lP5s7S1cb-2NyLl1DHTCVhi7aOtzR623gkcLb/?imgmax=800" width="32" height="43" /></a><a href="http://myvfpblog.blogspot.com/2009/09/foxquill-more-than-framework-foxquill.html"><img title="FoxQuill Home" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="FoxQuill Home" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1zgkKmj9gQC__ig5t-A7EmcZBdapbVTJmW9jXkyz8wur700nmtDR-zzpgJ0usFZcL8bD6wI4mdeYochIBZNwcK5sLThdD3Ibq8qT4qfxbenUbBtAD6IoEtY0oS5eAjtUFMUO9/?imgmax=800" width="48" height="64" /></a><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-vfpx-projects-this.html"><img title="VFPX Projects Home" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="VFPX Projects Home" src="http://lh4.ggpht.com/_MOmDLu4Rm5Y/SsG7vGV-2cI/AAAAAAAACCg/LnG3L-Zc1d4/Home_64_RGBA%5B1%5D.png?imgmax=800" width="64" height="85" /></a><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-miscellaneous-diverse.html"><img title="Miscellaneous Home" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="Miscellaneous Home" src="http://lh6.ggpht.com/_MOmDLu4Rm5Y/SsG7vWR74gI/AAAAAAAACCk/lkw3az3-eZA/Home_72_RGBA%5B1%5D.png?imgmax=800" width="72" height="96" /></a><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-windows-api-calling.html"><img title="Windows API Home" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="Windows API Home" src="http://lh3.ggpht.com/_MOmDLu4Rm5Y/SsG7vnG_i1I/AAAAAAAACCs/CXrlkWDBfqw/Home_96_RGBA%5B1%5D.png?imgmax=800" width="96" height="128" /></a><img title="News Home" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="News Home" src="http://lh3.ggpht.com/_MOmDLu4Rm5Y/SsG7wTrojkI/AAAAAAAACCw/Ai2538g7Awg/Home_128_RGBA%5B1%5D.png?imgmax=800" width="160" height="160" /><a title="http://myvfpblog.blogspot.com/2009/09/basics-home.html" href="http://myvfpblog.blogspot.com/2009/09/basics-home.html"><img title="Basics Home" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="Basics Home" src="http://lh4.ggpht.com/_MOmDLu4Rm5Y/SsG7w6mLMQI/AAAAAAAABs4/ZMCZlQncCSU/Home_96_RGBA%5B4%5D.png?imgmax=800" width="96" height="128" /></a><a title="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-tips-tricks-in-this.html" href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-tips-tricks-in-this.html"><img title="Tips&Tricks Home" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="Tips&Tricks Home" src="http://lh5.ggpht.com/_MOmDLu4Rm5Y/SsG7xcpCfLI/AAAAAAAABtA/lHwWlG5m9hI/Home_72_RGBA%5B4%5D.png?imgmax=800" width="72" height="96" /></a><a title="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-toolbox-in-this-section.html" href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-toolbox-in-this-section.html"><img title="Toolbox Home" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="Toolbox Home" src="http://lh6.ggpht.com/_MOmDLu4Rm5Y/SsG7xkSynnI/AAAAAAAABtE/t_FSa245s8o/Home_64_RGBA%5B4%5D.png?imgmax=800" width="64" height="85" /></a><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-complex-controls-no.html"><img title="Complex Controls Home" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="Complex Controls Home" src="http://lh3.ggpht.com/_MOmDLu4Rm5Y/SsG7yZVAklI/AAAAAAAACC4/gYXsXhOhQAo/Home_48_RGBA%5B2%5D.png?imgmax=800" width="48" height="64" /></a><a title="http://myvfpblog.blogspot.com/2009/09/neat-solutions-home.html" href="http://myvfpblog.blogspot.com/2009/09/neat-solutions-home.html"><img title="Neat Solutions Home" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="Neat Solutions Home" src="http://lh6.ggpht.com/_MOmDLu4Rm5Y/SsG7yqemKGI/AAAAAAAABtQ/XQgXPDq6Mw8/Home_32_RGBA%5B4%5D.png?imgmax=800" width="32" height="43" /></a> <br /></p> <hr /> <h1 style="font-family: verdana,sans-serif; color: #444444; background-color: #cccccc"><span style="font-size: x-large"><img title="VogelStrauss" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; margin: 43px 10px 0px; display: inline; border-top-width: 0px" border="0" alt="VogelStrauss" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiC64UnSsynX9EtiqoslWeOZCzL0CfJl2gSbA6i0eJwZbw7yOQh2K7Jkug8ysKM267162L-vAK7rMuTXkDexaZl6cM4EveMzViI32MPbAfVL5fbtZX47at5Vsk7ctyQ1NiGFv6T/?imgmax=800" width="131" align="left" height="131" /> </span><span style="font-size: small"></span></h1> <h1><font color="#000080"><strong><span style="font-size: x-large">Latest News</span><span style="font-size: small"> </span></strong></font></h1> <span style="font-size: small"></span> <h4><font color="#000080">This section of my VFP Blog gets filled at random times and with random content. <br /></font><font color="#000080">One could say, this is the remaining most blog-like part of my VFP Blog. <br /></font><font color="#000080">Most of the entries will be dealing with what I’ve added to the other sections of my blog lately. </font><font color="#000080">Thus, it seems to be a good idea to always check <em>The News</em> first…</font></h4> <p>.</p> <p>.</p> <p>.</p> <hr /> <p><strong>Saturday, January 24<sup>th</sup>, 2015</strong></p> <p><font style="background-color: #ffff00" size="5"><strong>Important Note</strong></font></p> <p>I’m just in the middle of restructuring my domains. I dropped some of them and moved some others from all over the place to one single provider. Now, it is easier for me to handle them. You know, a single provider means: one place to go for all tasks, which is nice. Although I prepared the task pretty well, alas, <strong><em>I forgot to backup my Foxpro files referenced from within this blog</em></strong>. This morning it was too late to do that. My German FoxQuill.de web-space was dropped dead. It was a really small web-space just holding some images and files and: I do have a local copy of all files missing at the moment! But, it will take me some time to upload them all up again… In the meanwhile, there will be no downloads available on my entire VFP-blog, <strong><em>which I’m awfully sorry for</em></strong>!</p> <p>I’m going to port this whole blog space to my German <em><font style="background-color: #ffff00"></font></em><em><font style="style">FoxQuill.de</font></em> site. Don’t panic it will still be written in English! :-) </p> <p>Finally, this blog-space will only hold the latest news, the headlines of what I recently added to my German FoxQuill site. It will become a kind of referrer, a handle for those who came and still come here to read the latest, and one fine day the last news about Visual FoxPro…</p> <p>Stay tuned, I will be up and running FoxQuill.de in a few weeks. </p> <hr /> <p><strong>Sunday, September 7<sup>th</sup>, 2014</strong></p> <p><font color="#000000"><font size="4"><strong>Added "ADSs, Hard Links & Junctions" under WINAPI And VFP Internals section <br /></strong></font></font>This post is about Alternate Data Streams, Hard Links and Junctions (it's still under construction) <font color="#000000"><a title="ADSs, Hard Links & Junctions link" href="http://myvfpblog.blogspot.com/2014/09/adss-hard-links-junctions.html" target="_blank"><img title="ADSs, Hard Links & Junctions link" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="ADSs, Hard Links & Junctions link" src="http://lh4.ggpht.com/-dedEE5rDc7M/VAyW0Q_OvmI/AAAAAAAAIYs/EdIrEJogPw8/OffSiteLink%25255B14%25255D.png?imgmax=800" width="11" height="7" /></a></font> </p> <hr /> <p><strong>Sunday, September 7<sup>th</sup>, 2014</strong></p> <p><font color="#000000"><font size="4"><strong>Added "Into The Void" under WINAPI And VFP Internals section  <br /></strong></font></font>This post is about another "Unknown" – <strong><em><font color="#9b00d3"><font color="#333333">The </font>.VOID.</font></em></strong> <font color="#000000"><a title="The Missing Type link" href="http://myvfpblog.blogspot.com/2014/09/the-missing-type-void.html" target="_blank"><img title="The Missing Type link" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="The Missing Type link" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiR7cYyNkqUsOeH4RI6BG89MY6bJKqKRfN2wxHlxSc0-ssaXi5FSg2JVvO6AT4XlNtKX7W3e6uxkofM54-VOkDVLgstOrEFLrhsSvHxO-p2GrDk90V4IYbDEmAgS_4X4q0G_3w5/?imgmax=800" width="11" height="7" /></a></font> </p> <hr /> <p><strong>Saturday, September 6<sup>th</sup>, 2014</strong></p> <p><font color="#000000" size="4"><strong>Added "The Madlen Effect" under WINAPI And VFP Internals section <br /></strong></font></p> <p>There is some almost unknown behavior that can be applied on any temporary VFP coursor. Madlen was the first VFP developer I know, who to dig that out! Exciting… <font color="#000000"><a title="The Madlen Effect link" href="http://myvfpblog.blogspot.com/2014/09/the-madlen-effect.html" target="_blank"><img title="The Madlen Effect link" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="The Madlen Effect link" src="http://lh5.ggpht.com/-zK4D6EZw-XE/VAyGQKQIvqI/AAAAAAAAIX8/ENAJeRWhEMw/OffSiteLink%25255B5%25255D.png?imgmax=800" width="11" height="7" /></a></font> </p> <hr /> <p><strong>Saturday, September 6<sup>th</sup>, 2014</strong></p> <p><font color="#000000" size="4"><strong>Added "The Scope Resolution Operator" under WINAPI And VFP Internals section <br /></strong></font></p> <p>Using VFP's <a href="http://msdn.microsoft.com/en-US/library/8ehdyws9(v=vs.80).aspx">Scope Resolution Operator</a> definitely is my least used method invocation strategy. Sounds familiar, right? Then, why is that so? Go and get the whole story… <font color="#000000"><a title="The Scope Resolution Operator link" href="http://myvfpblog.blogspot.com/2014/09/how-to-jump-over-hidden-hurdle.html" target="_blank"><img title="The Scope Resolution Operator link" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="The Scope Resolution Operator link" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUsJ7tAY9cBRMGSrHqnV4-5KQlZWqRb6os4iMbbmTD0MHD9da92krHydqqgCRgt2qc7ElTMDD7uFFaaI_H4TqYxkKchY5zfbmcxYyNFn3wM-0m0jf_r3dLBWcvTwCCaL0WK9sI/?imgmax=800" width="11" height="7" /></a></font> </p> <hr /> <p><strong>Saturday, September 6<sup>th</sup>, 2014</strong></p> <p><font color="#000000"><font size="4"><strong>Updated WINAPI And VFP Internals section  <br /></strong></font></font>There are a lot of new topics there – I'm just busily working on that threads <font color="#000000"><a title="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-windows-api-calling.html" href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-windows-api-calling.html" target="_blank"><img title="WINAPI And VFP Internals" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="WINAPI And VFP Internals" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcGIflsW2p-br2lCVfDVaK4jwtm-2JpeUzqJReZAjGI2uy59VZ7sO8OzEqH-wmHvJHxM2ZTIoXLiFWTXhnHEKzsZq28AcOFo7jlBhZpPclEzMgir73431vec6IPR5bYu-HcFDv/?imgmax=800" width="11" height="7" /></a></font> </p> <hr /> <p><strong><font color="#a5a5a5">Tuesday, September 2<sup>nd</sup>, 2014</font></strong></p> <p><font color="#a5a5a5"><font size="4"><strong>Updated Visual FoxPro – Toolbox section <br /></strong></font>Curious? Have a peek ;-) </font><a title="http://myvfpblog.blogspot.com/2014/03/preprocessor-and-compile-time-constants.html" href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-toolbox-in-this-section.html" target="_blank"><font color="#a5a5a5"><img title="Visual FoxPro – Toolbox section " style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Visual FoxPro – Toolbox section " src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-2Y8wjvnq0BD8nQ9UDVr0BP4lBjeaUGTzHuHBj6afSYeK3vRe5fcLWpfYozN-g9UggYllmvE0XwG6iRMJjYf20hpK1KvkIPmbvG68fgetfJMY3oF67E950uiwgS3rO6PUNUPQ/?imgmax=800" width="11" height="7" /></font></a><font color="#a5a5a5"> </font></p> <font color="#a5a5a5"> <hr /></font> <p><strong><font color="#a5a5a5">Tuesday, September 2<sup>nd</sup>, 2014</font></strong></p> <p><font color="#a5a5a5"><font size="4"><strong>Restructured my Windows API blog section  <br /></strong></font>I changed Windows API section to "WINAPI and VFP Internals" to hold more VFP-related contend. I didn't find the time to post some useful WINAPI examples anyway. This is an invitation to all VFP-Hackers: come in and have a look :-) </font><a title="http://myvfpblog.blogspot.com/2014/03/preprocessor-and-compile-time-constants.html" href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-windows-api-calling.html" target="_blank"><font color="#a5a5a5"><img title="Restructured Windows API Blog Section" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Restructured Windows API Blog Section" src="http://lh4.ggpht.com/-bEOeVRrnqRM/VAUxy6aPxFI/AAAAAAAAIPQ/Uq_ZbrokjTM/OffSiteLink%25255B4%25255D.png?imgmax=800" width="11" height="7" /></font></a><font color="#a5a5a5"> </font></p> <font color="#a5a5a5"> <hr /></font> <p><strong><font color="#a5a5a5">Tuesday, September 2<sup>nd</sup>, 2014</font></strong></p> <p><font color="#a5a5a5"><font size="4"><strong>Added "How to Jump Over the Hidden Hurdle" <br /></strong></font>This is a detailed examination of VFP's <strong><em>Scope Resolution Operator</em></strong> behavior, and what can be done with it beside invocation of some parent class behavior… </font><a title="http://myvfpblog.blogspot.com/2014/03/preprocessor-and-compile-time-constants.html" href="http://myvfpblog.blogspot.com/2014/08/vfp-basics-part-3.html" target="_blank"><font color="#a5a5a5"><img title="How to Jump Over the Hidden Hurdle" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="How to Jump Over the Hidden Hurdle" src="http://lh6.ggpht.com/-F_ExKyX9U1c/VAUVR_6FajI/AAAAAAAAIPY/-6zY_W905DI/OffSiteLink%25255B5%25255D.png?imgmax=800" width="11" height="7" /></font></a><font color="#a5a5a5"> </font></p> <font color="#a5a5a5"> <hr /></font> <p><strong><em><font color="#a5a5a5">Monday, September 1<sup>st</sup>, 2014</font></em></strong></p> <p><font color="#a5a5a5"><font size="4"><strong>Added VFP's BASICS (Part 3) <br /></strong></font>This is the <em>entry point</em> into a set of more general discussions like Multiple Inheritance, AOP, Multitasking, Design-b-Contract, and so on  </font><a title="http://myvfpblog.blogspot.com/2014/03/preprocessor-and-compile-time-constants.html" href="http://myvfpblog.blogspot.com/2014/09/how-to-jump-over-hidden-hurdle.html" target="_blank"><font color="#a5a5a5"><img title="VFP's BASICS (Part 3)" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="VFP's BASICS (Part 3)" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicELWLHaTewyY0iqssqdtDI6OpIxxkyl6EuUoU1EzylRPp_n_C64jJu5kxuoSaeBjdydlE_3MV-reRQheCdWot2SQBQ2vb69me3mRN4GS4Vnd6agq7nyVu_4AfvhXnsHWhro-Z/?imgmax=800" width="11" height="7" /></font></a><font color="#a5a5a5"> </font></p> <font color="#a5a5a5"> <hr /></font> <p><strong><em><font color="#a5a5a5">Sunday, August 31, 2014</font></em></strong></p> <p><font color="#a5a5a5"><font size="4"><strong>Added VFP's BASICS (Part 2) <br /></strong></font>Go and get your own copy of one of the most fundamental <strong><em>definite book</em></strong> about OOP here </font><a title="http://myvfpblog.blogspot.com/2014/03/preprocessor-and-compile-time-constants.html" href="http://myvfpblog.blogspot.com/2014/08/vfp-basics-part-2.html" target="_blank"><font color="#a5a5a5"><img title="VFP's BASICS (Part 2)" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="VFP's BASICS (Part 2)" src="http://lh6.ggpht.com/-JBko1YwfEUU/VANKKQ3BMOI/AAAAAAAAIJc/IHjo2ftjjGA/OffSiteLink%25255B4%25255D.png?imgmax=800" width="11" height="7" /></font></a><font color="#a5a5a5"> </font></p> <font color="#a5a5a5"> <hr /></font> <p><font color="#a5a5a5"><strong><em>Thursday, July 23, 2014, 19:25:00</em></strong> </font></p> <p><font color="#a5a5a5"><font size="4"><strong>Started "VFPX – FoxUnit"  <br /></strong></font>Lets get involved in VFP-based Unit-Testing. I will publish this series of posts under my <strong><em>VFPX Projects</em></strong> section, because of the FoxUnit project which is maintained by the VFPX Community today. Unit-Testing is only one aspect of an overall testing approach which should encompass <strong><em>Integration</em></strong>- and <strong><em>Acceptance-Testing</em></strong> as well. Go and get a first overview here </font><a title="http://myvfpblog.blogspot.com/2014/03/preprocessor-and-compile-time-constants.html" href="http://myvfpblog.blogspot.com/2014/07/vfpxfoxunit.html" target="_blank"><font color="#a5a5a5"><img title="VFPX – FoxUnit" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="VFPX – FoxUnit" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4BogLp0AxoHEsIh8GnXVrDB176CHVrrLFiTt_OFEovhKQhH4ROGvemz_TyCR6OMtz1G8namDlvbiECIHZh5SseBDwvd0A-ZFTpPUwDbdfkFXpI5qU8CBNiqfmHj1Nw0bY1Lop/?imgmax=800" width="11" height="7" /></font></a><font color="#a5a5a5"> </font></p> <hr /> <p><font color="#a5a5a5"><strong><em>Friday, March 28, 2014, 15:36:00</em></strong> </font></p> <p><font color="#a5a5a5"><font size="4"><strong>Started "Dynamic Declarations and Value Assignments"  <br /></strong></font>I must admit, the title of this post is a little bit misleading. Primarily, I only wanted to write about the bad habit of using VFP's Macro Substitutions over and over again instead of utilizing faster native commands. But in this context, there still is more to talk about. Thus, I started a more generally blog post dealing with any kind of native optimization, where 'native' means replacing a slow VFP command with another, faster one. I'm looking for your comments an additions! See you there! </font><a title="http://myvfpblog.blogspot.com/2014/03/preprocessor-and-compile-time-constants.html" href="http://myvfpblog.blogspot.com/2014/03/dynamic-declarations-and-value.html"><font color="#a5a5a5"><img title="Dynamic Declarations and Value Assignments" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Dynamic Declarations and Value Assignments" src="http://lh6.ggpht.com/-hne4zeTMkCY/UzWI6oxOlbI/AAAAAAAAIEg/cc9VVC3RpJ4/OffSiteLink%25255B4%25255D.png?imgmax=800" width="11" height="7" /></font></a><font color="#a5a5a5"> </font></p> <font color="#a5a5a5"> <hr /></font> <p><font color="#a5a5a5"><strong><em>Friday, March 28, 2014, 03:25:00</em></strong> </font></p> <p><font color="#a5a5a5"><font size="4"><strong>Added "Write protection for Properties"  <br /></strong></font>It took me a long way to find my favorite implementation for read-only properties in VFP. It had to be a fast one; it had to be a solid one (taking my forgetfulness into account); it had to be a generic one, and it had to support the concept of <em>Friends Classes</em> so that I could Unit test-drive my classes easily… </font><a title="http://myvfpblog.blogspot.com/2014/03/preprocessor-and-compile-time-constants.html" href="http://myvfpblog.blogspot.com/2014/03/write-protection-for-properties.html"><font color="#a5a5a5"><img title="Write protection for Properties" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Write protection for Properties" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTzaV41-tpj3SCTH84CuynlJpKINFo1s3n7AKsriwumzitz-Pkas6uI1VOrF6TUOxlDxozRMZn07Z8w6Ucz9lRGNNXzH5I8fSuqIfFeJTWUzV7UaBnOAx5daYZQuG7U8a3g3_z/?imgmax=800" width="11" height="7" /></font></a><font color="#a5a5a5"> </font></p> <font color="#a5a5a5"> <hr /></font> <p><font color="#a5a5a5"><strong><em>Thursday, March 27, 2014, 22:23:00</em></strong> </font></p> <p><font color="#a5a5a5"><font size="4"><strong>Added some "good to know" facts about VFP's preprocessor <br /></strong></font>Can there be anything cool about include files, #DEFINE statements and the way how VFP's preprocessor heckles them? I think so! Go an form an opinion about it yourself </font><a title="http://myvfpblog.blogspot.com/2014/03/preprocessor-and-compile-time-constants.html" href="http://myvfpblog.blogspot.com/2014/03/preprocessor-and-compile-time-constants.html"><font color="#a5a5a5"><img title="Some "Secrets" of VFP's Preprocessor Revealed" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Some "Secrets" of VFP's Preprocessor Revealed" src="http://lh5.ggpht.com/-R0kH0ZibxKg/UzSWv4VtdRI/AAAAAAAAID4/8FoslSpcKP8/OffSiteLink%25255B4%25255D.png?imgmax=800" width="11" height="7" /></font></a><font color="#a5a5a5"> </font></p> <hr /> <p><font color="#cccccc"><strong><em>Tuesday, March 18, 2014, 10:45:00</em></strong> </font></p> <p><font color="#cccccc"><font size="4"><strong>Added a neat solution – A ProjectHook "On Steroids" <br /></strong></font>Create a VCX ClassLib and code it in under 5 minutes - enjoy all day long </font><a href="http://myvfpblog.blogspot.com/2014/03/a-diet-hook-on-steroids.html"><font color="#cccccc"><img title="A Diet Hook On Steroids" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="A Diet Hook On Steroids" src="http://lh3.ggpht.com/-iTEfQWMJDwg/UygYxZrhNRI/AAAAAAAAIEA/TT_JwJ1f4TM/OffSiteLink%25255B5%25255D.png?imgmax=800" width="11" height="7" /></font></a><font color="#cccccc"> </font></p> <font color="#cccccc"> <hr /></font> <p><font color="#cccccc"><strong><em>Saturday, March 8, 2014, 00:10:10</em></strong> </font></p> <p><font color="#cccccc"><font size="4"><strong>Started publishing my FoxQuill Framework <br /></strong></font>Bon Appétit! </font><a href="http://myvfpblog.blogspot.com/2009/09/foxquill-more-than-framework-foxquill.html"><font color="#cccccc"><img title="FoxQuill yet another VFP Framework" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="FoxQuill yet another VFP Framework" src="http://lh4.ggpht.com/-tl-GQ5ZoHkg/UxqJqNThypI/AAAAAAAAICc/YixyPOHzG18/OffSiteLink%25255B5%25255D.png?imgmax=800" width="11" height="7" /></font></a><font color="#cccccc"> </font></p> <font color="#cccccc"> <hr /></font> <p><font color="#cccccc"><strong><em>Saturday, March 1, 2014, 00:05:00</em></strong> </font></p> <p><font color="#cccccc"><font size="4"><strong>Updated my Basics <br /></strong></font>There is new content at the end of my VFP's BASICS(Part 1) document. I finally added my rules #19 to #21 there. Enjoy! </font><a href="http://myvfpblog.blogspot.de/2008/04/vfp-editor-code-rtf2html-part-6.html"><font color="#cccccc"><img title="VFP's BASICS (Part 1)" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="VFP's BASICS (Part 1)" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7Q0TN98L8n7SY-eRaxQBPVYHAVo6L9RHPLeO1VsB5a9J1iDd4zw2ORnTQyeK1O7iFmduTXIiEbMWxK3am5AoLmpOErhcYCgjWA88gaokwSSD7FKWKbE6tu_G3H6EQB1zkLZWR/?imgmax=800" width="11" height="7" /></font></a></p> <font color="#cccccc"> <hr /></font> <p><font color="#cccccc"><strong><em>Thursday, January 10, 2014, 16:05:00</em></strong> </font></p> <p><font color="#cccccc"><font size="4"><strong>>> Fast Forward >>  <br /></strong></font>Wow, this is awesome! More than two years passed by without giving me enough spare time to write some lines like these! </font><font color="#cccccc">Today is my 55th anniversary. I’m still looking forward to finally complete some of my “never ending stories” here. Therefor, I will reactivate one of my older VFP sites (one will be </font><a href="http://www.foxquill.de"><font color="#cccccc">www.foxquill.de</font></a><font color="#cccccc">), because it seems easier to write and publish longer essays like I do via some dedicated internet site than to use this Google blog like I did in the past. I will only use this blog to announce new additions and updates I’ve made on my FoxQuill site.</font><font color="#cccccc"></font></p> <p><font color="#cccccc"></font></p> <hr /> <p><font color="#cccccc"><font size="1"><strong><em>Wednesday, August 30, 2011, 06:05:00</em></strong> </font></font></p> <p><font color="#cccccc"><font size="4"><strong><font size="3">As time goes by… </font> <br /></strong></font>I finished my C# course and passed the examine. Now, instead of starting using it, I’m facing a new challenge: <br />I need to set up some Apache-based internet sites (with cool interactivity)! Thus, I started learning (renewing) PHP and ALAX. <strong><em>I’m afraid, learning will never end</em></strong> :-)</font></p> <p><font color="#cccccc">I’m still working on my VFP TreeView (but not spending too much time on it at the moment). At least I will make a download link available. <br />I’m going to add more chapters to my FoxTools reference in the future as well as to my OOP-basics chapters, and: I have written an new exhaustive post about cool and unknown(!) </font><a title="http://myvfpblog.blogspot.com/2011/05/cool-vfp-event-binding.html" href="http://myvfpblog.blogspot.com/2011/05/cool-vfp-event-binding.html"><strong><font color="#cccccc">EVENTBINDING features</font></strong></a><font color="#cccccc">! <br /> <br />Finally, I’m afraid, I have to stop posting long “articles” here on this blog because of missing free time. Creating new VFP blog entries using my current blogger template is too time-consuming. I will reset this VFP blog to one of the common/regular layouts, so I can publish my future VFP-related latest news here in minutes, not in hours.</font></p> <p><font color="#cccccc">I won’t drop my VFP-related activities completely – never ever! But there will be another platform for my activities (watch out on </font><a href="http://www.alligora.com" target="_blank"><font color="#cccccc">www.alligora.com</font></a><font color="#cccccc">). </font></p> <font color="#cccccc"> <hr /></font> <p><font color="#a5a5a5"><strong><em>Monday, July 18, 2011, 13:00:00</em></strong> </font></p> <p><font color="#a5a5a5">Some of you found all my download links broken last days. This was caused by a high jacking attack on my CMSystem I was running on my FoxQuill.de website. I missed an important maintenance upgrade and found my CMS site cracked short time later. So, take my advice and never miss any CMS upgrades! I deleted my CMS test-drive installation (containing my blogger-resources as well). Thus, sorry for going offline for some days, now you should be able to download again. <br /> </font></p> <hr /> <p><font color="#a5a5a5"><strong><em>Monday, May 02, 2011, 24:00:00</em></strong> </font></p> <p><font color="#a5a5a5">Another step towards the final release of my native TreeView: I added the first part of hierarchical indexing </font><a title="http://myvfpblog.blogspot.com/2011/05/hierarchical-table-order-part-i.html" href="http://myvfpblog.blogspot.com/2011/05/hierarchical-table-order-part-i.html"><font color="#a5a5a5"><img title="hierarchical indexing for nerds ;-)" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="hierarchical indexing for nerds ;-)" src="http://lh5.ggpht.com/_MOmDLu4Rm5Y/Tb9gV7uqJEI/AAAAAAAAHhU/JeqhcEjqJ70/icon_go_up%5B8%5D.gif?imgmax=800" width="15" height="15" /></font></a><font color="#a5a5a5"> <br />Let me introduce to you *Bruno* – my RR </font><a title="http://myvfpblog.blogspot.com/2011/04/bruno-my-rr-rhodesian-ridgeback.html" href="http://myvfpblog.blogspot.com/2011/04/bruno-my-rr-rhodesian-ridgeback.html"><font color="#a5a5a5"><img title="Bruno my RR" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Bruno my RR" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxzQRsReLcWN_7L6quoP628xRXZh3-V2FzxqgYUzttgOp8HOQh1j8sp4i25rdN3NC89ffkweIG7XK5YM2MLEDRSjHOs43SgexV4Spa1DphQXJvfHENQ1gKqU8-5G5sl-Q8G3jE/?imgmax=800" width="15" height="15" /></font></a><font color="#a5a5a5"> </font></p> <font color="#a5a5a5"> <hr /></font> <p><font color="#a5a5a5"><strong><em>Friday, April 29, 2011, 22:25:00</em></strong> </font></p> <p><font color="#a5a5a5">Finally I found some time to start filling some old gaps; I added a first entry under the </font><a title="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-vfpx-projects-this.html" href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-vfpx-projects-this.html"><font color="#a5a5a5">VFPX projects section</font></a><font color="#a5a5a5"> </font><a title="http://myvfpblog.blogspot.com/2011/04/vfpx-help-file-corrected-supported-and.html" href="http://myvfpblog.blogspot.com/2011/04/vfpx-help-file-corrected-supported-and.html"><font color="#a5a5a5"><img title="Go to Post" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Go to Post" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBXYqWjTW73QU_XZ-08jjV2m-v9olh55Fkjf4mN_-gwY_KAZbhS8Sv9Us361MqycN26Obey779qmYmFw0ISetoZ1E1aLPChDWO4lXGRvWotEg6HxWHLvyyPHjd_HKPCQyUROlt/?imgmax=800" width="15" height="15" /></font></a><font color="#a5a5a5"> <br />Next, I restructured my </font><a title="http://myvfpblog.blogspot.com/2009/09/foxquill-more-than-framework-foxquill.html" href="http://myvfpblog.blogspot.com/2009/09/foxquill-more-than-framework-foxquill.html"><font color="#a5a5a5">FoxQuill framework section</font></a><font color="#a5a5a5"> because I am going to post new entries there ASAP. </font><a title="http://myvfpblog.blogspot.com/2011/04/foxquill-becomes-foxquillnet.html" href="http://myvfpblog.blogspot.com/2011/04/foxquill-becomes-foxquillnet.html"><font color="#a5a5a5"><img title="Go to Post" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Go to Post" src="http://lh6.ggpht.com/_MOmDLu4Rm5Y/Tbsh1JfWlJI/AAAAAAAAHb8/1-Holrp-JRU/icon_go_up%5B9%5D.gif?imgmax=800" width="15" height="15" /></font></a><font color="#a5a5a5"> <br />Last but not least, my native TreeView story develops further. There are only two or three post left to describe some needed background.</font></p> <font color="#a5a5a5"> <hr /></font> <p><font color="#a5a5a5"><strong><em>Monday, April 25, 2011, 23:45:00</em></strong> </font></p> <p><font color="#a5a5a5">As announced: I added a new entry under my “Tips & Tricks” section >>> <strong><em>LOADPICTURE() Function – Some Myths Revealed</em></strong>. </font><a title="http://myvfpblog.blogspot.com/2011/04/loadpicture-functionsome-myths-revealed.html" href="http://myvfpblog.blogspot.com/2011/04/loadpicture-functionsome-myths-revealed.html"><font color="#a5a5a5"><img title="Go to Post" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Go to Post" src="http://lh4.ggpht.com/_MOmDLu4Rm5Y/TbXuHrkocpI/AAAAAAAAHZc/bFb-_Bl5PTY/icon_go_up%5B7%5D.gif?imgmax=800" width="15" height="15" /></font></a><font color="#a5a5a5"> <br />Started publishing some thoughts under my framework section “FoxQuill”, too. </font><a title="http://myvfpblog.blogspot.com/2009/09/foxquill-more-than-framework-foxquill.html" href="http://myvfpblog.blogspot.com/2009/09/foxquill-more-than-framework-foxquill.html"><font color="#a5a5a5"></font></a><a title="http://myvfpblog.blogspot.com/2009/09/foxquill-more-than-framework-foxquill.html" href="http://myvfpblog.blogspot.com/2009/09/foxquill-more-than-framework-foxquill.html"><img title="Go to Post" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Go to Post" src="http://lh4.ggpht.com/_MOmDLu4Rm5Y/TbXuH6ETEXI/AAAAAAAAHcA/5i8teUbuXxI/icon_go_up%5B7%5D.gif?imgmax=800" width="15" height="15" /></a></a></a></p> <font color="#a5a5a5"> <hr /></font> <p><font color="#a5a5a5"><strong><em>Tuesday, April 12, 2011, 15:15:00</em></strong> </font></p> <p><font color="#a5a5a5">Added a new “How to…” under my Miscellaneous section. </font><a title="http://myvfpblog.blogspot.com/2008/02/got-seek-you-v6-installed.html" href="http://myvfpblog.blogspot.com/2008/02/got-seek-you-v6-installed.html"><font color="#a5a5a5"><img title="Go to Post" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Go to Post" src="http://lh6.ggpht.com/_MOmDLu4Rm5Y/TbXvH0ERiCI/AAAAAAAAHZk/Dqa5kEgr3pQ/icon_go_up%5B13%5D.gif?imgmax=800" width="15" height="15" /></font></a><font color="#a5a5a5"> <br />Busily working on my final native VFP TreeView. See chapter 5 under my Complex Controls section. </font><a title="http://myvfpblog.blogspot.com/2011/04/native-treeview-part-v.html" href="http://myvfpblog.blogspot.com/2011/04/native-treeview-part-v.html"><font color="#a5a5a5"><img title="Go to Post" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Go to Post" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEje1Iw8stL5giI29gJ1D5d6Jys4O6jKULKBnIl8MfYqizvu7rQXyil-2AQu-2ARZfwOiA1chZ6L-McIoc7NbVZ-Vg7XLe5oUE5YGDiLwDHTmbICyfzRUUZqhM3BfyWIvIqum-op/?imgmax=800" width="15" height="15" /></font></a><font color="#a5a5a5"> <br />Just going to release another very interesting entry under my Tips&Tricks section. Be prepared :-)</font></p> <hr /> <p><font color="#a5a5a5"><strong><em>Monday, April 4, 2011, 23:35:00</em></strong> </font></p> <p><font color="#a5a5a5">Gosh, I started a C# learning course end of last year – 6 month intensive fulltime-training:  8 hours a day! Folks I can tell: many new classes and new concepts to learn but after a while one gets used to it. Especially the VS2010 IDE is cool! VFP’s code editor and class/form designers look a little bit shabby after some month working exclusively with VS2010. The only feature I still was missing in VS is VFP’s command window. But then I found a little something called FastSharpForm written by Matthew Manela (see below)</font></p> <p><a title="FastSharpForm - Rapid .NET Scripting Created by Matthew Manela" href="http://matthewmanela.com/projects/fastsharp/" rel="nofollow" target="_blank"><font color="#a5a5a5"><img title="FastSharpForm" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="FastSharpForm" src="http://matthewmanela.com/wp-content/uploads/2009/05/FastSharpForm.png" width="240" height="190" /></font></a><font color="#a5a5a5"> </font></p> <p><font color="#a5a5a5">So, now I can hack in a simple line containing a C# expression or even a whole code block and click [run] – an Voilà! there it is, the result (or an error :-) Just like using VFP’s command window – well, almost. To be honest, still, there are missing a lot of well-known VFP features. But who knows, maybe Matthew will add some of them to his smart little helper in the future!</font></p> <p><font color="#a5a5a5"></font></p> <p><font color="#a5a5a5"></font></p> <font color="#a5a5a5"> <hr /></font> <p><font color="#a5a5a5"><strong><em>Tuesday, February 15, 2011, 23:22:00</em></strong> </font></p> <p><font color="#a5a5a5">Just “recovering” from the second removal within one year (the third within the last two years) - From now on the old saying: “Three removals are as bad as fire” makes much more sense! <br />After more than three month without any stable internet connection, it was good to see my VFP blog today filled with many comments waiting to be accepted/published. I am happy to see that there are many people still out there willing to read my writings. <br />At first glance, Visual FoxPro is getting closer to the binary nirvana year after year? (;-) Hold on! There is life in the old dog yet, and I am going to prove that pretty soon! Thus, stay tuned and be prepared…</font></p> <p><font color="#808080"></font></p> <p><font color="#808080"></font></p> <font color="#808080"> <hr /></font> <div style="font-family: verdana,sans-serif; color: #444444; background-color: #cccccc"><font color="#a5a5a5"><strong><em></em></strong></font><font color="#a5a5a5"><strong><em></em></strong></font><font color="#a5a5a5"><strong><em>Wednesday, September 15, 2010, 09:25:00</em></strong> Finally published an old demo (a VFP exe) you may want to play with while waiting for “the real thing” – the <strong><em>One and Only Native VFP TreeView</em> :-) <a href="http://myvfpblog.blogspot.com/2008/02/native-treeview-part-iv-b.html" target="_blank"><font color="#a5a5a5">http://myvfpblog.blogspot.com/2008/02/native-treeview-part-iv-b.html</font></a></strong> <strong><em>Thursday, August 26, 2010, 16:25:00</em></strong> Since </font><font color="#a5a5a5">my last posting some months went by neither giving me time to write any blog updates nor adding new stuff as expected. Please, don’t blame me for that! Even if I would like to post much more, reality is that driving this blog is only my hobby and not my profession. Beside my VFP work I began learning C# (using VS2010) which is another good exculpation for not fostering these pages during the past months.</font></div> <div style="font-family: verdana,sans-serif; color: #444444; background-color: #eeeeee"> <div style="color: #444444; background-color: #cccccc"><strong><u><font color="#000000"></font></u></strong></div> <div style="color: #444444; background-color: #cccccc"><strong><u><font color="#a5a5a5">There are some unfinished “projects” I started here that I definitely will bring to a presentable/usable state!</font></u></strong></div> <div style="color: #444444; background-color: #cccccc"><font color="#a5a5a5"><strong>1.) The “ominous” native VFP tree view</strong>. This still is a “living” work in progress! It was (and still is!) attracting interest! What’s going on “behind the green door” is that I’m busily working on some essential speed improvements, which tend to be much more than simple refactorings!</font></div> <div style="color: #444444; background-color: #cccccc"><font color="#a5a5a5"><strong>2.) The Global Resource Manager</strong>. This also is a work in progress! In fact, I’m actually working on that solution (parallel to writing these lines)!</font></div> <div style="color: #444444; background-color: #cccccc"><font color="#a5a5a5"><strong>3.) The Complete Foxtools Reference</strong>. Again, this isn’t forgotten, but does not have that high priority ATM.</font></div> <div style="color: #444444; background-color: #cccccc"><font color="#a5a5a5"><strong>4.) The RTF2HTML Converter</strong>. I dropped that project because there are enough free plug-ins available that do that job very well.</font></div> <div style="color: #444444; background-color: #cccccc"><font color="#a5a5a5"><strong>5.) VFP’S BASICS</strong>. My initial intension when starting this thread was to have a place where I can pile up my own OOP-related findings and believing so that I’m able to look them up whenever I needed to do so. Still, part II & III have to be written, even part I needs to be polished up, but like my Foxtools reference, this isn’t flagged “urgent” ATM.</font><font color="#a5a5a5"></font></div> </div> Burkhardhttp://www.blogger.com/profile/11631168041975170500noreply@blogger.comtag:blogger.com,1999:blog-26167158.post-76808837349750699632014-09-07T18:58:00.000+02:002014-09-07T20:00:10.243+02:00ADSs, Hard Links & Junctions<p><strong><font color="#ff8000" size="3">Version: 1.00.00 - last update: Sunday, September 6, 2014</font></strong></p> <p><a title="WINAPI & VFP Internals (Home)" href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-windows-api-calling.html"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 10px 0px 5px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="WINAPI & VFP Internals (Home)" border="0" alt="WINAPI & VFP Internals (Home)" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiu_gRJH6bbxr7M9eZRnBfu7q6ecI7UVdDvAfr7XGZyX0KT9XFovv3w_ALsr65wCai276cCImajkzDu37SyZEJ-7Lm7szx6LJP79TknW2EOphxWBGxp7ily5KMipq3Kzf4md2c1/?imgmax=800" width="48" height="48" /></a></p> <p><font color="#000000"><font size="2"><strong><font color="#4f81bd">Please note:</font><font color="#4f81bd"> </font></strong><font color="#4f81bd">This is a place holder post, just to create the actual link handles (all these nice-looking </font></font></font><font size="3"><font color="#4f81bd"><font size="2">buttons are the pest if one has to maintain all the linkage between them manually…</font> </font></font></p> <p> <hr /></p> <h3><font color="#4f81bd">This thread is about how to employ some COOL NTFS features</font></h3> <h1><font color="#4f81bd"></font></h1> <h1><font color="#4f81bd">ADSs, Hard Links & Junctions</font></h1> <p> </p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4zMR1QHNg1mfoI3jARd6qQEWu3p4QjhVU5PYOweuLoQAxK02qpMqAfxyFCGCQqKdOaxe4P9gnmZ4Tyjn9gjBs5M465Yrw1n8_ULXy00xgO7h59N_NkQZji5HPODgPTtoMfUWO/s1600-h/outerjunctionsunrollinnersymlink%25255B4%25255D.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="outerjunctionsunrollinnersymlink" border="0" alt="outerjunctionsunrollinnersymlink" src="http://lh3.ggpht.com/-qv232vmJ64Q/VAyaqf4BK2I/AAAAAAAAIZU/g_QQSRojorQ/outerjunctionsunrollinnersymlink_thumb%25255B2%25255D.png?imgmax=800" width="633" height="480" /></a></p> <p align="center"><font size="1"><sup><font size="1"><strong>'OuterJunctionsUnrollInnerSymlink.Png' with friendly permission by </strong></font><a title="Link Shell Extension" href="http://schinagl.priv.at/nt/hardlinkshellext/linkshellextension.html" target="_blank"><font size="1"><strong>Hermann Schinagl</strong></font></a></sup></font><a title="Link Shell Extension" href="http://schinagl.priv.at/nt/hardlinkshellext/linkshellextension.html" target="_blank"><font size="1"></font></a></p> <h3><font color="#4f81bd" size="3">In this post I will show you</font></h3> <ol> <li><font size="3">How to bootstrap/generate whole sets of classes at any level with the help of some <em>very small</em> PRG-based generators. </font></li> <li><font size="3">How 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. </font></li> <li><font size="3">How directories and files can be "decorated" with Alternate Data Streams to transport any of your extended file attributes, and even functionality!</font></li> <li><font size="3">How most of all those files are build using NTFS Hard Links and Directory Junctions. </font></li> <li><font size="3">How easy it is to move and copy your virtual class definitions around.</font></li> <li><font size="3">How your PEMs are represented by simple 'flat' TXT-files (with a .PRG extension)</font></li> </ol> <p><font size="3">Finally, we will create a <strong><em>recursive decent parser/generator</em></strong> based on a ridiculous simple script which is distributed into all directories & sub-directories of our virtual class definition (directory-)tree via NTFS Hard Links. <br />The script is invoked once (at the root class definition), and then recurs through our definitions. At every sub-directory it runs its own Hard Link copy, thus, simulating recursion.</font></p> <p><font size="3">The advantages of this approach are obvious, <em>ahem</em>, <strong>at least to me ;-)</strong></font></p> <p><font size="3"></font></p> <h3><em><font color="#4f81bd"><to be continued…></font></em></h3> <p> </p> <hr /><a title="WINAPI & VFP Internals (Home)" href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-windows-api-calling.html"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 10px 0px 5px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="WINAPI & VFP Internals (Home)" border="0" alt="WINAPI & VFP Internals (Home)" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmRNWoWhtmxSWQ6JgE5ZK_wL1c3NgV9r0ZQV62GihIg34rbfRnYpn_rmUdhjwzegyotEOjnrDB0LjKWrDbKD5i072Ck-Ug4poVhNuqwoyqTjB0ctV0ZPM_vwCptPZgo2PF6HPX/?imgmax=800" width="48" height="48" /></a> Burkhardhttp://www.blogger.com/profile/11631168041975170500noreply@blogger.com0tag:blogger.com,1999:blog-26167158.post-23012712255798453882014-09-07T03:09:00.000+02:002014-09-07T18:16:16.121+02:00The Missing Type – VOID<p><strong><font color="#ff8000" size="3">Version: 1.00.00 - last update: Sunday, September 7, 2014 [created]</font></strong></p> <p><a title="WINAPI & VFP Internals (Home)" href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-windows-api-calling.html"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 5px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="WINAPI & VFP Internals (Home)" border="0" alt="WINAPI & VFP Internals (Home)" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiHL5U3U5ocXD7HRZiqHJXmGEJaJPX-9RPNHL4gHBo89AGlzGzRwc0WON9KfGxZoEckrf9S9YtGO1x-WQVT6zkNmIh_3YQWQXfEAbJRdcX_EIZShbRm0Sbv7mDBhYgEIiMRT-i/?imgmax=800" width="48" height="64" /></a> <br /></p> <hr /> <h3><font color="#4f81bd">Is it possible to really return a 'NOTHING' from a method?</font></h3> <h1><font color="#4f81bd">Intro</font></h1> <p align="justify"><font size="3">FoxPro makes coding easy for us! We are allowed to name our methods <strong>Procedure</strong>s or <strong>Function</strong>s interchangeably. The Fox don't care if we return a value from one of our <strong>Procedure</strong>s, or if we omit it completely! The Fox gracefully adds his own Return .T. and, voilà, nothing can go wrong. What Lucky guys we are!</font></p> <h2 align="justify"><font color="#4f81bd">Some Short Mantras</font></h2> <p align="justify"><font size="3">The following "mantras" should remind you of some basics of almost any (non-functional) programming language.</font></p> <h2 align="justify"><font color="#0000ff" size="3"></font></h2> <h2 align="justify"><font color="#4f81bd">A Function is a Function is a Function</font></h2> <p align="justify"><font size="3">A class method that acts as a <strong><em>function</em></strong> should be declared so (if PRG-based in VFP).</font></p> <p align="justify"><strong><font size="4"><font face="Courier New"><span style="color: #0000ff">Function</span> MyFunc(tcParameter <span style="color: #0000ff">As</span> <span style="color: #0000ff">String</span>) <span style="color: #0000ff">As</span> Boolean</font></font></strong><strong><font size="4"><font face="Courier New"> <br /><span style="color: #0000ff">EndFunc</span></font></font></strong></p> <p align="justify"><font size="3">A Function must return at least on value. One should always code the return statement at the end of the Function, to remember novice VFP programmers of that fact!</font></p> <pre><font size="4"><strong><span style="color: #0000ff">Function</span> MyFunc(tcParameter <span style="color: #0000ff">As</span> <span style="color: #0000ff">String</span>) <span style="color: #0000ff">As</span> Boolean
<span style="color: #0000ff">Return</span> .T.
<span style="color: #0000ff">EndFunc</span></strong></font></pre>
<ul>
<li>
<div align="justify"><font size="3">A Function must not return more than one value (which can be an array in VFP 9, too)!</font></div>
</li>
<li>
<div align="justify"><font size="3">A Function can signal internal malfunctions, or parameter errors (broken contracts), by returning an appropriate error value, or by raising an error!</font></div>
</li>
<li>
<div align="justify"><font size="3">A Function <strong>must never</strong> alter its object's state.</font></div>
</li>
<li>
<div align="justify"><font size="3">A Function obeying to the rules above can be said to be <strong>side effects free</strong>.</font></div>
</li>
</ul>
<p align="justify"><font size="3"></font></p>
<h2 align="justify"><font color="#4f81bd">A Procedure is a Procedure is a Procedure</font></h2>
<p align="justify"><font size="3">A method that acts as a Procedure must be declared so, if PRG-based.</font></p>
<blockquote>
<pre><strong><font size="4"><span style="color: #0000ff">Procedure</span> MyProc(tcParameter <span style="color: #0000ff">As</span> <span style="color: #0000ff">String</span>) <span style="color: #0000ff">As</span> <font color="#9b00d3">Void</font>
<span style="color: #0000ff">EndProc</span></font></strong></pre>
</blockquote>
<ul>
<li>
<div align="justify"><font size="3">A Procedure must never return any value. Thus, its return type is called <font color="#9b00d3"><strong>VOID</strong></font>!</font></div>
</li>
<li>
<div align="justify"><font size="3">A Procedure is allowed to alter its object's state.</font></div>
</li>
<li>
<div align="justify"><font size="3">A Procedure can signal any internal malfunction, or parameter errors (broken contracts), only by raising an error!</font></div>
</li>
<li>
<div align="justify"><font size="3">A Procedure obeying to the rules above can be said to be <strong>well behaved</strong>.
<br /></font></div>
</li>
</ul>
<h3 align="justify"><font color="#4f81bd">What's Not Good About It?</font></h3>
<p align="justify"><font size="3">There's nothing really wrong! If only FoxPro would not return a Boolean .T. value from methods we named <strong>Procedure</strong>s in our code! </font></p>
<p align="justify"><font size="3">Instead of this odd behavior, wouldn't it be much cooler if FoxPro could really return <strong><em>nothing</em></strong> from a Procedure? That would have the consequence that any assignment of the return value of a procedure would raise an error, because one cannot add <strong><em>nothing</em></strong> to a variable.</font></p>
<h3 align="justify"><font color="#4f81bd">Why Would We Like to Have That?</font></h3>
<p align="justify"><font size="3">Maybe novice VFP programmers get tricked by the existence of the return value, wondering what the <.T.> return value is all about?</font></p>
<p align="justify"><font size="3">My personal favorite is that it always brings back my focus to the elemental rules described above! When I come to the point during coding, thinking about to return some value from a method I defined to be a Procedure before, then I'm instantly warned! It always seems to be a good thing to take a short break, or at least a deep breath, and then, start refactoring the formerly procedure-based concept!</font></p>
<p align="justify"><font size="3">Another real existing problem could also be solved. <strong><em><font color="#4f81bd">What if you need an additional value type?</font></em></strong> At the moment we have "U" for undefined, "X" for .Null. and a list of uppercase letters for all other real existing types. What, if we could make a property holding another <em>virtual type</em> of value, namely <font color="#9b00d3"><strong><em>.Void.</em></strong></font> <strong><em><font color="#9b00d3">returning an empty type-letter <" "> when queried</font></em></strong> using VFP's <font color="#0000ff" face="Courier New"><strong>Vartype()</strong></font> and <font color="#0000ff" face="Courier New"><strong>Type()</strong></font> functions?</font></p>
<p align="justify"><font size="3"></font></p>
<table border="2" cellspacing="0" cellpadding="2" width="784"><tbody>
<tr>
<td width="780" align="center">
<p align="center"><font color="#9b00d3"><strong><font size="3">A VOIDED value (.VOID.) is an abstract concept denoting some
<br /><em>Item <font color="#6c0095"><u>Without Content And Type</u></font></em></font></strong></font></p>
</td>
</tr>
</tbody></table>
<h3 align="justify"><font color="#0000ff"></font></h3>
<h3 align="justify"><font color="#0000ff"></font></h3>
<h3 align="justify"><font color="#0000ff"></font></h3>
<p><font color="#0000ff"></font></p>
<font color="#0000ff">
<h3><font color="#0000ff"></font><font color="#4f81bd">How to Engage The Concept?</font></h3>
</font>
<p align="justify"><font size="3">The integration into our existing code base is very simple and looks like this:</font></p>
<blockquote>
<pre><font size="4"><strong><span style="color: #0000ff">Procedure</span> MyProc(tcParameter <span style="color: #0000ff">As</span> <span style="color: #0000ff">String</span>) <span style="color: #0000ff">As</span> <font color="#9b00d3">Void</font>
<span style="color: #0000ff">Return</span> <span style="color: #0000ff">This</span>.Void
<span style="color: #0000ff">EndProc</span></strong></font></pre>
</blockquote>
<p align="justify"><font size="3">The above code overrides the default return value of <.T.> of the <strong><em><font color="#0000ff" face="Courier New">MyProc()</font></em></strong> Procedure. What gets returned <em><strong>now</strong></em> is the content of an property called <font color="#9b00d3"><strong><em>.void.</em></strong></font>
<br />Now, we only have to add the above <strong><em><font color="#0000ff" face="Courier New">Return</font></em></strong> statement to the end of our procedures, that's all it takes!</font></p>
<h3 align="justify"><font color="#4f81bd">What Happens if We Touch <font color="#4f81bd">The Void</font>?</font></h3>
<p align="justify"><font size="3">Not much, unless we try to <strong><em>assign</em></strong> a <em><strong><font color="#4f81bd">voided</font></strong></em> value to another variable/property, or try to use it in calculations. Here come the DOs and DONTs:</font></p>
<h4 align="justify"><font color="#4f81bd">DOs</font></h4>
<p align="justify"><font size="3">We can query a property, or the return value using Vartype() and Type() like so:
<br /><font color="#0000ff" face="Courier New"><strong>VARTYPE(<font color="#000000">m.goReferenz.MyProc()</font>)</strong></font>
<br /></font><font size="3"><font color="#0000ff" face="Courier New"><strong>TYPE("<font style="background-color: #ffff00" color="#000000">m.goReferenz.MyProc()</font>")
<br /></strong></font>Which will give you a <strong><em><font color="#9b00d3">.Void.</font></em></strong> return value, <strong><em>a value of without type and content</em></strong>!</font></p>
<h4 align="justify"><font color="#4f81bd">DONTs</font></h4>
<p align="justify"><font size="3">We <strong><em>cannot</em></strong> assign the property, or return value, to another variable like so:
<br /><font color="#0000ff" face="Courier New"><strong>loRetVal = m.goReferenz.MyProc()</strong></font>  <br />which would throw an exception immediately!</font></p>
<h3 align="justify"><font color="#4f81bd">What Gets Stored in The Void Property Actually?</font></h3>
<p align="justify"><font size="3">Well, to be exact, in VFP <strong><em><font color="#9b00d3">.VOID.</font></em></strong> <strong><em><font color="#9b00d3">is a value represented by a corrupted value structure </font></em></strong>(structure with empty 'ev_type' member). To understand the last sentence we have to know how VFP handles values internally (using C-structures). The elements of the structure describing the value handled by the structure. Short data-types are stored directly within the structure, strings (stored somewhere else in the heap) are pointed to by a special member of the structure. There is more about the VFP C-API basics in VFP's <strong><em>dv_foxhelp.chm</em></strong> file. Try the following URL into your Explorer:</font></p>
<blockquote>
<p align="justify"><font color="#4f81bd" size="3" face="Courier New"><strong>mk:@MSITStore:C:\Program%20Files\Microsoft%20Visual%20FoxPro%209\dv_foxhelp.chm::/html/ad9896fa-643e-48d3-a3b9-d738971e71a3.htm</strong></font></p>
</blockquote>
<p align="justify"><font size="3"><font color="#333333">the link above points to</font> one of the API-chapters called "Parameters in External Libraries".</font></p>
<h2 align="justify"><font color="#4f81bd">How to Get That Damage Done?</font></h2>
<p align="justify"><font size="3">This was cumbersome to find out! I started some years ago with a little test form like shown in the screenshot below. Note, that there will be NO download for the SCX, shown below, because you can write it on your own after having read all this, and if that is still interesting for you afterwards.</font></p>
<p align="justify"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px" title="My first little Void test" border="0" alt="My first little Void test" src="http://lh5.ggpht.com/-OvT1aSv7fzI/VAxcN6_Je4I/AAAAAAAAIXE/YvT7mcpII6o/15.jpg?imgmax=800" width="366" height="481" /></p>
<p align="left"><font size="3">I found VFP's value checking flaw incidentally while experimenting with some specific VFP behavior. At that time, I was chasing for detailed <font color="#0000ff" face="Courier New"><strong><em>.WriteExpression()</em></strong></font> and <font color="#0000ff" face="Courier New"><strong><em>.ReadExpression()</em></strong></font> method behavior, </font><font size="3"><font style="background-color: #ffff00">when I incidentally called the <font color="#0000ff" face="Courier New"><strong>Object.WriteExpression()</strong></font> method passing in an empty value, I encountered errors while trying to access the property subsequently!</font> </font></p>
<p align="justify"><font size="3">I created the above <em>demo form</em> only to preserve my findings. After I had finished my exhaustive observations of VFP's <font color="#0000ff" face="Courier New"><strong><em>.WriteExpression()</em></strong></font>, I came to some very interesting findings, I kept secret - until now…</font></p>
<h3 align="justify"><font color="#4f81bd">Something to Suit my Needs</font></h3>
<p align="left"><font size="3">When I needed a new <em>return value attribute</em> in my framework, I called it <em><strong>contract broken</strong></em>. I restarted thinking about the possibilities how to signal the fact back to a caller, that she just broke the <strong><em>signature contract</em></strong> protecting the current message.</font></p>
<p align="left"><font size="3">One part of any <strong><em>Function Contract</em></strong> covers the return value of the function. A warranted <strong><em>type</em></strong>, and a set of valid <strong><em>values</em></strong> is described in the contract there, <font color="#9b00d3">as well as the values to be returned if an error occurred!</font></font></p>
<p align="left"><font size="3">What could we do in cases where the returned value is of type <em>Variant – <strong>and</strong></em> there are no restrictions on the returned value, too? A returned .Null. value could be valid just as well as any other kind of date. What's still missing is a memory-based equivalent of a <font color="#0000ff" face="Courier New"><strong><em>BLANK</em></strong></font> field value in VFP.
<br /></font><font size="3">Okay, you might argue, in our case it's time to raise an exception. Right you are, I must admit, this is a proven way out of there. But…</font></p>
<p align="left"><font size="3">…signaling any "soft-error" stemming from a broken contract raising a <strong><em>VFP exception</em></strong> definitely is to much (IMHO)! User defined errors should be traded on another message transportation level. Exceptions are reserved for what they are intended to be – for all situations at runtime, <strong><em>where the system runs into a not predicted, invalid state (for whatever un-anticipated reasons)!</em></strong></font></p>
<p align="left"><font size="3">Thus, I designed my framework to never <strong><em>except</em></strong> any other 'return value' from a procedure (method) but the '<strong><em><font color="#9b00d3">.Void.</font></em></strong>' one. Soft-errors are reported back through an IN/OUT parameter that is passed in through a parameter object.</font></p>
<h3 align="justify"><font color="#4f81bd">How to Apply The Void?</font></h3>
<p align="justify"><font size="3">We could implement a protection scheme for our PEMs. If a caller isn't authorized to query our instance we could simply return our void property value and watch the <em><strong>"Kaboooom!" </strong></em>:-)</font></p>
<p align="justify"><font size="3">We also are able to change the <em>voided</em> property value from the inside. This could become handy in some internal programming scenarios: Chaining of procedure calls can be written more easily, if the involved procedures return some Boolean value all together, like so:</font></p>
<blockquote>
<pre><font size="3"><strong><span style="color: #008000">*\\_____________________________________</span>
<span style="color: #008000">*// Work the ToDoList</span>
<span style="color: #0000ff">Do</span> <span style="color: #0000ff">Case</span>
<span style="color: #0000ff">Case</span> Not <span style="color: #0000ff">This</span>.CheckPermission()
<span style="color: #0000ff">This</span>.<span style="color: #0000ff">Log</span>([<span style="background-color: #ffff00; color: red">CheckPermissionError</span>])
<span style="color: #0000ff">Case</span> Not <span style="color: #0000ff">This</span>.LoadConfig()
<span style="color: #0000ff">This</span>.<span style="color: #0000ff">Log</span>([<span style="background-color: #ffff00; color: red">LoadConfigError</span>])
<span style="color: #0000ff">Case</span> Not <span style="color: #0000ff">This</span>.BuildObject()
<span style="color: #0000ff">This</span>.<span style="color: #0000ff">Log</span>([<span style="background-color: #ffff00; color: red">BuildObjectError</span>])
<span style="color: #0000ff">Case</span> Not <span style="color: #0000ff">This</span>.StartObject()
<span style="color: #0000ff">This</span>.<span style="color: #0000ff">Log</span>([<span style="background-color: #ffff00; color: red">StartObjectError</span>])
<span style="color: #0000ff">Otherwise</span>
<span style="color: #008000">*\\_______________________________</span>
<span style="color: #008000">*// Start main app<br /></span></strong></font><font size="3"><strong><span style="color: #0000ff"> This</span>.StartEngine()
<span style="color: #0000ff">This</span>.ShowGui()
<span style="color: #0000ff">This</span>.ReadEvents()
<span style="color: #0000ff">This</span>.HouseKeeping()
<span style="color: #0000ff">EndCase</span></strong></font></pre>
</blockquote>
<blockquote>
<p align="justify"><font size="3">One nice thing is that we can change the real value of our <font color="#9b00d3">.void.</font> property from the inside on the fly! We are able to store any other 'unbroken' values there temporarily. Thus, to run the last example code above, we would simply store <.T.> to our <font color="#0000ff" face="Courier New"><strong><em>This.Void</em></strong></font> property before running the <font color="#0000ff" face="Courier New"><strong><em>Do Case</em></strong></font> chain above. Afterwards, we will reset our property back to its <font color="#000000"><em>voided</em></font> value.</font></p>
</blockquote>
<p align="justify"><font size="3">To make our code bullet-prove, we have to check all occurrences of VFP's <font color="#0000ff" face="Courier New"><strong><em>Vartype()</em></strong></font> and <font color="#0000ff" face="Courier New"><strong><em>Type()</em></strong></font> functions in our code, and try to evaluate, if a <em><font color="#9b00d3">.v</font><font color="#9b00d3">oid. </font></em>scenario might apply in one or more of our contexts!</font></p>
<p align="justify"><font size="3">The following code fragment shows us how to to test a property at runtime fail-safe:</font></p>
<blockquote>
<pre><strong><font size="3"><span style="color: #0000ff">If</span> <span style="color: #0000ff"><font color="#9b00d3"><em>Empty</em></font></span>(<span style="color: #0000ff">Vartype</span>(m.loInstance.<font color="#9b00d3">void</font>)
<span style="color: #0000ff">DebugOut</span> "<span style="background-color: #ffff00; color: red">Class instance is Void!</span>"
<span style="color: #0000ff">Endif</span></font></strong></pre>
</blockquote>
<p align="justify"><font size="3">We cannot test the return value of a method without running its behavior. Thus there is not much we can do <strong><em>to trap for a returned <font color="#9b00d3">void</font> value</em></strong>. Thus, there should be an appropriate documentation, or even better, an <em>Intellisense</em>-based guidance available, telling us what methods are functions and what other methods are procedures that will return <strong><em><font color="#9b00d3">THE </font><font color="#9b00d3">.VOID.</font></em></strong>!</font></p>
<h2 align="justify"><em><font color="#4f81bd">Some Evil Pitfall</font></em></h2>
<p align="justify"><font style="background-color: #ffff00" size="3">It may happen to you, that this trick doesn't work: You cannot call you object's <font color="#0000ff" face="Courier New"><em><strong>WriteExpression()</strong></em></font> without throwing an exception! </font></p>
<p align="justify"><font size="3">It took me some time spent on a lot of <em>investigative</em> testing to find out what causes this misbehavior to appear. This is not a trivial one, because it forces us to adapt out overall implementation strategy…</font></p>
<p align="justify"><font color="#9b00d3" size="3"><em>Stay tuned!</em></font></p>
<p align="justify"><em><font color="#9b00d3" size="3"></font></em></p>
<h3 align="justify"><em><font color="#4f81bd"><to be continued…></font></em></h3>
<p align="justify"> </p>
<hr />
<a title="WINAPI & VFP Internals (Home)" href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-windows-api-calling.html"><img style="background-image: none; border-right-width: 0px; margin: 10px 0px 5px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="WINAPI & VFP Internals (Home)" border="0" alt="WINAPI & VFP Internals (Home)" src="http://lh6.ggpht.com/-jAnfOA7heak/VAxcOtgfPRI/AAAAAAAAIXM/iPYzd0nnOMI/Home_48_RGBA84%25255B11%25255D.png?imgmax=800" width="48" height="64" /></a> Burkhardhttp://www.blogger.com/profile/11631168041975170500noreply@blogger.com0tag:blogger.com,1999:blog-26167158.post-23624264883907951792014-09-06T20:13:00.001+02:002014-09-07T19:03:47.740+02:00The Madlen Effect<p><strong><font color="#ff8000" size="3">Version: 1.00.00 - last update: Saturday, September 6, 2014</font></strong></p> <p><a title="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-windows-api-calling.html" href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-windows-api-calling.html"><img style="background-image: none; border-right-width: 0px; margin: 10px 0px 5px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="WINAPI & VFP Internals (Home)" border="0" alt="WINAPI & VFP Internals (Home)" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEid958rsLticHbxrT4bTBOlRzOqFAztc1PVTuHPhcYo4x2gpNxTc3cSSzarJcAM5HHCjCU6thoQLj0BQ0m0FbxbuIg6s-Hh5Mu1JwAmThS0v2aJHYLBjxa1MSputkcQIzDw3n9-/?imgmax=800" width="48" height="48" /></a></p> <hr /> <h3><font color="#4f81bd">This Thread is About Some Native VFP Cursor Behavior</font></h3> <p><font size="3">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 <em>that</em> '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. Madlen allowed me liberally to post about her findings on this blog. </font></p> <p><font size="3">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.</font></p> <p><font size="3"></font></p> <h1><em><font color="#4f81bd">The Madlen Effect</font></em></h1> <p><font size="3">Madlen discovered that, if you create a temporary cursor using an array-based schema definition stemming from a schema array created using VFP's <strong><em><font color="#0000ff" face="Courier New">AFields()</font></em></strong>, you better have to be very careful! Madlen used one of the DBC-based 'master' tables as her schema source, just as we all would have done it. Alas, in this particular case, the schema source table had some triggers attached. Naturally, these trigger expressions were caught by VFP's <font color="#0000ff" face="Courier New"><strong><em>AFIELDS()</em></strong></font> function, and got transferred into Madlen's schema definition array. From there they were applied to the new temporary cursor. What could I say, I think you might already have guessed it: <strong><em><font style="background-color: #ffff00" color="#0000ff">The trigger were alive in the newly created cursor, too!</font></em></strong> </font></p> <p><font size="3">Such an <strong><em><font color="#4f81bd">undocumented(?) side-effect</font></em></strong> may cause you a lot of headache! Not so much if you incidentally close the trigger procedure, which would raise a traceable exception immediately, but <strong><em>in cases you are not aware of the triggered behavior at all</em></strong>, wondering about 'strange' values appearing in you temporary cursor, <em>obviously</em> without any good reason…</font></p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQ-vjYbDE96h15V2T9UQtwQgsmhKY8_tjHKZ0G6LPyRo8Xz3IeED71Txor0r2I7Cw5HCLdFIxWcfPuhYXOk3mikET12QOJad1MlCMn614zT30urOuvz7LvqDzV1fCWRDpYGPqD/s1600-h/picard-fail_499x3276.jpg"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px" title="picard-fail_499x327" border="0" alt="picard-fail_499x327" src="http://lh3.ggpht.com/-j4zRCvTKD_0/VAtO0jNVgqI/AAAAAAAAIV8/y0R4FlO-GC8/picard-fail_499x327_thumb4.jpg?imgmax=800" width="519" height="347" /></a></p> <p align="center"><sup><strong><font color="#333333" size="1">I know, how that hurts…</font></strong></sup></p> <p><font color="#000000" size="3">I'm currently refactoring my top level modules' asynchronous message queues to incorporate VFP Cursors! What a show: Semi-persistent message queue stacks that don't pollute my DBC, but behave like the <strong><em><font color="#4f81bd">Big DBC-Bros</font></em></strong> do – somehow slick ;-)</font></p> <p><font color="#000000" size="3"><strong><em><to be continued…></em></strong></font></p> <hr /><a title="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-windows-api-calling.html" href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-windows-api-calling.html"><img style="background-image: none; border-right-width: 0px; margin: 10px 0px 5px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="WINAPI & VFP Internals (Home)" border="0" alt="WINAPI & VFP Internals (Home)" src="http://lh6.ggpht.com/-cYZyvW7sJJY/VAtO1FvChfI/AAAAAAAAIWE/v2B9LVkQmSI/Home_48_RGBA8%25255B1%25255D.png?imgmax=800" width="48" height="48" /></a> Burkhardhttp://www.blogger.com/profile/11631168041975170500noreply@blogger.com0tag:blogger.com,1999:blog-26167158.post-5040738182598382592014-09-06T03:30:00.000+02:002014-09-06T03:52:06.938+02:00VFP's BASICS (Code Generation)<p><strong><font color="#ff8000" size="3">Version: 1.00.00 - last update: Saturday, August 6, 2014</font></strong></p> <p> <p><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Multitasking in VFP" border="0" alt="Multitasking in VFP" src="http://lh4.ggpht.com/-9fhUrQT17P4/VApoutin-3I/AAAAAAAAISY/EgciNrqt57I/NavBack_48_RGBA141%25255B4%25255D.png?imgmax=800" width="48" height="64" /><a href="http://myvfpblog.blogspot.com/2009/09/basics-home.html"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Basics Home" border="0" alt="Basics Home" src="http://lh3.ggpht.com/_MOmDLu4Rm5Y/SsUm3ohH8ZI/AAAAAAAACK0/h6E9WYaWceA/NavHome_48_RGBA6.png?imgmax=800" width="48" height="64" /></a><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Feature Harvesting" border="0" alt="Feature Harvesting" src="http://lh5.ggpht.com/-0tkWqidJmGU/VApovG0mPmI/AAAAAAAAISc/x2lyYS9fhj4/NavForward_48_RGBA%25255B4%25255D.png?imgmax=800" width="48" height="64" />  <hr /></p> <h3><font color="#0000ff">This Thread is About Code Generating Strategies</font></h3> <p><font color="#000000" size="3">This is a place holder post, just to create the actual link handles (all these nice-looking </font><font color="#000000" size="3">buttons are the pest if one has to maintain all the linkage between them… </font></p> </p> <p><font color="#000000" size="3"><strong><em><a href="http://lh6.ggpht.com/-YkCU6shNHkM/VApovgwpEMI/AAAAAAAAISo/j8goOLT_KF8/s1600-h/NewBooks001%25255B3%25255D.jpg"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="Domain Specific Language books" border="0" alt="Domain Specific Language books" src="http://lh3.ggpht.com/-Z1YrhNB6cwY/VApowB08eJI/AAAAAAAAISs/U71tHITpmTc/NewBooks001_thumb.jpg?imgmax=800" width="219" height="244" /></a></em></strong></font></p> <p align="center"><sup><strong><font color="#333333" size="1">Some books I've read lately…</font></strong></sup></p> <p> </p> <p><font color="#000000" size="3">I'm currently working on a native VFP code parsing engine that is able to build all kinds of useful tree structures: Document-, Syntax, Code-, Inheritance, Object-, and Dependency-Trees, to name the most important. These tree structures, then, can be consumed by transformers, and generators to yield the desired output…</font></p> <p><font color="#000000" size="3"><strong><em><to be filled with content soon…></em></strong></font></p> <p><font size="3"></font></p> <p><font size="3"></font></p> <p><font size="3"><em></em></font></p> <hr /> <p><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Multitasking in VFP" border="0" alt="Multitasking in VFP" src="http://lh6.ggpht.com/-5dhEzbljBgM/VApowp2J8cI/AAAAAAAAIS0/AVTzUEmJ4og/NavBack_48_RGBA147%25255B3%25255D.png?imgmax=800" width="48" height="64" /><a href="http://myvfpblog.blogspot.com/2009/09/basics-home.html"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Basics Home" border="0" alt="Basics Home" src="http://lh3.ggpht.com/_MOmDLu4Rm5Y/SsUm3ohH8ZI/AAAAAAAACK0/h6E9WYaWceA/NavHome_48_RGBA6.png?imgmax=800" width="48" height="64" /></a><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Feature Harvesting" border="0" alt="Feature Harvesting" src="http://lh5.ggpht.com/-9lcc5R3TKgg/VApoxOsKfyI/AAAAAAAAIS8/0kfT0EaXa5A/NavForward_48_RGBA%25255B9%25255D.png?imgmax=800" width="48" height="64" /></p> Burkhardhttp://www.blogger.com/profile/11631168041975170500noreply@blogger.com0tag:blogger.com,1999:blog-26167158.post-21365227347198068012014-09-01T20:24:00.000+02:002014-09-02T02:45:18.282+02:00How to Jump Over the Hidden Hurdle<p><strong><font color="#ff8000" size="3">Version: 1.00.00 - last update: Monday, September 1<sup>st</sup>, 2014</font></strong></p> <p><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-windows-api-calling.html"><img style="background-image: none; border-right-width: 0px; margin: 10px 0px 5px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="WINAPI & VFP Internals (Home)" border="0" alt="WINAPI & VFP Internals (Home)" src="http://lh6.ggpht.com/-4ffL1RQrCAk/VAUKROOcZJI/AAAAAAAAINs/5CceA5cDXiU/Home_48_RGBA%25255B8%25255D.png?imgmax=800" width="48" height="48" /></a></p> <hr /> <h3><font color="#0000ff">Hiding a PEM in Visual FoxPro makes this feature unavailable for reuse and takes it out of inheritance, right? <br /><em><font color="#ff0000">Are You Sure</font><font color="#ff0000">?</font></em></font><font color="#ff0000">…</font></h3> <h1><font color="#0000ff">Intro</font></h1> <p><font color="#000000" size="3">If you've ever wondered what VFP's Scope Resolution Operator <strong><em>really</em></strong> is good for, this is the place to stay!</font></p> <h2><font color="#0000ff">VFP's Scope Resolution Operator (::)</font></h2> <p><font size="3">On the internet, </font><font size="3">there is not much to read about the <em>obviously orphaned</em> <strong>scope resolution operator</strong> provided since VFP 3.0. Most comments run out on telling you that it is better today to use VFP's <font color="#0000ff" face="Courier New"><strong>DODEFAULT()</strong></font> function to forward a message to the precursor.</font></p> <p><font size="3">Well, within the calling context of a simple <font color="#0000ff" face="Courier New"><strong>DODEFAULT()</strong></font> they are right, all together!</font></p> <p><font size="3">But, there is more to say about the <em>scope resolution operator</em> than what's written in the help file, or any internet site I reached so far (while searching for already published information dealing with this topic).</font></p> <p><font size="3">This post assumes that you are familiar with what is written about the <em>scope resolution operator</em> in VFP's documentation. At least, you should have a clue what you can do with it, according to its help file entries.</font></p> <h2><font color="#0000ff">What VFP's Scope Resolution Operator CAN and CAN NOT</font></h2> <p><font size="3">Okay, we know, we have to use the <em>class name</em> instead of the <em>instance name</em> when invoking a <em><strong>Scope Resolution Operator Call</strong></em>. </font><font size="3">L</font><font size="3">et's assume, we want to invoke a method from one of our classes named "SuperContainer" using VFP's <em>SROC</em> like so: </font></p> <p align="center"><font size="3"><font color="#0000ff" face="Courier New"><strong>llOkay = AbstractContainer::GetSecurityHandle(m.lcSecToken, This)</strong></font></font></p> <p align="left"><font size="3">… where <em>AbstractContainer</em> is the name of a parent class somewhere 'above' the current one in the inheritance tree. <font size="3">Let's use the following inheritance pedigree as a basis to ask some questions further below:</font></font></p> <p align="center"><a href="http://lh6.ggpht.com/-o8SDw3GnejM/VAUKRpYazXI/AAAAAAAAIN0/0MAVcDIhO1Y/s1600-h/4%25255B18%25255D.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Inheritance Example" border="0" alt="Inheritance Example" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnA5hjEKKC_u1Q3PuYgVwCE4M4yblj90otiF9ufOAi-EtgDUnVNSQrgTGFdkf-8a5uvdYbXDNIfFw0hkmQmjUuDp_qRBGpCY_2Tj4AP4doZmp2RFh13ypqrGQbWULMzUUzS-V2/?imgmax=800" width="603" height="482" /></a> <br /><font size="1"><strong>(click to enlarge)</strong></font></p> <h2 align="left"><font color="#0000ff">Can you answer the following questions?</font></h2> <ol> <ol> <li><font size="3">Inside a <em><font color="#0000ff" face="Courier New"><strong>ClsCnt_CtrolsHost</strong></font></em> class instance, what class names can be used in a SRO call without raising an exception?</font> </li> <li><font size="3">Can you use a different method name on your ancestor class (can you invoke <font color="#0000ff" face="Courier New"><em><strong>BaseContainer_GUI::<font color="#9b00d3">Move</font>()</strong></em></font> for example if such a method would exist)?</font> </li> <li><font size="3">Can you use the <em>base class name</em> of your class instance within your SRO invocation (can you invoke <font color="#0000ff" face="Courier New"><strong><em><font color="#9b00d3">Container</font>::Click()</em></strong></font> for example)?</font> </li> <li><font size="3">Can you use class names of other instantiated classes that are not part of your current inheritance pedigree (can you invoke <font color="#0000ff" face="Courier New"><strong><em><font color="#9b00d3">Super</font><font color="#9b00d3">Collection</font>::Add()</em></strong></font> for example if an instance of that collection-based class would exist in memory)?</font> </li> <li><font size="3">Can you use the class name of an descendant class (can you invoke <font color="#0000ff" face="Courier New"><strong><em><font color="#9b00d3">ClsCtrlHost_Toolbar</font>::Dock()</em></strong></font> for example if such a method would exist)?</font> </li> <li><font size="3">Can you invoke protected methods (can you invoke <font color="#0000ff" face="Courier New"><strong><em><font color="#0000ff">SuperContainer</font>::<font color="#9b00d3">RegisterItem</font>()</em></strong></font> for example)?</font> </li> <li><font size="3">Can you invoke hidden methods (can you invoke <font color="#0000ff" face="Courier New"><strong><em><font color="#0000ff">AbstractContainer</font>::<font color="#9b00d3">GetSecurityHandle</font>()</em></strong></font> for example)?</font> </li> <li><font size="3">Can you invoke method code "beyond" hidden methods (can you invoke <font color="#0000ff" face="Courier New"><strong><em><font color="#9b00d3">_Container::</font><font color="#9b00d3">GetSecurityHandle</font>()</em></strong></font> for example)?</font> </li> <li><font size="3">Will the SRO invocation on a parent class trigger any event-bound delegates on your current class instance?</font> </li> <li><font color="#9b00d3" size="3"><em>Will a SRO invocation trigger VFP events at all?</em></font></li> <li><font size="3">Will a SRO invocation cause the execution of <em><font color="#0000ff">DODEFAULT()</font></em>s?</font> </li> <li><font size="3">At what inheritance level then does the DODEFAULT() <em>pipelining</em> start?</font></li> <li><font size="3">Are there any behavioral differences between <em><font color="#0000ff">PRG-based</font></em>, <font color="#0000ff">VCX-based</font>, and <font color="#0000ff">M</font><font color="#0000ff">ixed</font> (VCX->PRG-based) classes?</font> </li> <li><font size="3">Is it possible to <em><font color="#0000ff">introduce </font><font color="#0000ff">recursion </font></em>(unwanted, or at will)?</font></li> </ol> </ol> <p><font size="3">As you can see, there's more about the VFP's Scope Resolution Operator than to think it's almost useless :-) Believe me, <strong><em>if you do know all about it</em></strong>, you will get one good new idea after the other how to employ <em>Scope Resolution Operator Calls</em> in unusual ways to solve unusual problems…</font></p> <h2><font color="#0000ff">Ending for today…</font></h2> <p><font size="3">One thing I would never do, even not in my wildest dreams, is to use the Scope Resolution Operator instead of a DODEFAULT(), at least in cases where a 'simple' DODEFAULT() is sufficient! The way I'm primarily using Scope Resolution Operator invocations is using them <em>indirectly</em>, like so:</font></p> <blockquote> <p><font size="3"><font color="#0000ff" face="Courier New"><strong><em>lcRetVal = Evaluate(laAnchestors[3]+"::"+m.lcFeatureName+"()")</em></strong></font></font></p> </blockquote> <p><font size="3">where the <font color="#000000">local <font face="Courier New"><strong><em>laAnchestors</em></strong></font></font> array was filled using one of VFP's <em><strong>reflection</strong>-related</em> function, like so:</font></p> <blockquote> <p><font size="3"><font color="#0000ff" face="Courier New"><strong><em>= ACLASS(laAnchestors, This)</em></strong></font>.</font></p> </blockquote> <p><font size="3"></font></p> <p><font size="3"></font></p> <h1><em><font color="#0000ff"><to be continued…></font></em></h1> <hr /><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-windows-api-calling.html"><img style="background-image: none; border-right-width: 0px; margin: 10px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="WINAPI & VFP Internals (Home)" border="0" alt="WINAPI & VFP Internals (Home)" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHOCSTYdevTPw-jEBBP3BJlyXKgXIrcx8BRsTBY-l4zpsJqxCTe8Ro31DOjYZLkRQe10GIAm30qVIaJnL8EA2NOMtrIAJXqMkDQ2Xwp7GDAWTfp3x76maRPRH33OVxVbMAx-Dt/?imgmax=800" width="48" height="48" /></a> Burkhardhttp://www.blogger.com/profile/11631168041975170500noreply@blogger.com2tag:blogger.com,1999:blog-26167158.post-53410170481273686232014-08-31T18:52:00.000+02:002014-09-06T03:55:12.623+02:00VFP's BASICS (Part 3)<p><span style="color: #0000ff"><span style="font-family: arial"><strong><span style="color: #000080"><font color="#ff6633" size="3">Version: 1.00.01 - Last Update: Monday, September, 1st, 2014</font></span></strong></span></span></p> <p><a href="http://myvfpblog.blogspot.com/2014/08/vfp-basics-part-2.html"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Basics (Part 2)" border="0" alt="Basics (Part 2)" src="http://lh5.ggpht.com/-Cspe90IJRP8/VASVh6elCDI/AAAAAAAAIKk/tc0NPK5vWuE/NavBack_48_RGBA14%25255B1%25255D.png?imgmax=800" width="48" height="64" /></a><a href="http://myvfpblog.blogspot.com/2009/09/basics-home.html"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Basics Home" border="0" alt="Basics Home" src="http://lh3.ggpht.com/_MOmDLu4Rm5Y/SsUm3ohH8ZI/AAAAAAAACK0/h6E9WYaWceA/NavHome_48_RGBA6.png?imgmax=800" width="48" height="64" /></a><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Next Entry" border="0" alt="Next Entry" src="http://lh3.ggpht.com/_MOmDLu4Rm5Y/SsUm3402z5I/AAAAAAAACK8/kqlaOLf4xP4/NavForward_48_RGBA8.png?imgmax=800" width="48" height="64" />  <hr /></p> <h3><font color="#0000ff">This Thread is About OOP BASICS</font></h3> <p><font color="#0000ff"><img style="border-right-width: 0px; margin: 0px 10px 0px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="" border="0" alt="OOP Basics with VFP" align="left" src="http://lh6.ggpht.com/VisualFoxPro9/SDF10MzQWqI/AAAAAAAAA2g/ywQOY9gHm6g/vfp_keyboard%5B4%5D.jpg" width="182" height="178" /></font></p> <p><font size="3">In this thread we will discuss diverse methods that can be used to implement OOP features that are not supported by Visual FoxPro natively.</font></p> <p><font size="3">Most of the time our "discussions" will be based on my FoxQuill framework, which implements features like Multiple Inheritance, Design-by-Contract, Aspect-Orientation, Behavior Injection, and Namespaces, just to name a few.</font></p> <h3><font color="#0000ff">Next Steps</font></h3> <p><font size="3">I will write short posts, which describe some very special (widely unknown/unrecognized) behavior of VFP, that I then can refer to in this more conceptual thread. Thus, you do not only have a theoretical OOP concept, then but also a concrete VFP-based solution that you can use as a starting point to run your own further experiments and implementations.</font></p> <h3><font color="#0000ff">Some Renaming</font></h3> <p><font size="3">As I scanned through my blog I noticed that I never posted any entries under the <strong><font style="background-color: #ffffff" color="#4f9cef">Windows API</font></strong> section. Well, I have tons of things to post there, but no time to do so! </font></p> <p><font size="3">Thus, I decided to expand this section to encompass <strong><em>Unknown VFP Behavior</em></strong>, too! I think, this is a good coupling, because you also can create a lot of 'weird' behavior within VFP using WIN-API calls ;-) To get the most out of it, I will also discuss some features of public FLL libraries that support WIN-API calls in this context.</font></p> <h3><font color="#0000ff">Please Note</font></h3> <p><font size="3">This writing is a work in progress, as I am using this thread to structure the timeline of my upcoming posts (in the first place). Please use it as a starting-point for your lookups. Also keep in mind that most of the <em>more or less unusual things</em> I will discuss here are targeted to <strong><font color="#0000ff">easy migration of VFP code</font><font color="#0000ff"> to other OOP languages</font></strong>. Thus, they may not be that valuable when applied to a <em><font color="#0000ff">VFP-only Project</font></em> lacking that need!</font></p> <hr /> <h1><font color="#0000ff">Overview</font></h1> <p><font size="3">This is an unfinished list of what we will talk about in this section.</font></p> <h4><img style="background-image: none; border-right-width: 0px; margin: 0px 10px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Multiple Inheritance in VFP" border="0" alt="Multiple Inheritance in VFP" align="left" src="http://lh6.ggpht.com/-_Rb8cGMNqX4/VASVimSTSnI/AAAAAAAAIKo/WM2FSQnDmj8/Doc_Light_1%25255B6%25255D.png?imgmax=800" width="54" height="67" /></h4> <h3><font color="#0000ff"></font></h3> <h3><font color="#0000ff">Multiple Inheritance in VFP</font></h3> <p><font size="3">The first question we have to ask is: <em>Should we support multiple inheritance within our platform/framework?</em> This is the most basic decision we have to make, because it will have a deep impact on our whole design! <br /></font></p> <h4><img style="background-image: none; border-right-width: 0px; margin: 0px 10px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Aspect Oriented Programming" border="0" alt="Aspect Oriented Programming" align="left" src="http://lh4.ggpht.com/-LxJmLZX0M4w/VASVjOaHCQI/AAAAAAAAIKw/nsvownlQQnU/Doc_Light_1%25255B11%25255D.png?imgmax=800" width="54" height="67" /></h4> <h3><font color="#0000ff">Aspect Oriented Programming</font></h3> <p><font color="#000000" size="3">Another big point is, to find out if it's possible to support <em>Aspect Oriented Programming</em>, introducing a generic implementation approach of so called <strong><em><font color="#0000ff">CCC</font></em></strong>s. A <strong><em><font color="#0000ff">Cross Cutting Concern</font></em></strong> is a feature (behavior!) that applies to classes used in any layer of our design – it is cross-cutting our horizontal domain layers. A class feature obviously belongs to the <strong><em><font color="#0000ff">CCC Feature Set</font></em></strong> if we find the same method code, and very often even the same method name, in classes belonging to any of our domains like: the GUI-, the BIZ-, and the DAT-Layer. This directly leads us to the following topic… <br /></font></p> <h4><img style="background-image: none; border-right-width: 0px; margin: 0px 10px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Namespaces in VFP" border="0" alt="Namespaces in VFP" align="left" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNZ5WbZKI1cjqFcPonT5JWYf_2QMzVkIt3SleSsS372MkYh2nTm1-VAg_nu8k4Xzkc2WO5W1Ae5L0VhVfYqEjcshSHTrekX_NwFqNUg3i0OiBg9QEGm66GcNqfphEbAacSoeJD/?imgmax=800" width="54" height="67" /></h4> <h3><font color="#0000ff">Namespaces in VFP</font></h3> <p><font size="3">If you ever faced the task to develop a reasonable migration path from your current VFP-based environment to another language, like C++, C#, or JAVA, just to name a few, you must have stumbled over all these weird VFP SET-tings, like <font color="#0000ff" face="Courier New"><strong><em>SET DATASESSION TO n</em></strong></font>, just to name the most prominent one. How can we handle them in other languages? My answer is: <strong><em>Let's introduce namespaces in VFP</em></strong> like I did in my FoxQuill Framework. <br /></font></p> <h4><img style="background-image: none; border-right-width: 0px; margin: 0px 10px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Multitasking in VFP" border="0" alt="Multitasking in VFP" align="left" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjb4Ak-2oGXHiw7WDC5rkpVwl4SO0rxVQZo-n7qILzwTLXpruCyJPaF4e-q0RMTBNvH2R5OaZfCQ42icvbD_1h_1SsDogwALFjvMYvEzeChb-cq5X2Ke0L-MiU521e1dNAse_v/?imgmax=800" width="54" height="67" /><font color="#0000ff"></font></h4> <h3><font color="#0000ff">Multitasking in VFP</font></h3> <p><font size="3">The time for multi-core processing has come! How can we introduce side-effect free multi-threading/tasking in Visual FoxPro? There are some really cool projects on the net targeting this feature (VFPX:<a href="https://vfpx.codeplex.com/wikipage?title=ParallelFox&referringTitle=Home" target="_blank">ParallelFox</a> is the most complete, IMHO). But we want more than just a "simulated" multi-treading based on a bunch of (very slow) VFP-EXE COM-Servers. We need 'Persistable' Message Queues, Conditional Activation, Execution Forking, and the like… <br /></font></p> <h4><a title="Code Generation (root)" href="http://myvfpblog.blogspot.com/2014/09/vfp-basics-code-generation.html"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px 18px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top: 0px; border-right: 0px; padding-top: 0px" title="Code Generation (root)" border="0" alt="Code Generation (root)" align="left" src="http://lh5.ggpht.com/-d8uEOS7QrvM/VAppfsh0nAI/AAAAAAAAITI/P-cXKBKIvIg/Doc_Full_0%25255B5%25255D.png?imgmax=800" width="54" height="67" /></a></h4> <h3><font color="#0000ff">Code Generation</font></h3> <p><font size="3">Sometimes, maybe, you're still using one of the old VFP Dinosaurs called the <em>Menu Generator</em>, even today. Back in the good old FP2.6 days, there were much more of these generators involved to create the finally outputted code. Many of the concepts introduced above cannot be realized without introducing a discrete code generation layer 'filling' VFP's gaps. And, fast and reliable <strong><em>Code Generation</em></strong> heavily depends on a suitable DSL (Domain Specific Language). Thus, we have to grow our own, to enable the following feature set… <br /></font></p> <h4><img style="background-image: none; border-right-width: 0px; margin: 0px 10px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Feature Harvesting" border="0" alt="Feature Harvesting" align="left" src="http://lh4.ggpht.com/-BHBnJCJesTA/VASVlYWWnWI/AAAAAAAAILU/0OQ-y_E4ZZY/Doc_Light_1%25255B27%25255D.png?imgmax=800" width="54" height="67" /><font color="#0000ff"></font></h4> <h3><font color="#0000ff">Feature Harvesting</font></h3> <p><font size="3">So, what's about our existing codebase? Do we have to start all over again to employ the newly introduced concepts? That would be to no avail, then, right? What we ALL need is some kind of code harvesting tool that enables us to analyze even large projects, building <strong><em>Dependence Trees</em></strong> as well as <strong><em>Code DOMs</em></strong>. This abstraction then can be used by our <strong><em>Code Generators</em></strong> to create any desired output… <br /></font></p> <h4><img style="background-image: none; border-right-width: 0px; margin: 0px 10px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Pattern Based Design" border="0" alt="Pattern Based Design" align="left" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgD48Css790cVZlGbH7GWEjNVgGuJCnOgES0cwXKBKr4RAHx5l9SU3Q77Q2XlOvlx2FmhcitqUmCbb9Vrmq0Mj-sITdFrhJdZ4tfxsW9ntBhx694tODFWfY7SCHUldPiZNGkTg1/?imgmax=800" width="54" height="67" /><font color="#0000ff"></font></h4> <h3><font color="#0000ff">Pattern Based Design</font></h3> <p><font size="3">There are design patterns for OOP, AOP, and DSL. I have extend my own <em>Pattern Vocabulary</em> defining additional patterns for Unit-Testing, Workflows, and Messaging. All patterns match internal templates, that can be used to parse, evaluate, extend, and transform data. Basically, my <strong><em>Patterns</em></strong> are abstract feature sets, that can be applied at design/runtime to manipulate, either the class definition, or their instances at runtime. <br /></font><font color="#0000ff" size="3"></font></p> <h4><img style="background-image: none; border-right-width: 0px; margin: 0px 10px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Persistent Objects" border="0" alt="Persistent Objects" align="left" src="http://lh3.ggpht.com/-8WE8qHoVXws/VASVmgY0PnI/AAAAAAAAILk/Rnn8D8l7di0/Doc_Light_1%25255B36%25255D.png?imgmax=800" width="54" height="67" /><font color="#0000ff"></font></h4> <h3><font color="#0000ff">Persistent Objects</font></h3> <p><font size="3">Serializing VFP class instances at runtime isn't that easy. But, if you've got the darn thing to work, you don't want to miss it any more! I've spent a lot of my free time to develop some serializing feature based on VFP-DBFs exclusively (and did it successfully, by the way!). But, what if you are migrating to some SQL-Server based environment. There must be a reasonable fast way to persist and retrieve VFP object(hives) from a <strong><em>set-based</em></strong> Data-Server, too! <br /></font></p> <h4><img style="background-image: none; border-right-width: 0px; margin: 0px 10px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Simplified Signatures" border="0" alt="Simplified Signatures" align="left" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZhjqY-bDO1ehFabjP0OAhyphenhyphenxbD2nmTKeIlBi4_x_AwUOc7H_f9ZKytjCWzScvtgGyvpPPWslOjbtXM1wkTwp3uJ7uEC4I_6Xzv64bOq5isrZZrFje9SCSq45ZqmM4Ipq1dUFVN/?imgmax=800" width="54" height="67" /><font color="#0000ff"></font></h4> <h3><font color="#0000ff">Simplified Signatures</font></h3> <p><font size="3">Do you know <a href="http://upload.wikimedia.org/wikipedia/commons/3/32/Lego_Color_Bricks.jpg" target="_blank">LEGO blocks</a>? Have a look at the picture I've linked and tell me <strong>what you see as an OOP developer?</strong> What made these little blocks so incredible successful? Why is it so easy, even for the untalented, to build (sometimes:-) really impressive <em><font color="#0000ff">Lego-thingies</font></em>? The answer is: Each <em>Lego block</em> has an interface which is very easy to handle! <strong><em>Every 'nub' on the top will fit into <font color="#0000ff">ANY</font> 'slot' in the bottom</em></strong>. Lego blocks only differ in the number of <em>nubs</em> they <em>implement</em>, which makes them distinct from each other. Let's keep the color of a Lego block out of this picture, because it don't belong the Lego block's <em>constructional interface</em>. Think about it for a while! If a Lego block is what we call a class in VFP, what is one <em>nub</em> of a Lego block then? And, how could we <em><font color="#0000ff">apply the uniformity of those nubs</font></em> to our own class features, so that instances of this new breed of classes can be used at runtime to compose large-scaled objects with ease?</font><font size="3"> <br /></font></p> <h4><img style="background-image: none; border-right-width: 0px; margin: 0px 10px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Stop Writing Code" border="0" alt="Stop Writing Code" align="left" src="http://lh4.ggpht.com/-Eu5ou8du-30/VASVnvl1KkI/AAAAAAAAIL0/R-gxY8j0Wlg/Doc_Light_1%25255B44%25255D.png?imgmax=800" width="54" height="67" /><font color="#0000ff"></font></h4> <h3><font color="#0000ff">Stop Writing Code</font></h3> <p><font size="3">This is my favorite continuation of the well-known slogan: <strong><em>Don't repeat yourself!</em></strong> Instead of writing code, we should better write templates, that enables our code generators to do this for us automatically. This will not only increase robustness/reliability, but will also speed up the <em>performance</em> of our complete development cycle! <br /></font></p> <p><font size="3"></font></p> <h4><img style="background-image: none; border-right-width: 0px; margin: 0px 10px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Strongly Typed Class Features" border="0" alt="Strongly Typed Class Features" align="left" src="http://lh5.ggpht.com/-NAmjD22dXS8/VASVoCgMdXI/AAAAAAAAIL8/v_L8VU1IxZw/Doc_Light_1%25255B48%25255D.png?imgmax=800" width="54" height="67" /><font color="#0000ff"></font></h4> <h3><font color="#0000ff">Strongly-Typed Class Features</font></h3> <p><font size="3">Boon and bane of VFP's type system is, that there barely is none. Boon and bane of (for example) C#'s type system is, that you cannot disable it completely… <br />If we want to employ any <strong><em><font color="#0000ff">design by contract enabled</font></em></strong> scheme, you have to employ some kind of type checking sub-system within VFP. Which is, in my humble opinion, easier to achieve, than the other way round: Trying to overcome the restrictions a rigid, strictly typed environment would put on us. <br /> <br /></font></p> <p><font size="3"></font></p> <h4><img style="background-image: none; border-right-width: 0px; margin: 0px 10px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Content Checked Class Features" border="0" alt="Content Checked Class Features" align="left" src="http://lh5.ggpht.com/-XK88mmwAFDk/VASVohzqJ-I/AAAAAAAAIME/31n6Krd6f9I/Doc_Light_1%25255B52%25255D.png?imgmax=800" width="54" height="67" /><font color="#0000ff"></font></h4> <h3><font color="#0000ff">Content-Checked Class Features</font></h3> <p><font size="3">I must admit, this is a poorly chosen term for "Implementing the real <strong>D</strong>esign-<strong>b</strong>y-<strong>C</strong>ontract scheme". But, that's exactly what I want to say: A main feature of the "real" implementation of Design-by-Contract is, that a <strong><em><font color="#0000ff">valid static feature</font></em></strong> (property) must not only hold a value of the right (class-defined) <strong><em>type, </em></strong>but also, in addition to that, must be within valid (class-defined!) boundaries! Both DbC features (strongly typed, and content-checked) are essential ingredients for creating bullet-proof applications.</font><font size="3"> <br /></font></p> <p><font size="3"></font></p> <h4><img style="background-image: none; border-right-width: 0px; margin: 0px 10px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Class And Object Reflection" border="0" alt="Class And Object Reflection" align="left" src="http://lh5.ggpht.com/-evtliOAbsXs/VASVpaBbVUI/AAAAAAAAIMQ/0Zh_xusjrBU/Doc_Light_1%25255B56%25255D.png?imgmax=800" width="54" height="67" /><font color="#0000ff"></font></h4> <h3><font color="#0000ff">Class And Object Reflection</font></h3> <p><font size="3">VFP offers a wide range of <strong><em><font color="#0000ff">Reflection</font></em></strong>-related functionality. But, as usual(?), there are some features missing, especially, if we're working with PRG-based classes only! This makes it necessary to introduce some home-grown <strong><em><font color="#0000ff">Meta-Data based Reflection Management</font></em></strong>, which can be easily migrated as well. <br /></font></p> <p><font size="3"></font></p> <h4><img style="background-image: none; border-right-width: 0px; margin: 0px 10px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="The Open Close Principle" border="0" alt="The Open Close Principle" align="left" src="http://lh4.ggpht.com/-8i8W2cllcv0/VASVp4OYVFI/AAAAAAAAIMY/nn_fkj3p9vw/Doc_Light_1%25255B60%25255D.png?imgmax=800" width="54" height="67" /><font color="#0000ff"></font></h4> <h3><font color="#0000ff">The Open Close Principle</font></h3> <p><font size="3">This is all about implementing the well-known <strong><em>Open Close </em></strong>principle. We should go for <strong><em>closed</em></strong> classes, disallowing modification of their features directly, that are <strong><em>open to extend them</em></strong>, in terms of inheritance, instead. Following the Open-Close-Principle inevitably leads us to another <em>problem domain</em>… <br /></font></p> <p><font size="3"></font></p> <h4><img style="background-image: none; border-right-width: 0px; margin: 0px 10px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Feature Extensibility" border="0" alt="Feature Extensibility" align="left" src="http://lh6.ggpht.com/-maRxYKVMmk8/VASVqZfgYZI/AAAAAAAAIMg/TkhQBmGqFZs/Doc_Light_1%25255B64%25255D.png?imgmax=800" width="54" height="67" /><font color="#0000ff"></font></h4> <h3><font color="#0000ff">Feature Extensibility</font></h3> <p><font size="3">This is all about how to practically manage extensibility at our class level within VFP. We will discuss Hook-Operations, Hidden Feature Layers, Meta-Data driven Extensions, Code Injection, Instance Cloaking, Runtime Compilation, CodeBlock Interpreting, just to name the most common/important ones. <br /></font><font size="3">Finally (<font color="#0000ff">this is damn cool!</font>), MAYBE, I will show you an <strong><font color="#0000ff"><em>unknown but documented (really!)</em> Native VFP behavior</font></strong> I've named <strong><em><font color="#ff0080">Member Runtime Extensions</font></em></strong>.</font></p> <p><font color="#0000ff" size="3"><strong><em></em></strong></font></p> <p><font color="#0000ff" size="3"><strong><em><to be continued…></em></strong></font></p> <p><font size="3"></font></p> <p><font size="3"></font></p> <p><font size="3"><em></em></font></p> <hr /> <p><a href="http://myvfpblog.blogspot.com/2014/08/vfp-basics-part-2.html"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Basics (Part 2)" border="0" alt="Basics (Part 2)" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZzgKeLzFoXYoF2yOYc5w3M_Za_D9Gwi-3kXKd2INFtzFARIW-iWTNgQzWno0XkQ0Dl5AojHDQcMeNYcoGxMiYM4cZzRBIZ3hcZt9enjTrq2gAWq9W6TTqQGzQLVrhzn5SL1pt/?imgmax=800" width="48" height="64" /></a><a href="http://myvfpblog.blogspot.com/2009/09/basics-home.html"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Basics Home" border="0" alt="Basics Home" src="http://lh3.ggpht.com/_MOmDLu4Rm5Y/SsUm3ohH8ZI/AAAAAAAACK0/h6E9WYaWceA/NavHome_48_RGBA6.png?imgmax=800" width="48" height="64" /></a><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Next Entry" border="0" alt="Next Entry" src="http://lh3.ggpht.com/_MOmDLu4Rm5Y/SsUm3402z5I/AAAAAAAACK8/kqlaOLf4xP4/NavForward_48_RGBA8.png?imgmax=800" width="48" height="64" /></p> Burkhardhttp://www.blogger.com/profile/11631168041975170500noreply@blogger.com2tag:blogger.com,1999:blog-26167158.post-69110910671417022152014-08-31T18:10:00.000+02:002014-09-01T17:58:24.502+02:00VFP's BASICS (Part 2)<p><span style="color: #0000ff"><span style="font-family: arial"><strong><span style="color: #000080"><font color="#ff6633">Version: 1.00.00 - Last Update: Sunday, August 31, 2014</font></span></strong></span></span></p> <p><a href="http://myvfpblog.blogspot.com/2008/04/vfp-editor-code-rtf2html-part-6.html"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Basics (Part 1)" border="0" alt="Basics (Part 1)" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1GjTvjqldZed127gn2rT5DOgYKBOt_6hElRxjjcGLp-RGPGUDstbkMHMWZqnrFg5q2YRVB5348NaOnC_k52n2OfO_EEF4QFj0aVdnAxDuURyjpQMr0i8yhAsszDzytAF9Ulk5/?imgmax=800" width="48" height="64" /></a><a href="http://myvfpblog.blogspot.com/2009/09/basics-home.html"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Basics Home" border="0" alt="Basics Home" src="http://lh3.ggpht.com/_MOmDLu4Rm5Y/SsUm3ohH8ZI/AAAAAAAACK0/h6E9WYaWceA/NavHome_48_RGBA6.png?imgmax=800" width="48" height="64" /></a><a href="http://myvfpblog.blogspot.com/2014/08/vfp-basics-part-3.html"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Basics (Part 3)" border="0" alt="Basics (Part 3)" src="http://lh3.ggpht.com/-vsIDy8Gnpsk/VASXnQ55IzI/AAAAAAAAINI/58VJOXxBj6g/NavForward_48_RGBA%25255B4%25255D.png?imgmax=800" width="48" height="64" /></a> </p> <hr /> <h3><strong><font color="#0000ff">This thread is all about OOP BASICS</font></strong></h3> <p><font color="#0000ff"><img style="border-right-width: 0px; margin: 0px 10px 0px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="" border="0" alt="OOP Basics with VFP" align="left" src="http://lh6.ggpht.com/VisualFoxPro9/SDF10MzQWqI/AAAAAAAAA2g/ywQOY9gHm6g/vfp_keyboard%5B4%5D.jpg" width="182" height="178" /></font></p> <p><font size="3">Finally I found a link to a free version of my all time favorite OOP-book:</font></p> <p align="center"><strong><font size="3"><font color="#d51ae3"><em>Object-Oriented <br />Software <br />Construction</em> <br /></font>SECOND EDITION</font></strong></p> <p align="center"><font size="3">by Bertrand Meyer </font></p> <p><font size="3">The 1370 pages are a must read if you want to fully understand some of my own approaches. This definite book has deeply influenced my basic understanding of what good OOP is all about, and changed many of my personal approaches implementing object oriented software with Visual FoxPro! </font></p> <p> </p> <p><a href="http://lh5.ggpht.com/-APVuERiAsLg/VANIXDY9-jI/AAAAAAAAIJI/hnEFCOxLoKE/s1600-h/image%25255B5%25255D.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/-30iH1pS3pew/VANIX3qqYEI/AAAAAAAAIJM/f9fpG48Nmj4/image_thumb%25255B3%25255D.png?imgmax=800" width="639" height="632" /></a></p> <p><font size="3">With such a lecture at hand for free, there is no reason for me to talk about general OOP things any longer! Go and <em>dig them out</em> yourself :-)</font></p> <h4><font color="#0000ff">After having read some chapters…</font></h4> <p><font size="3">… you may get a "feeling" like I did: </font></p> <p><font size="3">Step by step, chapter after chapter I read, I realized that almost all OOP languages, especially the latest .NET incarnations, should have been better invented by some <em><strong>Eiffel</strong></em> programmers!</font></p> <p><font size="3">The many ways Microsoft developers try to mend all those "holes" in their language designs, especially those stemming from a missing <em>Design-by-Contract</em> implementation at compiler level, seem ridiculous; especially, after having read Professor Meyer's brilliant statements about "the real way" of implementing that language feature.</font></p> <p><font size="3">Since my first reading (of the first edition) I tried to implement, at least a subset of, the superb features <em>design-by-contract</em> delivers to the developer, most of the attempts to no avail. </font></p> <p><font size="3">Finally, I had enough <em>good reasons</em> to stop haunting for an Eiffel-like implementation in VFP: <strong><em>too slow, to complex, to time-consuming</em></strong>, just to name a few. </font><font size="3"><font color="#d51ae3">And then I started to write <strong><em>slow, complex and time-consuming Unit-Test</em></strong> instead…</font> <br />…d</font><font size="3">reaming about the ability not only to be able to type-check, but also to be able to content-check my class features at runtime natively, nuking all these nasty Unit-Test scripts to dust!</font></p> <p><font size="3"><em><strong>Sounds familiar to you? I bet!</strong></em></font></p> <p><font color="#d51ae3" size="3"><strong><em>Keep rolling…</em></strong></font></p> <p><font size="3">BTW: Isn't it a <font color="#d51ae3">wonderful color scheme</font> that is used throughout the entire book? ;-)</font><font size="3"></font></p> <hr /><a href="http://myvfpblog.blogspot.com/2008/04/vfp-editor-code-rtf2html-part-6.html"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Basics (Part 1)" border="0" alt="Basics (Part 1)" src="http://lh6.ggpht.com/-YhZvKhVKz9s/VANO4KmSBjI/AAAAAAAAIKI/BZB4SYwW8aI/NavBack_48_RGBA%25255B13%25255D.png?imgmax=800" width="48" height="64" /></a><a href="http://myvfpblog.blogspot.com/2009/09/basics-home.html"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Basics Home" border="0" alt="Basics Home" src="http://lh3.ggpht.com/_MOmDLu4Rm5Y/SsUm3ohH8ZI/AAAAAAAACK0/h6E9WYaWceA/NavHome_48_RGBA6.png?imgmax=800" width="48" height="64" /></a><a href="http://myvfpblog.blogspot.com/2014/08/vfp-basics-part-3.html"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Basics (Part 3)" border="0" alt="Basics (Part 3)" src="http://lh6.ggpht.com/-pmX_i3zXhpI/VASXn_8mweI/AAAAAAAAINM/B-hV7bJigeo/NavForward_48_RGBA%25255B8%25255D.png?imgmax=800" width="48" height="64" /></a> Burkhardhttp://www.blogger.com/profile/11631168041975170500noreply@blogger.com1tag:blogger.com,1999:blog-26167158.post-83781411865121383602014-07-27T19:17:00.000+02:002014-07-27T13:38:01.883+02:00VFPX–FoxUnit<p><strong><font color="#ff8040">Version: 0.01.03 - last update: Sunday, July 27, 2014, 13:37:00 [<font color="#ff0000">fontsize change</font>]</font></strong></p> <p><a title="http://myvfpblog.blogspot.de/2011/04/vfpx-help-file-corrected-supported-and.html" href="http://myvfpblog.blogspot.de/2011/04/vfpx-help-file-corrected-supported-and.html"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="VFPX - Help file corrected, supported, and enhanced" border="0" alt="VFPX - Help file corrected, supported, and enhanced" src="http://lh3.ggpht.com/-kfVbUl07Oh0/U8_uO4qgtXI/AAAAAAAAIHg/6crtUHwAZ_s/NavBack_48_RGBA%25255B6%25255D.png?imgmax=800" width="48" height="64" /></a><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-vfpx-projects-this.html"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="VFPX Projects Home (TOC)" border="0" alt="VFPX Projects Home (TOC)" src="http://lh6.ggpht.com/-_IgMBCM_eNg/U8_uQQYVOOI/AAAAAAAAIHo/ZobIHgg6Jqs/NavHome_48_RGBA%25255B4%25255D.png?imgmax=800" width="48" height="64" /></a><a href="http://lh6.ggpht.com/-izTw9Bo2tXg/U8_uQzeHozI/AAAAAAAAIG4/atii1ClSnk0/s1600-h/NavForward_48_RGBA%25255B7%25255D.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Next Entry" border="0" alt="Next Entry" src="http://lh5.ggpht.com/-1xJN0kp-HCk/U8_uReiEsYI/AAAAAAAAIHA/QFuAxhte_GM/NavForward_48_RGBA_thumb%25255B3%25255D.png?imgmax=800" width="48" height="64" /></a></p> <hr /> <p><font color="#800000" size="3"><strong>Start unit-testing your VFP codebase – it is not too late, never!</strong></font></p> <p><font size="3">In the summer of 2004, </font><a title="http://www.visionds.com" href="http://www.visionds.com" target="_blank"><strong><em><font size="3"><font color="#0000ff">Vision</font><font color="#ff5c0f">pace</font></font></em></strong></a><font size="3"> announced an open-source project called </font><a title="http://www.foxunit.org" href="http://www.foxunit.org" target="_blank"><font size="3">FoxUnit</font></a><font size="3">, based on the Kent Beck book, "Test Driven Development by Example". </font></p> <p><a title="http://www.foxunit.org" href="http://www.foxunit.org" target="_blank"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Visionpace - FoxUnit" border="0" alt="Visionpace - FoxUnit" align="left" src="http://www.foxunit.org/Portals/0/FoxUnit_Logo.gif" width="200" height="79" /></a>              <a href="https://vfpx.codeplex.com/wikipage?title=FoxUnit&referringTitle=Home" target="_blank"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="VFPX - FoxUnit" border="0" alt="VFPX - FoxUnit" src="http://www.aksel.com/whitepapers/FoxUnit_files/image002.jpg" width="240" height="170" /></a></p> <p><font size="3">As an open-source project, it's supported not only by Visionpace developers, but also by other developers using it with full source code. The documentation still is sparse, so it can be tricky to get started. Go and read the rest of Andrew MacNeill's </font><em><font size="3">Using FoxUnit for Test-Driven Development document here </font><a title="http://www.aksel.com/whitepapers/FoxUnit.htm" href="http://www.aksel.com/whitepapers/FoxUnit.htm" target="_blank"><font size="3"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="http://www.aksel.com/whitepapers/FoxUnit.htm" border="0" alt="http://www.aksel.com/whitepapers/FoxUnit.htm" src="http://lh6.ggpht.com/-iNA2B0PseIc/U9TfrdG8KYI/AAAAAAAAIIo/GS2NEwcWkEc/OffSiteLink%25255B1%25255D.png?imgmax=800" width="11" height="7" /></font></a> <br /> <hr /></em></p> <h1><font color="#800000">Intro</font></h1> <p><font size="3">Unit-Testing is nothing new to software developers. In fact, the FoxUnit Unit-Testing application has been around for a while. Today it can be said that it is a pretty stable and reliable VFP solution. The question is: </font></p> <h3><font color="#800000">Why is the application of FoxUnit so uncommon amongst VFP developers?</font></h3> <p align="justify"><font size="3">I always had some good excuses not to use TDD (test driven development) at all. Some of them stemmed from my first experiences I made using FoxUnit a long time ago…</font></p> <p><font size="3"><strong>Unit-Testing in General</strong></font></p> <ul> <li><font size="3">is not easily adopted</font></li> <li><font size="3">is time consuming to implement</font></li> <li><font size="3">needs additional maintenance</font></li> <li><font size="3">can only cover a part of all testing issues</font></li> </ul> <p><font size="3"><strong>FoxUnit Especially</strong></font></p> <ul> <li><font size="3">is not documented very well</font></li> <li><font size="3">seems to be an ongoing, unfinished development effort</font></li> <li><font size="3">does not integrate with VFP very well</font></li> <li><font size="3">uses VFP scripts that require a lot of manual maintenance</font></li> <li><font size="3">does not support mocking natively</font></li> <li><font size="3">does not offer any professional support</font></li> </ul> <p align="justify"><font size="3">…just to name a few. </font><font color="#800000" size="3">But, wait, some of the things mentioned above got better over time!</font></p> <hr /> <h2> </h2> <h2><font color="#800000">Some Facts About FoxUnit (27.07.2014)</font></h2> <p align="justify"><font size="3">FoxUnit is a VFPX project since 2012(?) Thus, there should be a viable, supporting community today, and hopefully in the future, too!</font></p> <p align="justify"><font size="3">The FoxUnit documentation still is pretty sparse. But, hey(!), you are always welcome to change that :-)</font></p> <p align="justify"><font size="3">FoxUnit is a pure developer tool. Thus, there is not much written documentation (as usual). Today we still have to visit the source code to get the best out of it.</font></p> <p align="justify"><font size="3">The good thing about the source code is, that you don't have to study all of it to get started. You don't have to know all about the inner workings of the GUI-related classes immediately. It is enough to concentrate on the behavioral parts of the implementation and the provided templates (VFP scripts) to get started. I will show you what's important and what is not in a later part of this thread.</font></p> <p align="justify"><strong><font color="#800000" size="3"><em><to be continued…></em></font></strong></p> <div align="justify"> <hr /></div> <p align="justify"><a title="http://myvfpblog.blogspot.de/2011/04/vfpx-help-file-corrected-supported-and.html" href="http://myvfpblog.blogspot.de/2011/04/vfpx-help-file-corrected-supported-and.html"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="VFPX - Help file corrected, supported, and enhanced" border="0" alt="VFPX - Help file corrected, supported, and enhanced" src="http://lh3.ggpht.com/-i8wZlI0Qouc/U8_vsgfhsDI/AAAAAAAAIHw/-piMRAkkSvo/NavBack_48_RGBA%25255B11%25255D.png?imgmax=800" width="48" height="64" /></a><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-vfpx-projects-this.html"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="VFPX Projects Home (TOC)" border="0" alt="VFPX Projects Home (TOC)" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmyeJRGfREAupVS50L3qY7dZUFMmygcNCq1J0eGvgWCMaLfZUKPHfRvdGhDPoZ7xtTgPQTjQSl5dpEt8uRSe_WmtHqVB1YAVv-oArZ3Gen81wuXOlf1B3Id-ZkdOIt3tv2EkqK/?imgmax=800" width="48" height="64" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyMUtfggx_1Ip6frCCdwIIxPMDeuCRrra5-h-9yqWSapdlORilXxG8kO0nE6dCeM0mMqLjXnq5ouvYQrds4W9gQhofF8WPi-ws4jYS4yf7ome8-nFmxgPF1TLC3-cWL0PqL-y7/s1600-h/NavForward_48_RGBA%25255B11%25255D.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Next Entry" border="0" alt="Next Entry" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5tA0dZkZCgoj5g0BPE23kFD6OsRLst2Ybgln2qfaQgrOE-QIy6qHKCHd-NDeH5sPqFXa2v2nxZqrO3w5Zy75ILe34ks9LDwuzNPDTuly4kXdBuAhhYwEJG0jGX73XOU4GWTQF/?imgmax=800" width="48" height="64" /></a></p> Burkhardhttp://www.blogger.com/profile/11631168041975170500noreply@blogger.com0tag:blogger.com,1999:blog-26167158.post-51090825053769154622014-03-28T02:06:00.000+01:002014-03-28T15:27:34.500+01:00Dynamic Declarations and Value Assignments<p><strong><font color="#ff8000">Version: 2.00.00 - last update: Saturday, March 22, 2014, 12:30:00</font></strong></p> <p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Previous Entry (disabled ATM)" border="0" alt="Previous Entry (disabled ATM)" src="http://lh5.ggpht.com/_MOmDLu4Rm5Y/SsUqgE1PYwI/AAAAAAAACUw/hcCII_GE0vY/NavBack_48_RGBA6.png?imgmax=800" width="48" height="64" /><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-tips-tricks-in-this.html"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Tips & Tricks Home" border="0" alt="Tips & Tricks Home" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihLfEyfnO4dbE7rc3zyxMN4aApCogItvwVZvHTl2hReEVavmGzzghjw0GTVHzWJueN_w38A_8enHwsVoN8mwFYG6BOwoKFVKAUXXXjhNy4S0kBdlbzhy39kDFA3drmirZBDiLj/?imgmax=800" width="48" height="64" /></a><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Next Entry (disabled ATM)" border="0" alt="Next Entry (disabled ATM)" src="http://lh3.ggpht.com/_MOmDLu4Rm5Y/SsUqg2SyDMI/AAAAAAAACVA/pyUUeRv3T20/NavForward_48_RGBA7.png?imgmax=800" width="48" height="64" /> </p> <hr /> <h4><font color="#0000ff">This is all about how to avoid VFP's Macro Substitutions and other <em>SLOW</em> VFP commands, and how to substitute them with FASTER alternatives using <font style="background-color: #ffff00">VFP9.0</font></font></h4> <h1><font color="#0000ff">Intro</font></h1> <p>In case you do not already have noticed it, let me tell you again: <font color="#000000"><em><font color="#0000ff"><strong>I dislike VFP's Macro Substitutions!</strong></font> </em></font>At least when they are used unnecessarily, because IMHO, this is either evidence for the lack of VFP skills, or even worse, intellectual laziness! In most contexts macro substitutions are superfluous! I will give you examples how to code it the right way instead of lazily using macros. But here will be more…</p> <h3><font color="#0000ff">What will be in here</font></h3> <p>Beneath VFP's <em>Macro Substitution</em> there are a lot of functions and commands that run slower than others which do the same job in VFP 9. I will use this post to collect my findings, either found by myself, or found in the internet (then I will link to the source of course!), to give you a good starting point and a profound platform for your own 'native' speed optimizations.</p> <h3><font color="#0000ff">What will NOT be in here</font></h3> <p>This is not the place to discuss the basics of good programming. E.g. we will not talking about FOR…NEXT loop constructs and that it would be better to initialize variables outside the loop to speed things up. I'll leave this trivia to the plethora of <em>Beginners Books</em> out there in the wild. Go and get one of these if you're just starting your career as a programmer… <br /><strong>Keep in mind:</strong> This is a VFP 9.0 blog! Sure, some VFP 9.0 functionality I'm talking about now wasn't available in older versions. Maybe you still have to use VFP 8.0 (or even 7.0) - What a pity! I do believe that most of us are using VFP 9.0 today. Thus, there will be no discussions in this post how to solve a particular problem with one of the older versions of VFP!</p> <h2><font color="#0000ff">Please let me know!</font></h2> <p>If you have one or more good examples for speeding up your applications by simply replacing a slow VFP command with another faster one, please let me know! Please add a comment at the end of this post. I will review and add it when I'm going to moderate incoming comments next time.</p> <hr /> <h1><font color="#0000ff">Content</font></h1> <p>At the moment this section still is pretty disordered – I'm just starting to collect the tips. I will try to create some kind of useful categorization later.</p> <h3><font color="#0000ff"> <hr />Manipulation of variables</font></h3> <p><strong>Example:</strong> Create a private variable with a name stored in a class property</p> <pre><strong><font size="4"><span style="color: #008000">* Instead of doing it the uncool way:</span>
<span style="color: #0000ff">Local</span> lcName
lcName = <span style="color: #0000ff">This</span>.cVarName
<span style="color: #0000ff">Private</span> &lcName.
</font></strong><strong><font size="4"><span style="color: #008000">* Code it short & sweet like so:</span>
<span style="color: #0000ff">Private</span> (<span style="color: #0000ff">This</span>.cVarName)</font></strong></pre>
<p><strong>Example:</strong> Assign a value to the variable above</p>
<pre><strong><font size="4"><span style="color: #008000">* Instead to prove your brain death:</span>
<span style="color: #0000ff">Local</span> lcName
lcName = <span style="color: #0000ff">This</span>.cVarName
&lcName. = "<span style="background-color: #ffff00; color: red">123456</span>"<br /><span style="color: #008000">* Code it smart like </span></font></strong><strong><font size="4"><span style="color: #008000">this:</span>
<span style="color: #0000ff">Store</span> "<span style="background-color: #ffff00; color: red">123456</span>" <span style="color: #0000ff">TO</span> (<span style="color: #0000ff">This</span>.cVarName)</font></strong></pre>
<p><strong>Note: </strong>Using parenthesis with VFP's STORE command tells FoxPro not to store the value to the memory the variable is pointing to but to the memory the content of the variable is pointing to. A regular variable is called a (named) pointer. What we get when bracketing a variable is a pointer to a pointer, which also is called a <em>handle</em>. You can assign a value to a handle using VFP's STRORE command only!</p>
<h3><font color="#0000ff">
<hr />Restore Saved VFP Settings</font></h3>
<p><strong>Example:</strong> Saving Set("SAFETY")</p>
<pre><strong><font size="4"><span style="color: #0000ff">Local</span> lcSafety <span style="color: #0000ff">AS</span> <span style="color: #0000ff">String</span>
lcSafety = <span style="color: #0000ff">Set</span>("<span style="background-color: #ffff00; color: red">Safety</span>")
<span style="color: #0000ff">Set</span> <span style="color: #0000ff">Safety</span> <span style="color: #0000ff">Off</span>
<span style="color: #008000">*\\ Do wild things now</span>
<span style="color: #008000">*// and when done...</span>
<span style="color: #008000">* Instead of doing it the lazy way:</span>
<span style="color: #0000ff">Set</span> <span style="color: #0000ff">Safety</span> &lcSafety.
<span style="color: #008000">* Code it running fast and keep it portable!</span>
<span style="color: #0000ff">If</span> m.lcSafety == "<span style="background-color: #ffff00; color: red">ON</span>"
<span style="color: #0000ff">Set</span> <span style="color: #0000ff">Safety</span> <span style="color: #0000ff">ON</span>
<span style="color: #0000ff">EndIf</span></font></strong></pre>
<p><strong>Note:</strong> You temporarily saved a VFP setting and changed it to the state you needed. If it is an ON/OFF setting you do NOT need a complete IF…<em>THEN</em>..ELSE construct during restore, but a simple IF…ENDIF only! What do you think runs faster in average? I mean there is a good 50/50 chance that you will not have to reset the setting at all because it was already set just the way you needed it!</p>
<h3><font color="#0000ff">
<hr />Access Fields of an Aliased Table</font></h3>
<p><strong>Example:</strong> Read the value from a field named "PKey" of a table opened under an alias name stored in a property.</p>
<pre><strong><font size="4"><span style="color: #008000">* Instead of taking the long way home:</span>
<span style="color: #0000ff">Local</span> lcAlias
lcAlias = <span style="color: #0000ff">This</span>.cAlias
<span style="color: #0000ff">Return</span> &lcAlias..Pkey
<span style="color: #008000">* Code it as a one-liner and win!</span>
<span style="color: #0000ff">Return</span> <span style="color: #0000ff">Evaluate</span>(<span style="color: #0000ff">This</span>.cAlias+"<span style="background-color: #ffff00; color: red">.Pkey</span>")</font></strong></pre>
<p>Evaluate() runs faster than a Macro Substitution! Thus, you should always prefer Evaluate() to Macro Substitutions when dealing with table.fieldnames access!</p>
<strong><font color="#ff0000"><em>
<p>
<hr /></p>
<p><to be continued…></p>
</em></font></strong>
<hr /><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Previous Entry (disabled ATM)" border="0" alt="Previous Entry (disabled ATM)" src="http://lh5.ggpht.com/_MOmDLu4Rm5Y/SsUqgE1PYwI/AAAAAAAACUw/hcCII_GE0vY/NavBack_48_RGBA6.png?imgmax=800" width="48" height="64" /><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-tips-tricks-in-this.html"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Tips & Tricks Home" border="0" alt="Tips & Tricks Home" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihLfEyfnO4dbE7rc3zyxMN4aApCogItvwVZvHTl2hReEVavmGzzghjw0GTVHzWJueN_w38A_8enHwsVoN8mwFYG6BOwoKFVKAUXXXjhNy4S0kBdlbzhy39kDFA3drmirZBDiLj/?imgmax=800" width="48" height="64" /></a><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Next Entry (disabled ATM)" border="0" alt="Next Entry (disabled ATM)" src="http://lh3.ggpht.com/_MOmDLu4Rm5Y/SsUqg2SyDMI/AAAAAAAACVA/pyUUeRv3T20/NavForward_48_RGBA7.png?imgmax=800" width="48" height="64" /> Burkhardhttp://www.blogger.com/profile/11631168041975170500noreply@blogger.com3tag:blogger.com,1999:blog-26167158.post-12982666939821056382014-03-27T22:09:00.000+01:002014-04-30T13:25:04.862+02:00Write Protection for Properties<p><strong><font color="#ff8000">Version: 2.00.00 - last update: Friday, March 28, 2014, 2:48:00</font></strong></p> <p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Previous Entry (disabled ATM)" border="0" alt="Previous Entry (disabled ATM)" src="http://lh5.ggpht.com/_MOmDLu4Rm5Y/SsUqgE1PYwI/AAAAAAAACUw/hcCII_GE0vY/NavBack_48_RGBA6.png?imgmax=800" width="48" height="64" /><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-tips-tricks-in-this.html"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Tips & Tricks Home" border="0" alt="Tips & Tricks Home" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihLfEyfnO4dbE7rc3zyxMN4aApCogItvwVZvHTl2hReEVavmGzzghjw0GTVHzWJueN_w38A_8enHwsVoN8mwFYG6BOwoKFVKAUXXXjhNy4S0kBdlbzhy39kDFA3drmirZBDiLj/?imgmax=800" width="48" height="64" /></a><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Next Entry (disabled ATM)" border="0" alt="Next Entry (disabled ATM)" src="http://lh3.ggpht.com/_MOmDLu4Rm5Y/SsUqg2SyDMI/AAAAAAAACVA/pyUUeRv3T20/NavForward_48_RGBA7.png?imgmax=800" width="48" height="64" /> </p> <hr /> <h4><font color="#0000ff">This is about a useful, generic protection scheme you may want to add to your Base Classes.</font></h4> <h1><font color="#0000ff">Intro</font></h1> <p>Encapsulating data is one of the basics of OOP design. Protecting a property is called <em>information hiding</em>. Sometimes we do not want data to be totally hidden but accessible without loosing control over its integrity. That's the point when read-only properties come into play. There is no mystery about how to write protect a property in VFP. Just add an _Assign() method to it and you're almost done… unless you have to grant write access for an elected set of other objects, also called <strong><em>Friends</em></strong>.</p> <h3><font color="#0000ff">Once upon a time…</font></h3> <p>… I started trying something like this:</p> <pre><strong><font size="4"><span style="color: #0000ff">Define</span> <span style="color: #0000ff">Class</span> MySpecialOne <span style="color: #0000ff">As</span> <span style="color: #0000ff">Custom</span>
yResult = $0.0000
<span style="color: #0000ff">Protected</span> <span style="color: #0000ff">Procedure</span> yResult_Assign
<span style="color: #0000ff">Lparameters</span> tyResult <span style="color: #0000ff">As</span> <span style="color: #0000ff">Currency</span>
<span style="color: #0000ff">Error</span> 1740, "<span style="background-color: #ffff00; color: red">yResult</span>" <span style="color: #008000">&& "name" is a read-only property</span>
<span style="color: #0000ff">Endproc</span>
<span style="color: #0000ff">Enddefine</span></font></strong></pre>
<p>Apparently too much of a good thing. Now, the property value couldn't be changed at all. After that first try I changed my class design to use a <strong><em>protected</em></strong> property. But then, read access was lost for all other external class instances. What a mess, I had to add Getter/Setter functions accordingly to solve that:</p>
<pre><strong><font size="4"><span style="color: #0000ff">Define</span> <span style="color: #0000ff">Class</span> MySpecialThree <span style="color: #0000ff">As</span> <span style="color: #0000ff">Custom</span>
<span style="color: #0000ff">Protected</span> yResult
yResult = $0.0000
<span style="color: #0000ff">Protected</span> <span style="color: #0000ff">Procedure</span> Set_yResult
<span style="color: #0000ff">Lparameters</span> tyResult <span style="color: #0000ff">As</span> <span style="color: #0000ff">Currency</span>
<span style="color: #008000">*\\ A typical private Setter</span>
<span style="color: #0000ff">This</span>.yResult = m.tyResult
<span style="color: #0000ff">Endproc</span>
<span style="color: #0000ff">Function</span> Get_yResult() <span style="color: #0000ff">As</span> <span style="color: #0000ff">Currency</span>
<span style="color: #008000">*\\ A typical public getter</span>
<span style="color: #0000ff">Return</span> <span style="color: #0000ff">This</span>.yResult
<span style="color: #0000ff">Endproc</span>
<span style="color: #0000ff">Enddefine</span></font></strong></pre>
<p>At that point, because VFP doesn't support the <a title="A good (short) explanation of Bertrand Meyers excellent articles" href="http://martinfowler.com/bliki/UniformAccessPrinciple.html" target="_blank">uniform access principle</a>, my modification broke the inner workings of my application because I changed the interface of one class without reflecting that all over the place.</p>
<h3><font color="#0000ff">A Better Approach(?)</font></h3>
<p>Finally, I returned to my <strong>unprotected</strong> property. This time, I created a <strong><em>protected flag variable</em></strong> in my class that had to be set before assigning a new value to my <em>yResult property</em> to signal <em>write access granted</em>:</p>
<pre><strong><font size="4"><span style="color: #0000ff">Define</span> <span style="color: #0000ff">Class</span> MySpecialFour <span style="color: #0000ff">As</span> <span style="color: #0000ff">Custom</span>
yResult = $0.0000
<span style="color: #0000ff">Protected</span> lWriteGranted
lWriteGranted = .F.
<span style="color: #0000ff">Protected</span> <span style="color: #0000ff">Procedure</span> yResult_Assign
<span style="color: #0000ff">Lparameters</span> tyResult <span style="color: #0000ff">As</span> <span style="color: #0000ff">Currency</span>
<span style="color: #0000ff">If</span> Not <span style="color: #0000ff">This</span>.lWriteGranted
<span style="color: #0000ff">Error</span> 1740, "<span style="background-color: #ffff00; color: red">yResult</span>" <span style="color: #008000">&& "name" is a read-only property</span>
<span style="color: #0000ff">Else</span>
<span style="color: #0000ff">This</span>.yResult = m.tyResult
<span style="color: #0000ff">Endif</span>
<span style="color: #0000ff">Endproc</span>
<span style="color: #0000ff">Procedure</span> CalculateWhatEver() <span style="color: #0000ff">As</span> Void
<span style="color: #008000">*\\ Do some wild things here...</span>
<span style="color: #008000">*\\ ... then store result</span>
<span style="color: #0000ff">This</span>.lWriteGranted = .T.
<span style="color: #0000ff">This</span>.yResult = m.lyLocalValue
<span style="color: #008000">*\\ Never forget to reset flag!</span>
<span style="color: #0000ff">This</span>.lWriteGranted = .F.
<span style="color: #0000ff">Endproc</span>
<span style="color: #0000ff">Enddefine</span></font></strong></pre>
<p>This approach worked better, but there were three drawbacks: You had to write 2 additional lines of code (point one and two:-) and, if you forgot to reset the flag property at the end of your processing the whole write protection scheme rendered useless (point three). At least, the code had little impact on performance.</p>
<h3><font color="#0000ff">Refinement</font></h3>
<p>After a while I came up with the following neat solution to solve all of the above problems.</p>
<pre><strong><font size="4"><span style="color: #0000ff">Define</span> <span style="color: #0000ff">Class</span> MySpecialFive <span style="color: #0000ff">As</span> <span style="color: #0000ff">Custom</span>
yResult = $0.0000
<span style="color: #0000ff">Protected</span> lWriteGranted
lWriteGranted = .F.
<span style="color: #0000ff">Protected</span> <span style="color: #0000ff">Procedure</span> yResult_Assign
<span style="color: #0000ff">Lparameters</span> tyResult <span style="color: #0000ff">As</span> <span style="color: #0000ff">Currency</span>;
, tlInternal <span style="color: #0000ff">As</span> Boolean
<span style="color: #0000ff">If</span> Not (<span style="color: #0000ff">This</span>.lWriteGranted Or m.tlInternal)
<span style="color: #0000ff">Error</span> 1740, "<span style="background-color: #ffff00; color: red">yResult</span>" <span style="color: #008000">&& "name" is a read-only property</span>
<span style="color: #0000ff">Else</span>
<span style="color: #0000ff">This</span>.lWriteGranted = m.tlInternal
<span style="color: #0000ff">This</span>.yResult = m.tyResult
<span style="color: #0000ff">Endif</span>
<span style="color: #0000ff">Endproc</span>
<span style="color: #0000ff">Procedure</span> CalculateWhatEver() <span style="color: #0000ff">As</span> Void
<span style="color: #008000">*\\ Do some wild things again...</span>
<span style="color: #008000">*\\ ... then store result</span>
<span style="color: #0000ff">This</span>.yResult_Assign(m.lyLocalValue, .T.)
<span style="color: #008000">*//</span>
<span style="color: #0000ff">Endproc</span>
<span style="color: #0000ff">Enddefine</span></font></strong></pre>
<p>I must admit, I liked that solution, because it reduced the value assignment code down to one line again.</p>
<p>In fact, the code works well but takes twice as long to complete (no lunch for free)! Maybe you have to play with the class and watch the assignments in your debugger to understand what I mean. The slight performance degradation isn't noticeable on todays machines, all what remains is the clumpy assignment call. Anyway, <strong>write access can only be granted to methods of the class</strong>. All other external classes cannot write to the <em>yResult</em> property without additional arrangements are made for it.</p>
<h3><font color="#0000ff">Generic Getters/Setters</font></h3>
<p>One way to jump over that hurdle is to create a pair of generic methods like shown below. We also have to create one additional security property in our classes to hold our 'grant access token'. In the class <em><strong>MyBaseCustom</strong></em> below it is called <em><strong>eSecToken</strong></em> and may hold any kind of value you might consider useful.</p>
<pre><strong><font size="4"><span style="color: #0000ff">Define</span> <span style="color: #0000ff">Class</span> MyBaseCustom <span style="color: #0000ff">As</span> <span style="color: #0000ff">Custom</span>
<span style="color: #008000">*\\ test properties</span>
<span style="color: #0000ff">Dimension</span> aTest[<span style="background-color: #ffff00; color: red">1,2</span>]
cTest = "<span style="background-color: #ffff00; color: red">Hello World</span>"
<span style="color: #008000">*\\ class access security token</span>
<span style="color: #0000ff">Protected</span> eSecToken
eSecToken = "<span style="background-color: #ffff00; color: red">Secret</span>"
<span style="color: #008000">*//</span>
<span style="color: #0000ff">Procedure</span> SetValue
<span style="color: #0000ff">Lparameters</span> tcName <span style="color: #0000ff">As</span> <span style="color: #0000ff">String</span>;
, teValue <span style="color: #0000ff">As</span> Variant@;
, teSecToken <span style="color: #0000ff">As</span> Variant
<span style="color: #0000ff">If</span> Not <span style="color: #0000ff">This</span>.eSecToken == m.teSecToken
<span style="color: #008000">*\\ This.eSecToken holds class-global security</span>
<span style="color: #008000">*\\ token granting write access</span>
<span style="color: #0000ff">Error</span> "<span style="background-color: #ffff00; color: red">Security token wrong or missing</span>"
<span style="color: #008000">*//</span>
<span style="color: #0000ff">Else</span>
<span style="color: #008000">*\\ Write access granted</span>
tcName = <span style="color: #0000ff">Alltrim</span>(<span style="color: #0000ff">Transform</span>(m.tcName))
<span style="color: #0000ff">If</span> Not (Pemstatus(<span style="color: #0000ff">This</span>, m.tcName, 5) And ;
PemStatus(<span style="color: #0000ff">This</span>, m.tcName,3) == "<span style="background-color: #ffff00; color: red">Property</span>")
<span style="color: #0000ff">Error</span> "<span style="background-color: #ffff00; color: red">Property not found</span>"
<span style="color: #0000ff">Else</span>
<span style="color: #0000ff">If</span> <span style="color: #0000ff">Type</span>("<span style="background-color: #ffff00; color: red">This.</span>" + m.tcName, 1) == "<span style="background-color: #ffff00; color: red">A</span>" And;
<span style="color: #0000ff">Type</span>("<span style="background-color: #ffff00; color: red">m.teValue</span>", 1) == "<span style="background-color: #ffff00; color: red">A</span>"
<span style="color: #008000">*\\ array -> array handling</span>
<span style="color: #0000ff">Dimension</span> ("<span style="background-color: #ffff00; color: red">This.</span>"+m.tcName+"<span style="background-color: #ffff00; color: red">[1]</span>")
<span style="color: #0000ff">Local</span> lcTmp <span style="color: #0000ff">As</span> <span style="color: #0000ff">String</span>
lcTmp = "<span style="background-color: #ffff00; color: red">This.</span>"+m.tcName
<span style="color: #008000">*\\ I do HATE macro substitution! But in</span>
<span style="color: #008000">*\\ this case we have to use it!</span>
<span style="color: #0000ff">Acopy</span>(teValue, &lcTmp.)
<span style="color: #0000ff">Else</span>
<span style="color: #008000">*\\ all other (scalar) teValue handling</span>
<span style="color: #0000ff">Store</span> teValue <span style="color: #0000ff">To</span> ("<span style="background-color: #ffff00; color: red">This.</span>"+m.tcName)
<span style="color: #0000ff">Endif</span>
<span style="color: #0000ff">Endif</span>
<span style="color: #0000ff">Endif</span>
<span style="color: #0000ff">Endproc</span>
<span style="color: #0000ff">Function</span> GetValue
<span style="color: #0000ff">Lparameters</span> tcName <span style="color: #0000ff">As</span> <span style="color: #0000ff">String</span>;
, teSecToken <span style="color: #0000ff">As</span> Variant;
, tnResult <span style="color: #0000ff">As</span> <span style="color: #0000ff">Integer</span>@ <span style="color: #008000">&& in/out</span>
tnResult = 0 <span style="color: #008000">&& := scalar value will be returned</span>
<span style="color: #0000ff">Local</span> leRetVal <span style="color: #0000ff">As</span> Variant; <span style="color: #008000">&& scalar return value</span>
, llSilent <span style="color: #0000ff">As</span> <span style="color: #0000ff">Integer</span> <span style="color: #008000">&& no parameter errors</span>
leRetVal = .<span style="color: #0000ff">Null</span>.
llSilent = Pcount() > 2
<span style="color: #0000ff">If</span> Not <span style="color: #0000ff">This</span>.eSecToken == m.teSecToken
<span style="color: #008000">*\\ The .eSecToken property holds class-global</span>
<span style="color: #008000">*\\ security token granting write access</span>
tnResult = -1 <span style="color: #008000">&& error</span>
<span style="color: #0000ff">If</span> Not m.llSilent
<span style="color: #0000ff">Error</span> "<span style="background-color: #ffff00; color: red">Security token wrong or missing</span>"
<span style="color: #0000ff">Endif</span>
<span style="color: #008000">*//</span>
<span style="color: #0000ff">Else</span>
<span style="color: #008000">*\\ Read access granted</span>
tcName = <span style="color: #0000ff">Alltrim</span>(<span style="color: #0000ff">Transform</span>(m.tcName))
<span style="color: #0000ff">If</span> <span style="color: #0000ff">Type</span>("<span style="background-color: #ffff00; color: red">This.</span>"+m.tcName)== "<span style="background-color: #ffff00; color: red">U</span>"
<span style="color: #008000">*\\ Use Type() testing because we can be asked</span>
<span style="color: #008000">*\\ to return a single array element, too!</span>
tnResult = -2 <span style="color: #008000">&& := error</span>
<span style="color: #0000ff">If</span> Not m.llSilent
<span style="color: #0000ff">Error</span> "<span style="background-color: #ffff00; color: red">Property not found</span>"
<span style="color: #0000ff">Endif</span>
<span style="color: #008000">*//</span>
<span style="color: #0000ff">Else</span>
<span style="color: #008000">*\\ Don't forget: VFP 9 is able to return arrays!</span>
<span style="color: #0000ff">If</span> Pemstat(<span style="color: #0000ff">This</span>, m.tcName, 5) And ;
<span style="color: #0000ff">Type</span>("<span style="background-color: #ffff00; color: red">This.</span>" + m.tcName, 1) == "<span style="background-color: #ffff00; color: red">A</span>"
<span style="color: #008000">*\\ full array was requested!</span>
<span style="color: #0000ff">Local</span> lcTmp <span style="color: #0000ff">As</span> <span style="color: #0000ff">String</span>
lcTmp = "<span style="background-color: #ffff00; color: red">This.</span>" + m.tcName
tnResult = 1 <span style="color: #008000">&& := just an info - no error!</span>
<span style="color: #008000">*\\ I do HATE macro substitution! But in</span>
<span style="color: #008000">*\\ this case we have to use it!</span>
<span style="color: #0000ff">Return</span> @&lcTmp. <span style="color: #008000">&& >>>>>>>>>>>>>>>>>>>>>>>>></span>
<span style="color: #0000ff">Else</span>
<span style="color: #008000">*\\ property or single array element request</span>
leRetVal = <span style="color: #0000ff">Evaluate</span>("<span style="background-color: #ffff00; color: red">This.</span>"+m.tcName)
<span style="color: #0000ff">Endif</span>
<span style="color: #0000ff">Endif</span>
<span style="color: #0000ff">Endif</span>
<span style="color: #008000">*\\ at this point we will always return a non-scalar value</span>
<span style="color: #0000ff">Return</span> m.leRetVal
<span style="color: #0000ff">Endfunc</span>
<span style="color: #0000ff">Enddefine</span></font></strong></pre>
<p>Introducing the new GetValue() / SetValue() method pair we now have a generic, secured way to grant or revoke read/write access to our properties based upon a security token. This might be a string, a number or even an object. Our properties can be either natively PROTECTED properties, or properties decorated with an _ASSIGN() method as discussed at the beginning.</p>
<h3><font color="#0000ff">Raising an Event</font></h3>
<p>I would like to show you another possible implementation of read-only properties based on <em>VFP's Event Binding</em>. Because Event Binding is dynamically established at runtime it can be switched <em>On</em> and <em>Off</em> at will. Let's have a peek at the demo code:</p>
<pre><strong><font size="4"><span style="color: #0000ff">Define</span> <span style="color: #0000ff">Class</span> EvtBindAccess <span style="color: #0000ff">As</span> <span style="color: #0000ff">Custom</span>
<span style="color: #008000">*\\ Write Protected property</span>
cTest = "<span style="background-color: #ffff00; color: red">sensitive content</span>"
<span style="color: #008000">*\\ 'Grant Access' security token TypeOf(CHAR[20])</span>
<span style="color: #0000ff">Protected</span> eSecTokens
eSecTokens = "<span style="background-color: #ffff00; color: red">TeStaBChElLo123ItsME!</span>"
<span style="color: #008000">*//</span>
<span style="color: #0000ff">Protected</span> <span style="color: #0000ff">Function</span> <span style="color: #0000ff">Init</span>()
<span style="color: #008000">*\\ Enable 'Bypass Write Protection' by default</span>
<span style="color: #0000ff">This</span>.ByPassSwitch("<span style="background-color: #ffff00; color: red">ON</span>")
<span style="color: #008000">*//</span>
<span style="color: #0000ff">Return</span> .T.
<span style="color: #0000ff">Endfunc</span>
<span style="color: #0000ff">Protected</span> <span style="color: #0000ff">Procedure</span> ByPassSwitch(tcOnOff <span style="color: #0000ff">As</span> <span style="color: #0000ff">String</span>) <span style="color: #0000ff">As</span> Void
<span style="color: #0000ff">If</span> m.tcOnOff == "<span style="background-color: #ffff00; color: red">ON</span>"
= <span style="color: #0000ff">Bindevent</span>(<span style="color: #0000ff">This</span>, "<span style="background-color: #ffff00; color: red">cTest</span>", <span style="color: #0000ff">This</span>, "<span style="background-color: #ffff00; color: red">cTest_Enabler</span>", 2)
<span style="color: #0000ff">Else</span>
= Unbindevent(<span style="color: #0000ff">This</span>, "<span style="background-color: #ffff00; color: red">cTest</span>", <span style="color: #0000ff">This</span>, "<span style="background-color: #ffff00; color: red">cTest_Enabler</span>")
<span style="color: #0000ff">Endif</span>
<span style="color: #0000ff">Endproc</span>
<span style="color: #0000ff">Protected</span> <span style="color: #0000ff">Procedure</span> cTest_Assign(tcTest <span style="color: #0000ff">As</span> <span style="color: #0000ff">String</span>) <span style="color: #0000ff">As</span> Void
<span style="color: #008000">*\\ wellknown write protection implementation</span>
<span style="color: #0000ff">If</span> <span style="color: #0000ff">Vartype</span>(m.VeryComplexAndSecretVariableName) == "<span style="background-color: #ffff00; color: red">U</span>"
<span style="color: #0000ff">Error</span> 1740, "<span style="background-color: #ffff00; color: red">tcTest</span>" <span style="color: #008000">&& "name" is a read-only property</span>
<span style="color: #0000ff">Else</span>
<span style="color: #0000ff">This</span>.cTest = m.tcTest
<span style="color: #0000ff">Endif</span>
<span style="color: #0000ff">Endproc</span>
<span style="color: #0000ff">Protected</span> <span style="color: #0000ff">Procedure</span> cTest_Enabler(tcValue <span style="color: #0000ff">As</span> <span style="color: #0000ff">String</span>;
, tcSecToken <span style="color: #0000ff">As</span> Sting) <span style="color: #0000ff">As</span> Void
tcSecToken = <span style="color: #0000ff">Alltrim</span>(<span style="color: #0000ff">Transform</span>(m.tcSecToken))
<span style="color: #0000ff">If</span> <span style="color: #0000ff">Len</span>(m.tcSecToken) > 4 And ;
<span style="color: #0000ff">At</span>(m.tcSecToken, <span style="color: #0000ff">This</span>.eSecTokens) > 0
<span style="color: #0000ff">Private</span> VeryComplexAndSecretVariableName
VeryComplexAndSecretVariableName = .T.
<span style="color: #0000ff">Endif</span>
<span style="color: #008000">*\\ assig value</span>
<span style="color: #0000ff">This</span>.cTest = m.tcValue
<span style="color: #008000">*//</span>
<span style="color: #0000ff">Endproc</span>
<span style="color: #0000ff">Enddefine</span></font></strong></pre>
<p>There is a property called <strong><em>eSecTokens</em></strong> which holds a string (used as an array of characters) that offers 15 different security tokens each of five characters (an arbitrary length in this example). The protected method <strong><em>BypassSwitch()</em></strong> is called from object's <strong><em>Init()</em></strong> to bind the <strong><em>cTest_Enabler()</em></strong> event handler to the <strong><em>cTest</em></strong> property. Therefor, the 'bypass write protection' feature is enabled by default. Have a closer look at the event handler's signature: the <strong><em>cTest_Enabler()</em></strong> method accepts <u>TWO</u> parameters although it is only bound to a scalar property! If you're not sure what I'm pointing you to, go and read <a title="VFP Event Binding - all you have to know about it!" href="http://myvfpblog.blogspot.com/2011/05/cool-vfp-event-binding.html" target="_blank">this post</a> first!</p>
<p>Raising an event on the <strong><em>cTest</em></strong> property will raise the bound <strong><em>cTest_Enabler()</em></strong> event handler if we call it this way: <font size="4" face="Courier New"><strong>RaiseEvent(m.loEvtBindAccess,"cTest","New Precious Value","TeStaB")
<br /></strong></font>We pass two parameters to our <strong><em>cTest_Enabler() </em></strong>event handler. The event handler, in turn, checks the minimum security token length, and then verifies the token. If both tests pass it creates a PRIVATE (secret) variable and finally does the assignment. If the tests do not pass, no private variable is created – that's the only difference. Assigning the new value to our property raises the <strong>cTest_Assign()</strong> method which, in turn, checks if the secret variable exists…</p>
<h4><font color="#0000ff">Things to mention</font></h4>
<p>If you ever read VFP's BINDEVENT help topic from start to end reflecting on each single sentence, like I did, you might wonder why I'm <em>trying</em> to bind to a PROTECTED method in my <strong><em>EvtBindAccess</em></strong> Class. VFP's help states: </p>
<blockquote>
<p><em>You can bind to any valid Visual FoxPro object event, property, or method, including the <b>Access</b> and <b>Assign</b> methods. <font color="#ff0000">However, the event and delegate methods <strong><u>must be public, not protected or hidden</u></strong>, members of the class.</font></em> </p>
</blockquote>
<p>Voilà, we've just encountered another ambiguity in VFP's help files! <font color="#008000">You <strong><em>do can</em></strong> bind to any property of your own class from within your own class.</font> The help file statement "<em>must be public, not protected or hidden…"</em> applies to external objects at runtime only! </p>
<p>The <strong><em>cTest_Assign()</em></strong> method that implements the write protection now looks for a variable named <strong><em>VeryComplexAndSecretVariableName</em></strong> to be defined to grant write access. This differs from all previous examples and will also be used in our final implementation…</p>
<h3><font color="#0000ff">Friends</font></h3>
<p>I used the <em>write protection scheme</em> shown in the <em><strong>MySpecialFour</strong></em> class above a long time, until I encountered Unit-Testing. Suddenly, my herds of read-only (and protected) PEMs were no longer a proof of good OOP design only, but actively hindered my Unit-Test routines modifying object internals to successfully complete their tasks.
<br />A Unit-Test instance is nothing else but another external object seen from the perspective of the class instance being tested. Thus, the Unit-Test instance cannot write to the tested classes' read-only properties as long as you use any of the approaches described above! The Unit-Test instance should be considered "a friend" of your class, that is, the Unit-Test object should be granted read/write access to ALL of your test classes' PEMs! And, the Unit-Test scenario is only a representative for many others sharing the same 'design problem'!</p>
<h4><font color="#0000ff">Friends Class Instances</font></h4>
<p>A <strong><em>Friends Class Instance</em></strong> (let's name them <strong><em>Friends</em></strong> from now on) should be able to access otherwise locked PEMs of another <em>Friend</em>. The only way to get there is to use variables. Lets script a first draft:</p>
<pre><strong><font size="4"><span style="color: #0000ff">Define</span> <span style="color: #0000ff">Class</span> MySpecialSix <span style="color: #0000ff">As</span> <span style="color: #0000ff">Custom</span>
yResult = $0.0000
<span style="color: #0000ff">Procedure</span> yResult_Assign
<span style="color: #0000ff">Lparameters</span> tyResult <span style="color: #0000ff">As</span> <span style="color: #0000ff">Currency</span>
<span style="color: #0000ff">If</span> <span style="color: #0000ff">Type</span>("<span style="background-color: #ffff00; color: red">SECRET_FLAG</span>") == "<span style="background-color: #ffff00; color: red">U</span>"
<span style="color: #0000ff">Error</span> 1740, "<span style="background-color: #ffff00; color: red">yResult</span>" <span style="color: #008000">&& "name" is a read-only property</span>
<span style="color: #0000ff">Else</span>
<span style="color: #0000ff">This</span>.yResult = m.tyResult
<span style="color: #0000ff">Endif</span>
<span style="color: #0000ff">Endproc</span>
<span style="color: #0000ff">Procedure</span> CalculateWhatEver() <span style="color: #0000ff">As</span> Void
<span style="color: #008000">*\\ Do some wild things here...</span>
<span style="color: #008000">*\\ ... then store result</span>
<span style="color: #0000ff">Private</span> SECRET_FLAG
SECRET_FLAG = .T.
<span style="color: #0000ff">This</span>.yResult = -4654.1234
<span style="color: #008000">*//</span>
<span style="color: #0000ff">Endproc</span>
<span style="color: #0000ff">Enddefine</span></font></strong></pre>
<p><em><strong>Sidekick:</strong></em> Have a look at the <em><strong>MySpecialFive</strong></em> class above: <strong><span style="color: #0000ff">Type</span>("<span style="background-color: #ffff00; color: red">SECRET_FLAG</span>") == "<span style="background-color: #ffff00; color: red">U</span>"</strong> isn't the fastest way to check for existence of a memory variable! Using <strong><span style="color: #0000ff">Vartype</span>(<span style="background-color: #ffff00; color: red">m.SECRET_FLAG</span>) == "<span style="background-color: #ffff00; color: red">U</span>"</strong> does the same job but executes faster! </p>
<p><strong><em>Nice:</em></strong> Because the private variable goes out of scope when we returning from the method it was created in, we cannot forget to reset it.</p>
<p><strong><em>Drawbacks:</em></strong> We have to assign a value to a private variable to really 'create' it. The instruction '<strong><em><font color="#0000ff">Private </font>SECRET_FLAG</em></strong>' differs from '<strong><em><font color="#0000ff">Local</font> SECRET_FLAG</em></strong>' in that the latter does create a (boolean) variable for us, the <em>Private</em> statement only declares that we are going to do so!</p>
<h3><font color="#0000ff">Extending the Scheme</font></h3>
<p>Let's play on the fact that we have to store a value to our private variable to <em>create</em> it. Instead of just storing a <strong><em>.T.</em></strong> or <strong><em>.F.</em></strong> in it we could add more 'friendship' information there. But there is more we should consider! Think about a chain of subsequent calls to sub-routines. A private variable stays in scope form the point we created it along the following calls to sub-methods, even if some of the subsequent calls <em>jump out</em> of your object's boundaries.</p>
<h4><font color="#0000ff">Breaking Encapsulation with Intend</font></h4>
<p>If you create a private variable and then call a method of another (external) object, or access one of its properties, your private variable still is visible there. <em>That's why you should otherwise avoid using private variables in OOP, because <strong>that's how they break encapsulation!</strong></em>
<br />In our case this is just what we want to achieve: Establishing a <strong><em>controlled</em></strong> way to bypass object encapsulation!</p>
<h4><font color="#0000ff">Shadowing</font></h4>
<p>One 'feature' of private variables in VFP is called <strong><em>shadowing</em></strong>. If you are going to create a generic protection algorithm based on "<em>carrying private variables around</em>", this feature comes in handy! Think about the following scenario:
<br />You have three different classes called <em>Class_A</em>, <em>Class_B,</em> and <em>Class_C</em> all stemming from the same superclass. Thus, they all implement the same protection algorithm (behavior). <strong>Depending on the roles they play at runtime</strong> <em>Class_A</em> should be a friend of <em>Class_B</em> and <em>Class_B</em> in turn should be a friend of <em>Class_C</em>. <em>Class_A</em> should be granted read/write access to one or more PEMs of <em>Class_B</em>, but <strong>not</strong> to PEMs of <em>Class_C;</em> <em>Class_B</em> should be granted read/write access to one or more PEMs of <em>Class_C</em>.</p>
<p>Now, if <em>Class_A</em> writes to a property of <em>Class_B</em> from within one of its methods like this…</p>
<pre><strong><font size="4"><span style="color: #0000ff">Procedure</span> CallFriend(tcMyFriendsName <span style="color: #0000ff">As</span> <span style="color: #0000ff">String</span>) <span style="color: #0000ff">As</span> Void
<span style="color: #0000ff">Local</span> loMyFriend <span style="color: #0000ff">As</span> Object
loMyFriend = <span style="color: #0000ff">This</span>.GetRefFromName(m.tcMyFriendsName)
<span style="color: #0000ff">If</span> <span style="color: #0000ff">Vartype</span>(m.loMyFriend) == "<span style="background-color: #ffff00; color: red">O</span>"
<span style="color: #008000">*\\ enable bypassing write protection</span>
<span style="color: #0000ff">Private</span> pcSECRET_FLAG
pcSECRET_FLAG = <span style="color: #0000ff">This</span>.<span style="color: #0000ff">Name</span>
<span style="color: #008000">*\\ write to the r/o property</span>
m.loMyFriend.cProtectedValue = <span style="color: #0000ff">This</span>.cProtectedValue
<span style="color: #0000ff">Endif</span>
<span style="color: #0000ff">Endproc</span></font></strong></pre>
<p>… then the assignment could trigger a subsequent message from <em>Class_B</em> to <em>Class_C</em> like so:</p>
<pre><strong><font size="4"><span style="color: #0000ff">Procedure</span> cProtectedValue_Assign(tcNewVal <span style="color: #0000ff">As</span> <span style="color: #0000ff">String</span>) <span style="color: #0000ff">As</span> Void
<span style="color: #0000ff">If</span> <span style="color: #0000ff">Vartype</span>(m.pcSECRET_FLAG) == "<span style="background-color: #ffff00; color: red">C</span>" And;
<span style="color: #0000ff">Len</span>(m.pcSECRET_FLAG) > 7 And ;
<span style="color: #0000ff">At</span>(m.pcSECRET_FLAG, <span style="color: #0000ff">This</span>.cMyFriendsNames) > 0
<span style="color: #008000">*\\ assign value</span>
<span style="color: #0000ff">This</span>.cProtectedValue = m.tcNewVal
<span style="color: #008000">*\\ cascade message to my friend</span>
<span style="color: #0000ff">This</span>.CallFriend(<span style="color: #0000ff">This</span>.cMyFriendsName)
<span style="color: #0000ff">Else</span>
<span style="color: #0000ff">Error</span> 1740, "<span style="background-color: #ffff00; color: red">cProtectedValue</span>" <span style="color: #008000">&& r/o property</span>
<span style="color: #0000ff">Endif</span>
<span style="color: #0000ff">Endproc</span></font></strong></pre>
<p>The method <strong><em>CallFriend()</em></strong> of the <em>Class_B</em> instance that gets called from its own <strong><em>cProtectedValue_Assign()</em></strong> method will create a <strong><em><u><font color="#0000ff">new</font></u></em></strong> private variable <strong><em>pcSECRET_FLAG</em></strong>, now holding the name of <em>Class_B</em>. This private variable, although it has the same name, does not simply overwrite the content of the first one created by the <em>Class_A</em> instance, but <strong><em><font color="#0000ff">overlays</font></em></strong> it opaquely. In fact, at the moment when our Class_B instance assigns its value to the Class_C instance, <em><u><strong>two</strong></u> <strong>pcSECRET_FLAG</strong> variables exist</em>, where the second one <strong><em><font color="#0000ff">SHADOWS</font></em></strong> the first one created by the <em>Class_A</em> instance. When returning from the <strong><em>CallFriend()</em></strong> method of the Class_B instance the second <strong><em>pcSECRET_FLAG</em></strong> variable goes out of scope. Thus, the first is not longer shadowed, it becomes visible/accessible again.</p>
<p><strong><em>Nice:</em></strong> VFP's <em>shadowing feature</em> of private variables frees us from taking care about name clashes!</p>
<h4><font color="#0000ff">Identifying Friends</font></h4>
<p>Sometimes it is not enough to know that an object sending a message is the instance of a <strong><em>friends class</em></strong>. Maybe hundreds of instances of the same class exist at the same time and we only want to grant write access to few of them depending on the role they play. The question is, <strong><em>how can we identify a unique instance</em></strong> without having its object reference to compare to?</p>
<h4><font color="#0000ff">Object Identity</font></h4>
<p>It is said that an object is described by three attributes: <strong>State</strong>, <strong>Behavior</strong>, and <strong>Identity</strong>. Let's focus on the aspect of <strong><em>object identity</em></strong>. VFP gives each object a unique identity. In fact, when we compare objects with each other using the equal operator (=) we are comparing their <strong>Identities</strong>! VFP has another <strong><em>CompObj()</em></strong> function that allows us to compare objects' <strong>State & Appearance</strong> instead. </p>
<h4><font color="#0000ff">Examples</font></h4>
<p>Type in the following lines in your command window and watch the results echoed to your VFP's desktop:</p>
<pre><strong><font size="4">goX = <span style="color: #0000ff">CreateObject</span>("<span style="background-color: #ffff00; color: red">container</span>")
goY = <span style="color: #0000ff">CreateObject</span>("<span style="background-color: #ffff00; color: red">container</span>")
? m.goX = m.goY <span style="color: #008000">&& .F.</span>
? m.goX = m.goX <span style="color: #008000">&& .T.</span>
? m.goY = m.goY <span style="color: #008000">&& .T.</span>
? <span style="color: #0000ff">Compobj</span>(m.goX, m.goY) <span style="color: #008000">&& .T. same state and appearance</span>
<span style="color: #008000">*\\ changing the appearance</span>
goY.<span style="color: #0000ff">Top</span> = 10
? <span style="color: #0000ff">Compobj</span>(m.goX, m.goY) <span style="color: #008000">&& .F. appearance differs</span>
? m.goY = m.goY <span style="color: #008000">&& .T. always</span>
<span style="color: #008000">*\\ reset appearance</span>
goY.<span style="color: #0000ff">Top</span> = 0
? <span style="color: #0000ff">Compobj</span>(m.goX, m.goY) <span style="color: #008000">&& .T. same appearance again</span>
<span style="color: #008000">*\\ changing appearance </span>
Addpropery(m.goY, "<span style="background-color: #ffff00; color: red">Bottom</span>", m.goY.<span style="color: #0000ff">Top</span>+m.goY.<span style="color: #0000ff">Height</span>)
? <span style="color: #0000ff">Compobj</span>(m.goX, m.goY) <span style="color: #008000">&& .F. appearance differs</span>
<span style="color: #008000">*\\ assign object reference to another variable</span>
m.goX = m.goY
? m.goX = m.goY <span style="color: #008000">&& .T. both variables pointing to the same object</span>
? <span style="color: #0000ff">Compobj</span>(m.goX, m.goY) <span style="color: #008000">&& .T. of course</span>
</font></strong></pre>
<p><strong><em>Drawback</em></strong>: We must use object references to compare these special object attributes. Another important thing to keep in mind is that <strong>State & Appearance</strong>, <strong>Behavior</strong>, and <strong>Identity</strong> are runtime related attributes in this context. We are not talking about our classes, but about their instances!</p>
<h4><font color="#0000ff">Text-Based Object Identifiers</font></h4>
<p>What we need is some simple representation of an <em>Object's Identity</em>. Surely, we could generate GUIDs and store them in each class instance we create. But that would be too much of a good thing because GUIDs are long and time-consuming to create. We do not need a worldwide unique identifier to tag our instances, but a tinier one, only scoped to the running VFP session where our objects <em>live</em>. The following class definition shows a short excerpt of my solution:</p>
<pre><strong><font size="4"><span style="color: #0000ff">Define</span> <span style="color: #0000ff">Class</span> _CustomTest <span style="color: #0000ff">As</span> <span style="color: #0000ff">Custom</span>
<span style="color: #0000ff">Protected</span> cCls2015, cSys2015
cCls2015 = <span style="color: #0000ff">Sys</span>(2015)
<span style="color: #0000ff">Function</span> <span style="color: #0000ff">Init</span>() <span style="color: #0000ff">As</span> Boolean
<span style="color: #0000ff">This</span>.cSys2015 = <span style="color: #0000ff">Sys</span>(2015)
<span style="color: #0000ff">Return</span> .T.
<span style="color: #0000ff">Endfunc</span>
<span style="color: #0000ff">Function</span> GetIdentity(tcCaller <span style="color: #0000ff">As</span> <span style="color: #0000ff">String</span>) <span style="color: #0000ff">As</span> <span style="color: #0000ff">String</span>
<span style="color: #008000">*\\ protection scheme left out in this demo</span>
<span style="color: #0000ff">Return</span> <span style="color: #0000ff">This</span>.cCls2015+<span style="color: #0000ff">This</span>.cSys2015
<span style="color: #0000ff">Endfunc</span>
<span style="color: #0000ff">Enddefine</span></font></strong></pre>
<p>The value assignment <strong><em>cCls2015 = Sys(2015)</em></strong> stores a unique procedure name (10 characters) to VFP's <strong><em><font color="#0000ff">ClassTemplate Object</font></em></strong>. Thus, ALL instances of that class will have the same ID that was generated when the first object of that class was instantiated in the current VFP process. The (second) value assignment <strong><em>cSys2015 = Sys(2015)</em></strong> stores a unique procedure name (10 characters) to <em>each <strong><font color="#0000ff">Individual Instance</font></strong></em>. Thus, we will end up returning a 20 character string from the <strong><em>GetIdentity()</em></strong> method which is the <em>Identity </em>(string) we need. We now can use <strong><em>LEFT(m.cID, 10)</em></strong> to query the <em><font color="#0000ff">unique runtime ID of the <strong>class template</strong></font></em>. Using <strong><em>RIGHT(m.ID, 10)</em></strong> will return the <em><font color="#0000ff">unique runtime ID of the <strong>class instance</strong></font> </em>instead.</p>
<p><strong><em>BTW</em></strong>: In our case it is absolutely sufficient to use SYS(2015) generated values because we only need unique IDs generated within the same VFP process. And that is exactly what SYS(2015) does!</p>
<h3><font color="#0000ff">Generic Implementation</font></h3>
<p>There is nothing bad about using private variables within our OOP environment in a controlled manner. It is a design decision we make to simplify some generic implementation issues. Let's gather our requirements encountered so far.</p>
<ul>
<li>First, we need an <strong><em>Access Protection Scheme</em></strong> (read-write, read-only, write-only, internal-only) that incorporates our <em><strong>Friends Access Pattern</strong></em>. </li>
<li>In addition to that it would be nice to be able to <strong><em>Signal a given State</em></strong> while running along an execution path without the need to pass the state information through additional parameters from method to method. </li>
<li>Finally, these requirements should work seamlessly with our concept of <em><strong>Text-based Object Identifiers</strong></em>. </li>
</ul>
<p>Text-Based Object Identifiers are build upon VFP's Sys(2015) function and are <strong><em>always stored in protected properties</em></strong> of our classes. Once the classes' ID keys are created they must not change - under no circumstances! We will implement a <strong><em>Secured Getter</em></strong> to enable <em><strong>Friends Classes</strong></em> to read each other's <strong><em>Object Identifier</em></strong> values. In addition to that we will implement <em><strong>Secured Setters</strong></em> to enable classes to establish a <strong><em>Friends Link</em></strong> among each others at runtime.
<br />Therefor, we have to define a <em>Common Security ID</em>. This <em>Global Security Token</em> should be stored in a global include file which will be included in all classes that are using our <em>Friends Classes Scheme</em>. Using a <a title="Things you should really know about VFP's compile-time constants" href="http://myvfpblog.blogspot.com/2014/03/preprocessor-and-compile-time-constants.html" target="_blank">well-designed hierarchy of include files</a> can help us achieving our goals without much work.</p>
<p>The following function shows how the <em>Common Security ID</em> is passed in and then gets compared against the object's own copy of it:</p>
<pre><strong><font size="4"><span style="color: #0000ff">Function</span> AGetFriends(tcAuthorityID <span style="color: #0000ff">As</span> <span style="color: #0000ff">String</span>) <span style="color: #0000ff">As</span> <span style="color: #0000ff">Array</span>
tcAuthorityID = <span style="color: #0000ff">Transform</span>(m.tcAuthorityID)
<span style="color: #0000ff">If</span> m.tcAuthorityID == <span style="color: #0000ff">This</span>.cAutId
<span style="color: #0000ff">Return</span> @<span style="color: #0000ff">This</span>.aFriends
<span style="color: #0000ff">Endif</span>
<span style="color: #0000ff">Endfunc</span></font></strong></pre>
<h4><font color="#0000ff">Two Different Kinds of Private Variables</font></h4>
<p>We will implement two different ways of wrapping our sensitive information in private variables. The first will use <strong><em>static variable names</em></strong> to benefit from VFP's shadowing feature, the other will use <strong><em>secret variable names</em></strong> based on the <em>Object Identifiers Naming Scheme</em>. The first will be used to pass the <em>Secret Object Identifiers</em> around, the second will be used to pass around arbitrary data of any type. The _Custom class below is a 'ready to use' SuperClass with behavior that can be transferred to other VFP base class types, too.</p>
<pre><strong><font size="4"><span style="color: #0000ff">Define</span> <span style="color: #0000ff">Class</span> _Custom <span style="color: #0000ff">As</span> <span style="color: #0000ff">Custom</span>
<span style="color: #008000">*\\ Public interface</span>
eWhatever = .<span style="color: #0000ff">Null</span>.
oParent = .<span style="color: #0000ff">Null</span>.
<span style="color: #008000">*\\ Protected (internal only)</span>
<span style="color: #0000ff">Protected</span> <span style="color: #0000ff">Array</span> aFriends[<span style="background-color: #ffff00; color: red">1</span>]
<span style="color: #0000ff">Dimension</span> aFriends[<span style="background-color: #ffff00; color: red">1</span>]
<span style="color: #0000ff">Protected</span> cCls2015, cSys2015, cAutId, cAutCnt
cCls2015 = <span style="color: #0000ff">Sys</span>(2015)
cSys2015 = "<span style="background-color: #ffff00; color: red"></span>"
cAutId = "<span style="background-color: #ffff00; color: red">{B02103F0-1AA8-4cda-9CCA-DEB455BB9574}</span>"
cAutCnt = "<span style="background-color: #ffff00; color: red">pcAuthorityContainer</span>"
<span style="color: #008000">*\\ Hidden (this classLevel only)</span>
<span style="color: #008000">*\\ --- none ---</span>
<span style="color: #008000">*//______________________________________________________</span>
<span style="color: #0000ff">Protected</span> <span style="color: #0000ff">Function</span> <span style="color: #0000ff">Init</span>(teWhatEver <span style="color: #0000ff">As</span> Variant) <span style="color: #0000ff">As</span> Boolean
<span style="color: #0000ff">Private</span> pcWorkInProgress
<span style="color: #0000ff">Store</span> "<span style="background-color: #ffff00; color: red">INIT</span>" <span style="color: #0000ff">To</span> m.pcWorkInProgress
<span style="color: #0000ff">Local</span> llOkay <span style="color: #0000ff">As</span> Boolean
llOkay = .T.
<span style="color: #0000ff">With</span> <span style="color: #0000ff">This</span>
.aFriends[<span style="background-color: #ffff00; color: red">1</span>] = "<span style="background-color: #ffff00; color: red"></span>"
.eWhatever = m.teWhatEver
.cSys2015 = <span style="color: #0000ff">Sys</span>(2015)
<span style="color: #0000ff">Endwith</span>
<span style="color: #0000ff">If</span> <span style="color: #0000ff">This</span>.InitBefore(@llOkay)
llOkay = <span style="color: #0000ff">This</span>.InitDo(m.llOkay)
<span style="color: #0000ff">Endif</span>
<span style="color: #0000ff">This</span>.InitAfter(@llOkay)
<span style="color: #0000ff">This</span>.eWhatever = .<span style="color: #0000ff">Null</span>.
<span style="color: #0000ff">Return</span> m.llOkay
<span style="color: #0000ff">Endfunc</span>
<span style="color: #0000ff">Protected</span> <span style="color: #0000ff">Function</span> InitBefore(tlOkay <span style="color: #0000ff">As</span> Boolean@) <span style="color: #0000ff">As</span> Boolean
<span style="color: #0000ff">Endfunc</span>
<span style="color: #0000ff">Protected</span> <span style="color: #0000ff">Function</span> InitDo(tlOkay <span style="color: #0000ff">As</span> Boolean) <span style="color: #0000ff">As</span> Boolean
<span style="color: #0000ff">Return</span> m.tlOkay
<span style="color: #0000ff">Endfunc</span>
<span style="color: #0000ff">Protected</span> <span style="color: #0000ff">Procedure</span> InitAfter(tlOkay <span style="color: #0000ff">As</span> Boolean) <span style="color: #0000ff">As</span> Void
<span style="color: #0000ff">Endproc</span>
<span style="color: #008000">*\\______________________________________________________</span>
<span style="color: #0000ff">Protected</span> <span style="color: #0000ff">Function</span> <span style="color: #0000ff">Destroy</span>() <span style="color: #0000ff">As</span> Void
<span style="color: #0000ff">Private</span> pcWorkInProgress
<span style="color: #0000ff">Store</span> "<span style="background-color: #ffff00; color: red">DESTROY</span>" <span style="color: #0000ff">To</span> m.pcWorkInProgress
<span style="color: #0000ff">If</span> <span style="color: #0000ff">This</span>.DestroyBefore()
<span style="color: #0000ff">This</span>.DestroyDo()
<span style="color: #0000ff">Endif</span>
<span style="color: #0000ff">This</span>.DestroyAfter()
<span style="color: #0000ff">Endfunc</span>
<span style="color: #0000ff">Protected</span> <span style="color: #0000ff">Function</span> DestroyBefore() <span style="color: #0000ff">As</span> Boolean
<span style="color: #0000ff">Endfunc</span>
<span style="color: #0000ff">Protected</span> <span style="color: #0000ff">Procedure</span> DestroyDo() <span style="color: #0000ff">As</span> Void
<span style="color: #0000ff">Endfunc</span>
<span style="color: #0000ff">Protected</span> <span style="color: #0000ff">Procedure</span> DestroyAfter() <span style="color: #0000ff">As</span> Void
<span style="color: #0000ff">Endproc</span>
<span style="color: #008000">*\\______________________________________________________</span>
<span style="color: #0000ff">Function</span> GetIdentity(tcAuthorityID <span style="color: #0000ff">As</span> <span style="color: #0000ff">String</span>) <span style="color: #0000ff">As</span> <span style="color: #0000ff">String</span>
<span style="color: #0000ff">Return</span> <span style="color: #0000ff">Iif</span>(Trans(m.tcAuthorityID) == <span style="color: #0000ff">This</span>.cAutId,;
<span style="color: #0000ff">This</span>.cCls2015+<span style="color: #0000ff">This</span>.cSys2015, "<span style="background-color: #ffff00; color: red"></span>")
<span style="color: #0000ff">Endfunc</span>
<span style="color: #008000">*\\______________________________________________________</span>
<span style="color: #0000ff">Protected</span> <span style="color: #0000ff">Function</span> IsFriend(tcIdentity <span style="color: #0000ff">As</span> <span style="color: #0000ff">String</span>) <span style="color: #0000ff">As</span> Boolean
<span style="color: #0000ff">Return</span> <span style="color: #0000ff">Ascan</span>(<span style="color: #0000ff">This</span>.aFriends, m.tcIdentity,1,-1,1,2+4) > 0
<span style="color: #0000ff">Endfunc</span>
<span style="color: #008000">*\\______________________________________________________</span>
<span style="color: #0000ff">Procedure</span> AddFriend(tcAuthorityID <span style="color: #0000ff">As</span> <span style="color: #0000ff">String</span> ;
, tcIdentity <span style="color: #0000ff">As</span> <span style="color: #0000ff">String</span>) <span style="color: #0000ff">As</span> Void
tcAuthorityID = <span style="color: #0000ff">Transform</span>(m.tcAuthorityID)
tcIdentity = <span style="color: #0000ff">Transform</span>(m.tcIdentity)
<span style="color: #0000ff">If</span> m.tcAuthorityID == <span style="color: #0000ff">This</span>.cAutId Or ;
m.tcAuthorityID == <span style="color: #0000ff">This</span>.cCls2015+<span style="color: #0000ff">This</span>.cSys2015
<span style="color: #0000ff">If</span> <span style="color: #0000ff">Empty</span>(<span style="color: #0000ff">This</span>.aFriends[<span style="background-color: #ffff00; color: red">1</span>])
<span style="color: #0000ff">This</span>.aFriends[<span style="background-color: #ffff00; color: red">1</span>] = m.tcIdentity
<span style="color: #0000ff">Else</span>
<span style="color: #0000ff">If</span> Not <span style="color: #0000ff">This</span>.IsFriend(m.tcIdentity)
<span style="color: #0000ff">Local</span> lnNewFriendsCount <span style="color: #0000ff">As</span> <span style="color: #0000ff">Integer</span>
lnNewFriendsCount = <span style="color: #0000ff">Alen</span>(<span style="color: #0000ff">This</span>.aFriends) + 1
<span style="color: #0000ff">Dimension</span> <span style="color: #0000ff">This</span>.aFriends[<span style="background-color: #ffff00; color: red">m.lnNewFriendsCount</span>]
<span style="color: #0000ff">This</span>.aFriends[<span style="background-color: #ffff00; color: red">m.lnNewFriendsCount</span>] = m.tcIdentity
<span style="color: #0000ff">Endif</span>
<span style="color: #0000ff">Endif</span>
<span style="color: #0000ff">Endif</span>
<span style="color: #0000ff">Endproc</span>
<span style="color: #008000">*\\______________________________________________________</span>
<span style="color: #0000ff">Function</span> GetFriendByIndex(tcAuthorityID <span style="color: #0000ff">As</span> <span style="color: #0000ff">String</span> ;
,tnIndex <span style="color: #0000ff">As</span> <span style="color: #0000ff">Integer</span>) <span style="color: #0000ff">As</span> <span style="color: #0000ff">String</span>
tcAuthorityID = <span style="color: #0000ff">Transform</span>(m.tcAuthorityID)<br /> <span style="color: #0000ff">Local</span> lcIdentity <span style="color: #0000ff">As</span> <span style="color: #0000ff">String<br /> lcIdentity = "<span style="background-color: #ffff00; color: red"></span>" </span>
<span style="color: #0000ff">If</span> m.tcAuthorityID == <span style="color: #0000ff">This</span>.cAutId Or ;
m.tcAuthorityID == <span style="color: #0000ff">This</span>.cCls2015+<span style="color: #0000ff">This</span>.cSys2015
<span style="color: #0000ff">Do</span> <span style="color: #0000ff">Case</span>
<span style="color: #0000ff">Case</span> <span style="color: #0000ff">Empty</span>(<span style="color: #0000ff">This</span>.aFriends[<span style="background-color: #ffff00; color: red">1</span>])
<span style="color: #0000ff">Case</span> Not <span style="color: #0000ff">Vartype</span>(m.tnIndex) == "<span style="background-color: #ffff00; color: red">N</span>"
<span style="color: #0000ff">Case</span> Not <span style="color: #0000ff">Between</span>(m.tnIndex, 1, <span style="color: #0000ff">Alen</span>(<span style="color: #0000ff">This</span>.aFriends))
<span style="color: #0000ff">Otherwise</span>
lcIdentity = <span style="color: #0000ff">This</span>.aFriends[<span style="background-color: #ffff00; color: red">m.tnIndex</span>]
<span style="color: #0000ff">Endcase</span>
<span style="color: #0000ff">Endif</span>
<span style="color: #0000ff">Return</span> m.lcIdentity
<span style="color: #0000ff">Endfunc</span>
<span style="color: #008000">*\\______________________________________________________</span>
<span style="color: #0000ff">Function</span> AGetFriends(tcAuthorityID <span style="color: #0000ff">As</span> <span style="color: #0000ff">String</span>) <span style="color: #0000ff">As</span> <span style="color: #0000ff">Array</span>
tcAuthorityID = <span style="color: #0000ff">Transform</span>(m.tcAuthorityID)
<span style="color: #0000ff">If</span> m.tcAuthorityID == <span style="color: #0000ff">This</span>.cAutId
<span style="color: #0000ff">Return</span> @<span style="color: #0000ff">This</span>.aFriends
<span style="color: #0000ff">Endif</span>
<span style="color: #0000ff">Endfunc</span>
<span style="color: #008000">*\\______________________________________________________</span>
<span style="color: #0000ff">Procedure</span> ResetObject(m.tcIdentity <span style="color: #0000ff">As</span> <span style="color: #0000ff">String</span>) <span style="color: #0000ff">As</span> Void
<span style="color: #0000ff">Local</span> lcMode <span style="color: #0000ff">As</span> <span style="color: #0000ff">String</span>
<span style="color: #008000">*\\ get mode; flag unauthorized calls</span>
lcMode = <span style="color: #0000ff">Iif</span>(Not (m.tcIdentity == <span style="color: #0000ff">This</span>.cAutId Or;
m.tcIdentity == <span style="color: #0000ff">This</span>.cCls2015+<span style="color: #0000ff">This</span>.cSys2015);
, "<span style="background-color: #ffff00; color: red">REJECT</span>" ;
, <span style="color: #0000ff">Iif</span>(<span style="color: #0000ff">Vartype</span>(m.pcWorkInProgress) == "<span style="background-color: #ffff00; color: red">U</span>" ;
, "<span style="background-color: #ffff00; color: red">FULL</span>", m.pcWorkInProgress))
<span style="color: #0000ff">If</span> m.lcMode == "<span style="background-color: #ffff00; color: red">REJECT</span>"
<span style="color: #0000ff">Return</span> <span style="color: #008000">&& >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>></span>
<span style="color: #0000ff">Endif</span>
<span style="color: #0000ff">With</span> <span style="color: #0000ff">This</span>
<span style="color: #008000">*\\ nullify properties that may hold external references</span>
<span style="color: #0000ff">Store</span> .<span style="color: #0000ff">Null</span>. <span style="color: #0000ff">To</span> .oParent
<span style="color: #0000ff">Endwith</span>
<span style="color: #0000ff">If</span> m.lcMode == "<span style="background-color: #ffff00; color: red">DESTROY</span>"
<span style="color: #008000">*\\ we're done</span>
<span style="color: #0000ff">Return</span> <span style="color: #008000">&& >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>></span>
<span style="color: #0000ff">Endif</span>
<span style="color: #0000ff">If</span> Not m.lcMode == "<span style="background-color: #ffff00; color: red">INIT</span>"
<span style="color: #008000">*\\ do NOT redimension array properies when called</span>
<span style="color: #008000">*\\ from INIT() because they are preset in class</span>
<span style="color: #0000ff">Dimension</span> <span style="color: #0000ff">This</span>.aFriends[<span style="background-color: #ffff00; color: red">1</span>]
<span style="color: #0000ff">Endif</span>
<span style="color: #008000">*\\ run (the rest of) full object reset from here on</span>
<span style="color: #0000ff">With</span> <span style="color: #0000ff">This</span>
<span style="color: #0000ff">Store</span> "<span style="background-color: #ffff00; color: red"></span>" <span style="color: #0000ff">To</span> .aFriends
<span style="color: #0000ff">Store</span> .<span style="color: #0000ff">Null</span>. <span style="color: #0000ff">To</span> .eWhatever
<span style="color: #0000ff">Endwith</span>
<span style="color: #008000">*//</span>
<span style="color: #0000ff">Endproc</span>
<span style="color: #0000ff">Enddefine</span></font></strong></pre>
<p>Actually, the ResetObject() method does not belong to the core of our <em>Friends Classes</em> concept, but shows how a private variable with a fixed name (m.pcWorkInProgress) can be utilized to pass around additional process attributes without using a property one could forget to reset at the end of the process.</p>
<h3><font color="#0000ff">That's all for now</font></h3>
<p>Hope I could help to enlighten you a little bit :-) To be honest, there is nothing wrong with any of the approaches described above! As long as you select one and stay with it to be consistent across your projects, I'm fine with it :-)</p>
<blockquote>
<p><font color="#c0504d"><em>Keep things rolling…</em></font></p>
</blockquote>
<hr />
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Previous Entry (disabled ATM)" border="0" alt="Previous Entry (disabled ATM)" src="http://lh5.ggpht.com/_MOmDLu4Rm5Y/SsUqgE1PYwI/AAAAAAAACVE/zipRh2o787I/NavBack_48_RGBA5.png?imgmax=800" width="48" height="64" /><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-tips-tricks-in-this.html"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Tips & Tricks Home" border="0" alt="Tips & Tricks Home" src="http://lh3.ggpht.com/_MOmDLu4Rm5Y/SsUqgjBv1-I/AAAAAAAACVI/aOCOSR_3xzA/NavHome_48_RGBA5.png?imgmax=800" width="48" height="64" /></a><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Next Entry (disabled ATM)" border="0" alt="Next Entry (disabled ATM)" src="http://lh3.ggpht.com/_MOmDLu4Rm5Y/SsUqg2SyDMI/AAAAAAAACVQ/R3zN9NE1Tgw/NavForward_48_RGBA5.png?imgmax=800" width="48" height="64" /></p> Burkhardhttp://www.blogger.com/profile/11631168041975170500noreply@blogger.com3tag:blogger.com,1999:blog-26167158.post-50578802273492812082014-03-27T22:08:00.000+01:002014-07-31T14:06:29.920+02:00VFP's Preprocessor's Constant Definition Handling<p><font color="#0000ff"></font></p> <p><strong><font color="#ff8000" size="3">Version: 1.00.01 - last update: Tuesday, July 31, 2014, 12:35:00 [<font color="#ff0000" size="1">fixed some minor typos and reformatted font size</font>]</font></strong></p> <p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Previous Entry (ATM disabled!)" border="0" alt="Previous Entry (ATM disabled!)" src="http://lh5.ggpht.com/_MOmDLu4Rm5Y/SsUqgE1PYwI/AAAAAAAACUw/hcCII_GE0vY/NavBack_48_RGBA6.png?imgmax=800" width="48" height="64" /><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-tips-tricks-in-this.html"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Tips & Tricks Home" border="0" alt="Tips & Tricks Home" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihLfEyfnO4dbE7rc3zyxMN4aApCogItvwVZvHTl2hReEVavmGzzghjw0GTVHzWJueN_w38A_8enHwsVoN8mwFYG6BOwoKFVKAUXXXjhNy4S0kBdlbzhy39kDFA3drmirZBDiLj/?imgmax=800" width="48" height="64" /></a><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Next Entry (ATM disabled!)" border="0" alt="Next Entry (ATM disabled!)" src="http://lh3.ggpht.com/_MOmDLu4Rm5Y/SsUqg2SyDMI/AAAAAAAACVA/pyUUeRv3T20/NavForward_48_RGBA7.png?imgmax=800" width="48" height="64" /></p> <hr /> <h3><font color="#0000ff">Things you should really <em>know</em> about VFP's compile-time constants</font></h3> <h1><font color="#0000ff">Intro</font></h1> <p><font size="3">There are some new things I've learned about <strong><em>Include Files</em></strong> and their content lately! Here comes what could be said is common knowledge amongst VFP developers:</font></p> <ol> <li><font size="3">It is always good to let all your classes <em>include</em> one .H-file! </font></li> <li><font size="3">It is even better if these "low-level" includes are populated sparsely, including one (or more) "top-level" include files in turn. </font></li> <li><font size="3">Defined constants cannot be redefined, unless they are undefined first! Even worse, VFP will complain about redefining constants! <font style="background-color: #ffffff">(<strong><em>Well this is only half the truth as I will show you!</em></strong>)</font> </font></li> <li><font size="3">The last point above implies that you have to maintain a well-ordered hierarchy of <em>including include files</em>! </font></li> </ol> <h3><font color="#0000ff"> <hr /> <br />A Well-Organized Hierarchy</font></h3> <p align="justify"><font size="3">Maintaining a <strong><em>well-organized hierarchy</em></strong> of include files means that we have to be aware of <em>which .H-files include which others </em>and <em><u>HOW</u></em> they include them!  <br />If you ask yourself why I'm stressing the word <em><strong>HOW</strong></em>, let me tell you, there is a good reason to do so! I will show you in a minute why…</font></p> <h3><font color="#0000ff">My Favorite Approach</font></h3> <ol> <p align="left"><font size="3">My favorite approach is to give each of my include file levels a name.</font></p> <li> <p align="left"><font size="3">The top level is the <strong><em>ROOT Level</em></strong>, which is FoxPro itself. There is the <strong>FoxPro.H</strong> file that we all know well, that should be made our top-level include. </font></p> </li> <li> <p align="left"><font size="3">The second level is the <strong><em>Framework Level</em></strong> – in my case this is the FoxQuill Framework. Thus, there is a the <strong>FoxQuill.H</strong> file, which in turn includes some further <em>Framework Includes</em>. </font></p> </li> <li> <p align="left"><font size="3">The third level is the <strong><em>Project Level</em></strong> – this is where you should put your project related constants. </font></p> </li> <li> <p align="left"><font size="3">Finally, the forth level is the <strong><em>ClassLibrary Level</em></strong> – each class in a class library should at least share one common include file, or include its own. </font></p> </li> </ol> <h3><font color="#0000ff">Base Include File Schema</font></h3> <p><font size="3">The above leads us to the following <strong><em>Base Include File Schema</em></strong>:</font></p> <blockquote> <p><font size="3">FoxPro.h <font size="1">–> is included in –></font> FoxQuill.h <font size="1">–> is included in –></font> ProjectName.h <font size="1">–> is included in –></font> ClassName.h </font></p> </blockquote> <p><font size="3">You may do the same thing with your compile-time localization include files. E.g. like this:</font></p> <blockquote><font size="3"> <p>General.En.h<font size="1"> –> is included in –> </font>Framework.En.h<font size="1"> –> is included in –></font> ProjectName.En.h<font size="1"> –> is included in –> </font>ClassName.En.h</p> </font></blockquote> <h3><font color="#0000ff">How VFP Resolves Constant Definitions</font></h3> <p align="justify"><font size="3">Let's have a look on how VFP resolves compile-time constants defined in your include files, especially, how VFP deals with <em>duplicate</em> declarations!</font></p> <p align="justify"><font size="3">There is one error, I bet, you have already seen more than once:</font></p> <p align="justify"><font size="3"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px" title="VFP Compile-Time Error 'Constant is already created with #DEFINE'" border="0" alt="VFP Compile-Time Error 'Constant is already created with #DEFINE'" src="http://lh6.ggpht.com/-WGZ9DPqrFiA/UzSTw83KIDI/AAAAAAAAIDk/9mnB4Ik30EI/1%25255B9%25255D%25255B3%25255D.jpg?imgmax=800" width="340" height="143" /></font></p> <p align="justify"><font size="3">This error (#1725) simply tells us that we've just tried to redefine an existing constant definition. Sometimes it's no fun to find the place, where the first definition takes place, especially when working with someone else's legacy code that uses a lot of nested include files! Sometimes, the best we could do is to add a quick #UNDEF statement before we #DEFINE our own constant. But this <em>may</em> break some legacy code relying on the old value! These kind of weird situations are all stemming from some simple mistakes made by the guys that wrote the legacy code a long time ago, because they were unaware of <em><strong><font color="#ff0000">how to nest include files the right way</font></strong></em>!</font></p> <p align="justify"><font size="3">The <em>Base Include File Schema</em> introduced above is a hierarchical one. That means, compared with a class inheritance tree, that <em>higher level include files</em> contain more common/global definitions. The deeper we dive into our include file hierarchy, the more specific our defines should become.</font> </p> <h3><font color="#0000ff">As Short Quiz</font></h3> <p><font size="3">Let us approach the essence of this writing playing a little pop quiz. Try answering the following questions <em>without</em> consulting VFP's documentation or trying them out in VFP's command window!</font></p> <hr /> <p align="left"><font size="3">Question#1: What code line below caused the <em>Error Message Box</em> above to pop up with error#1725 ?</font></p> <pre><strong><font size="4">#<span style="color: #0000ff">DEFINE</span> FRAMEWORK_NAME "<span style="background-color: #ffff00; color: red">FoxQuill </span>"
#<span style="color: #0000ff">DEFINE</span> FRAMEWORK_NAME "<span style="background-color: #ffff00; color: red">FoxQuill </span>"
#<span style="color: #0000ff">DEFINE</span> FRAMEWORK_NAME "<span style="background-color: #ffff00; color: red">foxquill</span>"
</font></strong></pre>
<p align="justify"><font size="3">VFP's help topic <strong>#DEFINE ... #UNDEF Preprocessor Directive</strong> states it: "<em>You can redefine a <strong>#DEFINE</strong> <font color="#ff0000"><strong>only</strong></font> if you do not change the value. If you change the <strong>#DEFINE</strong> to a different value, Visual FoxPro generates an error.</em>" That's why the right answer is: "<u>The second line!</u>". If you have answered in addition to that: "The 3rd line will cause the same error, too!", you will get an additional bonus point :-)</font></p>
<p align="left"><font size="3"><font size="3">
<hr />Question</font>#2: Does the second line below generates an error?</font></p>
<pre><strong><font size="4">#<span style="color: #0000ff">DEFINE</span> FRAMEWORK_NAME "<span style="background-color: #ffff00; color: red">FoxQuill</span>"
#<span style="color: #0000ff">DEFINE</span> FRAMEWORK_NAME "<span style="background-color: #ffff00; color: red">foxquill</span>"</font></strong></pre>
<p align="justify"><font size="3">The right answer is: "<u>Yes!</u>". "foxquill" == ""FoxQuill" is not true because it is a different value for VFP's preprocessor (that doesn't care about your SET EXACT setting). We cannot redefine a constant to a different value. Thus, FoxPro will complain about it!</font></p>
<p align="justify"><font size="3"><font size="3">
<hr />Question</font>#3: Assume, we have an include file named <strong><em>FoxQuill.h</em></strong> with the following one line content:
<br /></font><font face="Courier New"><strong><font color="#0000ff" size="4">#Define FoxQuill_Version V9.0</font></strong></font></p>
<p align="justify"><font size="3">Now, look at the code lines below (without cheating/testing it!). What do you think? Will there be an error, and if so, which line will cause it.</font></p>
<pre><strong><font size="4">#<span style="color: #0000ff">Define</span> FOXQUILL_VERSION "<span style="background-color: #ffff00; color: red">V9.0</span>"
#<span style="color: #0000ff">INCLUDE</span> foxquill.h<font size="2"> <span style="color: #008000">&& file is accessible (in our search path)</span></font>
#<span style="color: #0000ff">Define</span> FOXQUILL_VERSION "<span style="background-color: #ffff00; color: red">V9.0</span>"
</font></strong></pre>
<p align="justify"><font size="3">The right answer#3 is: "<u>No!</u>". This code fragment will <em>compile without errors</em>! If you guessed it wrong, don't panic, here's another chance to collect some more points ;-)</font></p>
<p align="justify"><font size="3"><font size="3">
<hr />Question</font>#4: Let's reuse the above"FoxQuill.h" include file. Look at the code lines below. What do you think? Will there now be an error, and if so, which line will cause it this time?</font></p>
<pre><strong><font size="4">#<span style="color: #0000ff">INCLUDE</span> foxquill.h<font size="2"> <span style="color: #008000">&& file is accessible in our search path</span></font>
#<span style="color: #0000ff">Define</span> FOXQUILL_VERSION "<span style="background-color: #ffff00; color: red">V9.0</span>"
#<span style="color: #0000ff">Define</span> FOXQUILL_VERSION V9.0</font></strong></pre>
<p align="justify"><font size="3">The right answer is: "<u>Yes! Line#2 will cause an error</u>". The first local define is a redefinition of the <em>FoxQuill_Version</em> constant defined in our <em>foxquill.h</em> file from <strong><font color="#0000ff">V9.0</font></strong> to <strong><font color="#0000ff">"V9.0"</font></strong>. BTW: If you comment that line out the code will compile without errors, you should know why by now.</font></p>
<p align="justify"><font size="3">Be honest, how many points did you gather without cheating? Let me tell you, before I examined VFP's preprocessor behavior thoroughly, I had no clue! </font></p>
<h3><font color="#0000ff">Nesting Include Files as Usual</font></h3>
<p align="left"><font size="3">I was used to nest my include files like this:</font></p>
<blockquote>
<pre><font size="4"><strong><span style="color: #008000">* Content of MasterInc.H </span>
#<span style="color: #0000ff">Include</span> FoxPro.h
#<span style="color: #0000ff">Define</span> MyFrameVersion 1.0
#<span style="color: #0000ff">Define</span> MasterPassword "<span style="background-color: #ffff00; color: red">Rumpelstielschen</span>"
<span style="color: #008000">*… many other definitions to follow </span>
<span style="color: #008000">* EOF MasterInc.H</span>
<span style="color: #008000">* Content of ProjectInc.H </span>
#<span style="color: #0000ff">Include</span> MasterInc.H
#<span style="color: #0000ff">Define</span> MyAppName "<span style="background-color: #ffff00; color: red">AppSpy.Exe</span>"
#<span style="color: #0000ff">Define</span> MyAppVersion 1.0
#<span style="color: #0000ff">Define</span> AppPassword "<span style="background-color: #ffff00; color: red">VerySecret</span>"
<span style="color: #008000">* … many other definitions to follow </span>
<span style="color: #008000">* EOF ProjectInc.H</span></strong></font></pre>
</blockquote>
<p align="justify"><font size="3">If you place your nested #INCLUDEs at the top of your include files you <strong><em>loose the feature to overwrite</em></strong> any definition made in those 'higher level' include files. On the other hand, using the approach above, you can rely on VFP complaining about any redefinitions you may have introduced in you actual include file unintentionally.</font></p>
<p align="justify"><font size="3">Actually, the latter is a feature I do not miss very much, if at all!</font></p>
<h3><font color="#0000ff">A Better Way of Nesting Include Files</font></h3>
<p><font size="3">Let's reorganize the above include files like so:</font></p>
<blockquote>
<pre><font size="4"><strong><span style="color: #008000">* Content of MasterInc.H </span>
#<span style="color: #0000ff">Define</span> MyFrameVersion 1.0
#<span style="color: #0000ff">Define</span> MasterPassword "<span style="background-color: #ffff00; color: red">Rumpelstielschen</span>"
<span style="color: #008000">* … many other definitions to follow </span>
#<span style="color: #0000ff">Include</span> FoxPro.h
<span style="color: #008000">* EOF MasterInc.H<br /></span>
<span style="color: #008000"><br />* Content of ProjectInc.H </span>
#<span style="color: #0000ff">Define</span> MyAppName "<span style="background-color: #ffff00; color: red">AppSpy.Exe</span>"
#<span style="color: #0000ff">Define</span> MyAppVersion 1.0
#<span style="color: #0000ff">Define</span> AppPassword "<span style="background-color: #ffff00; color: red">VarySecret</span>"
<span style="color: #008000">* … many other definitions to follow </span>
#<span style="color: #0000ff">Include</span> MasterInc.H
<span style="color: #008000">* EOF ProjectInc.H</span>
</strong></font></pre>
</blockquote>
<p><font size="3">Now, if we overwrite, lets say, the framework version like so:</font></p>
<blockquote>
<pre><font size="4"><strong><span style="color: #008000">* Content of ProjectInc.H </span>
#<span style="color: #0000ff">Define</span> MyFrameVersion 2.0
#<span style="color: #0000ff">Define</span> MyAppName "<span style="background-color: #ffff00; color: red">AppSpy.Exe</span>"
#<span style="color: #0000ff">Define</span> MyAppVersion 1.1
#<span style="color: #0000ff">Define</span> AppPassword "<span style="background-color: #ffff00; color: red">VarieSikret</span>"
<span style="color: #008000">* … many other definitions to follow </span>
#<span style="color: #0000ff">Include</span> MasterInc.H
<span style="color: #008000">* EOF ProjectInc.H</span></strong></font></pre>
</blockquote>
<p align="center"><font size="3"><font style="background-color: #ffff00" color="#0000ff"><strong>Foxpro will not complain about the redefinition!</strong></font></font></p>
<p align="justify"><font size="3">even better:</font></p>
<p align="center"><font style="background-color: #ffff00" color="#0000ff" size="3"><strong>VFP will disregard the assignment made in the higher level MasterInc.H file completely.</strong></font></p>
<p align="justify"><font size="3">As a logical consequence, we don't have to use any #UNDEFINE statements at at deeper nesting level any longer. Look at the content of the <em>ProjectInc.h</em> file above: The <em><font color="#0000ff" face="Courier New"><strong>#Define MyFrameVersion 2.0</strong></font></em> definition is the <strong><em>first time definition</em></strong>, which we know cannot be redefined later without releasing it beforehand.</font></p>
<h4 align="justify"><font color="#0000ff">Bug or Feature?</font></h4>
<p align="justify"><font size="3">I am not sure if this is a feature or a bug in VFP's preprocessor! But my findings have proven it:</font></p>
<p align="center"><font size="3"><font color="#0000ff"><font style="background-color: #ffff00"><em><font color="#0000ff">You can include </font>duplicate redefinitions</em> <em>from another include file AFTER</em> you have defined your primary ones!</font><font style="background-color: #ffff00"> <font color="#ff0000">But not the other way round!</font></font></font></font></p>
<p align="justify"><font size="3">Therefor, if you accustom yourself to including <em><strong>higher level include files always and only at the end of your lower level include files</strong></em>, you will gain some kind of OOP-ish <strong><em>overwrite in subclass</em></strong> feature, and in addition to that, you will spare coding time (no #UNDEFINEs any more)!</font></p>
<p>
<hr /></p>
<h3><font color="#0000ff">Another <em>Cool</em> Preprocessor Feature</font></h3>
<p align="justify"><font size="3">Another feature of VFP's preprocessor is widely unknown/disregarded! Although VFP's help file tells us: "<em>Compile time constants are not recognized when placed within quotation marks</em>" (see help topic #DEFINE ... #UNDEF Preprocessor Directive), <strong><em><font color="#0000ff"><font style="background-color: #ffff00"><font style="style">this is not the whole truth</font>!</font></font></em></strong></font></p>
<p align="justify"><font size="3">Everybody knows, VFP recognizes three kinds of string delimiters, <em>but </em>VFP's preprocessor does only recognize two of them! Strings that are delimited with square brackets like [<span style="background-color: #ffff00; color: red">V9.0</span>] <strong><em>are processed</em></strong> by VFP's preprocessor, indeed!</font></p>
<p align="justify"><font size="3">Have a look at he following lines:</font></p>
<pre><strong><font size="4">#<span style="color: #0000ff">DEFINE</span> FOXQUILL FoxQuill2
?[<span style="background-color: #ffff00; color: red">Welcome to FOXQUILL</span>]
?[<span style="background-color: #ffff00; color: red">Welcome to foxquill</span>]
?[<span style="background-color: #ffff00; color: red">Welcome to FoxQuillFramework</span>]
?[<span style="background-color: #ffff00; color: red">Welcome to !foxquill.Framework</span>]
?[<span style="background-color: #ffff00; color: red">Welcome to *foxquill-Framework</span>]</font></strong></pre>
<p>They produce the following output:</p>
<p><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 15px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Output of preprocessed strings" border="0" alt="Output of preprocessed strings" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAeNqHrtXXlbTjy5GzXfu4QZApbwfv5n8UISwH3yri1-YtdDK0SiGcY4Nv7_SRbDX-c-ogQGaZBWvN0SgAltNPsm435ZSoLZE6nU9a3EZZx6GkZPp1RHBpaMzHNVF7IrFEDqB8/?imgmax=800" width="208" height="93" /></p>
<p align="justify"><font size="3">We can observe two things: While looking for replacements VFP's preprocessor does a <em>case-insensitive</em> search (1), and always matches whole words(2)!</font></p>
<h3><font color="#0000ff">Do not Pollute Your Include Files</font></h3>
<p align="justify"><font size="3"><font color="#000000">What has the above to do with polluting include files? </font>Well, what are you normally doing if you want to use a string constant in your project files all over the place? Right, you will define it in one of your include files maybe like this: <strong><em>#Define FRAMEWORK_NAME_STRING "FoxQuill" </em></strong></font><font size="3">just in case you will decide one fine day to give your work another name, which is a good thing to have in place! Now, in your code you may address your constant like so:</font></p>
<pre><strong><font size="4">oForm.<span style="color: #0000ff">Caption</span> = "<span style="background-color: #ffff00; color: red">Welcome to the new version of the </span>" + ;
FRAMEWORK_NAME_STRING + "<span style="background-color: #ffff00; color: red"> Framework!</span>"</font></strong></pre>
<p align="justify"><font size="3">Wow, this is a lot of code to type in! Now have a look at the <em>non-polluting</em> solution. First, drop the include file definition completely, then code:</font></p>
<pre><strong><font size="4">oForm.<span style="color: #0000ff">Caption</span> = [<span style="background-color: #ffff00; color: red">Welcome to the new version of the Foxquill Framework!</span>]</font></strong></pre>
<p align="justify"><font size="3">That's all it takes! You are still as flexible as when using the first approach! If you ever will decide to change your framework name to something else it will be sufficiently early to add some <strong><em>#Define FOXQUILL FoxQuill.Net</em></strong> to your include file that day in the future!</font></p>
<h5><font color="#0000ff"><em>Let's end today like Bob Ross always does:</em></font></h5>
<h5><font color="#0000ff"><em>"Happy <strike>painting</strike> coding!" ;-)</em></font></h5>
<hr />
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Previous Entry (ATM disabled!)" border="0" alt="Previous Entry (ATM disabled!)" src="http://lh5.ggpht.com/_MOmDLu4Rm5Y/SsUqgE1PYwI/AAAAAAAACUw/hcCII_GE0vY/NavBack_48_RGBA6.png?imgmax=800" width="48" height="64" /><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-tips-tricks-in-this.html"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Tips & Tricks Home" border="0" alt="Tips & Tricks Home" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihLfEyfnO4dbE7rc3zyxMN4aApCogItvwVZvHTl2hReEVavmGzzghjw0GTVHzWJueN_w38A_8enHwsVoN8mwFYG6BOwoKFVKAUXXXjhNy4S0kBdlbzhy39kDFA3drmirZBDiLj/?imgmax=800" width="48" height="64" /></a><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Next Entry (ATM disabled!)" border="0" alt="Next Entry (ATM disabled!)" src="http://lh3.ggpht.com/_MOmDLu4Rm5Y/SsUqg2SyDMI/AAAAAAAACVA/pyUUeRv3T20/NavForward_48_RGBA7.png?imgmax=800" width="48" height="64" /></p> Burkhardhttp://www.blogger.com/profile/11631168041975170500noreply@blogger.com2tag:blogger.com,1999:blog-26167158.post-84656421229317259712014-03-18T10:45:00.001+01:002014-03-18T22:49:25.977+01:00A Diet Hook On Steroids<p><strong><font color="#ff8000">Version: 1.01.02 - last update: Tuesday, March 18, 2014, 22:49:00</font></strong></p> <p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Previous Chapter" border="0" alt="Previous Chapter" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfiW1nwvQFcbRbr3_Jp7uIHLtlICF1h95cSOYC4dMKAEScWnwJPR6pD1cqRD9geulOxJh9nRGprhgDDmyCvrwZBSMXuQ3oszZZCkDkAUfjKgku2UYeisGzMBBlqqeIwwP9wEdO/?imgmax=800" width="48" height="64" /> <a title="http://myvfpblog.blogspot.com/2009/09/neat-solutions-home.html" href="http://myvfpblog.blogspot.com/2009/09/neat-solutions-home.html"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Neat Solutions Home (TOC)" border="0" alt="Neat Solutions Home (TOC)" src="http://lh5.ggpht.com/-JaOV0ulMrBM/UygVlTuvD5I/AAAAAAAAIBw/bfyhIuq3hJE/NavHome_48_RGBA%25255B4%25255D.png?imgmax=800" width="48" height="64" /></a> <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Next Chapter" border="0" alt="Next Chapter" src="http://lh5.ggpht.com/-3RSJuzW4bz4/UygVl99JLAI/AAAAAAAAIB0/aE8IW2GFLcI/NavForward_48_RGBA%25255B5%25255D.png?imgmax=800" width="48" height="64" /> </p> <hr /> <h4><font color="#004000">This thread is about how to start your own hook project. In this first chapter I will show you my own ProjectHook base only. Later we will talk about some ugly bugs, how to work around them, and how design your Hook Classes best.</font></h4> <h2><font color="#004000">Intro</font></h2> <p>I did not start using ProjectHooks with all of my projects before the VFP team gave them Activate() and Deactivate() hook methods. Working on a whole bunch of projects simultaneously, most of them with a little different set of settings, made maintaining the correct environment for developing, testing and building a real nightmare. VFP's ProjectHooks matured over time and finally we got the 'full-blown' version we are still using today.</p> <p>At that time I started equipping all my different projects with ProjectHooks. Their major task was the change management of development settings. As we all know, every activation (event) of a VFP Project raises the ProjectHook's Activate() event. Thus, this is the best place to adjust VFP's development environment accordingly.</p> <h3><font color="#004000">How to Stay Flexible</font></h3> <p>Of course, I began thinking about how to keep things flexible enough to let me change all needed variant settings (and other stuff) on the fly. For example, hardcoding a sequence of SET PATH TO …. ADDITIVE statements into each ProjectHook over and over again certainly is not a good idea. That's why I implemented a loop that scanned the Project's Files collection to create a search path from all files' paths automatically for me. Alas! Sometimes that was to much of a good thing and I found myself again hardcoding a list of SET PATH statements for one or two "very special" Projects.</p> <h3><font color="#004000">First Working Result</font></h3> <p>I ended up with a really cool default ProjectHook (at least I thought that it was 'cool') that had a whole bunch of valuable features which could be configured using property based switches that, in turn, got their values from external configuration files. In fact, a lot of these switches I integrated only to suppress some behavior I've implemented before.</p> <p>Sometimes a good object oriented programming style seems to be simply incompatible with the requirements you have to fulfill.</p> <h3><font color="#004000">The Configuration Dilemma</font></h3> <p>Finally I got all switches and methods into place. All was up and running, until… I had to create a new "very special" Project needing a "very special" ProjectHook. I must admit, I had to consult my own (sparse) documentation hoping to find a path through my homegrown jungle of methods and switches leading me to the place where I had to implement my desired behavior. Since then, it was clear in my mind that my approach was a one-way street into a fatal program morass. <br />That time I started studying the VFPX ProjectHookX project which had/has a very clean and cool design. But I had not enough spare time to refactor my own Hooks that way. Thus, I decided to temporarily work without a ProjectHook "re-using" VFP's Environment Manager instead…</p> <h3><font color="#004000">A Stroke of Luck</font></h3> <p>Before I started adding ProjectHooks to every Project, I was using VFP's Environment Manager pretty extensively (you may have seen some screen shots of it in one of my other sections:-). What I like most about the Environment Manager is its ease of use. </p> <p><font color="#004000"><strong><em>If we only could combine ProjectHook functionality (signaling an active project change) with Environment Manager functionality (configuring the development environment)!</em> </strong></font></p> <p>But wait, WE CAN, don't we?!</p> <h3><font color="#004000">The Solution</font></h3> <p>After a short stop at VFP's XSOURCES I came up with a super-slim ProjectHook that calls into the EnvMgr.App to set an <em>EnvironmentSet</em> defined there.</p> <h4><font color="#004000">The Environment Manager API</font></h4> <ul> <li>One neat thing is that the Environment Manager can be run as a stand alone application (without the hosting TaskPane). Thus, it can be called directly, and, in addition to that, it can be run in a silent, GUI-less mode! </li> <li>Another option that can be used is passing in the name of the Environment Manager driving table. If we do not want to use the default one, we are allowed to pass in a different table name instead. This opens up the world of team working where we would store only one centralized EnvMgr driving table to be used by the Environment Managers off all developers. </li> <li>Last but not least we can pass a parameter to tell the Environment Manager to add a menu bar to VFP's <em>Tools</em> menu from where we can start it directly without the need of launching VFP's TaskPane.App first! </li> </ul> <p>I ran some tests and, it works like a charm!</p> <h3><font color="#004000">The Code</font></h3> <p>Because I have not enough time to upload my ProjectHook's VCX files I put them into a PRG listed below. I believe that you will not have any problems to convert the code back into a local VCX-based class to run some test on your own.</p> <pre><strong><span style="color: #0000ff">Define</span> <span style="color: #0000ff">Class</span> fq_minimal_hook <span style="color: #0000ff">As</span> <span style="color: #0000ff">ProjectHook</span>
cLookupId = "<span style="background-color: #ffff00; color: red"></span>"
lAddMenu = .T.
lActivateEnabled = .T.
<span style="color: #0000ff">Name</span> = "<span style="background-color: #ffff00; color: red">fq_minimal_hook</span>"
<span style="color: #0000ff">Procedure</span> <span style="color: #0000ff">Init</span>
<span style="color: #0000ff">If</span> <span style="color: #0000ff">Empty</span>(<span style="color: #0000ff">This</span>.cLookupId)
<span style="color: #0000ff">This</span>.cLookupId = <span style="color: #0000ff">Juststem</span>(<span style="color: #0000ff">_VFP</span>.ActiveProject.<span style="color: #0000ff">Name</span>)
<span style="color: #0000ff">EndIf</span>
<span style="color: #0000ff">If</span> <span style="color: #0000ff">This</span>.lAddMenu
<span style="color: #008000">*\\ Place a new MenuBar on VFP's TOOLS menu (below the "Toolbox" Bar)</span>
<span style="color: #0000ff">Do</span> (<span style="color: #0000ff">Home</span>(0) + "<span style="background-color: #ffff00; color: red">EnvMgr.App</span>") <span style="color: #0000ff">With</span> "<span style="background-color: #ffff00; color: red">-m</span>"
<span style="color: #0000ff">This</span>.lAddMenu = .F.
<span style="color: #008000">*//</span>
<span style="color: #0000ff">Endif</span>
<span style="color: #0000ff">Endproc</span>
<span style="color: #0000ff">Procedure</span> <span style="color: #0000ff">Activate</span>
<span style="color: #008000">*\\ Run EnvMgrStart.Prg in EnvMgr.App passing in the name of </span>
<span style="color: #008000">*\\ the project which should match the environment name</span>
<span style="color: #008000">*\\ stored in EnvMgr.Setname</span>
<span style="color: #0000ff">If</span> <span style="color: #0000ff">This</span>.lActivateEnabled
<span style="color: #0000ff">Do</span> (<span style="color: #0000ff">Home</span>(0) + "<span style="background-color: #ffff00; color: red">EnvMgr.App</span>") <span style="color: #0000ff">With</span> <span style="color: #0000ff">This</span>.cLookupId, .T.
<span style="color: #0000ff">_Screen</span>.<span style="color: #0000ff">Caption</span> = ;
"<span style="background-color: #ffff00; color: red">FoxQuill Development Environment V9.0 - [Environment -> </span>"+;
<span style="color: #0000ff">Proper</span>(<span style="color: #0000ff">This</span>.cLookupId)+"<span style="background-color: #ffff00; color: red">]</span>"
<span style="color: #0000ff">Endif</span>
<span style="color: #008000">*//</span>
<span style="color: #0000ff">Endproc</span>
<span style="color: #0000ff">Procedure</span> <span style="color: #0000ff">QueryModifyFile</span>
<span style="color: #0000ff">Lparameters</span> toFile <span style="color: #0000ff">As</span> VisualFoxpro.IFoxPrjFile, tcClassName <span style="color: #0000ff">As</span> <span style="color: #0000ff">String</span>
<span style="color: #0000ff">If</span> <span style="color: #0000ff">JustStem</span>(toFile.<span style="color: #0000ff">Name</span>) == "<span style="background-color: #ffff00; color: red">__pjxhookactivationswitch</span>" <span style="color: #008000">&& must be lower case!</span>
<span style="color: #0000ff">This</span>.lActivateEnabled = Not <span style="color: #0000ff">This</span>.lActivateEnabled
<span style="color: #0000ff">Wait</span> <span style="color: #0000ff">Window</span> <span style="color: #0000ff">Nowait</span> "<span style="background-color: #ffff00; color: red">Activation behaviour </span>" + ;
<span style="color: #0000ff">Iif</span>(<span style="color: #0000ff">This</span>.lactivateenabled, "<span style="background-color: #ffff00; color: red">ENABLED</span>", "<span style="background-color: #ffff00; color: red">DISABLED</span>") + ;
"<span style="background-color: #ffff00; color: red"> for </span>" + <span style="color: #0000ff">JustFName</span>(<span style="color: #0000ff">_VFP</span>.ActiveProject.<span style="color: #0000ff">Name</span>) ;
<span style="color: #0000ff">Timeout</span> 2
<span style="color: #008000">*\\ do not open the dummy file!</span>
<span style="color: #0000ff">Nodefault</span>
<span style="color: #008000">*//</span>
<span style="color: #0000ff">Endif</span>
<span style="color: #0000ff">Endproc</span>
<span style="color: #0000ff">Enddefine</span></strong></pre>
<h3><font color="#004000">Some Final Code Comments</font></h3>
<p>The code in the <font color="#0000ff" size="3" face="Courier New"><strong>QueryModifyFile()</strong></font> method supports <strong>enabling/disabling</strong> of the ProjectHook's <strong><font color="#0000ff" size="3" face="Courier New">Activate()</font></strong> behavior. Just add (e.g.) a TXT-file to your project with the name <strong><em>__PjxActivationSwitch.txt</em></strong> (don't forget to exclude it). Double-clicking the file in the Project Manager toggles the state of the <font color="#0000ff" size="3" face="Courier New"><strong>lActivateEnabled</strong></font> property which in turn controls execution within the <font color="#0000ff" size="3" face="Courier New"><strong>Activate()</strong></font> method.</p>
<p>My latest ProjectHook versions do not have any properties that control behavioral aspects any longer! Thus, there is no need to create and maintain external configuration files that must be parsed and evaluated at runtime. Behavior gets loaded dynamically like implemented in the VFPX project. Environment handling is delegated to VFP's Environment Manager completely. </p>
<h4><font color="#004000">Inner Workings of the EnvMgr</font></h4>
<p>The Environment Manager uses a two-level lookup internally to locate your <em>EnvironmentSet</em>. In the first place it searches the <strong>EnvMgr.Lookupid</strong> column of its driving table. This column contains the unique IDs of the <em>EnvironmentSets</em> (amongst other things). The IDs are <font color="#0000ff" size="3" face="Courier New"><strong>Sys(2015)</strong></font> generated values that are not difficult to unearth (I will show you in a moment how to spot them). If the EnvMgr cannot locate your ID value it searches the <strong>EnvMgr.Setname</strong> column next. The <em>Setname c</em>olumn holds the name you gave the <em>EnvironmentSet</em> when adding it in the Environment Manager. <u>This is the name the ProjectHook will pass to the EnvMgr, too.</u> </p>
<p><em><strong><font color="#004000">How does the ProjectHook knows what name you gave to your EnvironmentSet?</font></strong></em></p>
<h4><font color="#004000">Convention over Configuration…</font></h4>
<p><strong><font color="#004000">… is a well-known slogan today</font></strong>. And it is a good one, believe me. I've learned it the hard way! Either you do some <em>configuration</em> which is time-consuming (<strong><font color="#ff0000">= bad</font></strong>), or you keep with the <em>convention</em> and, in our case, use the same name for your <em>EnvironmentSet</em> and your <em>Project</em> (which doesn't cost you even a single second <strong><font color="#008000">= good</font></strong>). This is what the ProjectHook does. It keeps with the (unwritten) convention that both, the <em>EnvironmentSet</em> and the <em>Project File</em> share the same name if they belong to the same Project: <font color="#0000ff" size="3" face="Courier New"><strong>UPPER(ALLTRIM(Envmgr.Setname) == JUSTSTEM(_VFP.ActiveProject.Name)</strong></font>. This denoted by the orange lines in the the screenshot below.</p>
<h3><font color="#004000">Need More Speed?</font></h3>
<p>From the above follows that you have to pass in an existing <font color="#0000ff" size="3" face="Courier New"><strong>Sys(2015)</strong></font>value to avoid the second <font color="#0000ff" size="3" face="Courier New"><strong>Locate</strong></font>. Okay, let's lose some time configuring a high-speed ProjectHook ;-) Let's say you set up a VFP Project called <em><strong>AppSpy.Pjx</strong>,</em> and that you set up an <em>EnvironmentSet</em> for it, too. First, you have to create a subclass of the ProjectHook. Let's name it <em><strong>AppSpyHook</strong></em>. Now, you have to find out what unique ID the EnvMgr had given to your EnvironmentSet to assign that value to the <strong><em>cLookupID</em></strong> property at design-time. This is easily done as you can see on the screenshot below. Open the TaskPane Manager, select the Environment Manager, then hover with your mouse over your <em>EnvironmentSet</em> entry. You will see the lookup key displayed in VFP's status bar. This is the <em>key value</em> you have to assign to the <strong><em>cLookupId</em></strong> property in your ProjectHook's class code!</p>
<p><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="PjxHookEnvMgrLookupID" border="0" alt="PjxHookEnvMgrLookupID" src="http://lh6.ggpht.com/-rw2ir5eDpyk/Uyi9qCq9E7I/AAAAAAAAIC0/-p7dv4tlSe0/PjxHookEnvMgrLookupID%25255B6%25255D.jpg?imgmax=800" width="837" height="390" /></p>
<p>You may create and use the following on key label to save some handwriting / typing: </p>
<pre><strong><span style="color: #0000ff">On</span> <span style="color: #0000ff">Key</span> <span style="color: #0000ff">Label</span> f8 <span style="color: #0000ff">_cliptext</span> = <span style="color: #0000ff">Substr</span>(<span style="color: #0000ff">_vfp</span>.StatusBar, <span style="color: #0000ff">At</span>("<span style="background-color: #ffff00; color: red">WITH</span>", <span style="color: #0000ff">_vfp</span>.StatusBar)+6,10)</strong></pre>
<p>Press F8 when you see the ID value in <em>VFP's StatusBar</em>. After pasting the key value back into your code editor window your class header should now look like this:</p>
<pre><strong><span style="color: #0000ff">Define</span> <span style="color: #0000ff">Class</span> fq_minimal_hook <span style="color: #0000ff">As</span> <span style="color: #0000ff">ProjectHook</span>
clookupid = "<span style="background-color: #ffff00; color: red">_3P90VWP8P</span>"
laddmenu = .T.
lactivateenabled = .T.
<span style="color: #0000ff">Name</span> = "<span style="background-color: #ffff00; color: red">fq_minimal_hook</span>"
<span style="color: #0000ff">Procedure</span> <span style="color: #0000ff">Init</span>
<span style="color: #0000ff">If</span> <span style="color: #0000ff">Empty</span>(<span style="color: #0000ff">This</span>.clookupid)</strong></pre>
<p>Save your class and assign it to your AppSpy Project Manager. Next time you open your AppSpy Project the AppSpyHook will call the EnvMgr sending the "_3P90VWP8P" key. BTW: This frees you from using the same <em>EnvironmentSet</em> name there. Maybe you want to use a more meaningful, or totally different key value now.</p>
<p>This "faster" version of your ProjectHook does not run noticeably faster! The only difference between this "high speed" ProjectHook and our first implementation is that it took much longer to implement (and you had to know much more details). Decide for yourself which way you want to take: the classic configuration oriented, or the promising convention based approach…</p>
<h3><font color="#004000">The End</font></h3>
<p>I hope that you found this entry chapter useful. Please let me know if you have encountered any side effects while playing with this tiny ProjectHook. Next time we will talk about constellations where a Hook's Activate() isn't raised, why you should not check-in a hook-enabled project into Microsoft's Team Foundation Server (TFS) and other weird things. </p>
<h4><font color="#004000">To wet your appetite…</font></h4>
<p>ProjectHooks are <strong><em>loosely coupled</em></strong> with their (parental) Project objects only. You may <strong><em>exchange them on the fly</em></strong>, thereby changing the whole Project behavior dynamically without the need to close and re-open the Project Manager first. Have you ever asked yourself what happens to your ProjectHook instances (that are 'linked' to your Project objects) when you issue a CLEAR ALL in VFP's command window? Simply put a <font face="Courier New"><strong><font size="3"><span style="color: #0000ff">Wait</span> <span style="color: #0000ff">Window</span> "<span style="background-color: #ffff00; color: red">I'm dying!</span>"</font></strong></font> in your ProjectHook's Destroy() method, instantiate your class, assign the reference to any open Project Manager instance, and finally issue a CLEAR ALL. <em><font color="#004000">What do you see and what does that mean?</font></em></p>
<p><font color="#004000"><strong><em>Stay tuned, enjoy!</em></strong></font></p>
<hr /><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Previous Chapter" border="0" alt="Previous Chapter" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX0Vm971-0mz3X9yR7MP7OXtRg4rSaSvOECWpMbwMg2A0-y3sN3DQdpUxuZXttPjYsBNU3_JSYL7v8ScS4Z60r6uwnAufIbY1TRwcSaYcLreSsYWYPLfzUBKjdBEnFpnUpVKEJ/?imgmax=800" width="48" height="64" /> <a title="http://myvfpblog.blogspot.com/2009/09/neat-solutions-home.html" href="http://myvfpblog.blogspot.com/2009/09/neat-solutions-home.html"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Neat Solutions Home (TOC)" border="0" alt="Neat Solutions Home (TOC)" src="http://lh4.ggpht.com/-f0JLSGJIhMY/Uyi_Ynyp_cI/AAAAAAAAIDE/Bck0ibSMp6U/NavHome_48_RGBA%25255B4%25255D.png?imgmax=800" width="48" height="64" /></a> <img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Next Chapter" border="0" alt="Next Chapter" src="http://lh4.ggpht.com/-fZlAEFIo5xQ/Uyi_ZBjn67I/AAAAAAAAIDM/gCmx_4Y-xR8/NavForward_48_RGBA%25255B5%25255D.png?imgmax=800" width="48" height="64" /> Burkhardhttp://www.blogger.com/profile/11631168041975170500noreply@blogger.com0tag:blogger.com,1999:blog-26167158.post-14255543294521859532014-03-08T02:47:00.001+01:002014-03-08T03:21:00.560+01:00Core Components<p><strong><font color="#ff8040">Version: 1.00.00 - last update: Friday 7th of March 2014, 17:00:00</font></strong></p> <p><a href="http://myvfpblog.blogspot.com/2014/03/foxquill-overview.html"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Previous Entry" border="0" alt="Previous Entry" src="http://lh4.ggpht.com/-jWOm_5gPk5M/Uxp2h1KGoOI/AAAAAAAAH-Y/MaBvTVnQrbg/NavBack_48_RGBA%25255B4%25255D.png?imgmax=800" width="48" height="64" /></a> <a href="http://myvfpblog.blogspot.de/2009/09/foxquill-more-than-framework-foxquill.html"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="FoxQuill Home" border="0" alt="FoxQuill Home" src="http://lh6.ggpht.com/-384qZhKAXdQ/Uxp2iSi-PzI/AAAAAAAAH-g/eOYaRCe2rE0/NavHome_48_RGBA1%25255B4%25255D.png?imgmax=800" width="48" height="64" /></a> <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Next Entry" border="0" alt="Next Entry" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCLj1yDmD0viki56SwjS9fDOyKn-DpmO0WvDGHRuWS6-N8p5YjFZypo2tpR7GpZ4YrkMNFarrqPIGBgoTnUP1kkuIOuO0zAmaQq_eOVLOrbNTkesQJqhLBY_cOKfTZdc050e99/?imgmax=800" width="48" height="64" /> </p> <hr /><font color="#9b00d3"><a href="http://lh6.ggpht.com/-XJIzFRhmPb4/Uxp2jgT9v1I/AAAAAAAAH-w/558JYE7ObuI/s1600-h/FoxQuill20117%25255B3%25255D.png"><img style="background-image: none; border-right-width: 0px; margin: 3px 5px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="FoxQuill20117" border="0" alt="FoxQuill20117" align="left" src="http://lh5.ggpht.com/-xpbMGoc9qSY/Uxp2kI3aH-I/AAAAAAAAH-0/iVhaG3uK_2U/FoxQuill20117_thumb.png?imgmax=800" width="82" height="101" /></a></font> <h3><font color="#9b00d3">This is an overview of <em>FoxQuill's</em> basic building blocks. Note: I will add content here while I'm writing about the components in detail in the other sections.</font></h3> <p>I said it in my (previous) overview chapter: <em>FoxQuill</em> is a<font color="#000000"> <em><strong>M</strong>anaged <strong>R</strong>untime <strong>E</strong>nvironment</em> (<em>MRE</em>) </font>for all kind of <em>business related VFP class instances</em>. This is a sounding statement. Let me fill it with more concrete explanations for you, now.</p> <h4><font color="#9b00d3"> <hr />FoxQuill's Main Core Component is called <em>The Kernel</em></font></h4> <p>The <em>Kernel</em> is a <em>VFP Container</em> that hosts all other <em>Core Components</em>. The <em>Kernel</em> does not implement any important functionality but publishing an interface to access its members. The <em>Kernel Members</em> (the <em>Core Components</em>) implement the <em>Kernel Infrastructure Layer</em> (<em>KIL</em>). Based on this infrastructure the <em>Kernel</em> then creates an <em>Object Management Layer</em> (<em>OML</em>). Classes belonging to the <em>OML</em> are typically named <em>Managers</em>, <em>Controllers</em>, and <em>Handlers</em>. We will discuss them later in detail. Finally, the <em>OML</em> loads the <em>Application</em> which is, generally said, the set of all class instances used to create the application specific appearance and behavior the user is interacting with. The following diagram shows this hierarchy.</p> <p><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="The Layers of FoxQuill's Managed Runtime Environment" border="0" alt="Layers of FoxQuill's Managed Runtime Environment" src="http://lh5.ggpht.com/-Qn0JC6LeOVQ/Uxp2lXRV1DI/AAAAAAAAIAs/tK-RkaypV-c/Kernel001%25255B1%25255D.jpg?imgmax=800" width="394" height="163" /></p> <p>Internally, the <em>Kernel</em> creates a public variable (normally "MY") holding a reference to the <em>Construct Component</em> which belongs to the <em>Infrastructure Layer</em>. The <em>My-Reference</em> can be compared with the well-known <em>goApp-Reference</em> used in many other implementations. Thus, in the <em>FoxQuill</em> universe all code that addresses an object in any layer will look like this:</p> <p align="center"><font color="#0000ff" size="3" face="Courier New"><strong>lnAnswer = My.Bios.MessageBoxes.QueryAppQuit.Show()</strong></font></p> <p>As you will see later, the above <strong>Command</strong> follows a common <em>FoxQuill Object Notation Scheme</em>: </p> <p align="center"><font size="3" face="Courier New"><strong>ConstructRef.ManagerRef.ControllerRef.HandlerRef.Method()</strong></font></p> <p>Another common <em>FoxQuill Object Notation Scheme</em> for <strong>querying</strong> a property looks like this:</p> <p align="center"><font color="#0000ff" size="3" face="Courier New"><strong>llSingleton = My.Settings.System.AppIsSingleton.Value</strong></font></p> <p>Again, this <em>Query</em> follows the same common <em>FoxQuill Addressing Scheme</em>: </p> <p align="center"><font size="3" face="Courier New"><strong>Result = ConstructRef.ManagerRef.ControllerRef.HandlerRef.Value</strong></font></p> <p>We will discuss that issue in more detail in the <em>Kernel </em>chapter.<font color="#9b00d3"> </font></p> <hr /><font color="#9b00d3"><em></em></font> <h4><font color="#9b00d3">FoxQuill's Object Pool is called <em>The Construct</em></font></h4> <p>Basically, the <em>Construct</em> is-a VFP <em>Collection</em>. The <em>Construct</em> stems from a "new" <em>FoxQuill BaseClass</em> called <em><strong><font color="#9b00d3">ObjectCollection</font></strong></em>. As with any native <em>VFP Collection</em> <em>ObjectCollections </em>can be stacked inside each other, again and again. The most prominent extension of the native VFP Collection class is the ability of the <em>ObjectCollection</em> to address stacked <em>ObjectCollections</em> like shown in the examples above. Trying this with native VFP Collections we would have to write the first example like so:</p> <p><font color="#0000ff" size="3" face="Courier New"><strong>lnAnswer = My("Bios").Item("MessageBoxes").Item("QueryAppQuit").Show()</strong></font></p> <p>What a mess :-) But now, we are able to store <em>ObjectCollections</em> in <em>ObjectCollections</em>, in <em>ObjectCollections</em>, in… without the need to use the collection's Item() method to drill down into the containment hierarchy. You can read all about the implementation details in the <em>Construct</em> chapter.</p> <p>The <em>ObjectCollection</em> not only is a <em>Core Component</em> but really a <strong><font color="#9b00d3"><em>Key Component</em></font></strong> that makes <em>programming the FoxQuill Framework</em> a hassle-free experience! </p> <hr /><font color="#9b00d3"></font> <h4><font color="#9b00d3">FoxQuill's Class Manager is called <em>The Factory</em></font></h4> <p>Like the <em>Construct</em> <em>FoxQuill's Factory</em> is-a <em><strong>ObjectCollection</strong></em>. The <em>Factory</em> is able to instantiate any kind of object and 'Do' any kind of form, as long as the definition can be found in the <em>Factory's driving-table</em>.</p> <p>Another feature of the <em>Factory</em> is the ability to return a <em>factory string</em> suitable for creating objects on the fly using VFP's macro substitution. In rare cases this might be helpful but is not recommended!</p> <p>The Factory also supports the creation of <em>Member Objects</em> within other containers, and collections.</p> <p>Another prominent feature of <em>FoxQuill's Factory</em> is the ability to create any object <strong>within its own distinct data session</strong>! Internally the <em>Factory</em> keeps track of all created objects and their data sessions.</p> <p>The <em>driving-table</em> also stores information about <em>Object Relations</em>! Thus, the <em>Factory</em> knows which sibling, or child objects have to be instantiated in which 'parental' data session!</p> <p>There's a lot more to say about additional features. You can read more about the details in the <em>Factory</em> chapter later on. </p> <hr /> <h4><font color="#9b00d3">FoxQuill's Data Manager is called <em>The GPStore</em></font></h4> <p>Like any other <em>Core Component</em> the <em>General Purpose Store</em> is-a <em><strong>ObjectCollection</strong></em>. To simplify VFP-table based system data handling to the max all system data is stored in one table only! Well, almost :-) In Fact there are three tables which together make up a <em>GPStore</em>. I will explain that in more detail in the <em>GPStore</em> chapter. But…</p> <p align="center"><strong>All data is stored in a highly redundant, de-normalized, serialized way!</strong> </p> <p>What does this mean? Well, in short, a <em>GPStore</em> does <u>not</u> organize its data using the relational column/row addressing directly!</p> <p align="justify"><font style="background-color: #cccccc"><strong>A short side-kick:</strong> The relational theory describes a set of columns as the representation of a data structure (similar to a class). The rows are then instances of that structure (similar to a set of objects stemming from the same class only differing in their appearance). In the relational world we now can address each data field (each atomic information) using column/row addressing.</font></p> <p>A <em>GPStore</em> places each atomic field value in a distinct record! If we want to store a regular record (with, let's say, 10 columns) inside a <em>GPStore System</em> we will end up having 10 distinct records each holding one atomic field value. This is meant by <strong>serializing</strong> the data.</p> <p>To keep track of which <em>GPS-Record</em> maps to which column/record of the native VFP source table we have to add these meta-information to our <em>GPStore-Table</em> adding extra columns. Amongst the <em>Mapping Information</em> columns there are further columns to describe the <em>Data Type</em> of the stored value, its <em>Dimension(s)</em> and <em>other Meta-Data</em>. <br />Normally, this meta-data is stored only once in the table header of a regular VFP table. Because the GPStore table has to store its "class definition" meta-data together with each data value in every <em>GPS-Record again and again, </em>this is a highly redundant way of storing data. In terms of <em>Relational Normalization Theory</em> we would say "the GPStore data table is de-normalized to rot in hell" :-)</p> <p><em><strong>Why would we pay such a high price acting against all odds?</strong></em></p> <p>The answer is: <strong><font color="#9b00d3">Freedom</font></strong>! We are free to change our data class schemas (the 'virtual table headers') from one record-set to the next without the need of exclusive file access to alter our table structure. But there is much more! We can add as much meta-data to each data record as we need. The <em>GPStore</em> for example supports <em>data versioning</em>, <em>data translation</em>, <em>access security</em>, <em>encryption</em>, <em>relations</em>, and more! Imagine: You now can ask your GPStore to retrieve information about the the string "Heinz" and perhaps you get the answer: "Heinz" was found 3 times denoted by 'First Name', 1 time denoted by 'Last Name', and 2 times denoted by 'City'. Then you can ask the GPStore to retrieve the whole record where 'Heinz' is used as a 'Last Name' and get back a VFP data object with all fields restored from the serialized records.</p> <p>To restore serialized data back to a cursor that can be consumed by FoxPro <em>FoxQuill's GPStore </em>employs a special Serializer/DeSerializer object. The rest of this exiting story can be read in the GPStore chapter in the next future… </p> <hr /> <h4><font color="#9b00d3">FoxQuill's Unified Messaging System is called <em>The Matrix</em></font></h4> <p>Like any other <em>Core Component</em> the <em>Matrix</em> is-a <em><strong>ObjectCollection</strong></em>. "What the hack is a <em>Unified Messaging System</em> for?" you may have asked yourself, don't you? :-)</p> <p>Basically, the Matrix translates human-readable object paths (like <font color="#0000ff" size="3" face="Courier New"><strong>My.Logging.TextFile.ErrorLog</strong></font>) into machine-readable ones like <font color="#0000ff" size="3" face="Courier New"><strong>1.23.12.55.</strong></font> </p> <p>Without diving too deep into details we can state that if both expressions above address the same class instance in <em>FoxQuill's</em> working memory, and <em>My</em> is the reference of the <strong>Construct</strong> (which equals <strong>1</strong> here), then the <strong>Logging</strong> object must be item <strong>23</strong> of the <em>Construct</em> ObjectCollection, the <strong>TextFile</strong> object must be item <strong>12</strong> of the <em>Logging</em> ObjectCollection, and the <strong>ErrorLog</strong> object must be item <strong>55</strong> of the <em>TextFile</em> ObjectCollection. </p> <p>Adding up the Item-IDs along the object path (transforming them to a dot-separated string) will give us a new key expression we will use within the Matrix ObjectCollection. <em>But, what will be stored in the Matrix ObjectCollection using the key "1.23.12.55." and why?</em> </p> <p>Well, <em>FoxQuill</em> introduces a set of <em>'virtual' classes</em> called <strong><font color="#9b00d3"><em>Smart Interfaces</em></font></strong>. A <em>Smart Interface</em> object does <strong>not</strong> wrap, or decorate its implementation object. A <em>Smart Interface</em> is a placeholder, a so called <strong>binding proxy</strong> based on VFP's EMPTY class that represents the <em>Handler</em> Object within the <em>Matrix</em>. Every <em>Handler</em> supports one <strong>or more</strong> <em>Smart Interfaces</em>.</p> <p>When the Factory instantiates, let's say, a <em>Customer Form</em> for us that form instance will be stored somewhere in the <em>Construct</em> maybe under "<font color="#0000ff" size="3" face="Courier New"><strong>My.Gui.Forms.CustomerMain</strong></font>". Notice, that the <font color="#0000ff" size="3" face="Courier New"><strong>CustomerMain</strong></font> reference is not our form's reference but the reference of the <em>Construct's Handler</em> 'wrapping' our form reference! </p> <p>Together with our form stored in its <em>Handler</em> inside the <em>Construct</em> at least one <em>Smart Interface</em> object is created and stored in the <em>Matrix ObjectCollection</em> using a machine-readable key that equivalently 'points to' our <em>Form Handler</em>.</p> <p>All <strong>Public PEMs</strong> of our form will be represented within the <em>Smart Interface</em> by adding a <strong>simple property</strong> to it. These properties will be solely used as <strong>handles for an event binding</strong> that takes place in the next step of the process: <br />The <em>Matrix</em> binds the <em>Handler</em> of our new form (in our example the <font color="#0000ff" size="3" face="Courier New"><strong>.CustomerMain</strong></font> object) to each of the <em>Smart Interface Properties</em> in a predefined (table-driven) way. After that, the <em>Matrix</em> broadcasts a message <em><strong>NewFormCreated</strong></em> so that all other <em>Smart Interface Objects</em> that are interested in that message will get the chance to signal that <em>Application-global</em> event to their own <em>Handlers</em>.</p> <p>Messages are no longer sent from one object to another directly but solely through and to their <em>Smart Interfaces</em>. <strong><font color="#9b00d3"><em>Handlers</em> </font></strong>implementing a generic contracting scheme. They check incoming and outgoing parameter values against their contracts ensuring the correctness of the message signatures. There is much more to say about the collaboration between <em>Smart Interfaces</em> and the <em>Handlers</em> they are bound to… You will find the whole story in the <em>Matrix</em> chapter.</p> <p>Bottom line is: With the help of the <em>Matrix</em> you can forget any hard-coded 'object reference wiring'. Just code against the generic messaging interface of your classes' <em>Handler</em>, that's all. The last thing you have to do is to set up some records in the <em>Matrix driving table</em> that define the bindings you need for your form to interact correctly. BTW, that job can also be done later at runtime! </p> <hr /> <h4><font color="#9b00d3">FoxQuill's Task-Oriented App-Manager is called <em>The Workflow</em></font></h4> <p>Like any other <em>Core Component</em> the <em>Workflow</em> is-a <em><strong>ObjectCollection</strong></em>. The main task of the <em>Workflow Manager</em> is to "drive" your application. Look at your own implementations for example. You will find some entry point where your application starts. From there you almost always can follow a narrow execution path that finally leads to some open tables, some running business objects with your main form bound to their properties, before you enter VFP's READ EVENT loop. This is a good example for an application workflow. Better said, this is good example for a <strong><em><font color="#9b00d3">Process</font></em></strong> defined in <em>FoxQuill's Workflow Manager</em>. In <em>FoxQuill's Workflow Manager</em> context <em>Controllers</em> are called <em>Processes</em> and <em>Handlers</em> are called <em><strong><font color="#9b00d3">Tasks</font></strong></em>. Each Task you define can manage an unlimited count of <strong><em><font color="#9b00d3">Steps</font></em></strong>.</p> <p>Sometimes it is not advisable to split a simple workflow up in too fine-grained <em>Steps</em>. Often it is enough to hard-code a whole <em>Process</em> just into one single <em>Step</em>. The idea behind the scenes of <em>FoxQuill's Workflow Management</em> is, as always, to create <strong>reusability</strong> even if the code looks 'procedural' that much. You may think about setting up your development environment for a given project and a special scenario. Maybe you want to run some code every time you entering the debugging mode. If you encounter an invariant sequence of code lines that is only varied using some external values and you find yourself typing in those code lines again and again (or copy & paste them again and again) you obviously found a code fragment that should be better wrapped into a <em>Step Class</em>.</p> <p>The biggest advantage using <em>Processes</em>, <em>Tasks,</em> and <em>Steps</em> is that they all can be scripted. In other words, they can be dynamically altered at runtime!</p> <p>Another big plus of using <em>FoxQuill's Workflow Management</em> is that all <em>Actions</em> defined within a <em>Step</em> are recorded and can be replayed later. This also leads to an almost unique feature called <strong><font color="#9b00d3">Forward Recovery</font></strong>. The users of a FoxQuill-based application get a new option beside <em><strong>save-or-cancel editing</strong></em> called <em><strong>suspend editing</strong></em>. They may not only <em><strong>close</strong></em> their data entry forms but <em><strong>suspend</strong></em> them. The next day they can <em><strong>resume editing</strong></em> by the help of <em>Forward Recovery</em>. <br />Finally, using FoxQuill's Workflow enables <strong><font color="#9b00d3">Undo</font></strong> actions. This feature can be compared to VFP's <em>Transactions</em> that can be rolled back at any point before <em>End Transaction</em> took place. There is much more to talk about. Get the rest in the <em>Workflow</em> chapter. </p> <hr /> <h4><font color="#9b00d3">Final thoughts</font></h4> <p>If you followed my writing you may have asked yourself, if the additional layers introduced by <em>FoxQuill's Managed Runtime Environment</em> would not have a negative impact on performance and clarity. Believe me, they don't have! </p> <p><strong>First, let's talk about Handlers</strong>. These guys handle our workhorse classes. What are they doing when they implement the contracting that shields our implementations from false input parameter values? Well, they take the parameter checking code out of our implementation methods, thereby making our methods easier to read (even running a little bit faster). Of course, our parameter checking code was only relocated which means it still gets executed (slowing down things again:-). </p> <p>But this is irrelevant compared to the advantages we will gain! A <em>Handler</em> is capable of handling an unlimited count of class instances of the same type (the class type he was designed to handle). Let's open a second and third instance of our form. Now we <strong>do have</strong> a positive impact on performance and memory footprint because our parameter checking code was only loaded once inside the <em>Handler</em>! But that's not all by far! </p> <p>Handling a form does not only mean checking parameters, but is much more, like resizing, refreshing, repositioning, and other things. All these issues should be taken out of the form class. The optimal form class in a <em>FoxQuill MRE</em> has no code in its methods at all! Okay, let's put two or three lines in the Form's QueryUnload() method but that's all! The one and only task of a FoxQuill form is being the host for the controls we dropped on it! Form resizing, and repositioning of form controls is left to the <em>Form Handler</em>. Even better, repositioning of form controls is delegated via a second <em>Smart Interface</em> to a specialized <em>Layout Manager</em>.</p> <p><strong>Now, let's talk about Controllers</strong>. While each <em>Handler Class</em> is designed to support only one specific <em>Class Type</em>, each <em>Controller Class</em> is designed to support only one specific <em>Handler Base Type.</em> This said, it should be clear that a <em>Form Controller</em> will only 'control' <em>Form Handlers</em>, just as a <em>MessageBox Controller</em> will only 'control' <em>MessageBox Handlers</em>. <br />What does 'control' mean in this context? Well, to put it bluntly, <em>Controllers</em> do not control very much, at least the vast majority. There is a chain of responsibility established between Handlers an Controllers instead. If some functionality is common to all <em>Handlers</em> it will be implemented in their <em>Controller</em> class, instead of moving it upwards the <em>Handler </em>class hierarchy. Thus, we can choose a totally different <em>BaseClass</em> type for a specific <em>Handler</em> without loosing the common functionality. Our new, let's say, <em>Custom</em>-based <em>Handler</em> calls its <em>Parent Controller</em> if it needs some common <em>Handler </em>functionality implemented there. <br />BTW: The <em>Layout Controller</em> is one of <em>FoxQuill's Controllers</em> that <strong>do</strong> 'control' its <em>Layout Handlers</em> to synchronize the activities of these sibling <em>Handlers.</em> But that's another story…</p> <p><strong>Finally, let's talk about Managers</strong>. FoxQuill's Managers are grouped by the <strong><font color="#9b00d3">Aspects</font></strong> they manage. There is a <em>Manager</em> for <em>Security</em>, <em>Basic IO Operations</em>, <em>Logging</em>, <em>Error handling</em>, and many many more. Some of these <em>Aspects</em> are no real <em>AOP Aspects</em> because they are restricted to only one <em>Application Layer</em> and therefor no <em>Cross Cutting Concern</em>. Most what was said about Controllers also is true for Managers. There is a chain of responsibility established between <em>Controllers</em> and <em>Managers</em>. If some functionality is common to all <em>Controllers</em> it will be implemented in their corresponding <em>Manager</em> class instead of moving it upwards the <em>Controller</em> class hierarchy.</p> <p>How to implement a bullet-proof handling of <em>Cross Cutting Concerns</em> based on the FoxQuill Framework goes far beyond this document, even the entire Blog, and maybe subject of a separate essay to be written at some indefinite future date:-) </p> <p>Cheers!</p> <hr /> <p><a href="http://myvfpblog.blogspot.com/2014/03/foxquill-overview.html"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Previous Entry" border="0" alt="Previous Entry" src="http://lh4.ggpht.com/-GwCGDRn9dgw/Uxp2mHz5jyI/AAAAAAAAH_M/9E-2MPEcu7g/NavBack_48_RGBA%25255B9%25255D.png?imgmax=800" width="48" height="64" /></a> <a href="http://myvfpblog.blogspot.de/2009/09/foxquill-more-than-framework-foxquill.html"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="FoxQuill Home" border="0" alt="FoxQuill Home" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHwreTr062ZbhoLdTzhmFqnDP5LaofulQ9IenLrv-QSRMeumep7Ms7v5FKPqN-lHMhp_ECYm_fqXXJBmk_qD5EUmHOWuhp4F3p_-RaWYx1tynsQR-kshye1aU07uQVLFNYgVwp/?imgmax=800" width="48" height="64" /></a> <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Next Entry" border="0" alt="Next Entry" src="http://lh5.ggpht.com/-8MvMUjUhaHE/Uxp2mr_EEJI/AAAAAAAAH_c/ws0xbLDcCME/NavForward_48_RGBA8%25255B8%25255D.png?imgmax=800" width="48" height="64" /></p> Burkhardhttp://www.blogger.com/profile/11631168041975170500noreply@blogger.com0tag:blogger.com,1999:blog-26167158.post-35889330427159856942014-03-06T21:09:00.000+01:002014-03-08T03:23:29.182+01:00FoxQuill an Overview<p><strong><font color="#ff8040">Version: 1.00.02 - last update: Friday 7th of March 2014, 13:25:00</font></strong></p> <p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Previous Entry" border="0" alt="Previous Entry" src="http://lh6.ggpht.com/-c8m1qCAtlvo/UxjWELDNs-I/AAAAAAAAH7c/7BwPnlXlj1U/NavBack_48_RGBA%25255B10%25255D.png?imgmax=800" width="48" height="64" /> <a href="http://myvfpblog.blogspot.de/2009/09/foxquill-more-than-framework-foxquill.html"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="FoxQuill Home" border="0" alt="FoxQuill Home" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTvlPIDnjCpYBuB4pjPrj21Nwx9IVu8w00UaUXSAYVMJrAdU9ow39QYsjI39NtRkCO-FTIvuXfnnr43Mwm5PqgVVpd5TcrEOV9T8u8_sp4w1Iw4vqXeYNguN7zWCn7AeN2eGGZ/?imgmax=800" width="48" height="64" /></a> <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Next Entry" border="0" alt="Next Entry" src="http://lh3.ggpht.com/-MgB4rio98B0/UxjWFS3pOlI/AAAAAAAAH7o/WFwBinhjCUc/NavForward_48_RGBA%25255B8%25255D.png?imgmax=800" width="48" height="64" /> </p> <hr /> <h3><font color="#9b00d3"><img style="background-image: none; border-right-width: 0px; margin: 3px 10px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="FoxQuill2011" border="0" alt="FoxQuill2011" align="left" src="http://lh3.ggpht.com/-ROe6D7oAEhs/UxjbKQ69OUI/AAAAAAAAH8s/rAh461BNhv8/FoxQuill2011%25255B7%25255D.png?imgmax=800" width="82" height="101" />This is a short introduction of what is so special about the <em>FoxQuill framework</em> and why I decided to do it just that way.</font></h3> <p><em>FoxQuill</em> is not a framework only! Of course, <em>FoxQuill</em> incorporates a whole bunch of class libraries bundled with many cool tools to manage and maintain them. But that is not all, by far! </p> <h4><font color="#9b00d3"></font></h4> <h4><font color="#9b00d3">A Managed Runtime Environment</font></h4> <p>The <em>design</em> of FoxQuill's underlying <em>software architecture</em> can be called a <em><strong>Managed Runtime Environment for Biz-Objects</strong></em>. This is a runtime system where the <em>Task Fulfillment Instances</em> (all implementation components that make up the application a user actually is interacting with) are controlled by an superordinate governing like shown in the next diagram.</p> <p><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="FoxQuill's Managed Runtime Environment" border="0" alt="FoxQuill's Managed Runtime Environment" src="http://lh3.ggpht.com/-UKq_dxbGvpk/UxkZBEc1ZSI/AAAAAAAAIA8/uymjjpNRiRc/ScreenShot_ResourceGuide_WebPlusX_008%25255B3%25255D.jpg?imgmax=800" width="260" height="132" /></p> <p>Therefore, in the first place, FoxQuill is a <strong><em>Generic Collaboration Controller</em></strong> at runtime!</p> <h4><font color="#9b00d3">The Encapsulation-Collaboration Gap</font></h4> <p>While a good <em>OOP Class Design</em> promotes <strong>encapsulation</strong> (to support of reuse of classes) a good <em>APP Design</em> has to stress the <strong>collaboration</strong> of the concrete implementations of these classes. I named that <em>the Encapsulation-Collaboration Gap</em>. What I'm talking about here is easy to grasp. Remember your last contact with an unknown VFP framework! After having spent hours of exploring the (sometimes) genius code inside the classes (stored in uncountable libraries) you finally may have asked yourself the elementary question: "How do I put all these <em>gizmos</em> together to create something useful for my client?" </p> <p>Baking a tasty cake needs more than having all ingredients at hand! You need the knowledge how to mix them, and how to tamper with them to get the desired result:-) Let us stay with this real world example and ask: "Wouldn't it be nice to have a cake baking machine we could feed with our ingredients, select the cake we want from a menu, press the "BAKE" button, and finally watch it to do the nasty (and error prone!) job of joining, mixing, tasting, adding some more of this and that, tasting again, and finally baking our perfect cake - every time we want it, every time with the same perfect result?"</p> <p>Encapsulated class components (the ingredients of our application) are not capable to mix/combine themselves into something working at a larger scale by design! This led me to the question: "Is it possible to alter my class design to overcome the <em>Encapsulation-Collaboration Gap</em> issue without breaking any rules of (good) OOP-design?" The FoxQuill framework is the result of my mediation!</p> <p><strong><font color="#9b00d3">App-Generators? No-Way!</font></strong></p> <p>I hate "Application Generators"! Look at the one you've got for free when installing VFP on your disk (see screen shot below)</p> <p><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="VFP's native App Generator" border="0" alt="VFP's native App Generator" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhA7lm8-eb6mhIqguu82g4ToPC7ftlZ_IdvM77kYwgdXaxz2YIO8x99d6wT-nOrTJWYWsXXIV6e4swQ8Px82G2szq3XPtktLYEUXdVFeL4oV75PF-Kx3fyrhw9qXYVqylgyjC1r/?imgmax=800" width="226" height="244" /></p> <p>Be honest, did you ever create <em>something productive</em> with that generator for your clients? I did not! I even refused to dive deeper into the workings of VFP's free App Generator simply because I never wanted to be forced into the constraints of someone else's mind/knowledge.</p> <p>FoxQuill will NEVER put any constraints on you. You can enhance or alter every single aspect of it. Okay, maybe you will argue that you can 'pimp' the VFP Application Generator the same way to make it do what you want. But, to be honest, this can only be accomplished by understanding/knowing all and everything about it! Most of the components (classes) of that solution heavily rely on other parts of the same project which is called a (very!) tight coupling! This is one of the number one reasons why it is so hard to get used to an unknown framework/solution!</p> <h4><font color="#9b00d3">The solution</font></h4> <p>Free your 'workhorse' classes from being responsible to interact with others (in their method code) by delegating all collaborating code to another higher level! More than that, keep your 'workhorse' classes from being <em>polluted</em> by parameter checking code in that you move out that responsibility to another specialized level of government and you will get what FoxQuill is all about!</p> <p><strong><font color="#9b00d3">What FoxQuill finally is</font></strong></p> <p>FoxQuill is a framework that gives you all <strong><em>base classes</em></strong> you need during your daily coding challenge. All you have to do is to make your subclasses stemming from a FoxQuill base class to let the outcome run flawlessly within a FoxQuill controlled environment.</p> <p>FoxQuill is a runtime environment that implements its own contracting, messaging, event-binding, and data- binding schemes. In short, it delivers a complete object's life-time cycle management (including object's interactions!) to free the re-using developer from taking care of all of these issues!</p> <hr /> <p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Previous Entry" border="0" alt="Previous Entry" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi88fuPYC4mJgLmiLYj-nKqm9y_Kisa4rCTzNqSVSm_xpFNJVaCCoLTr3rb9XdjerJe6-QcXJ8jTH1dLsWCEKPXjAl9pYQX1mmiWLMspKBo4ABOPcQEl3mxrrInEpUvL_gEaPTh/?imgmax=800" width="48" height="64" /> <a href="http://myvfpblog.blogspot.de/2009/09/foxquill-more-than-framework-foxquill.html"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="FoxQuill Home" border="0" alt="FoxQuill Home" src="http://lh5.ggpht.com/-PCmdeSKeb0M/UxjWGakfz-I/AAAAAAAAH74/C_WxHonbrRs/NavHome_48_RGBA%25255B9%25255D.png?imgmax=800" width="48" height="64" /></a> <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Next Entry" border="0" alt="Next Entry" src="http://lh4.ggpht.com/-QtenyTdsK28/UxjWG3c4ZRI/AAAAAAAAH8E/ZZoZ9Z0JrAA/NavForward_48_RGBA%25255B9%25255D.png?imgmax=800" width="48" height="64" /></p> Burkhardhttp://www.blogger.com/profile/11631168041975170500noreply@blogger.com0tag:blogger.com,1999:blog-26167158.post-1346088679537558822011-05-13T00:40:00.000+02:002011-08-31T14:52:42.180+02:00Cool VFP Event Binding<p><strong><font color="#ff8040">Version: 1.00.00 - last update: Wednesday, August 30, 2011, 14:25:00</font></strong></p> <p><a title="http://myvfpblog.blogspot.com/2011/05/hierarchical-table-order-part-i.html" href="http://myvfpblog.blogspot.com/2011/05/hierarchical-table-order-part-i.html"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Previous Entry" border="0" alt="Previous Entry" src="http://lh4.ggpht.com/-Q5xN0BkdiVQ/Tl4oYqaLn3I/AAAAAAAAHi0/g67d6xvu5Ss/NavBack_48_RGBA534%25255B13%25255D.png?imgmax=800" width="48" height="64" /></a><a title="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-tips-tricks-in-this.html" href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-tips-tricks-in-this.html"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Tips & Tricks Home" border="0" alt="Tips & Tricks Home" src="http://lh6.ggpht.com/-ATghy9SY14Q/Tl4oY5BcaUI/AAAAAAAAHi4/ht6qjU9lqKU/NavHome_48_RGBA534%25255B4%25255D.png?imgmax=800" width="48" height="64" /></a><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Next" border="0" alt="Next Entry" src="http://lh4.ggpht.com/-2Qgt42SOJNo/Tl4oZQkwoCI/AAAAAAAAHi8/BxaicRx9XI4/NavForward_48_RGBA645%25255B8%25255D.png?imgmax=800" width="48" height="64" />  <hr /></p> <h4><font color="#000080"><font style="font-weight: bold">Recently, I reviewed some of my elder VFP </font><font style="font-weight: bold">event binding code and stumbled upon some unknown(?) COOL behavior!</font></font></h4> <h1><font style="font-weight: bold" color="#000080">Intro</font></h1> <p>Instantiating objects from classes, calling their methods, passing (parameter) values  back and forth between them, is our bread and butter business. Since VFP introduced <strong><em>event binding</em></strong> a whole new universe of possibilities arose. This post cannot cover the whole subject in detail; one has to write a book for that to come close. Thus, I am going to show you the most interesting (partially unknown!) aspects of event binding today.</p> <h2><font color="#000080"><font style="font-weight: bold">What You Should Know</font></font></h2> <p>Well, you should have worked with VFP’s event binding. At least, you should have read about it! I’m going to discuss the following commands and functions:</p> <pre><strong><font color="#0000ff" size="3">BINDEVENT(oEventSource, cEvent, oEventHandler, cDelegate [, nFlags])<br /></font></strong><strong><font color="#0000ff" size="3">UNBINDEVENTS(oEventSource, cEvent, oEventHandler, cDelegate)<br /></font></strong><font size="3"><strong><font color="#0000ff">AEVENTS( ArrayName [, 0 | 1 | oEventObject ] )<br /></font></strong><strong><font color="#0000ff">RAISEEVENT( oEventSource, cEvent [, eParm1...] )</font></strong></font></pre>
<p>You should be familiar with the above commands, especially with the correct application of the <strong><em>[, nFlags]</em></strong> parameter! At least you should know the difference between <strong><em>nFlags:= 0</em></strong> and <strong><em>nFlags:= 1</em></strong> and you should also know the difference between that first pairing and the second set: <strong><em>nFlags:= 2</em></strong> and <strong><em>nFlags:= 3</em></strong>.</p>
<p>Event binding makes it possible to extend otherwise <em>sealed</em> classes, even at runtime! Event binding makes your class design extendable and thus, reusable by others without touching your source code at all! <strong>Great benefits often have some drawbacks, which especially is true in case of VFP’s event binding implementation</strong>. Binding to VFP’s events is quickly learned; securely implementing custom events and handle unsolicited binding-clients the right way seems to be a little bit more challenging! Finally, <em><font color="#9b00d3"><strong>binding parameterized delegates to scalar and non-scalar properties</strong></font></em>, can be regarded <strong><em><font color="#9b00d3">mastering the </font><font color="#9b00d3">fine art of event binding! </font></em></strong></p>
<h2><font style="font-weight: bold" color="#000080">A Deeper Understanding</font></h2>
<p>To gain a better understanding of what’s going on we have to make clear some terms and talk about some differences, first. A lot of VFP-newbies make errors in reasoning, while implementing method code for VFP events like shown below:</p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="7" border="0" alt="7" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7eKFXmt3u_Fv2T2vypPfIOjgbkk5m4UdSuKP_xdNXZ0YA_9aHdizxPdVgEkJfY9Uy1I_IVT1G0tBJz1pIiIalOiNh7Z5Vh-XTs4QOXCw2vr24dDoe-dwyOoN7ylmHAk9zKHqT/?imgmax=800" width="641" height="132" /></p>
<p>Answer the following questions:
<br />“<font style="background-color: #ffffff">What <strong><em>kind</em></strong> of code is the above line after we saved the form class?</font>
<br />Is the call to “THIS.oLstGLOBALMEM.Requery()” the <font color="#0000ff" face="Courier New"><strong>Form1.Activate()</strong></font> event now?
<br />Can we manipulate VFP’s form activation behavior through adding code, maybe like so:</p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="1" border="0" alt="1" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj96tOjetYkm2Oz7cp4A9S382cyEmUXLNoi_RW2a3LNgUo_s8gcSRcx87JygnAcLsWj6qX5CKgMG5ZqF_1r4nouUH2Fa8VQSTxuED_7kCwRJ0IYBTRI1vc8BSwWjzMMz6BU9HNT/?imgmax=800" width="641" height="132" /></p>
<p>Can we hinder VFP to activate the form through code inserted here, anyway? </p>
<p><strong>The answer simply is: “NO!”<u>
<br /></u></strong>
<br />VFP’s <strong><em>form activate event</em></strong> is a simple <strong><font color="#dd8484">NOTIFICATION</font></strong>. The code we are adding in the editor has nothing to do with <strong><em>handling the form activation itself!</em></strong> VFP has already done all that handling completely and transparently behind the scenes before passing back programmatic control to our code block above. <strong>Our code solely is a <font color="#dd8484">NOTIFICATION REACTION</font></strong>. The only reason to add custom code to such kind of VFP event is that we want some code to be executed automatically every time our form gets activated (maybe to signal the form activation to another observer instance within our framework).</p>
<p>There are other kinds of native VFP events. First, let’s look at the <strong><em>INIT() event</em></strong> which is a public feature of every VFP class:</p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2" border="0" alt="2" src="http://lh3.ggpht.com/-0baWvLrNquU/Tl4oat4ekeI/AAAAAAAAHjI/9hsSsBObC9Q/24.png?imgmax=800" width="641" height="157" /></p>
<p>Everybody knows: returning a Boolean FALSE from <strong><em>Init()</em></strong> will cancel the whole instantiation process. In terms of completing object construction, our code can be considered an addition to VFP’s internal event sequence. VFP’s <strong><em>Init() events</em></strong> are <em>notifications</em> as well. But, they are also <strong><font color="#d16349">EXTENDABLE.</font></strong> Seen from that point of view, the event acts like a program hook and our code is some kind of a <font color="#d16349"><strong>POST-EVENT HOOK IMPLEMENTATION</strong></font>.</p>
<p>Finally, there is a third kind of native VFP events. One of them, the <strong><em>KeyPress() event</em></strong>, is shown below:</p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="3" border="0" alt="3" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEga8BZxodXZ9uHMN7xniir2GPknA7sqO9RCWcp1qwo50UA8I1slKqMoBvytJX6M85nw9upDR8od5tI7DJkwBAR0vk6qdNrTlfAjXws6WYqBzohdtJKoXbDhCWNHuKKhqENGLUVE/?imgmax=800" width="641" height="204" /></p>
<p>Code entered here may override VFP’s native implementation completely. Typically, in such a case you are using the <font color="#0000ff" face="Courier New"><strong>NODEFAULT</strong></font> keyword to tell VFP that you are going to override it’s native behavior. You may re-enable (execute) VFP’s native behavior at any time through issuing a <font color="#0000ff" face="Courier New"><strong>DODEFAULT()</strong></font> in your source code. Thus, I call those native VFP events <strong><font color="#c0504d">OVERRIDABLE EVENTS</font></strong> and code added here (as long as it overrides VFP’s native behavior) is the real <font color="#c0504d"><strong>EVENT IMPLEMENTATION</strong></font>.</p>
<h4><font style="font-weight: bold" color="#000080">Let us summarize VFP’s event types:</font></h4>
<p><strong><font color="#dd8484" size="3">NOTIFICATIONS</font></strong> are VFP post-event hooks where we can add our own REACTIONS.</p>
<p><font color="#d16349" size="3"><strong>EXTENSIONS</strong></font> are VFP post-event hooks where we can add our own IMPLEMENTATIONS.</p>
<p><strong><font color="#c0504d" size="3">OVERRIDES</font></strong> are VFP pre-event hooks where we can substitute VFP’s native behavior with our own IMPLEMENTATION.</p>
<h3><font style="font-weight: bold" color="#000080">
<hr />Calling vs. Raising</font></h3>
<p><strong><font style="background-color: #ffc000">An event must be raised!</font></strong> We neither call, nor do we raise any native VFP <strong>event implementation</strong> directly! Instead, what we do is, we call or raise our custom code added to a native VFP event. Internally, VFP treats our custom code like any other ordinary method. If you visit VFP help on <font color="#0000ff" face="Corbel"><strong>BINDEVENT()</strong></font> you can read what is explained in case <strong><em>nFlag := 3</em></strong> >> <font color="#0000ff">Call event code before delegate code. Do not trigger event (call delegate code) when <strong><em><u>simple method calls occur</u></em>.</strong></font> VFP is able to differentiate between a “simple method call” and the “raising of an event”, which is done using the <font color="#0000ff" face="Courier New"><strong>RAISEEVENT()</strong></font> command. Superficially, it doesn’t make any difference at all because our method code gets executed just fine in any case. </p>
<p>Another newbie error in reasoning is to assume, one could trigger VFP’s native behavior through raising the event. No, very sorry, but we CANNOT move the mouse over a VFP form instance by doing something like this: </p>
<pre><strong><font size="2"><span style="color: #0000ff">RAISEEVENT</span>(oForm1 ,"<span style="background-color: #ffff00; color: red">MouseMove</span>", 10, 10)</font></strong></pre>
<p>Nothing would happen – I’m afraid, we have to use VFP’s <font color="#0000ff" face="Courier New"><strong>MOUSE</strong></font> command further on. BTW: Reading VFP’s help file, <font color="#0000ff" face="Courier New"><strong>RAISEEVENT()</strong></font> still is called a <strong><em>function</em></strong> there, although only returning TRUE like any other VFP <strong>procedure</strong>. Maybe some of you remember VFP’s early implementations of <font color="#0000ff" face="Courier New"><strong>RAISEEVENT()</strong></font>better than I do! I believe version #1 of <font color="#0000ff" face="Courier New"><strong>RAISEEVENT()</strong></font>was able to return values from the handler methods (if they had some <font color="#0000ff" face="Courier New"><strong>RETURN <whatever></strong></font> code implemented). That behavior was dropped in a later VFP release, because it caused some unsolvable erroneous side-effects. Nowadays, <font color="#0000ff" face="Courier New"><strong>RAISEEVENT()</strong></font>does not return a value other than any other regular procedure does: TRUE. Thus, IMHO - <font color="#0000ff" face="Courier New"><strong>RAISEEVENT()</strong></font>is not a <em>function</em>, but a <strong><em>command</em></strong>!
<br />VFP’s help on <font color="#0000ff" face="Courier New"><strong>RAISEEVENT()</strong></font>starts with >> <font color="#0000ff">You can use <b><font face="Courier New">RAISEEVENT()</font></b> to raise, or trigger, an event from a custom method. <strong><u>Though <font face="Courier New">RAISEEVENT()</font> applies primarily to custom methods</u></strong>, you can use it for raising native events and methods, too.</font> It is true that in most cases we will use <font color="#0000ff" face="Courier New"><strong>RAISEEVENT()</strong></font> to “ennoble” our custom methods (to become distinguishable events)!</p>
<h2><font style="font-weight: bold" color="#000080">Implementing a Custom Event</font></h2>
<p>Let’s implement our own custom event to see how things work together. These are the steps we need:</p>
<ol>
<li>Define event (create a method with or without parameters).</li>
<li>Optionally, implement event behavior within the event method. </li>
<li>Optionally, you may want to implement security as described further below. </li>
<li>Optionally, describe event signature and binding flag values. </li>
<li>Implement a trigger either using <font color="#0000ff" face="Courier New"><strong>RAISEEVENT()</strong></font> somewhere in your code, or within a distinct trigger method. </li>
</ol>
<p>The easiest step is the first: Define the event method and its signature. If no parameters have to be passed and you want to create a simple <strong><font color="#dd8484">NOTIFICATION</font></strong>, just add an empty method to your class and you’re done! We already talked about the missing return value because raising an event is not comparable to calling a function (which should always return exactly one value), but more to executing a command (which never should return a value). We could argue to compensate a missing return value by passing parameters by reference (to get back some results from there). Obviously, this was “foreseen” by some joker at Microsoft, because this option was dropped completely! If we bind to an event method with one or more parameters in its signature and the event gets raised with one or more values passed in by reference, a trappable error is thrown and our <font color="#0000ff" face="Courier New"><strong>RAISEEVENT()</strong></font>call will fail. The best alternative we have is using <strong><em>Parameter Objects</em></strong>, as objects are always passed by reference. Thus, my favorite <strong>minimal default event implementation</strong> looks like this: </p>
<pre><strong><font size="2"><span style="color: #0000ff">PROCEDURE</span> LogOn(toPara <span style="color: #0000ff">AS</span> OBJECT) <span style="color: #0000ff">AS</span> VOID
<span style="color: #008000">*\\ this event gets raised when the user</span>
<span style="color: #008000">*\\ clicks the [Submit]-button on the </span>
<span style="color: #008000">*\\ login dialog form</span>
<span style="color: #0000ff">ENDPROC</span></font></strong></pre>
<p>The event source code above consists of descriptive remark lines only. The parameter object passed in <strong><em>toPara</em></strong> is a minimalistic  data container object coming from a tiny factory method like shown below:</p>
<pre><strong><font size="2"><span style="color: #0000ff">FUNCTION</span> CreatePara(tcName <span style="color: #0000ff">AS</span> <span style="color: #0000ff">String</span>, tcPassword <span style="color: #0000ff">AS</span> <span style="color: #0000ff">String) <span style="color: #0000ff">AS</span> ParaObject</span>
<span style="color: #0000ff"> LOCAL</span> loEvtMsgInfo <span style="color: #0000ff">AS</span> Object
m.loEvtMsgInfo = <span style="color: #0000ff">CREATEOBJECT</span>("<span style="background-color: #ffff00; color: red">EMPTY</span>")
<span style="color: #0000ff"> ADDPROPERTY</span>(m.loEvtMsgInfo, "<span style="background-color: #ffff00; color: red">Name</span>", m.tcName)
<span style="color: #0000ff"> ADDPROPERTY</span>(m.loEvtMsgInfo, "<span style="background-color: #ffff00; color: red">Password</span>", m.tcPassword)
<span style="color: #0000ff">RETURN</span> m.loEvtMsgInfo<br /><span style="color: #0000ff">ENDFUNC</span></font></strong></pre>
<p>Because there is no event behavior to implement, I am ready to implement my trigger code (which is step #5 in the above enumeration). The submit-button’s <font color="#0000ff" face="Courier New"><strong>click()</strong></font> event is the perfect place to implement my trigger code:</p>
<pre><strong><font size="2"><span style="color: #0000ff">PROCEDURE</span> oSubmitButton.<span style="color: #0000ff">Click</span>() <span style="color: #0000ff">AS</span> VOID
<span style="color: #008000">*\\</span>
<span style="color: #0000ff">RAISEEVENT</span>(<font color="#0000ff">THIS</font>.oHandler<span style="color: #0000ff"> </span>,;
"<span style="background-color: #ffff00; color: red">LogOn</span>" ,;
<span style="color: #0000ff"><font color="#000000">goFactory</font></span>.CreatePara(<span style="color: #0000ff">Thisform</span>.TxtName.<span style="color: #0000ff">Value</span>,;
<span style="color: #0000ff">Thisform</span>.txtPassWord.<span style="color: #0000ff">Value</span>))
<span style="color: #008000">*//</span>
<span style="color: #0000ff">ENDPROC</span></font></strong></pre>
<hr />
<h2><font color="#000080"><font style="font-weight: bold">Consuming a Custom Event</font></font></h2>
<p>Every <strong><em>event handler</em></strong> who wants to consume our new event must bind to it using VFP’s <font color="#000080" face="Courier New"><strong>BINDEVENT()</strong></font> function. Terms used, when talking about event binding, come in pairings like <strong><em>event source</em></strong> and <strong><em>event handler</em></strong>, or <strong><em>raise event</em></strong> and <strong><em>bind event.</em></strong> Finally there is a <strong><em>flag value</em></strong> used in VFP’s <font color="#000080" face="Courier New"><strong>BINDEVENT()</strong></font> function to fine-tune internal signaling. To successfully establish a native VFP event binding we need two object references, as it is not possible to use an old-fashioned procedure as the event handler! (BTW: There is a <a title="http://vfpx.codeplex.com/" href="http://vfpx.codeplex.com/" rel="nofollow" target="_blank">VFPX</a> project called “<a title="http://vfpx.codeplex.com/wikipage?title=VFP2C32&referringTitle=Home" href="http://vfpx.codeplex.com/wikipage?title=VFP2C32&referringTitle=Home" target="_blank">VFP2C32</a>”, maintained by Christian Ehlscheid, that gives you the ability to use procedural delegates – but only for <strong><em>Win-Event binding</em></strong>.) In any case, one object is called the <em>source of the event</em>, the other the <em>handler of the event</em>. There are other naming pairs like <strong><em>publisher</em></strong> and <strong><em>subscriber</em></strong> often used in COM documentations, or <strong><em>signal</em></strong> and <strong><em>slot</em></strong> used by Nokias Qt (C++ IDE). Anyway, the <strong><em>event source</em></strong> has a public <strong><em>event</em></strong> (-method or -property) we must know by name and what <strong>signature</strong> is used when the event is raised by the trigger, so that we can bind our <strong><em>event handler</em></strong> object to it. Our <strong><em>event handler</em></strong> object must have a corresponding <strong><em>delegate method</em></strong> (no properties - only methods - are allowed as delegates) with the method signature that has at least enough parameters to receive all values passed in by the <font color="#0000ff" face="Courier New"><strong>RAISEEVENT()</strong></font> trigger.</p>
<h3><font color="#000080"><font style="font-weight: bold">Sidekick: Property-based Event Binding Part I</font></font></h3>
<p><strong><font color="#0000ff">Keep in mind:</font></strong> When binding to a <strong>PROPERTY</strong>-based event, our handler <em>should be</em> a parameter-less delegate method. At this moment, it doesn’t make much sense to use a delegate with one or more parameters, because a simple value assignment to an event-bound property CANNOT lead to a <strong><em>signature mismatch</em></strong>. There are two other things to keep in mind about <strong><em>property binding</em></strong>: </p>
<ol>
<li>Property binding can be compared to implementing a <font color="#0000ff" face="Courier New"><strong>PropertyName_Assign()</strong></font> method. The delegate gets called every time some value is stored in the so decorated property, just like any _ASSIGN() method is triggered. Read access NEVER leads to delegate invocation. </li>
<li>Executing a <font color="#0000ff" face="Courier New"><strong>RAISEEVENT()</strong></font>on a property causes nothing else but a re-assignment of the current property value. In other words, the actual property value stays unchanged. Therefore, <strong><font face="Courier New">oForm1.<font color="#0000ff">HEIGHT</font> = oForm1.<font color="#0000ff">HEIGHT</font></font></strong> can be considered to be internally treaded like a “simple method call”, whereas <font face="Courier New"><strong><font color="#0000ff">RAISEVENT</font>(oForm1, “<font style="background-color: #ffff00" color="#ff0000">HEIGHT</font>”)</strong></font> internally is recognized as the “event of property value re-assignment”. </li>
</ol>
<p>Most of this is theory only, taken from VFP’s help files! You will get more comprehensive insights later in this post (in <em>property-based event binding part II</em> below).</p>
<h2><font color="#000080"><font style="font-weight: bold">
<hr />Generic Events and Handlers</font></font></h2>
<p><font style="background-color: #ffff00">Even carefully reading of VFP’s help may lead to some misunderstanding!</font> This is what is written about the delegate parameter of <font color="#0000ff" face="Courier New"><strong>BINDEVENT()</strong></font>:
<br /><font color="#0000ff"><strong><em>cDelegate:</em></strong>
<br />Specifies the method, or "delegate", that handles the event for oEventHandler. <strong><u>The delegate method must have the same parameters as the event specified in cEvent.</u></strong> You can call the <b>AEVENTS( ) </b>function to retrieve an object reference to the event source. If the delegate method does not have enough parameters to handle those passed by the event, Visual FoxPro generates an error.</font></p>
<p>The underlined sentence above may make you believe, that both, the event’s and the delegate’s signatures must be identical. <font style="background-color: #ffff00" color="#ff0000"><strong>This is not true!</strong></font> Only the last sentence fully tells the truth: the handler’s delegate signature must be capable to receive all parameters that were passed in during event invocation. This is nothing really new. We all have seen parameterization errors stemming from method calls in cases a caller tried to pass more parameters than there were implemented. On the other hand, calling any method passing less parameters than the implementation has, does work like a charm, at least the invocation. The same is true while raising an event. Under the hood, VFP does not draw a distinction between event methods and other methods when it comes to parameter passing. Thus, it is absolutely legal to create a set of generic event handler methods that can be bound to any (generic) event method! <strong><font color="#0000ff">Keep in mind:</font></strong> VFP’s maximum number of parameters that can be interchanged during all kind of calls is #26, which is more than enough, IMHO. This capacity also is the upper limit of VFP’s <font color="#0000ff" face="Courier New"><strong>RAISEEVENT()</strong></font>command. If you really need more, switch to a parameter object! </p>
<h3><font color="#000080">A “Generic” Event</font></h3>
<p><strong>An event cannot be generic in the truest sense of the word!</strong> Only the <em><strong>event method signature</strong></em> can be generic, in that the method accepts all possible 26 input parameters!</p>
<p>Let’s create a form and add an event method with such generic signature. Next, we will add some event behavior (just for initial testing). The final result looks like so:</p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="4" border="0" alt="4" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjP-Lxhrx1mHqAUbS4RVRAlbi5WMniwc0SlCVR1jDkGmTQd3StJkjJh2AU2kEMHu9nEUEQR1Q9t8Wf1BdyuWlkhe9nELyIB-aRnXIdOWei6pzGuNxqBk3kr4y6AqFYpt0rdWfo6/?imgmax=800" width="589" height="465" /></p>
<p>Lets DO the form and invoke the <font color="#0000ff" face="Courier New"><strong>EvtSendOut()</strong></font> method using a regular method call from VFP’s command window:</p>
<pre><strong>m.testform2.EvtSendOut("<span style="background-color: #ffff00; color: red">What</span>","<span style="background-color: #ffff00; color: red">a</span>","<span style="background-color: #ffff00; color: red">difference</span>","<span style="background-color: #ffff00; color: red">a</span>","<span style="background-color: #ffff00; color: red">day</span>","<span style="background-color: #ffff00; color: red">makes!</span>")</strong></pre>
<p>The result, as expected, is shown below:</p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="5" border="0" alt="5" src="http://lh6.ggpht.com/-Q9AT0gVxLHE/Tl4obvbllkI/AAAAAAAAHjU/1ZnkdgeaLwE/54.png?imgmax=800" width="391" height="124" /></p>
<p>Now, raise the <font color="#0000ff" face="Courier New"><strong>EvtSendOut()</strong></font> method as a custom event typing the following line of code into VFP’s command window:</p>
<pre><strong><span style="color: #0000ff">RAISEEVENT</span>(m.testform2, "<span style="background-color: #ffff00; color: red">Evtsendout</span>", "<span style="background-color: #ffff00; color: red">What</span>","<span style="background-color: #ffff00; color: red">a</span>","<span style="background-color: #ffff00; color: red">difference</span>","<span style="background-color: #ffff00; color: red">a</span>","<span style="background-color: #ffff00; color: red">day</span>","<span style="background-color: #ffff00; color: red">makes!</span>")</strong></pre>
<p>Again, the result is the same, as shown below:</p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="6" border="0" alt="6" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhhoBRrhS0k7VrJoRCcbts-cUIfiJAPT06107ffaCWGZaPqZCxq1FUkgjsl16WLLCiTjfCnL90vW7x2vKelmDjLv6A_gsraMSiy3ZXRUOakjwU-m74zjrEQzMFjGFobwhmVZlG/?imgmax=800" width="391" height="124" /></p>
<p>You may play with different parameterizations of the <font color="#0000ff" face="Courier New"><strong>RAISEEVENT()</strong></font> command. <strong><font color="#008080">As long as you do not try to pass more than 26 parameters, all invocations will be executed successfully.</font></strong></p>
<p>Let’s prove that we cannot raise a custom event passing in a parameter by reference. With the test form still running type the following code lines into VFP’s command window and execute them one by one:</p>
<pre>x = "<span style="background-color: #ffff00; color: red">Hallo</span>"
m.testform2.Evtsendout(x)
m.testform2.Evtsendout(@x)
<span style="color: #0000ff">RAISEEVENT</span>(m.testform2, "<span style="background-color: #ffff00; color: red">Evtsendout</span>",x)
<span style="color: #0000ff">RAISEEVENT</span>(m.testform2, "<span style="background-color: #ffff00; color: red">Evtsendout</span>",@x)</pre>
<p>Only the last command will throw an exception, like shown below:</p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="9" border="0" alt="9" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2b3F571Agji3_uAvl_0a7lKS0_3CyZuyid6R5pDv75626A0S3ljsUcVhsofP7fyfCrvO8GViyA1AlH5jTvsgoW2gUASgVqxLH1cCQvu3ZwyTnkU1vXtQWZJDtCkQpAwDs49ek/?imgmax=800" width="558" height="216" /></p>
<p>It is the “Missing operand” error #1231. Well, “Missing operand” sounds strange indeed, but there is an error – as I promised :-)</p>
<h3><font style="font-weight: bold" color="#000080">A “Generic” Delegate</font></h3>
<p>What’s true for the event is true for the delegate, too: <strong>A delegate cannot be generic in the truest sense of the word!</strong> Only the <em><strong>delegate method signature</strong></em> can be generic, in that the method accepts all possible 26 input parameters! Let’s complete this first test-drive. Initially, we filled our <strong><em>event</em></strong> (method) with code that would be better placed in a <strong><em>delegate</em></strong> (method). Let’s add such a <strong><em>delegate</em></strong> to our form and copy the whole implementation to the new <strong><em>delegate</em></strong>. Keep only the <font color="#0000ff" face="Courier New"><strong>LPARAMETERS</strong></font> statement in the <strong><em>event</em></strong>. The intermediate result should look like this:</p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="10" border="0" alt="10" src="http://lh5.ggpht.com/-vEiWo_EQIDM/Tl4ocx8LeeI/AAAAAAAAHjg/MsCCRpVVxqo/104.png?imgmax=800" width="585" height="642" /></p>
<p>Again, we will use VFP’s command window for manually binding and triggering. Save the form and create two named instances like so:</p>
<pre><strong><span style="color: #0000ff">DO</span> <span style="color: #0000ff">Form</span> c:\<your <span style="color: #0000ff">path</span>>\testform2.scx <span style="color: #0000ff">NAME</span> Sender
<span style="color: #0000ff">DO</span> <span style="color: #0000ff">Form</span> c:\<your <span style="color: #0000ff">path</span>>\testform2.scx <span style="color: #0000ff">NAME</span> Receiver
m.Sender.<span style="color: #0000ff">Caption</span> = "<span style="background-color: #ffff00; color: red">Sender</span>"
m.receiver.<span style="color: #0000ff">Caption</span> = "<span style="background-color: #ffff00; color: red">Receiver</span>"</strong></pre>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="11" border="0" alt="11" src="http://lh3.ggpht.com/-mhFUl_5TATQ/Tl4odcd_-XI/AAAAAAAAHjk/L6v6KPouQP0/115.png?imgmax=800" width="563" height="73" /></p>
<p>Now it is time to link the receiver to the sender using an appropriate <strong><font color="#0000ff" face="Courier New">BINDEVENT()</font></strong> command. Our first binding does not use a special <strong><em>nFlags</em></strong> value. VFP defaults to <strong><em>nFlags = 0</em></strong> in that case.</p>
<pre><strong>? <span style="color: #0000ff">BINDEVENT</span>(m.sender, "<span style="background-color: #ffff00; color: red">EvtSendOut</span>", m.Receiver, "<span style="background-color: #ffff00; color: red">OnSendOut</span>")</strong></pre>
<p>Now, trigger the event on the sender form like so:</p>
<pre><strong><span style="color: #0000ff">RAISEEVENT</span>(m.sender, "<span style="background-color: #ffff00; color: red">Evtsendout</span>", "<span style="background-color: #ffff00; color: red">What</span>","<span style="background-color: #ffff00; color: red">a</span>","<span style="background-color: #ffff00; color: red">difference</span>","<span style="background-color: #ffff00; color: red">a</span>","<span style="background-color: #ffff00; color: red">day</span>","<span style="background-color: #ffff00; color: red">makes!</span>")</strong></pre>
<p>The delegate code of the receiver form executes and echoes the text out <em><strong>on the currently activated form:</strong></em> </p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="12" border="0" alt="12" src="http://lh5.ggpht.com/-9Xk_Vnj4rQU/Tl4odqAsOUI/AAAAAAAAHjo/PfpY-JrgSA4/126.png?imgmax=800" width="560" height="74" /></p>
<p>Changing the parameter count (within the valid boundaries) executes just fine! Try the following, if you like:</p>
<pre><strong><span style="color: #0000ff">RAISEEVENT</span>(m.sender, "<span style="background-color: #ffff00; color: red">Evtsendout</span>", "<span style="background-color: #ffff00; color: red">What</span>","<span style="background-color: #ffff00; color: red">a</span>","<span style="background-color: #ffff00; color: red">difference</span>","<span style="background-color: #ffff00; color: red">a</span>","<span style="background-color: #ffff00; color: red">day</span>","<span style="background-color: #ffff00; color: red">makes!</span>", "<span style="background-color: #ffff00; color: red">Come</span>", "<span style="background-color: #ffff00; color: red">on</span>", "<span style="background-color: #ffff00; color: red">Baby!</span>")</strong></pre>
<p>Keep both forms open and read ahead – we will reuse them in the next chapter.</p>
<h3><font color="#0000ff"><font style="font-weight: bold">Benefits of Using Generic Signatures</font></font></h3>
<p>Using generic signatures with your <strong><em>events</em></strong> and <strong><em>delegates</em></strong> frees you from keeping track of parameter count changes, which otherwise must be kept in sync over three different places (event, delegate and trigger) if you raise the parameter count used by the trigger. This does not mean that you must not keep your implementations in sync with the parameters coming in :-) <strong><font style="background-color: #ffff00" color="#ff0000">Keep in mind</font></strong>: Always placing 26 LPARAMETERS in your event-related methods <strong><em>slows down program execution slightly</em></strong>, because VFP has to create 26 local variables each time the methods must be invoked. I’m using my own special breed of generic method signatures within my frameworks and never encountered any performance hits, because I reduced the parameter count of my framework class methods down to three. The first parameter is the name of the method/service, the second is a parameter object which may take as many parameter properties as needed, the last parameter is the object reference of the sender.</p>
<h2><font color="#0000ff"><font style="font-weight: bold">
<hr />Implementing a Custom Event-Handler</font></font></h2>
<p>We have seen that <strong><em>calling</em></strong> a method <u>must not</u> differ from <strong><em>raising</em></strong> it, <em><strong>seen from the view-point of someone who triggers the execution</strong></em> in one way or the other. A noticeable difference may only appear for the <em>event handler side</em> of the binding. Using <strong><em>nFlags</em></strong> values of 2 and 3 in the <strong><font color="#0000ff" face="Courier New">BINDEVENT()</font></strong> command only invoke the event handler’s delegate when the event was triggered using <font color="#0000ff" face="Courier New"><strong>RAISEEVENT()</strong></font>. Using <strong><em>nFlags</em></strong> values of 0 and 1 in the <strong><font color="#0000ff" face="Courier New">BINDEVENT()</font></strong> command <strong><em>additionally</em></strong> also invoke the event handler’s delegate when the event was triggered using a regular method call. Check it out! You can do that with only two lines of code if the above 2-forms test environment is still set and running:</p>
<pre><strong><span style="color: #0000ff">UNBINDEVENTS</span>(m.sender)
<span style="color: #0000ff">BINDEVENT</span>(m.sender, "<span style="background-color: #ffff00; color: red">EvtSendOut</span>", m.Receiver, "<span style="background-color: #ffff00; color: red">OnSendOut</span>", 2)</strong></pre>
<p>With the nFlags value set to 2, try to invocate the event handler’s delegate through triggering the event using a simple method call like so:</p>
<pre>m.sender.EvtSendOut("<span style="background-color: #ffff00; color: red">EvtSendOut</span>", "<span style="background-color: #ffff00; color: red">What</span>","<span style="background-color: #ffff00; color: red">a</span>","<span style="background-color: #ffff00; color: red">difference</span>","<span style="background-color: #ffff00; color: red">a</span>","<span style="background-color: #ffff00; color: red">day</span>","<span style="background-color: #ffff00; color: red">makes!</span>", "<span style="background-color: #ffff00; color: red">Come</span>", "<span style="background-color: #ffff00; color: red">on</span>", "<span style="background-color: #ffff00; color: red">Baby!</span>")</pre>
<p>Nothing happens – as I told you! <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smiley" src="http://lh5.ggpht.com/-iIjlbKZnsl8/Tl4oeNj2JzI/AAAAAAAAHjs/ZKtWYKITFlA/wlEmoticon-smile2.png?imgmax=800" /> </p>
<p><font style="background-color: #ffc000" size="2"></font><font style="background-color: #ffff00">After all, <strong><u>IMHO</u></strong>, only <strong><font color="#0000ff" face="Courier New">BINDEVENT()</font></strong> commands in code using <strong><em>nFlags</em></strong> values of 2 or 3 should be legitimate for today’s event binding implementations,</font> which must not mean that there are no good reasons for using  <strong><em>nFlags</em></strong> values of 0 and 1. If one has to bind to legacy methods that were realized a long time ago (when event binding still was a foreign word for VFP developers), one is forced to use <strong><em>nFlags</em></strong> values of 0 or 1 while binding to methods that never will be raised but always gets called (the old-fashioned way). In addition to that, there are some native VFP “events” (like <b><font color="#0000ff" face="Courier New">GotFocus()</font></b>, <b><font color="#0000ff" face="Courier New">LostFocus()</font></b>, <b><font color="#0000ff" face="Courier New">InteractiveChange()</font></b>, and <font color="#0000ff" face="Courier New"><strong>ProgrammaticChange()</strong></font>) that are treated as method calls internally by VFP, so that we are forced to use a <strong><em>nFlags</em></strong> value of either 0 or 1. My suggestion always is: NEVER bind to VFP’s native properties and methods/events directly, but implement your own custom event system/scheme. I will show you my own (more sophisticated:-) implementation in a future posting…</p>
<p>The table below shows all four possible values (bit flag values) counting the bits starting with #0. The “trigger all” row represents both bit#0 states, the “trigger only raised” row shows the two bit#1 states. Both bits are OR-combined. The four resulting values are printed in bold within the matrix. Just to make this part of my writing complete: <strong>Bit #3</strong> of the <strong><em>nFlags</em></strong> parameter is used to <strong>prevent recursion</strong> in case of <strong><em>Window Message Binding</em></strong> (which isn’t discussed in this posting).</p>
<table border="1" cellspacing="0" cellpadding="2" width="484"><tbody>
<tr>
<td valign="top" width="212">
<p><font size="4"><strong>nFlags values</strong></font></p>
</td>
<td valign="top" width="134">
<p>invoke delegate
<br /><strong><em>before</em></strong> event</p>
</td>
<td valign="top" width="136">
<p>invoke delegate
<br /><strong><em>after</em></strong> event</p>
</td>
</tr>
<tr>
<td valign="top" width="212">
<p>Bit #0 >> trigger all</p>
</td>
<td valign="top" width="134">
<p><strong><font size="2">0</font></strong></p>
</td>
<td valign="top" width="136">
<p><strong><font size="2">1</font></strong></p>
</td>
</tr>
<tr>
<td valign="top" width="212">
<p>bit #1 >> trigger only raised</p>
</td>
<td valign="top" width="134">
<p><strong><font size="2">2</font></strong></p>
</td>
<td valign="top" width="136">
<p><strong><font size="2">3</font></strong></p>
</td>
</tr>
</tbody></table>
<p>Seen from my personal point of view (as a framework developer), there are many different objects at runtime lurking around to bind to my events. I divide these event handler objects into two groups: one group want to process parameters  <strong>BEFORE</strong> my own implementation processes them, the other (lazy:-) group can wait until my event code is finished, receiving the parameters <strong>AFTER</strong> my implementation returns. </p>
<h3><font style="font-weight: bold" color="#000080"><font color="#000080"><font style="font-weight: bold">
<hr />Sidekick: Property-based Event Binding Part II</font></font></font></h3>
<p>Binding to properties makes it even easier to understand what’s going on under the hood: Those delegates that were bound to a scalar property with <strong><em>nFlags</em></strong> values of 0 or 2 can only show the old property value (before the assignment takes place), delegates that were bound to the property with <strong><em>nFlags</em></strong> values of 1 or 3 will always show the new property value (the “after-assignment-value”). The following listings show us two generic <strong><em>property-delegates</em></strong>. You may add them to our form before test-drive them. Bind both delegates to a property like shown below. <strong>BTW</strong>, the method signature of a regular <em>property-delegate</em> always is empty because we do not <strong><em><u>need</u></em></strong> any parameters, as long as we are solely assigning new values. I underlined the word “need” bold italic because it is important to stress this for a good reason: </p>
<p align="center"><font style="background-color: #ffff00" size="4">we do not need any parameters, <strong><font style="style">but it is not forbidden to implement some</font></strong>, as I will show you later in this chapter!</font></p>
<p>This is the test code we will run next:</p>
<pre><strong><span style="color: #0000ff">ADDPROPERTY</span>(<span style="color: #0000ff">_SCREEN</span>, "<span style="background-color: #ffff00; color: red">nTest</span>")
<span style="color: #0000ff">DO</span> <span style="color: #0000ff">Form</span> c:\<your <span style="color: #0000ff">path</span>>\testform2.scx
<span style="color: #0000ff">BINDEVENT</span>(<span style="color: #0000ff">_Screen</span>, "<span style="background-color: #ffff00; color: red">nTest</span>", m.testform2, "<span style="background-color: #ffff00; color: red">OnPropertyBefore</span>")
<span style="color: #0000ff">BINDEVENT</span>(<span style="color: #0000ff">_Screen</span>, "<span style="background-color: #ffff00; color: red">nTest</span>", m.testform2, "<span style="background-color: #ffff00; color: red">OnPropertyAfter</span>", 1)
<span style="color: #0000ff">_Screen</span>.nTest = 1
<span style="color: #0000ff">RAISEEVENT</span>(<span style="color: #0000ff">_SCREEN</span>, "<span style="background-color: #ffff00; color: red">nTest</span>")</strong></pre>
<pre><font face="Calibri">You may also want to implement some ”<strong><font color="#0000ff">laBindings[3]</font></strong>“– test code like the following two listings show:</font></pre>
<pre><strong><span style="color: #0000ff">PROCEDURE</span> OnPropertyAfter() <span style="color: #0000ff">AS</span> VOID
<span style="color: #008000">*\\ a generic property-event delegate </span>
<span style="color: #0000ff">LOCAL</span> <span style="color: #0000ff">ARRAY</span> laBindings[<span style="background-color: #ffff00; color: red">3</span>] AS Variant
<span style="color: #0000ff">LOCAL</span> lnCount <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>
<span style="color: #008000">*\\ AEVENTS( ) returns a three-element array containing </span>
<span style="color: #008000">*\\ an object reference to the current event source, </span>
<span style="color: #008000">*\\ the name of the triggered event, </span>
<span style="color: #008000">*\\ and how the event was triggered. 1 - RAISEEVENT() </span>
<span style="color: #008000">*\\ 2 - Method call </span>
lnCount = <span style="color: #0000ff">AEVENTS</span>(laBindings, 0)
<span style="color: #0000ff">IF</span> m.lnCount > 0
<span style="color: #0000ff">LOCAL</span> eValue <span style="color: #0000ff">AS</span> Variant
<span style="color: #0000ff">WITH</span> laBindings[<span style="background-color: #ffff00; color: red">1</span>]
eValue = <span style="color: #0000ff">EVALUATE</span>("<span style="background-color: #ffff00; color: red">.</span>" + laBindings[<span style="background-color: #ffff00; color: red">2</span>])
<span style="color: #0000ff">ENDWITH</span>
? "<span style="background-color: #ffff00; color: red">New value is </span>" + <span style="color: #0000ff">TRANSFORM</span>(m.eValue)
<span style="color: #0000ff">ENDIF</span>
<span style="color: #0000ff">ENDPROC</span>
</strong></pre>
<pre><strong><span style="color: #0000ff">PROCEDURE</span> OnPropertyBefore() <span style="color: #0000ff">AS</span> VOID
<span style="color: #008000">*\\ a generic property-event delegate</span>
<span style="color: #0000ff">LOCAL</span> <span style="color: #0000ff">ARRAY</span> laBindings[<span style="background-color: #ffff00; color: red">3</span>] AS Variant
<span style="color: #0000ff">LOCAL</span> lnCount <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>
<span style="color: #008000">*\\ AEVENTS( ) returns a three-element array containing </span>
<span style="color: #008000">*\\ an object reference to the current event source, </span>
<span style="color: #008000">*\\ the name of the triggered event, </span>
<span style="color: #008000">*\\ and how the event was triggered. 1 - RAISEEVENT() </span>
<span style="color: #008000">*\\ 2 - Method call</span>
lnCount = <span style="color: #0000ff">AEVENTS</span>(laBindings, 0)
<span style="color: #0000ff">IF</span> m.lnCount > 0
<span style="color: #0000ff">LOCAL</span> eValue <span style="color: #0000ff">AS</span> Variant
<span style="color: #0000ff">WITH</span> laBindings[<span style="background-color: #ffff00; color: red">1</span>]
eValue = <span style="color: #0000ff">EVALUATE</span>("<span style="background-color: #ffff00; color: red">.</span>" + laBindings[<span style="background-color: #ffff00; color: red">2</span>])
<span style="color: #0000ff">ENDWITH</span>
? "<span style="background-color: #ffff00; color: red">Value assignment for </span>" + laBindings[<span style="background-color: #ffff00; color: red">2</span>] + "<span style="background-color: #ffff00; color: red"> triggered!</span>"
? "<span style="background-color: #ffff00; color: red">Old value is </span>" + <span style="color: #0000ff">TRANSFORM</span>(m.eValue)
<span style="color: #0000ff">ENDIF</span>
<span style="color: #0000ff">ENDPROC</span></strong></pre>
<p>VFP returns a “trigger type”-value (0-System, 1-RaiseEvent, 2-MethodCall) in the third array element of the local array “laBindings”. Okay, you may think, all this is pretty straight forward and matches VFP’s help documentation one by one. <font style="background-color: #ffff00" color="#ff0000"><strong>But, this is not true!</strong></font> There are some important points:  <strong><font style="background-color: #ffff00">1st</font></strong>, VFP’s event binding related help is not correct in some places and <strong><font style="background-color: #ffc000">2nd</font></strong>, some helpful things are not mentioned at all.</p>
<p><font style="background-color: #ffff00"><strong>1a.)</strong></font> You can read about the <strong><font color="#0000ff" size="1" face="Courier New">AEVENTS(arrayname,0)</font></strong> version in VFP’s help file: “<em><strong><font color="#ff0000"><font color="#000000">The third array element indicates how an event was triggered. </font>If the event is a <u>property</u>, this value can be 1 or 2. The value is 2 if the property is set or assigned.</font></strong></em>” <font style="background-color: #ffff00" color="#ff0000"><strong>Simply, this is not true!</strong></font> In our above example <font color="#0000ff" face="Courier New"><strong>laBindings[3]</strong></font> never will hold the value 2 (two). During my testing sometimes I got a <em>zero</em> or the value <em>one</em> but never a <em>two</em>! Thus, the correct statement must be: “<em><strong><font color="#ff0000"><font color="#000000">The third array element indicates how an event was triggered.</font></font><font color="#008040"> If the event is a <u>property</u>, this value can be 0 or 1. The value is 1 (= RAISEEVENT())  if the delegate was triggered using the RAISEEVENT() function! In all other cases the third array element is 0 (= System).</font></strong></em>”</p>
<p><font style="background-color: #ffff00"><strong>1b.)</strong></font> Assigning a value to any <strong><em>scalar</em></strong> property with bound delegates <strong><em><u>always fires all delegates</u></em></strong>! In other words: You may bind to a property with a nFlags-value of 2 or 3 which would suppress delegate execution in case of a simple method call when applied to a VFP method. Later, when assigning a value to the property, you might expect that the delegates will not be called. Sorry, but that doesn’t work <u>for scalar values</u>! This leads to the next oddity:</p>
<p><font style="background-color: #ffff00"><strong>1c.)</strong></font> Assigning a value to any <strong><em>non-scalar</em></strong> property (to an array property) just works as expected – well, almost! Instead: <strong>An array value assignments do not trigger bound delegates at all</strong>! At least: doing a <font color="#0000ff" face="Courier New"><strong>RAISEEVENT()</strong></font> on an array-property fires <strong><em><u>ALL</u></em></strong> bound delegates just like described in 1b.) above!</p>
<p>Let’s create some examples to make things a little bit clearer: </p>
<p>Given one source- and one target object named “oSource” as the event source object and “oHandler” as the event handler object, let us define two properties on the source object: “oSource.cProp” and “oSource.aProp[1]”, so that we have one scalar and one non-scalar property at our disposal.  Now, let’s add two _Assign() methods for both properties: “oSource.cProp_Assign()” and “oSource.aProp_Assign()”. Finally, let us add four delegate methods called “delegate0()” to “delegate3()” to our handler object.</p>
<p>Now, we can run code like this from VFP’s command window:</p>
<pre><strong>oSource = <span style="color: #0000ff">NEWOBJECT</span>("<span style="background-color: #ffff00; color: red">cSource</span>", "<span style="background-color: #ffff00; color: red">testlib.vcx</span>")
oTarget = <span style="color: #0000ff">NEWOBJECT</span>("<span style="background-color: #ffff00; color: red">cTarget</span>" , "<span style="background-color: #ffff00; color: red">testlib.vcx</span>")
<span style="color: #008000">*\\ bind to the scalar property</span>
<span style="color: #0000ff">BINDEVENT</span>(oSource, "<span style="background-color: #ffff00; color: red">cProp</span>", oTarget, "<span style="background-color: #ffff00; color: red">Delegate0</span>", 0)
<span style="color: #0000ff">BINDEVENT</span>(oSource, "<span style="background-color: #ffff00; color: red">cProp</span>", oTarget, "<span style="background-color: #ffff00; color: red">Delegate1</span>", 1)
<span style="color: #0000ff">BINDEVENT</span>(oSource, "<span style="background-color: #ffff00; color: red">cProp</span>", oTarget, "<span style="background-color: #ffff00; color: red">Delegate2</span>", 2)
<span style="color: #0000ff">BINDEVENT</span>(oSource, "<span style="background-color: #ffff00; color: red">cProp</span>", oTarget, "<span style="background-color: #ffff00; color: red">Delegate3</span>", 3)
<span style="color: #008000">*\\ now bind to the non-scalar property</span>
<span style="color: #0000ff">BINDEVENT</span>(oSource, "<span style="background-color: #ffff00; color: red">aProp</span>", oTarget, "<span style="background-color: #ffff00; color: red">Delegate0</span>", 0)
<span style="color: #0000ff">BINDEVENT</span>(oSource, "<span style="background-color: #ffff00; color: red">aProp</span>", oTarget, "<span style="background-color: #ffff00; color: red">Delegate1</span>", 1)
<span style="color: #0000ff">BINDEVENT</span>(oSource, "<span style="background-color: #ffff00; color: red">aProp</span>", oTarget, "<span style="background-color: #ffff00; color: red">Delegate2</span>", 2)
<span style="color: #0000ff">BINDEVENT</span>(oSource, "<span style="background-color: #ffff00; color: red">aProp</span>", oTarget, "<span style="background-color: #ffff00; color: red">Delegate3</span>", 3)</strong></pre>
<p>The first version of our delegate code is almost identical in all event handler methods . Is echoes out the three <font color="#0000ff" face="Courier New"><strong>AEVENTS(array,0)</strong></font> array values.</p>
<pre><strong><span style="color: #0000ff">LOCAL</span> <span style="color: #0000ff">ARRAY</span> laEvt[<span style="background-color: #ffff00; color: red">3</span>]
IF <span style="color: #0000ff">AEVENTS</span>(laEvt,0) > 0
? "<span style="background-color: #ffff00; color: red">Handler 0 ---------------------</span>"
? "<span style="background-color: #ffff00; color: red">laEvt[1] = </span>" + <span style="color: #0000ff">TRANSFORM</span>(laEvt[<span style="background-color: #ffff00; color: red">1</span>])
? "<span style="background-color: #ffff00; color: red">laEvt[2] = </span>" + <span style="color: #0000ff">TRANSFORM</span>(laEvt[<span style="background-color: #ffff00; color: red">2</span>])
? "<span style="background-color: #ffff00; color: red">laEvt[3] = </span>" + <span style="color: #0000ff">TRANSFORM</span>(laEvt[<span style="background-color: #ffff00; color: red">3</span>])
<span style="color: #0000ff">ENDIF</span></strong></pre>
<p>You only have to vary the handler number. Replace “Handler 0 ----“ with “Handler 1 ----“, “Handler 2 ----“, and “Handler 3 ----“ in the four different delegates.  <br />Now, add some echo statements to the <font face="Courier New"><strong>cProp_Assign()</strong></font> hook like: </p>
<p><strong><span style="color: #0000ff">LPARAMETERS</span> vNewVal
<br />? "<span style="background-color: #ffff00; color: red">cProp_Assign() before assignment - value is '</span>" + <span style="color: #0000ff">TRANSFORM</span>(<span style="color: #0000ff">THIS</span>.cprop) + "<span style="background-color: #ffff00; color: red">'</span>"
<br /><span style="color: #0000ff">THIS</span>.cprop = m.vNewVal
<br />? "<span style="background-color: #ffff00; color: red">cProp_Assign() after assignment - value is '</span>" + <span style="color: #0000ff">TRANSFORM</span>(m.vNewVal) + "<span style="background-color: #ffff00; color: red">'</span>"</strong></p>
<p>and for the <font face="Courier New"><strong>aProp_Assign()</strong></font> hook and like:</p>
<pre><strong><span style="color: #0000ff">LPARAMETERS</span> vNewVal, m.nIndex1
? "<span style="background-color: #ffff00; color: red">aProp_Assign() before assignment</span>"
<span style="color: #0000ff">IF</span> <span style="color: #0000ff">ISNULL</span>(m.nIndex1) <span style="color: #008000">&& user didn't pass in a subscript</span>
?? "<span style="background-color: #ffff00; color: red"> - value is '</span>" + <span style="color: #0000ff">TRANSFORM</span>(<span style="color: #0000ff">THIS</span>.aprop) + "<span style="background-color: #ffff00; color: red">'</span>"
<span style="color: #0000ff">THIS</span>.aprop = m.vNewVal
<span style="color: #0000ff">ELSE</span>
?? "<span style="background-color: #ffff00; color: red"> - value is '</span>" + <span style="color: #0000ff">TRANSFORM</span>(<span style="color: #0000ff">THIS</span>.aprop[<span style="background-color: #ffff00; color: red">m.nIndex1</span>]) + "<span style="background-color: #ffff00; color: red">'</span>"
<span style="color: #0000ff">THIS</span>.aprop[<span style="background-color: #ffff00; color: red">m.nIndex1</span>] = m.vNewVal
<span style="color: #0000ff">ENDIF</span>
? "<span style="background-color: #ffff00; color: red">aProp_Assign() after assignment - value is '</span>" + <span style="color: #0000ff">TRANSFORM</span>(m.vNewVal) + "<span style="background-color: #ffff00; color: red">'</span>"</strong></pre>
<p>Now we can assign a value e.g. to the scalar <font face="Courier New"><strong>cProp</strong></font> property: <strong>oSource.cProp = "<span style="background-color: #ffff00; color: red">Hello World!</span>"</strong> and watch the sequence that gets echoed out to VFP’s desktop:</p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Output" border="0" alt="Output" src="http://lh4.ggpht.com/-QLMT0bqVrZM/Tl4oeRhIEHI/AAAAAAAAHjw/Yu1osMFMNog/Output1.png?imgmax=800" width="400" height="318" /></p>
<p>The first line is generated by the first <strong>? "<span style="background-color: #ffff00; color: red">cProp_Assign() before assignment - value is '</span>" + <span style="color: #0000ff">TRANSFORM</span>(<span style="color: #0000ff">THIS</span>.cprop) + "<span style="background-color: #ffff00; color: red">'</span>"</strong>  expression.  <br />During execution of the second statement: <strong><span style="color: #0000ff">THIS</span>.cprop = m.vNewVal </strong>all four event handlers are raised, which generate the “Handler x ------------------------------“ … output lines, one after the other.
<br />Finally, the second <strong>? "<span style="background-color: #ffff00; color: red">cProp_Assign() after assignment - value is '</span>" + <span style="color: #0000ff">TRANSFORM</span>(m.vNewVal) + "<span style="background-color: #ffff00; color: red">'</span>"</strong> expression is executed.  <br />As you can see, the handlers #1 and #3 are definitely firing AFTER the value assignment, whereas handlers #0 and #2 only can show the initial empty string value. Anyway, all four handlers fired!</p>
<p>Now let’s have a short look what happens if we assign a value to the (non-scalar) array property like so: <strong>oSource.aProp = "<span style="background-color: #ffff00; color: red">Hello World!</span>"</strong> and watch the sequence that gets echoed out to VFP’s desktop:</p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="1[1]" border="0" alt="1[1]" src="http://lh6.ggpht.com/-8Z0mUTHxEq8/Tl4oexQ8hKI/AAAAAAAAHj0/rDrrWnIWGWI/113.png?imgmax=800" width="398" height="41" /></p>
<p>As you can see, no event handler gets called at all! </p>
<p><font style="background-color: #ffff00"><strong>1d.)</strong></font> RAISING a <em>scalar</em> property like so: <span style="color: #0000ff">RAISEEVENT</span>( oSource, "<span style="background-color: #ffff00; color: red">cProp</span>")  does NOT trigger an existing  _Assign() method, because internally VFP does not execute a real self-assignment, but only invokes all bound delegates. This produces the following output:</p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="7[1]" border="0" alt="7[1]" src="http://lh4.ggpht.com/-fL__-YCYGcw/Tl4off6U6nI/AAAAAAAAHj4/i0amZbNh9Q0/713.png?imgmax=800" width="227" height="285" /></p>
<p>The output shown above is the same when we are raising our <em>non-scalar array</em> property! Thus, we can state that VFP’s property-raising behavior is consistent for both property types (scalar and non-scalar ones)!</p>
<p><font style="background-color: #ffc000"><strong>2a.)</strong></font>  VFP’s help file is missing some interesting things that should also be known! What’s about resetting a property to the class-default using VFP’s <font color="#0000ff" face="Courier New"><strong>ResetToDefault()</strong></font> method?
<br />This is what will happen, if you issue the following commands: </p>
<pre><strong>oSource.ResetToDefault("<span style="background-color: #ffff00; color: red">aProp</span>")</strong><font face="Calibri"> or <br /></font><strong>oSource.ResetToDefault("<span style="background-color: #ffff00; color: red">cProp</span>")</strong></pre>
<p>They yield in the following output ( I added this: <strong>? '<span style="background-color: #ffff00; color: red">ResetToDefault("</span>' + m.cProperty + '<span style="background-color: #ffff00; color: red">")</span>'  </strong>to the <font color="#000000">form’s <font face="Courier New"><strong>ResetToDefault()</strong></font></font> method):</p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="5[1]" border="0" alt="5[1]" src="http://lh6.ggpht.com/-i0ngagubalk/Tl4ofuMV6jI/AAAAAAAAHj8/JoinnWvfHPw/513.png?imgmax=800" width="349" height="325" /></p>
<p>When resetting the form’s non-scalar .aProp[] property only a single </p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="6[1]" border="0" alt="6[1]" src="http://lh6.ggpht.com/-ig5VrsNeKwg/Tl4ogJ1rSmI/AAAAAAAAHkA/GVzxHYhNH4I/613.png?imgmax=800" width="169" height="29" /></p>
<p>is echoed out. The two most interesting parts to remember are:
<br />1st) <strong>Resetting a (non-scalar) array property</strong> neither raises an event handler nor does it call an existing _ASSIGN() method!
<br />2nd) On the other hand, <strong>resetting a scalar property does it all</strong>, but with one interesting difference: all event handlers, as well as the _Assign() method call itself are invoked AFTER VFP’s internal ”resetting process” has finished work! You can see above that the property value already is empty when the Assign() method call (followed by the event handler invocations) takes place. What exactly is going on while resetting an array property cannot be monitored due to the 1st limitation.
<br />3rd) One final thing to mention is, that trying to <strong>reset an array property</strong> back to it’s class default using code like: <font face="Courier New"><strong>.<font color="#0000ff">ResetToDefault</font>("<font style="background-color: #ffff00" color="#ff0000">array_property_name</font>")</strong></font> is useless! Neither a changed array dimension will be restored, nor will the remaining array elements be set to .F. again. This is the default behavior documented in VFP’s help file.</p>
<font style="style"><strong>
<p>
<hr /></p>
<p align="center"><font size="4">The following section is for all VFP PROs (who think they know all and everything ;-)</font></p>
</strong></font><font style="background-color: #ffc000"><strong>
<hr />
<p>2b.)</p>
</strong> We can bind any event handler to a property. Better said, we can parameterize a property-event handler without limitation (okay, within VFP’s maximum parameter count limit). The best is jet to come: <strong><font style="background-color: #ffff00">We can raise a property with as much parameters as we want (within VFP’s maximum parameter count limit), as long our delegate is able to receive/handle the parameter values! <font color="#ff0000">You are not that exited?</font></font><font style="background-color: #ffff00"> Wait, better think twice!</font></strong></font>
<p>VFP’s <font color="#0000ff" face="Courier New"><strong>AEVENTS()</strong></font> function is a nice to have thing, when we need to find out what the source of the event was. Creating a local 3-element array that gets filled with the appropriate information first, sometimes sounds like creating to much overhead. At least in tight loops raising slow delegates very often can become a speed-bottleneck at runtime. Naturally, after having mentioned that we can bind any kind of parameterized delegate to a property, it is easy to guess, what comes next: <strong><u><font color="#9b00d3" size="3"><em>Let us use parameterized delegates on properties!</em></font></u></strong></p>
<p>The diagram below seems a little bit confusing at first sight. Thus, let me explain what it should depict. To keep things as simple as possible at the beginning there are 4 object in our example: one form (on the GUI layer) with two interface objects (at the wiring layer) and one manager/controller object (in the business/system layer). </p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLk2nMcsnvInCUPxdzehyGnLXAwU19MliulmeA6mOAKayyWERxQN3JBS7_9Bx_LtoC41FQshuZCJGOuHa5Ouxoazk-3WdgAaNnntv_DG3P8iDlbq3QRARSozZdXl4jSjlxOdbM/?imgmax=800" width="820" height="726" /></p>
<p>A reference of each form interface object will be stored in the form (the thick black lines). The form’s <font color="#0000ff" face="Courier New"><strong>Resize()</strong></font> and <font color="#0000ff" face="Courier New"><strong>Moved()</strong></font> events may implement trigger code like the following (a reference to the “Position&Size” interface object is stored in the form’s “oInterfacePosAndSize” property:</p>
<pre><strong><span style="color: #008000">*\\ Trigger code in the form's MOVE() event</span>
<span style="color: #0000ff">RAISEEVENT</span>( <span style="color: #0000ff">THIS</span>.oInterfacePosAndSize,;
"<span style="background-color: #ffff00; color: red">Position</span>", ;
<span style="color: #0000ff">THIS</span>, ;
<span style="color: #0000ff">THIS</span>.<span style="color: #0000ff">Left</span>, ;
<span style="color: #0000ff">THIS</span>.<span style="color: #0000ff">Top</span>, ;
<span style="color: #0000ff">THIS</span>.<span style="color: #0000ff">Width</span>, ;
<span style="color: #0000ff">THIS</span>.<span style="color: #0000ff">Height</span> </strong>)</pre>
<p>and</p>
<pre><strong><span style="color: #008000">*\\ Trigger code in the form's RESIZE() event</span>
<span style="color: #0000ff">RAISEEVENT</span>( <span style="color: #0000ff">THIS</span>.oInterfacePosAndSize,;
"<span style="background-color: #ffff00; color: red">Size</span>", ;
<span style="color: #0000ff">THIS</span>, ;
<span style="color: #0000ff">THIS</span>.<span style="color: #0000ff">Left</span>, ;
<span style="color: #0000ff">THIS</span>.<span style="color: #0000ff">Top</span>, ;
<span style="color: #0000ff">THIS</span>.<span style="color: #0000ff">Width</span>, ;
<span style="color: #0000ff">THIS</span>.<span style="color: #0000ff">Height</span> )</strong></pre>
<p>The cool thing about these constructs is that they run without errors <strong><u>even if there is no delegate attached/bound</u></strong>. In other words: we can set up a series of EMPTY-based interface objects like shown above, link them to their implementation instances and bind triggers and delegates to their properties. You can move such a form and resize it as you like, there will be no delay. The form instance behaves absolutely “normal”! Firing triggers that raise events on unbound properties is a totally transparent process.</p>
<p>Now, what’s next? Okay, our form layout controller instance is very interested in what users are doing with our forms. But, instead of holding/storing a form reference (working directly with the public interface of each form), the form layout controller only binds his delegates and triggers to the properties “Position” and “Size” <strong>of the form’s interface object</strong>. The signatures of the delegates are shown below:</p>
<pre><strong><span style="color: #008000">*\\ Handler signature in the form layout controller's <u>OnPosChange()</u> delegate </span>
<span style="color: #0000ff">LPARAMETERS</span> oSender <span style="color: #0000ff">AS</span> Object, ;
tnLeft <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>, ;
tnTop <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>, ;
tnWidth <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>, ;
tnHeight <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span></strong></pre>
<p>and</p>
<pre><strong><span style="color: #008000">*\\ Handler signature in the form layout controller's <u>OnSizeChange()</u> delegate </span>
<span style="color: #0000ff">LPARAMETERS</span> oSender <span style="color: #0000ff">AS</span> Object, ;
tnLeft <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>, ;
tnTop <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>, ;
tnWidth <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>, ;
tnHeight <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span></strong></pre>
<p>Now, moving or resizing the form will cause invocation of the bound delegates of the layout controller. Of course, you have to implement something useful there. I leave that to your imagination. One thing should also be mentioned: Using parameterized event raising on properties passing a self reference as one of the parameters frees the event handler from using VFP’s AEVENTS() function to retrieve such a sender reference!
<br />Additionally , you may want to shorten the signature of your “raise-events”. Two parameters are enough: the sender reference and a parameter object. This is just the way most of .NET’s event binding works. </p>
<p>What we have now is a ultra-lightweight EMPTY object containing as much scalar properties as we need. We only need to know the name of the property, because the property only has to exist – the property value doesn’t matter, it is irrelevant. The property can be seen as some kind of binding-handle: a unique address we can bind our handlers to and raise our events. Our delegate implementations should test then for a parameter count > 0 to reassure the property-event was  RAISED and not triggered by a simple value assignment, like so:</p>
<pre><strong><span style="color: #008000">*\\ Handler code in the form layout controller's OnSizeChange() delegate </span>
<span style="color: #0000ff">LPARAMETERS</span> oSender <span style="color: #0000ff">AS</span> Object, ;
tnLeft <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>, ;
tnTop <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>, ;
tnWidth <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>, ;
tnHeight <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>
<span style="color: #008000">*\\ only process invocations stemming from a RAISEEVENT()</span>
<span style="color: #0000ff">IF</span> <font color="#0000ff">PCOUNT()</font> = 0
<span style="color: #0000ff">RETURN</span>
<span style="color: #0000ff">ENDIF</span>
</strong><span style="color: #008000"><strong>*//</strong> </span></pre>
<h4><font color="#000080"><font style="font-weight: bold">More benefits</font></font></h4>
<p>The technique I presented here is based on using EMPTY-based objects to setup some kind of generic event binding. Sure, you can use other “full-blown” VFP classes instead to add more functionality to your interface objects. In my own <strong><em>FoxQuill</em></strong> framework I call these extended interfaces “smart interfaces”, because they are able to host contracts to validate incoming, as well as outgoing parameter values. This is my way to completely separate inter-object messaging/communication from function implementation. </p>
<p>Passing ultra-lightweight  interface objects around saves you from spreading your real object references all over the place. Dangling references are almost unknown to my personal framework, since I’m using these binding-proxy objects. Another benefit is: now we can split our objects’ interfaces and group them on a logical basis: one set representing queries, another set represents commands, and two others hold events and exceptions. </p>
<p>Finally imagine: you will be able to pass all those interfaces into an environment (I call mine “The Matrix”:-) where some generic (data-driven) mechanism links logical children to their parents and/or service-providers to their service-subscribers. That way, all your (implementing) objects can be stored in one place (I call mine “The Construct”:-) and the inter-object communication system can be set up (even dynamically at runtime). Implementing security related message redirections or adding some extensions to an existing workflow has never been easier to realize!</p>
<h2><font style="font-weight: bold" color="#000080">
<hr />
<hr />Protect Your Events</font></h2>
<p>Let’s assume there is a password dialog object asking your end-user to enter her name and password in two textboxes. If the password dialog class is one of your framework goodies, maybe your way of returning the user name and password is based on event binding. Thus, your dialog class may have an event called <strong><em>Logon()</em></strong>. You are raising the <strong><em>Logon()</em></strong> event when the end-user clicks the login-button on your dialog, passing an EMPTY-based object containing to fields: <strong><em>UserName</em></strong> and <strong><em>UserPass</em></strong>. Let’s further assume that password encryption and verification is part of another business-layer and not implemented in your GUI (bravo!). Then, there is a short timeframe, since you’ve raised <em><strong>Logon()</strong></em>, where the password exists unprotected in a <em>data capsule</em> that may be intercepted by anyone who had access to your login dialog before! Shure, there are better ways to pass sensitive data in such a case, <u>but this is only an example</u>!</p>
<h2><font style="font-weight: bold" color="#000080">What Do We Need</font></h2>
<p>We need a little VFP project we can use for our experiments. Let’s set up a tiny <strong><em>login dialog</em></strong> class and a second class representing the junior version of a <strong><em>Password Manager</em></strong> just to have two instances between which we can establish our binding.</p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="spyVSspy" border="0" alt="spyVSspy" src="http://lh4.ggpht.com/-qEgDaHPVAq0/Tl4ohD3JwyI/AAAAAAAAHkI/2683RGffjv4/spyVSspy3.jpg?imgmax=800" width="60" height="59" />Finally, let’s build a <strong><em>spy class</em></strong> that tries to monitor the login dialog’s <strong><em>Logon()</em></strong> event to intercept and catch the user’s name/password combination. </p>
<pre><strong><span style="color: #0000ff"><font color="#a5a5a5"></font></span></strong></pre>
<h2><font color="#000080"><font style="font-weight: bold">Securing Events</font></font></h2>
<p><strong><u>Back to the golden thread!</u></strong> Let’s use the form we already created for our first test-drive. I saved it under a new name “<strong>LOGIN.SCX”</strong>. Below there are two screenshots showing the login form’s GUI layout in development mode and at runtime:</p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="13" border="0" alt="13" src="http://lh3.ggpht.com/-5RRkH-Wap50/Tl4ohXjTGvI/AAAAAAAAHkM/wHgR2mk5zus/134.png?imgmax=800" width="478" height="174" /></p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="14" border="0" alt="14" src="http://lh5.ggpht.com/-Qrgju26TiM0/Tl4oh7SPpSI/AAAAAAAAHkQ/GWxFMtscGiQ/145.png?imgmax=800" width="436" height="116" /></p>
<p>Clicking the <font style="background-color: #00ff00">[Submit (ENTER)]</font>-button executes the following code:</p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="15" border="0" alt="15" src="http://lh5.ggpht.com/-80AWSbfV_nU/Tl4oiIBmAII/AAAAAAAAHkU/fb_E877tksU/154.png?imgmax=800" width="691" height="149" /></p>
<p>During  form’s initialization I added a data object like so:</p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="16" border="0" alt="16" src="http://lh6.ggpht.com/-9o19tZZv1NY/Tl4oig0t21I/AAAAAAAAHkY/q2OLpiJDN7Q/164.png?imgmax=800" width="661" height="166" /></p>
<p>Pressing ESC or clicking the <font style="background-color: #ff0000">[Abort (ESC)]</font>-button executes the following code:</p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="17" border="0" alt="17" src="http://lh6.ggpht.com/-39tJH9ULy4k/Tl4oi2Ksl6I/AAAAAAAAHkc/mOf1iI_xdIs/174.png?imgmax=800" width="630" height="170" /></p>
<p>My event method <font color="#0000ff" face="Courier New"><strong>.EvtSendOut()</strong></font> stays untouched. I added a new <strong><font color="#0000ff" face="Courier New">.Trigger()</font></strong> method from where <font color="#0000ff" face="Courier New"><strong>.EvtSendOut()</strong></font> is raised or called, which depends on the 3rd parameter that can be passed into my <strong><font color="#0000ff" face="Courier New">.Trigger()</font></strong>method: 1 – RAISEEVENT() | 2 – Method call. The 4th parameter of my <strong><font color="#0000ff" face="Courier New">.Trigger()</font></strong>method passes security-related information.  I decided to decode the security test type numbering so that it is easy maps to VFP’s <strong><em>nFlags</em></strong> values. The table below tells you about the integer mapping:</p>
<table border="1" cellspacing="0" cellpadding="2" width="635"><tbody>
<tr>
<td valign="top" width="65"><font style="background-color: #ffff00">value</font></td>
<td valign="top" width="568"><font style="background-color: #ffff00">description</font></td>
</tr>
<tr>
<td valign="top" width="65">0</td>
<td valign="top" width="568">no security testing at all (just pull the trigger :-)</td>
</tr>
<tr>
<td valign="top" width="65">1</td>
<td valign="top" width="568">unbind all event handlers that are using <strong>nFlags = 0</strong> for their delegate bindings</td>
</tr>
<tr>
<td valign="top" width="65">2</td>
<td valign="top" width="568">unbind all event handlers that are using <strong>nFlags = 1</strong> for their delegate bindings</td>
</tr>
<tr>
<td valign="top" width="65">4</td>
<td valign="top" width="568">unbind all event handlers that are using <strong>nFlags = 2</strong> for their delegate bindings</td>
</tr>
<tr>
<td valign="top" width="65">8</td>
<td valign="top" width="568">unbind all event handlers that are using <strong>nFlags = 3</strong> for their delegate bindings</td>
</tr>
<tr>
<td valign="top" width="65">16</td>
<td valign="top" width="568">repeat check (to protect against timer-driven spy-ware)</td>
</tr>
</tbody></table>
<p>Needless to say, the bit values from above <strong>can be combined</strong> to “filter out” more than one group. If you want to block all delegates bound with <strong><em>nFlags</em></strong> values of 0, 1, and 2, just pass a seven (7) to the <strong><font color="#0000ff" face="Courier New">.Trigger()</font></strong>method. Naturally, there is no native VFP way to <strong><em>filter out</em></strong> established bindings. Thus, we have to get rid of the unwanted bindings using old-fashioned “hammer-style”: <strong><em>Just Unbind Them<font style="background-color: #ff0000"></font></em></strong><font color="#000000"><strong><em> </em></strong>:-) </font>Of course, good spy-ware would try to re-establish it’s “wiretapping”. The only way to achieve that successfully, is using a timer. Therefore, I added the option (add +16 to the 4th parameter) to set a marker flagging that the security test is no longer optional!</p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="18" border="0" alt="18" src="http://lh3.ggpht.com/-KslB5-k6ty0/Tl4ojvTOU0I/AAAAAAAAHkg/n1YAM6Hkkvs/185.png?imgmax=800" width="730" height="427" /></p>
<p>The screenshot above shows my test environment with actually 4 running spy instances. Each spy has bound itself to the login form (that is the caption- and borderless child window inside the Password Manager) with a different <strong><em>nFlags</em></strong> value (to proof that my protection scheme really works as expected) My login form’s trigger method was called from the [Submit]-button allowing only delegates bound with <strong><em>nFlags = 3</em></strong> to stay linked, because (as I mentioned before) the guys with <strong><em>nFlags</em></strong> 0 or 1 are <strong><u>no real event handlers</u></strong> today (IMHO)! The rest of the guys has to wait, until I finish processing – thus, they must bind with <em><strong>AFTER INVOCATION := 3</strong></em>! This gives me room to process the unprotected login data (you can see it below: the new caption of my Password Manager form displays it). Naturally, before returning from my password manager, I changed the originally entered name and password to some less valuable text ;-) which was captured by spy #4 (numbered from top to bottom on the screen shot). Have a good time with that, SPY#4! <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Zwinkerndes Smiley" src="http://lh4.ggpht.com/-TGnDCKH1SDo/Tl4oj1oGCpI/AAAAAAAAHkk/S_fjrj2Nb2c/wlEmoticon-winkingsmile2.png?imgmax=800" /> </p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/-zg2XU2O7d7A/Tl4okm5evKI/AAAAAAAAHko/M0k8qyp9lL0/image4.png?imgmax=800" width="728" height="428" /></p>
<p>
<hr /><a title="Download EventTest.Zip from here" href="http://resources.foxquill.de/eventtest.zip" rel="nofollow" target="_blank"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 12px 12px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top: 0px; border-right: 0px; padding-top: 0px" title="download" border="0" alt="download" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimpvCYfH8YQ2InykklfVEND2b8ezs4xwj0clLD6iSjZs4oBKpfThupiSJkaG1KfRFY1S-fe_iPMr9_8bGsGd6FX9Cegjrc7CtdCrvFT58oFtVIY_jhdccOKp2Hs1SfW2y9eF31/?imgmax=800" width="77" height="67" /></a></p>
<h2><font style="font-weight: bold" color="#000080">Where is the Beef?</font></h2>
<p><font size="2"><<<  Here it is! Use this download link to get all sources to play with… </font></p>
<h2><font style="font-weight: bold" color="#000080">Final Thoughts</font></h2>
<p>Native event binding is one of the most useful features that were added to VFP over the time! To be honest, I started developing my own VFP framework not until event binding was introduced! Even though there are many little bumps on the floor (especially, when applying event binding to VFP’s native properties), up to now, I never found another development environment that gave me more freedom to create extraordinary specialties with ease! </p>
<hr />
<p><a title="http://myvfpblog.blogspot.com/2011/05/hierarchical-table-order-part-i.html" href="http://myvfpblog.blogspot.com/2011/05/hierarchical-table-order-part-i.html"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Previous Entry" border="0" alt="Previous Entry" src="http://lh5.ggpht.com/-_oGMYzhOYn0/Tl4ola5xkgI/AAAAAAAAHkw/yc7nIBUq2jc/NavBack_48_RGBA%25255B6%25255D.png?imgmax=800" width="48" height="64" /></a><a title="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-tips-tricks-in-this.html" href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-tips-tricks-in-this.html"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Home" border="0" alt="Tips & Tricks Home (TOC)" src="http://lh6.ggpht.com/-afOHUMke75k/Tl4oljrl_GI/AAAAAAAAHk0/fg8MXBGz_xY/NavHome_48_RGBA%25255B3%25255D.png?imgmax=800" width="48" height="64" /></a><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="NavForward_48_RGBA" border="0" alt="NavForward_48_RGBA" src="http://lh5.ggpht.com/-usfcq9v2K1s/Tl4ol21z5nI/AAAAAAAAHk4/3W0xWL6JVq0/NavForward_48_RGBA%25255B6%25255D.png?imgmax=800" width="48" height="64" /></p> Burkhardhttp://www.blogger.com/profile/11631168041975170500noreply@blogger.com9tag:blogger.com,1999:blog-26167158.post-70589853633495274192011-05-12T11:09:00.000+02:002011-08-31T14:39:11.136+02:00Hierarchical Table Order (Part I)<p><strong><font color="#ff8040"></font></strong></p> <p><strong><font color="#ff8040">Version: 0.01.70 - last update: Wednesday, August 30, 2011, 14:35:00 (page links updated)</font></strong></p> <p><a title="http://myvfpblog.blogspot.com/2011/04/loadpicture-functionsome-myths-revealed.html" href="http://myvfpblog.blogspot.com/2011/04/loadpicture-functionsome-myths-revealed.html"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Previous Entry" border="0" alt="Previous Entry" src="http://lh4.ggpht.com/_MOmDLu4Rm5Y/Tb9c6hvawvI/AAAAAAAAHgA/ZT3MmCjRH5I/NavBack_48_RGBA53%5B4%5D.png?imgmax=800" width="48" height="64" /></a><a title="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-tips-tricks-in-this.html" href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-tips-tricks-in-this.html"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Tips & Tricks Home (TOC)" border="0" alt="Tips & Tricks Home (TOC)" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTcnMCjbPpxrlP7YYyO82b0iSvUcOfysn-BIEiGhHTgsA-NdBJ9dpwtjQeGiVlMgDkEK5WYAtVbCNCfGsfqmwhaJ_1vqf53mKadYGV8z94mm_l7_sdSuS98hyphenhyphenpEb2nffFa4OVR/?imgmax=800" width="48" height="64" /></a><a title="http://myvfpblog.blogspot.com/2011/05/cool-vfp-event-binding.html" href="http://myvfpblog.blogspot.com/2011/05/cool-vfp-event-binding.html"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Next Entry" border="0" alt="Next Entry" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbYcMe2Coy4DcDQN2f6QkylYrWWFBnFHNRhq9P36OvjGfXaaIhcntWWzHxVEDhJ8nWf-U50sTPK4g4bHQUAMpfMEV0AJ_np2HmyZ05S4Um9mZktIJ-zP2-EabDiSKGcuA5JZ-p/?imgmax=800" width="48" height="64" /></a>  </p> <hr /> <font color="#000080" size="3"> <h4><font style="font-weight: bold" color="#000080">All you have to know about sorting table data hierarchically</font></h4> <h1><font style="font-weight: bold" color="#000080">Intro</font></h1> </font> <p>When I implemented my first version of a native VFP TreeView control – just to see if it was feasible – I created the controlling driver table the typical “at least 2-columns” way. You still can download that outdated first try from <a title="http://resources.foxquill.de/gridtree_alpha_01.zip" href="http://resources.foxquill.de/gridtree_alpha_01.zip" rel="nofollow" target="_blank">here</a> – just in case you want to peep at the table structure in question :-) After many, many hours of testing I found a couple of neat solutions to master all speed bottlenecks I encountered during test-driving my first VFP TreeView results. Today, I like to present to you one of the most interesting basics: how to sort a DBF-table hierarchically on only one column’s data <strong><em>WITHOUT loosing to much speed!!!</em></strong></p> <h3><font style="font-weight: bold" color="#000080">Hierarchical data - abstract</font></h3> <p>Some guys out here, even profs of computer sciences, claim that any set(s) of items can be organized hierarchically. Almost all taxonomies, numeric or non-numeric ones, have one thing in common: a one to many relationship between their members, spanning a tree-like structure stemming from one shared root element. </p> <h3><font style="font-weight: bold" color="#000080">Hierarchies – concrete</font></h3> <p>Looking at objects at runtime, even during design-time while using “instance programming” in VFP, we immediately notice that any object has its unique identity and at least one reference path through which we can access its public members. Let’s have a look on a pretty common example showing how to print out the content of a VFP application’s textbox:</p> <p><font color="#0000ff" size="2" face="Courier New"><strong>? m.goApp.oFormManager.Items(“AddressForm.1”).oPgfMaster.oPage1.oCntLeftPane.oTxtFirstName.Value</strong></font></p> <p>Nothing extravagant so far. So, what do we have here? There seems to be a public variable called “goApp” pointing to a global application object. Obviously, the application object contains some kind of form manager object, through which we can retrieve a form reference. In this case it is one of our address entry forms, from which a reference was stored in the form manager’s collection using a key value “AddressForm.1”. On this form there is a page frame <em>oPgfMaster</em> with a page <em>oPage1</em> containing a VFP container object <em>oCntLeftPane</em> that holds the textbox <em>oTxtFirstName</em> we are looking for. Wow, finally we hold our textbox reference; from there we can print out the content of its <em>value</em> member. Well, I said it already, nothing special so far. </p> <p>Let’s map this concrete implementation snapshot to the more abstract description: the <strong><em>root element</em></strong> of our reference path is our global reference <strong><em>m.goApp</em></strong>. From there we start walking the reference path <em>down</em> to our textbox object. There may be more than one textbox named <strong><em>oTxtFirstName</em></strong> in our application at the same time (especially if we’ve enabled multi-instance editing), but NOT inside the parent container named <strong><em>oCntLeftPane</em></strong> – the one that resides on <strong><em>oPage1</em></strong> of <strong><em>oPgfMaster</em></strong> of <em><strong>.ITEM(“AddressForm.1”)</strong></em> managed by our app’s <em><strong>FormManager</strong></em>. <br />That said, everybody should understand what <strong><em><font color="#c0504d">OBJECT IDENTITY</font></em></strong> is now. Every object has its own distinct and unique identity. In addition to that, as long as everything works flawlessly, there should be at least one reference path (like the one shown above) through which we are able to access each object individually. What we also see is, that the taxonomy tree spans from left to right. In other words, the <em>one to many</em> relations are written from left to right along the reference path: the form manager has many forms to manage, a form may contain more than one (top-level) page frame, a page frame usually has more than one page on it, and so on. Whereas every child can only belong to one parent at a time – at least, when it comes to real containment (in VFP). In other words: We cannot <font color="#0000ff" face="Courier New"><strong>ADDOBJECT()</strong></font> a new class instance to more than one parental container object. In contrast to that, it is possible to add an object’s reference to more than only one other object through storing the reference to a property like so: </p> <li><font face="Courier New"><strong><font color="#0000ff">goApp.oCustomObjects.AddObject(“oMainForm”, “MyMainFormClass”)</font><font color="#008080"> && add object into real container </font></strong></font></li> <li><font face="Courier New"><strong><font color="#0000ff">loForm = goApp.oCustomizations.oMainForm </font><font color="#008080">&& retrieve a local working copy of object reference </font></strong></font></li> <li><font face="Courier New"><strong><font color="#0000ff">goApp.oFormManager.ADD(m.loForm, “AddressForm.1”) </font><font color="#008080">&& a VFP collection is no container!</font></strong></font><font face="Courier New"><strong><font color="#0000ff"></font></strong></font> </li> <li><font face="Courier New"><strong><font color="#0000ff">oApp.oSecurityManager.oMainForm = m.loForm</font><font color="#008080"> && loose coupling only</font></strong></font> <p>and so on. <br />Line #4 shows how some security manager gets its main form reference. This reference assignment results only in loose coupling. This is no real containment-ship! Best proof: our main form has NO <em><strong>THIS.PARENT</strong></em> reference (to the security manager!) BTW, even when we use the <font color="#0000ff" face="Courier New"><strong>ADD()</strong></font> method of the form manager collection, like shown on line #3 above, VFP internally does not establish a real containment there! VFP’s collection is no real container class but – well – a collection :-) Only on line #1 above, during instantiation, we added the form object to our custom container instance <strong><em>as a real child</em></strong>.</p> <p>That said, we can recap that any VFP object reference used as a variable can be assigned many times to many different objects’ properties. In contrast to that, the object itself can only be instantiated once by another parent container class instance using ADDOBJECT() or NEWOBJECT(). I name this kind of parent objects (which references can be retrieved from within any child’s method using <strong>THIS.PARENT</strong>) the <font color="#0000ff"><strong>REAL PARENTS</strong></font> or short the <strong><font color="#0000ff">CONTAINERS</font></strong>. All other objects holding references may only have some kind of <strong>logical parental relationship</strong> and therefor are called <strong><font color="#0000ff">LOGICAL PARENTS</font></strong>! Again, <strong><font color="#c0504d">there is no native support for logical parent-ship in VFP</font></strong>, only containment-ship is fully implemented!</p> <h4><font style="font-weight: bold" color="#000080">A Short C# PEEK</font></h4> <p>.NET languages, like C#, don’t have neither functionality, nor class methods comparable to VFP’s <font color="#0000ff" face="Courier New"><strong>THIS.ADDOBJECT()</strong></font> or <font color="#0000ff" face="Courier New"><strong>THIS.NEWOBJECT()</strong></font>. You can instantiate any GUI control just the way you would do it in VFP with non-visual classes. Making a GUI control instance visible to the user is a simple act of adding the control’s reference to some form’s  <em>controls collection</em>. Simulating the procedure in VFP would look like so:</p> <p><font color="#0000ff" face="Courier New"><strong>loTextBox = CREATEOBJECT(“MyTextboxClass”) <br />loMainForm.Controls.ADD(m.loTextBox)</strong></font></p> <p>In .NET every container has a controls collection – just like VFP – to which a child object (reference of a class instance) can be added dynamically. </p> <h3><font style="font-weight: bold" color="#000080">Hierarchies – a General Approach</font></h3> <p>The only nice thing about long, descriptive reference names is, that most of the tokens we are using there are (more or less) easy to memorize. Even if I did not write the above code myself, I am still able to grasp the idea where to go to get the searched first name value. One of the downsides of descriptive names is that a computer program is not able to deal with the deeper sense transported with the names, like humans do. VFP tokenizes the names and stores them in an internal table (go and Google for VFP’s <strong><em>NTI – name table index</em></strong> entries). There is not much more you can do with them, but search for existence (e.g.  using <font color="#0000ff" face="Courier New"><strong>PEMSTAT()</strong></font>). Well, you can setup a (complex) naming convention schema if you like but you have to write all of the necessary rule parsers and all the other weird stuff to enforce it on your own. Adding another semantic class to VFP’s variable- and property names introduce a whole new universe of troubles to solve. <br />Thus, my proposal is pretty different – <strong><font size="2">I say: “Stop using object <u>names</u>!”</font></strong></p> <p>No, I do <em>not</em> mean “stop using names at all” but only in the first place! Let me show you how the textbox object’s value example above may be written within my FoxQuill framework:</p> <p><font color="#0000ff" size="2" face="Courier New"><strong>? _GlobMem(“1.102.1.15.1.4.1.2.23.”).Value</strong></font></p> <p>Okay, you’re right, that looks pretty cryptic! But, using some custom <em>intellisense functions</em> make the whole thing as clear as any “verbose” name approach.  The idea behind my notation is, to substitute human readable reference names with a <em>very simple to understand</em> enumeration schema! These are my basic rules:</p> </li> <li>Every class instance (object) has a unique (running) number that makes it distinguishable from all other sibling objects at the same level (of containment). </li> <li>Object numbering starts with <1>. (All <0>-based object references are reserved for internal use!) </li> <li>All objects exactly have at least one <em>logical</em> parent. There can only be <u>one</u> <strong><em>start-point object</em></strong> that must not have any logical parent (the <em><strong>root</strong></em>). </li> <li>The reference path to any object is written using n-dimensional array notation. (In VFP we have to use strings for that.) </li> <li><strong>Relation rule #1</strong>: Child numbers are written next to their logical parent IDs on the right side, separated by a dot. </li> <li><strong>Relation rule #2</strong>: Sibling objects have the same logical parent string and differ only in their own running number. <p>Let’s look at an example to make things a little bit clearer: <br />There’s a form with a container grouping a label and a textbox: <font color="#0000ff" face="Courier New"><strong>oForm1.oCntFirstName.oLblFName</strong></font> and <font color="#0000ff" face="Courier New"><strong>oForm1.ocntFirstName.oTxtFName</strong></font> </p> <p>Let’s say that the form is the root object in this example. Then there are the following <strong>VECTOR</strong> expressions:</p> <table border="0" cellspacing="0" cellpadding="2" width="542"><tbody> <tr> <td valign="top" width="221">Form Vector</td> <td valign="top" width="37">>> </td> <td valign="top" width="282">“1.”</td> </tr> <tr> <td valign="top" width="221">Container Vector</td> <td valign="top" width="37">>></td> <td valign="top" width="282">“1.1.”</td> </tr> <tr> <td valign="top" width="221">Label Vector</td> <td valign="top" width="37">>></td> <td valign="top" width="282">“1.1.1.”</td> </tr> <tr> <td valign="top" width="221">Textbox Vector</td> <td valign="top" width="37">>> </td> <td valign="top" width="282">“1.1.2.”</td> </tr> </tbody></table> <p>I named my “numbered reference paths” <em><strong>vectors</strong></em>. Every vector carries some implicit information:</p> </li> <li>It points to exactly one object, the so called <em><strong>endpoint object </strong></em>(the <em><strong>endpoint</strong></em>). Thus, it may be used as a <strong><em>unique identity descriptor</em></strong> for that endpoint! </li> <li>It describes the parental hierarchy (the containment path) from the <strong><em>root</em></strong> to the <strong><em>endpoint</em></strong>. </li> <li>Each number within a vector expression (separated by a dot) is called a <strong><em>dimension</em></strong>. Dimensions are enumerated from left to right. </li> <li>The <em>dot-count</em> of a vector expression reflects the vector’s <strong><em>dimension width</em></strong> :=  <font color="#0000ff" face="Courier New"><strong>lnDW = OCCURS(".", Vector)</strong></font> <br />      In our example above the textbox vector has an overall <strong><em>dimension width</em></strong> of <3>. </li> <li>If we want to add a child to any object (even to non-containers!) we simply add the child to the object’s <strong><em>child dimension</em></strong>. <p>Let’s look at another example. Let’s say, we want to add some new controls to our form above. This was our form’s vector: <strong>“1.”</strong> <br />Now, let us add a PageFrame along with the existing container (at the same containment level). This is the vector expression of our new PageFrane: <strong>“1.2.”</strong> <br />Next, let us add three pages to the our PageFrane. These are the vector expressions of our new Pages: <strong>“1.2.1.”</strong>, <strong>“1.2.2.”</strong> and <strong>“1.2.3.”</strong> <br />Finally, let us add a container with another label and textbox to the 2nd page of our new PageFrane. <br />These are the corresponding vector expressions: <strong>“1.2.2.1.”</strong> (the container), <strong>“1.2.2.1.1.”</strong> (the label) and <strong>“1.2.2.1.2.”</strong> (the textbox).</p> <div> <p><img style="background-image: none; border-right-width: 0px; margin: 6px 12px 6px 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="hierarchical demo" border="0" alt="hierarchical demo" src="http://lh4.ggpht.com/_MOmDLu4Rm5Y/Tb9c7wAJyuI/AAAAAAAAHgM/6Pny79h7BtI/5%5B4%5D.png?imgmax=800" width="304" height="328" /> <br />Now, the hierarchical object relations should look like in the image above. Naturally, we could have used named references as well: <br /><font color="#0000ff" face="Courier New"><strong>? oForm.oPageFrame.oPage2.oContainer1.oTextBox1.Value</strong></font> is the same like this: <font color="#0000ff" face="Courier New"><strong>? oConstruct(“1.2.2.1.2.”)</strong></font> given that there is some collection-based object named <strong><font color="#0000ff" face="Courier New">oConstruct</font></strong> that holds a keyed reference to our textbox instance.</p> <h3><font style="font-weight: bold" color="#000080">More to come</font></h3> <font color="#0000ff" face="Courier New"><font color="#0000ff" face="Courier New"></font></font> <p>There are many more things to talk about when explaining “name-less” object reference constructions in-depth: how to maintain references using keyed collection, or how to organize (re-)numbering in case of object deletions. I will describe those different aspects pretty soon in later postings. We will talk about the so-called “zero-nodes” (e.g. “0.0.0.0.0.”), you will hear about a generic “inter-object messaging” system built into an object collection I named “<font color="#0000ff"><strong>the Matrix</strong></font>”). Finally, I will show you how simple otherwise complex object maintenance tasks can be realized if one uses a collection-based class instance storage (I named mine “<font color="#0000ff"><strong>the Construct</strong></font>”)… <em><font color="#c0504d"><strong>(“The blue or the red one, Nero?” ;-)</strong></font></em></p> <h3><font style="font-weight: bold" color="#000080">Hierarchical data – The Solution</font></h3> <p>The screen shot <u>above</u> shows a TreeView which displays all items sorted correctly. Now, lets create a VFP free table to type in some test data. The outcome could look like the screen shot <u>below</u>:</p> <p><img style="background-image: none; border-right-width: 0px; margin: 6px 12px 6px 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Hierarchical table entries not ordered" border="0" alt="Hierarchical table entries not ordered" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNTDGAnDW-jbcXjY15angGC27YkUDql2f4RGV7I5drllmT1wr44N1mbpqXLl9ac1r_sxmVjEYTsEONErMGJIuTpfZGmbI9-vnLObqcsPElcslc8WmhKSMAnaz0D5vBH1u1ZdFO/?imgmax=800" width="569" height="733" /></p> <p>At this early stage, the table has only one VARCHAR (binary) field called <strong><em>Vector</em></strong> which is 240 characters long. I like the VARCHAR field type, because there are no trailing blanks that have to be removed every time when fetching table data into memory. I think of VARCHAR as a regular CHAR field with an implicit <font color="#0000ff" face="Courier New"><strong>RTRIM() </strong></font>functionality. BTW, be aware of the following: <strong>If you change a CHAR field to the VARCHAR field later,</strong> any data that has been already entered will retain its trailing spaces. An example: Maybe you have a table with a column named <em>Clastname</em>  (maybe a <em>C(80)</em> field). After 500 record were entered you decide to change your <em>Clastname</em> field to the new VARCHAR type V(80).  After that, another 500 address records were entered. Now, running through all 1000 records showing the effective content length of your <em>Clastname</em> field like so: <font color="#0000ff" face="Courier New"><strong>? LEN(Clastname)</strong></font> will show you, that the first 500 records all still print out > <strong>80</strong> <! Only the newly entered 500 records print their real “<font color="#0000ff" face="Courier New"><strong>RTRIM()</strong></font>ed” <em>varchar-lengths</em>!</p> <p><strong>Thus, after changing an existing CHAR field containing data(!) to VARCHAR you should run a <font color="#0000ff" face="Courier New">REPLACE ALL fieldname WITH ALLTRM(fieldname)</font>ASAP!</strong></p> <p>The screenshot above shows us the non-ordered list of entries (their so-called <em>chronological ordering</em>). Now, lets add an index and activate it like so:</p> <p><img style="background-image: none; border-right-width: 0px; margin: 6px 12px 6px 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Hierarchical table entries with simple ordering" border="0" alt="Hierarchical table entries with simple ordering" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBzGGx2WNEamgN8achHAX55-_u1MaktnSfNUPX-m17QbucglAwV5PD-Kr2aFG_-VsHFSRzFCbE4hRpyfgRyG4b1CbmZDq9x9Ln7xPzxDAznPDzMsxanVDXgAK-xtTp2ggtl7Dn/?imgmax=800" width="607" height="733" /></p> <p>Adding a regular VFP index on the Vector column does not result in <strong><em>correct hierarchical sorting</em></strong>. As we can see, <font color="#ff0000"><strong>the records starting with “100.2.” should be sorted <em>before</em> those starting with  “100.10.”.</strong></font> Hierarchical data cannot be indexed using simple INDEX ON … commands without wrecking the correct hierarchical sort order. One way to overcome this would be to do a <font color="#0000ff" face="Courier New"><strong>SORT TO <NewTable> </strong></font>for the whole table immediately after a change happened. This is absolutely impracticable! Another approach could be to use a refreshable view. Alas, REQUERIES  would become to slow, because the whole driving cursor has to be refreshed, even if only one record has been changed. What we need is something to generate an outcome like the following:</p> <p><img style="background-image: none; border-right-width: 0px; margin: 6px 12px 6px 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Hierarchical table entries with CBV ordering" border="0" alt="Hierarchical table entries with CBV ordering" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjV8woU_aYn8Ungbp671bZDy-ouP-QhDrUgweBzNOVsXnZp_QhlQaGyTAyczWEgSyxxAejyRFFs0QUqFmrnpXpgUCAOOywEizObGkm1I3W9Lmhy1mxzo48e8kfr7XuDsoYonr1q/?imgmax=800" width="579" height="737" /></p> <p>What is missing above is a second column that I named “Cbv” that holds the magic salt. BTW: the column/index name <strong><font color="#0000ff" size="3">CBV</font></strong> stands for <strong><font color="#0000ff" size="3">C</font>ompacted <font color="#0000ff" size="3">B</font>inary <font color="#0000ff" size="3">V</font>iew</strong> which describes the kind of data stored in that column. CBV-data can be indexed using a simple Visual FoxPro <font color="#0000ff" face="Courier New"><strong>INDEX ON Cbv TAG ‘cbv’</strong></font> command to solve all our hierarchical ordering problems! <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smiley" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdITO_KtLxpAGpG7xr0mCDtmhcCZ5Ru2HAgRVmelkQGrehRf68NgIUoRHbvRCmgrOo_LGh3pauFnyHBWB1Idcdkzh0tchCVwaEXh_9ive438hDBc6U82AjV0uNEMMvnC2lmEOg/?imgmax=800" /> </p> <p>Before I show you the final implementation, here are some things one has to think about when dealing with VFP’s limited DBF-capacities: A CHAR field is limited in size to 254 (maximum), the size of a compound key is limited even more: 240 bytes is the maximum per index key, if the collating sequence is set to MACHINE. </p> <p>We could argue that it is easy to retain the correct sort order. We only have to use dimension values with leading zeros like so:</p> <table border="1" cellspacing="0" cellpadding="2" width="591"><tbody> <tr> <td valign="top" width="589">000000100.000000000.000000000.000000000.</td> </tr> <tr> <td valign="top" width="589">000000100.000000001.000000000.000000000.</td> </tr> <tr> <td valign="top" width="589">000000100.000000002.000000020.000000410.</td> </tr> <tr> <td valign="top" width="589">000000100.000000002.000000010.000000000.</td> </tr> <tr> <td valign="top" width="589">000000100.000000003.000000000.000000000.</td> </tr> </tbody></table> <p>Well, that is absolutely right! But, how many dimensions do we need to allocate and how many items should then be provided within each dimension? One upper boundary is our 240 bytes we cannot exceed due to FoxPro’s index limitation. Thus, if we reserve 9 bytes for each dimension plus the dimension delimiting dot, we would end up using 10 bytes per dimension. That means, that we have 24 dimensions with enough address space to reference 999,999,999,999 items within each dimension. Seen from a capacity view point only, the dimensions seem huge enough. But, using our regular decimal system in combination with leading zeros that have to fill up every place throughout all used records generates more difficulties than it solves. <br />Fist of all, there is a huge performance hit when dealing with larger record sets. Imagine we have over 100,000 TreeView records; then a new TreeView item has to be added to a dimension which then will become the one with the highest <strong>dimension width</strong> (a new deepest TreeView nesting level will be reached). All existing 100,000 TreeView records have to be touched to add a new dummy set of “000000000.” to their existing string.</p> <p> <table border="1" cellspacing="0" cellpadding="2" width="703"><tbody> <tr> <td valign="top" width="701">000000100.000000000.000000000.000000000.<strong>000000001. << adding  this one means:</strong></td> </tr> <tr> <td valign="top" width="701">000000100.000000001.000000000.000000000.<strong><font color="#400000">000000000. << add dummies to all others!</font></strong></td> </tr> <tr> <td valign="top" width="701">000000100.000000002.000000020.000000410.<strong><font color="#400000">000000000. << ditto.</font></strong></td> </tr> <tr> <td valign="top" width="701">000000100.000000002.000000010.000000000.<strong><font color="#400000">000000000.<strong><font color="#400000"><< ditto.</font> </strong></font></strong></td> </tr> <tr> <td valign="top" width="701">000000100.000000003.000000000.000000000.<strong><font color="#400000">000000000.<strong><font color="#400000"><< ditto.</font> </strong></font></strong></td> </tr> </tbody></table> </p> <p>Adding plus re-indexing renders this approach useless when running larger TreeViews. This technique is feasible only, if one is working with really small record sets, like in a Outlook scenario shown below:</p> <p><img style="background-image: none; border-right-width: 0px; margin: 6px 12px 6px 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Outlook's navigational TreeView" border="0" alt="Outlook's navigational TreeView" src="http://lh4.ggpht.com/_MOmDLu4Rm5Y/Tb9c91RZqtI/AAAAAAAAHgg/dxglhfvjVxE/6%5B4%5D.png?imgmax=800" width="341" height="362" /></p> <p>Such kind of Outlook-style TreeViews are not used to display bulky data sets, but are employed for pure menu navigation purposes only! Thus, they are pretty much static, seen from the <em>node count and ordering</em> point of view.</p> <h3><font style="font-weight: bold" color="#000080">The CBV Column</font></h3> <p>VFP brought us some cool functions and enhancements. Two of them are enhancements to the complementary CTOBIN() and BINTOC() functions. I do not want to re-type here what everyone can read in VFP’s help file about both function. Instead, I want to quote what is written in VFP’s help file in an additional chapter dealing with improved indexing support: </p> <hr /> <blockquote> <h4><strong><font color="#8080ff">Create Small Indexes Using BINTOC( ) Sample</font></strong></h4> <p><b>File:</b> ...\Samples\Solution\Db\Index1.scx</p> <p>This sample shows various indexing schemes you can use with numeric and integer data types to get significant savings in index size and disk space consumed. In addition, smaller sized indexes usually result in faster searches. The <b>BINTOC()</b> function makes it possible for you to convert an integer (numeric) value to a binary character representation.</p> <p><b>Syntax</b></p> <p>BINTOC(<i>nExpression</i> [, <i>nSize</i>])</p> <p>Depending on the size of your expression, you can set the <i>nSize</i> parameter to accommodate the value of your expression in the least amount of characters.</p> <p>The following line of code creates an index on a numeric field:</p> <p><font color="#0000ff" face="Courier New"><strong>INDEX on line_no TAG line_no</strong></font></p> <p>The next time you are working with indexes on numeric integer data, consider using something like the following:</p> <p><font color="#0000ff" face="Courier New"><strong>INDEX on BINTOC(line_no,1) TAG line_no</strong></font></p> </blockquote> <hr /> <p>After playing with both functions for a while (BTW: there is a very informative demo under VFP’s Task Pane >> Solution Samples >> New in Visual FoxPro 9.0 >> BINTOC binary conversion) I started coding some routines to help me creating binary compacted string representations of the dimension values of my Vector column. The following listing takes a readable Vector expression like <strong><em>454.42.753.146.8.1.77</em></strong> and returns a CBV value that can be used for hierarchical indexing:</p> <pre><strong><font size="2"><span style="color: #008000">***---------------------------------------------------------------------------</span>
<span style="color: #008000">*\\ Compact a "readable" VECTOR expression like 12.455.3.5566.1. into a</span>
<span style="color: #008000">*\\ compressed binary vector string (with fixed dimension blocksizes!)</span>
<span style="color: #0000ff">FUNCTION</span> CompressVector(tcVector <span style="color: #0000ff">AS</span> <span style="color: #0000ff">STRING</span>, tnBlockSize <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>) <span style="color: #0000ff">AS</span> <span style="color: #0000ff">STRING</span>
<span style="color: #008000">*\\ check input params</span>
<span style="color: #0000ff">IF</span> NOT <span style="color: #0000ff">VARTYPE</span>(m.tcValue) == "<span style="background-color: #ffff00; color: red">C</span>" OR <span style="color: #0000ff">EMPTY</span>(m.tcValue)
<span style="color: #0000ff">RETURN</span> "<span style="background-color: #ffff00; color: red"></span>" <span style="color: #008000">&& error condition</span>
<span style="color: #0000ff">ELSE</span>
<span style="color: #008000">*\\ Next line is necessary only if <tcVector>-data stems from a CHAR field </span>
<span style="color: #008000">*** tcVector = ALLTRIM(m.tcVector)</span>
<span style="color: #008000">*//</span>
<span style="color: #0000ff">ENDIF</span>
<span style="color: #008000">*\\ let block size default to MAX_BLOCKSIZE</span>
<span style="color: #0000ff">IF</span> NOT ( <span style="color: #0000ff">VARTYPE</span>(m.tnBlockSize) == "<span style="background-color: #ffff00; color: red">N</span>" AND <span style="color: #0000ff">INLIST</span>(m.tnBlockSize, 4, 8) )
tnBlockSize = MAX_BLOCKSIZE <span style="color: #008000">&& MAX_BLOCKSIZE == 8 at the moment<br /></span> <span style="color: #0000ff">ENDIF</span>
<span style="color: #008000">*//</span>
<span style="color: #0000ff">LOCAL</span> lnLoop <span style="color: #0000ff">AS</span> <span style="color: #0000ff">INTEGER</span> ,; <span style="color: #008000">&& local loop variable</span>
lcNewVector <span style="color: #0000ff">AS</span> <span style="color: #0000ff">STRING</span> <span style="color: #008000">&& local temprary string buffer </span>
lcNewVector = "<span style="background-color: #ffff00; color: red"></span>"
<span style="color: #008000">*// define a symbol HSORT_SEPARATOR ”.”</span>
<span style="color: #0000ff">FOR</span> lnLoop = 1 <span style="color: #0000ff">TO</span> <span style="color: #0000ff">OCCURS</span>(HSORT_SEPARATOR, m.tcVector)
lcNewVector = m.lcNewVector + ;
<span style="color: #0000ff">BINTOC</span>(<span style="color: #0000ff">INT</span>(<span style="color: #0000ff">VAL</span>(<span style="color: #0000ff">GETWORDNUM</span>(m.tcVector, m.lnLoop, HSORT_SEPARATOR))), "<span style="background-color: #ffff00; color: red">BRS</span>")
<span style="color: #0000ff">NEXT</span>
<span style="color: #0000ff">RETURN</span> m.lcNewVector
<span style="color: #0000ff">ENDFUNC</span></font></strong></pre>
<p>The code I’m posting here is limited in that it allows only a fixed block size of 8 bytes at the moment. In other words, to save some extra bytes, I do not store dots between each dimension data any longer but use a fixed block size (of 8 bytes) instead. The final version will support 4 bytes and 2 bytes as well.  The rule of thumb is: The less block size each dimension occupies, the more dimensions can be used to nest hierarchical (e.g. TreeView-) items. The following screenshot shows you the second <strong><em>Cbv</em></strong> column filled with: <font color="#0000ff" face="Courier New"><strong>REPLACE ALL Cbv WITH CompressVector(Vector)</strong></font> and then <font color="#0000ff" face="Courier New"><strong>INDEX ON Cbv TAG ‘Cbv’</strong></font>. Setting the order to <strong><em>Cbv</em></strong> afterwards results in the sorted browse like shown below:</p>
<p><img style="background-image: none; border-right-width: 0px; margin: 6px 12px 6px 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="The filled Cbv column" border="0" alt="The filled Cbv column" src="http://lh6.ggpht.com/_MOmDLu4Rm5Y/Tb9c-JJiswI/AAAAAAAAHgk/m7b7Y7zUUMo/HierarchicalTable004%5B3%5D.png?imgmax=800" width="606" height="740" /></p>
<p>There are some other interesting side effects:
<br />For instance, it is possible to drop the <em>Vector</em> column completely before starting digital delivery of your application. Okay, it is pretty easy to spot what kind of encryption is running behind the scenes. Anyway, there is no human readable numbering any longer, which is a better protection than none at all :-)
<br />With a second retrieval function (I called mine “DeCompressVector”) it is also possible to recreate the <strong><em>Vector</em></strong> column values from the <strong><em>Cbv</em></strong> column values. You will find all functions below (at the end of this post).
<br />Because the binary vector expressions are unique (due to the uniqueness of object identity) they can also be used as primary keys!</p>
</div>
<h3><font style="font-weight: bold" color="#000080">End of Part I</font></h3>
<div>
<p>This is the the end of my first part showing you how to setup a table to get sorted hierarchically on one column only! Keep in mind that there will be more supporting functions which will help us maintaining <strong><em>TreeView driving tables</em></strong> using a binary vector column like shown above. The most common scenarios that need to be supported are: </p>
</div>
</li>
<li>Inserting one or more items (creating table rows with appropriate <strong><em>Cbv</em></strong> values). </li>
<li>Deleting item(s). </li>
<li>Moving item(s). </li>
<li>Reorganizing driving table (re-indexing). </li>
<li>Re-creating (readable) Vector column entries, in case they were dropped.
<p>In addition to that there will be even more functions to support specific TreeView behavior like expanding/collapsing branches and other things. </p>
<p><img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-sun" alt="Sonne" src="http://lh4.ggpht.com/_MOmDLu4Rm5Y/Tb9c-hBeRRI/AAAAAAAAHgo/oskVR8Nbyp0/wlEmoticon-sun%5B2%5D.png?imgmax=800" /> <font color="#f79646" size="3"><strong>Happy coding </strong></font></p>
<hr />
<h3><font color="#000080"><font style="font-weight: bold">The X-Files</font></font></h3>
<pre><strong><span style="color: #0000ff">SET</span> <span style="color: #0000ff">PROCEDURE</span> <span style="color: #0000ff">TO</span> (<span style="color: #0000ff">SYS</span>(16)) <span style="color: #0000ff">ADDITIVE</span>
<span style="color: #0000ff">RETURN</span>
<span style="color: #008000">*\\ ***************** //* </span>
<span style="color: #008000">*** ***************** ***</span>
<span style="color: #008000">*** HierachicSort.prg ***</span>
<span style="color: #008000">*** ***************** ***</span>
<span style="color: #008000">*// ***************** //*</span>
#<span style="color: #0000ff">DEFINE</span> HSORT_SEPARATOR "<span style="background-color: #ffff00; color: red">.</span>"
#<span style="color: #0000ff">DEFINE</span> MAX_BLOCKSIZE 8
#<span style="color: #0000ff">IF</span> .F. <span style="color: #008000">&& ===================================================================</span>
</strong><strong><font color="#000000">MAX_BLOCKSIZE represents the maximum <span style="color: #0000ff">number</span> <span style="color: #0000ff">of</span> bytes it takes <span style="color: #0000ff">to</span>
<span style="color: #0000ff">compress</span> one <span style="color: #0000ff">dimension</span> <span style="color: #0000ff">value</span> <span style="color: #0000ff">of</span> a given VECTOR-<span style="color: #0000ff">Expression</span>. <span style="color: #0000ff">At</span> the moment
(within Visual FoxPro) MAX_BLOCKSIZE MUST BE an 8 bytes <span style="color: #0000ff">Character</span> <span style="color: #0000ff">expression</span>
<span style="color: #0000ff">for</span> <span style="color: #0000ff">CTOBIN</span>() using "</font></strong><span style="background-color: #ffff00; color: red"></span><span style="background-color: #ffff00; color: red"></span><span style="background-color: #ffff00; color: red">N..</span><span style="background-color: #ffff00; color: red"></span>"<strong><font color="#000000"> </font></strong><strong><font color="#000000"><span style="color: #0000ff">as</span> the 2nd parameter <span style="color: #0000ff">to</span> work correctly.
The <span style="color: #0000ff">BlockSize</span> setting <span style="color: #0000ff">is</span> <span style="color: #0000ff">set</span> <span style="color: #0000ff">for</span> <span style="color: #0000ff">ALL</span> <span style="color: #0000ff">Dimension</span>. <span style="color: #0000ff">In</span> other words:
One CANNOT mix 1, 2, 4 and 8 bit dimensions!
The <span style="color: #0000ff">compact</span> <span style="color: #0000ff">index</span> (.<span style="color: #0000ff">cdx</span>) we <span style="color: #0000ff">use</span> <span style="color: #0000ff">for</span> hierachial sorting has a maximum <span style="color: #0000ff">width</span>
<span style="color: #0000ff">of</span> 240 caracters. Thus, we can <span style="color: #0000ff">store</span> vectors <span style="color: #0000ff">with</span> up <span style="color: #0000ff">to</span> 30 dimensions using
an 8-bytes <span style="color: #0000ff">width</span> (30 <span style="color: #008000">* 8 = 240) or 60 dimensions using a 4-bytes width</span>
accordingly. The highest scalar <span style="color: #0000ff">dimension</span> <span style="color: #0000ff">value</span> that can be compresses <span style="color: #0000ff">into</span>
8 bytes <span style="color: #0000ff">is</span> (15 places) which <span style="color: #0000ff">is</span> 999,999,999,999,999 => 999 trillions!
BTW:
9,007,199,254,740,992 <span style="color: #0000ff">is</span> VFP'<span style="background-color: #ffff00; color: red">s mamimum digits of precision in NUMERIC </span>
computations (16 digits).
<span style="color: #0000ff">In</span> other words: <span style="color: #0000ff">At</span> the moment we are able <span style="color: #0000ff">to</span> handle VECTOR-<span style="color: #0000ff">Expression</span> up <span style="color: #0000ff">to</span>
30 dimensions <span style="color: #0000ff">with</span> <span style="color: #0000ff">each</span> <span style="color: #0000ff">dimension</span> holding up <span style="color: #0000ff">to</span> 999999999999999 possible
sub-dimensions or nodes!</font>
#<span style="color: #0000ff">ENDIF</span> <span style="color: #008000">&& ===================================================================</span>
<span style="color: #008000">***---------------------------------------------------------------------------</span>
<span style="color: #008000">*\\ Compress a given string/numeric value</span>
<span style="color: #008000">*\\ Parameter checking and function overloading</span>
<span style="color: #0000ff">FUNCTION</span> <span style="color: #0000ff">Compress</span>(teValue <span style="color: #0000ff">AS</span> VARIANT) <span style="color: #0000ff">AS</span> <span style="color: #0000ff">STRING</span>
<span style="color: #008000">*\\ the largest <teValue> integer value is 999999999999999</span>
<span style="color: #0000ff">IF</span> <span style="color: #0000ff">VARTYPE</span>(m.teValue) == "<span style="background-color: #ffff00; color: red">N</span>"
<span style="color: #0000ff">IF</span> m.teValue > 999999999999999
<span style="color: #008000">*\\ error condition</span>
<span style="color: #0000ff">RETURN</span> "<span style="background-color: #ffff00; color: red"></span>"
<span style="color: #0000ff">ELSE</span>
<span style="color: #008000">*\\ call implementation</span>
<span style="color: #0000ff">RETURN</span> CompressNumber(m.teValue)
<span style="color: #0000ff">ENDIF</span>
<span style="color: #0000ff">ELSE</span>
<span style="color: #0000ff">IF</span> <span style="color: #0000ff">VARTYPE</span>(m.teValue) == "<span style="background-color: #ffff00; color: red">C</span>" AND NOT <span style="color: #0000ff">EMPTY</span>(m.teValue)
<span style="color: #008000">*\\ the largest <teValue> string value is >999999999999999<</span>
<span style="color: #0000ff">IF</span> m.teValue > "<span style="background-color: #ffff00; color: red">999999999999999</span>"
<span style="color: #008000">*\\ error condition</span>
<span style="color: #0000ff">RETURN</span> "<span style="background-color: #ffff00; color: red"></span>"
<span style="color: #0000ff">ELSE</span>
<span style="color: #008000">*\\ call implementation</span>
<span style="color: #0000ff">RETURN</span> CompressString(<span style="color: #0000ff">ALLTRIM</span>(m.teValue))
<span style="color: #0000ff">ENDIF</span>
<span style="color: #0000ff">ELSE</span>
<span style="color: #008000">*\\ error condition</span>
<span style="color: #0000ff">RETURN</span> "<span style="background-color: #ffff00; color: red"></span>"
<span style="color: #0000ff">ENDIF</span>
<span style="color: #0000ff">ENDIF</span>
<span style="color: #0000ff">ENDFUNC</span>
<span style="color: #008000">***---------------------------------------------------------------------------</span>
<span style="color: #008000">*\\ Compress a given string (compress() function overload#1)</span>
<span style="color: #0000ff">FUNCTION</span> CompressString(tcValue <span style="color: #0000ff">AS</span> <span style="color: #0000ff">STRING</span>) <span style="color: #0000ff">AS</span> <span style="color: #0000ff">STRING</span>
<span style="color: #008000">*\\ Do the job w/o parameter testing</span>
<span style="color: #0000ff">RETURN</span> <span style="color: #0000ff">BINTOC</span>(<span style="color: #0000ff">INT</span>(<span style="color: #0000ff">VAL</span>(m.tcValue)), "<span style="background-color: #ffff00; color: red">BRS</span>")
<span style="color: #008000">*//</span>
<span style="color: #0000ff">ENDFUNC</span>
<span style="color: #008000">***---------------------------------------------------------------------------</span>
<span style="color: #008000">*\\ Compress a given number (compress() function overload#2)</span>
<span style="color: #0000ff">FUNCTION</span> CompressNumber(tnValue <span style="color: #0000ff">AS</span> <span style="color: #0000ff">NUMBER</span>) <span style="color: #0000ff">AS</span> <span style="color: #0000ff">STRING</span>
<span style="color: #008000">*\\ Do the job w/o parameter testing</span>
<span style="color: #0000ff">RETURN</span> <span style="color: #0000ff">BINTOC</span>(m.tnValue, "<span style="background-color: #ffff00; color: red">BRS</span>")
<span style="color: #008000">*//</span>
<span style="color: #0000ff">ENDFUNC</span>
<span style="color: #008000">***---------------------------------------------------------------------------</span>
<span style="color: #008000">*\\ Decompress a given (compacted) binary string value</span>
<span style="color: #0000ff">FUNCTION</span> DeCompress(tcValue <span style="color: #0000ff">AS</span> <span style="color: #0000ff">STRING</span>, tnBlockSize <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>) <span style="color: #0000ff">AS</span> <span style="color: #0000ff">STRING</span>
<span style="color: #008000">*\\ check input params</span>
<span style="color: #0000ff">IF</span> NOT <span style="color: #0000ff">VARTYPE</span>(m.tcValue) == "<span style="background-color: #ffff00; color: red">C</span>" OR <span style="color: #0000ff">EMPTY</span>(m.tcValue)
<span style="color: #0000ff">RETURN</span> "<span style="background-color: #ffff00; color: red"></span>" <span style="color: #008000">&& error condition</span>
<span style="color: #0000ff">ENDIF</span>
<span style="color: #008000">*\\ let block size default to MAX_BLOCKSIZE</span>
<span style="color: #0000ff">IF</span> NOT ( <span style="color: #0000ff">VARTYPE</span>(m.tnBlockSize) == "<span style="background-color: #ffff00; color: red">N</span>" AND <span style="color: #0000ff">INLIST</span>(m.tnBlockSize, 4, 8) )
tnBlockSize = MAX_BLOCKSIZE <span style="color: #008000">&& MAX_BLOCKSIZE always == 8 in VFP</span>
<span style="color: #0000ff">ENDIF</span>
<span style="color: #008000">*//</span>
<span style="color: #0000ff">IF</span> <span style="color: #0000ff">LEN</span>(m.tcValue) = m.tnBlockSize
<span style="color: #0000ff">RETURN</span> DeCompressValue(m.tcValue)
<span style="color: #0000ff">ELSE</span>
<span style="color: #0000ff">IF</span> <span style="color: #0000ff">LEN</span>(m.tcValue) <= m.tnBlockSize
<span style="color: #0000ff">RETURN</span> DeCompressValue(<span style="color: #0000ff">PADR</span>(m.tcValue, m.tnBlockSize, <span style="color: #0000ff">CHR</span>(0)))
<span style="color: #0000ff">ELSE</span>
<span style="color: #0000ff">RETURN</span> DeCompressValue(<span style="color: #0000ff">LEFT</span>(m.tcValue, m.tnBlockSize))
<span style="color: #0000ff">ENDIF</span>
<span style="color: #0000ff">ENDIF</span>
<span style="color: #008000">*//</span>
<span style="color: #0000ff">ENDFUNC</span>
<span style="color: #008000">***---------------------------------------------------------------------------</span>
<span style="color: #008000">*\\ Decompress() standard implementation</span>
<span style="color: #0000ff">FUNCTION</span> DeCompressValue(tcValue <span style="color: #0000ff">AS</span> <span style="color: #0000ff">STRING</span>) <span style="color: #0000ff">AS</span> <span style="color: #0000ff">STRING</span>
<span style="color: #008000">*\\ parameter checking is done in ExpandValue()</span>
<span style="color: #0000ff">RETURN</span> <span style="color: #0000ff">TRANSFORM</span>(<span style="color: #0000ff">INT</span>(<span style="color: #0000ff">CTOBIN</span>(m.tcValue, "<span style="background-color: #ffff00; color: red">NRS</span>")))
<span style="color: #008000">*//</span>
<span style="color: #0000ff">ENDFUNC</span>
<span style="color: #008000">***---------------------------------------------------------------------------</span>
<span style="color: #008000">*\\ Compact a "readable" VECTOR expression like 12.455.3.5566.1. into a</span>
<span style="color: #008000">*\\ compressed binary vector string (with fixed dimension blocksizes!)</span>
<span style="color: #0000ff">FUNCTION</span> CompressVector(tcVector <span style="color: #0000ff">AS</span> <span style="color: #0000ff">STRING</span>, tnBlockSize <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>) <span style="color: #0000ff">AS</span> <span style="color: #0000ff">STRING</span>
<span style="color: #008000">*\\ check input params</span>
<span style="color: #0000ff">IF</span> NOT <span style="color: #0000ff">VARTYPE</span>(m.tcValue) == "<span style="background-color: #ffff00; color: red">C</span>" OR <span style="color: #0000ff">EMPTY</span>(m.tcValue)
<span style="color: #0000ff">RETURN</span> "<span style="background-color: #ffff00; color: red"></span>" <span style="color: #008000">&& error condition</span>
<span style="color: #0000ff">ELSE</span>
<span style="color: #008000">*\\ Next line is necessary only if <tcVector>-data stems from a CHAR field </span>
<span style="color: #008000">*** tcVector = ALLTRIM(m.tcVector)</span>
<span style="color: #008000">*//</span>
<span style="color: #0000ff">ENDIF</span>
<span style="color: #008000">*\\ let block size default to MAX_BLOCKSIZE</span>
<span style="color: #0000ff">IF</span> NOT ( <span style="color: #0000ff">VARTYPE</span>(m.tnBlockSize) == "<span style="background-color: #ffff00; color: red">N</span>" AND <span style="color: #0000ff">INLIST</span>(m.tnBlockSize, 4, 8) )
tnBlockSize = MAX_BLOCKSIZE <span style="color: #008000">&& MAX_BLOCKSIZE always == 8 in VFP</span>
<span style="color: #0000ff">ENDIF</span>
<span style="color: #008000">*//</span>
<span style="color: #0000ff">LOCAL</span> lnLoop <span style="color: #0000ff">AS</span> <span style="color: #0000ff">INTEGER</span> ,; <span style="color: #008000">&& local loop variable</span>
lcNewVector <span style="color: #0000ff">AS</span> <span style="color: #0000ff">STRING</span> <span style="color: #008000">&& local temprary string buffer </span>
lcNewVector = "<span style="background-color: #ffff00; color: red"></span>"
<span style="color: #008000">*//</span>
<span style="color: #0000ff">FOR</span> lnLoop = 1 <span style="color: #0000ff">TO</span> <span style="color: #0000ff">OCCURS</span>(HSORT_SEPARATOR, m.tcVector)
lcNewVector = m.lcNewVector + ;
<span style="color: #0000ff">BINTOC</span>(<span style="color: #0000ff">INT</span>(<span style="color: #0000ff">VAL</span>(<span style="color: #0000ff">GETWORDNUM</span>(m.tcVector, m.lnLoop, HSORT_SEPARATOR))), "<span style="background-color: #ffff00; color: red">BRS</span>")
<span style="color: #0000ff">NEXT</span>
<span style="color: #0000ff">RETURN</span> m.lcNewVector <span style="color: #008000">&& + "."</span>
<span style="color: #0000ff">ENDFUNC</span>
<span style="color: #008000">***---------------------------------------------------------------------------</span>
<span style="color: #008000">*\\ Expand a compressed (binary) VECTOR string into a "readable" VECTOR</span>
<span style="color: #008000">*\\ expression like 12.455.3.5566.1.</span>
<span style="color: #0000ff">FUNCTION</span> DeCompressVector(tcExpression <span style="color: #0000ff">AS</span> <span style="color: #0000ff">STRING</span>, tnBlockSize <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>) <span style="color: #0000ff">AS</span> <span style="color: #0000ff">STRING</span>
<span style="color: #008000">*\\ check input params</span>
<span style="color: #0000ff">IF</span> NOT <span style="color: #0000ff">VARTYPE</span>(m.tcExpression) == "<span style="background-color: #ffff00; color: red">C</span>" OR <span style="color: #0000ff">EMPTY</span>(m.tcExpression)
<span style="color: #0000ff">RETURN</span> "<span style="background-color: #ffff00; color: red"></span>" <span style="color: #008000">&& error condition</span>
<span style="color: #0000ff">ENDIF</span>
<span style="color: #008000">*\\ default block size to max block size</span>
<span style="color: #0000ff">IF</span> NOT ( <span style="color: #0000ff">VARTYPE</span>(m.tnBlockSize) == "<span style="background-color: #ffff00; color: red">N</span>" AND <span style="color: #0000ff">INLIST</span>(m.tnBlockSize, 4, 8) )
tnBlockSize = MAX_BLOCKSIZE <span style="color: #008000">&& MAX_BLOCKSIZE is always 8 in VFP</span>
<span style="color: #0000ff">ENDIF</span>
<span style="color: #008000">*//</span>
<span style="color: #0000ff">LOCAL</span> lnLoop <span style="color: #0000ff">AS</span> <span style="color: #0000ff">INTEGER</span> ,; <span style="color: #008000">&& local loop variable</span>
lcNewVector <span style="color: #0000ff">AS</span> <span style="color: #0000ff">STRING</span> <span style="color: #008000">&& local temprary string buffer</span>
lcNewVector = "<span style="background-color: #ffff00; color: red"></span>"
<span style="color: #008000">*//</span>
<span style="color: #0000ff">FOR</span> lnLoop = 0 <span style="color: #0000ff">TO</span> ( <span style="color: #0000ff">LEN</span>(tcExpression) / m.tnBlockSize ) - 1
m.lcValue = <span style="color: #0000ff">SUBSTR</span>(m.tcExpression, m.lnLoop <span style="color: #008000">* m.tnBlockSize + 1, m.tnBlockSize)</span>
lcNewVector = m.lcNewVector + ;
<span style="color: #0000ff">TRANSFORM</span>(<span style="color: #0000ff">INT</span>(<span style="color: #0000ff">CTOBIN</span>( ;
<span style="color: #0000ff">SUBSTR</span>(m.tcExpression, m.lnLoop <span style="color: #008000">* m.tnBlockSize + 1, m.tnBlockSize),;</span>
"<span style="background-color: #ffff00; color: red">NRS</span>"))) + "<span style="background-color: #ffff00; color: red">.</span>"
<span style="color: #0000ff">NEXT</span>
<span style="color: #0000ff">RETURN</span> m.lcNewVector
<span style="color: #0000ff">ENDFUNC</span></strong></pre>
<hr /><a title="http://myvfpblog.blogspot.com/2011/04/loadpicture-functionsome-myths-revealed.html" href="http://myvfpblog.blogspot.com/2011/04/loadpicture-functionsome-myths-revealed.html"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Previous Entry" border="0" alt="Previous Entry" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnb0BSjS5xd-9GoDA7uRvkMTL1gQUBce6c1COnH1Hv-2dnLED7h_FU-aOs2xBXqtFutPneS0Ajy10seHuSCpxOnC1haiyKVe9DepSTCdkCbLXK1ijqPPfkK9WmxTs5CJb1nSsK/?imgmax=800" width="48" height="64" /></a><a title="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-tips-tricks-in-this.html" href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-tips-tricks-in-this.html"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Tips & Trics Home (TOC)" border="0" alt="Tips & Trics Home (TOC)" src="http://lh6.ggpht.com/-JviBkwZoMjE/Tl4qmc0CMjI/AAAAAAAAHlE/8rfM1PIE0EU/NavHome_48_RGBA%25255B6%25255D.png?imgmax=800" width="48" height="64" /></a><a title="http://myvfpblog.blogspot.com/2011/05/cool-vfp-event-binding.html" href="http://myvfpblog.blogspot.com/2011/05/cool-vfp-event-binding.html"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Next Entry" border="0" alt="Next Entry" src="http://lh4.ggpht.com/-Jprh9MD6ir4/Tl4qm2sSn_I/AAAAAAAAHlQ/W-5BSCVrrWY/NavForward_48_RGBA%25255B3%25255D.png?imgmax=800" width="48" height="64" /></a>
</li> Burkhardhttp://www.blogger.com/profile/11631168041975170500noreply@blogger.com6tag:blogger.com,1999:blog-26167158.post-39067114732039106052011-04-30T15:42:00.000+02:002011-04-30T16:55:04.168+02:00Bruno - My RR (Rhodesian Ridgeback)<p><strong><font color="#ff8040">Version: 1.00.01 - last update: Saturday, April 30, 2011, 16:50:00</font></strong></p> <p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Previous Entry" border="0" alt="Previous Entry" src="http://lh4.ggpht.com/_MOmDLu4Rm5Y/Tbwg-1eQQ7I/AAAAAAAAHeE/TCO2VI9JvYU/NavBack_48_RGBA%5B2%5D.png?imgmax=800" width="48" height="64" /><a title="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-miscellaneous-diverse.html" href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-miscellaneous-diverse.html"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Miscellaneous Home (TOC)" border="0" alt="Miscellaneous Home (TOC)" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdf0-CmHRqNRZjrJqPWHjc-rbkxtgTe946HM5fW70EwWuV8iNAZVtop6pP2OPaBLKPcUbmbugdnpUjLyzrOVyBEEBnZfky9BtUISEjo4IPVD-9Hf4eRyBYvTSvgZoT43DjOvC8/?imgmax=800" width="48" height="64" /></a><a title="http://myvfpblog.blogspot.com/2008/02/got-seek-you-v6-installed.html" href="http://myvfpblog.blogspot.com/2008/02/got-seek-you-v6-installed.html"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Next Entry" border="0" alt="Next Entry" src="http://lh6.ggpht.com/_MOmDLu4Rm5Y/Tbwg_SgUdrI/AAAAAAAAHeM/PeL8bQSpBnQ/NavForward_48_RGBA%5B7%5D.png?imgmax=800" width="48" height="64" /></a> </p> <hr /> <p><font color="#0000ff" size="2"><strong>Everybody should have one <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Zwinkerndes Smiley" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJaUrt8x5yf_nF8cppfsj4a3t2WydRiShuBYx5yQMGaBVQ2uxvWkI_YIVSegl00sceOIFQpf_EFi7Kl-R9xTRt_Lkejf2X_6FwvPaQ0TqSuP_08pCPNJib6N7pyfS5TX_eX2U4/?imgmax=800" />  </strong></font></p> <p><font color="#0000ff" size="2"><strong>Let me introduce to you, BRUNO, my four years old RR boy <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smiley" src="http://lh5.ggpht.com/_MOmDLu4Rm5Y/Tbwclm4Wz9I/AAAAAAAAHcc/kkhX2Ffxv4Y/wlEmoticon-smile%5B2%5D.png?imgmax=800" /></strong></font></p> <p><img style="background-image: none; border-right-width: 0px; margin: 6px 11px 6px 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Attentive" border="0" alt="Attentive" src="http://lh5.ggpht.com/_MOmDLu4Rm5Y/TbwcmfdXvII/AAAAAAAAHcg/PFrnGLN7w6c/Bruno_Wohnzimmer_Kronenstrasse%5B37%5D.jpg?imgmax=800" width="800" height="1067" /></p> <p><img style="background-image: none; border-right-width: 0px; margin: 6px 12px 6px 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Bruno with tooth-brush" border="0" alt="Bruno with tooth-brush" src="http://lh3.ggpht.com/_MOmDLu4Rm5Y/TbwcnbA5cBI/AAAAAAAAHck/Y2SPgiQP30Y/Bruno_Spielzeug_im_Maul%5B19%5D.jpg?imgmax=800" width="800" height="1421" /></p> <p><img style="background-image: none; border-right-width: 0px; margin: 6px 12px 6px 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Bruno on sofa" border="0" alt="Bruno on sofa" src="http://lh6.ggpht.com/_MOmDLu4Rm5Y/TbwcnopjZuI/AAAAAAAAHco/cIcf3pcOcJo/Bruno_Sofa_Kronenstrasse%5B12%5D.jpg?imgmax=800" width="800" height="450" /></p> <p><img style="background-image: none; border-right-width: 0px; margin: 6px 12px 6px 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Watch out!" border="0" alt="Watch out!" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3TEhQNpoXMYnXOkQhYMybLX54D3Cyx2OHF0luuzXwf_Q7jmgJ4ICrL3myVpGiqCwdmSTvxklnLW3GXnL2lSVMM1K36l4iVvQ4D9NSjV_B1SMWiRC6YVE3R0M817rc-ojH3lPS/?imgmax=800" width="800" height="1065" /></p> <p><img style="background-image: none; border-right-width: 0px; margin: 6px 12px 6px 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Bruno the black-nose Reindeer" border="0" alt="Bruno the black-nose Reindeer" src="http://lh6.ggpht.com/_MOmDLu4Rm5Y/TbwcpTbcWDI/AAAAAAAAHcw/Lo3FEzG8dCU/Bruno_Elchgeweih%5B12%5D.jpg?imgmax=800" width="800" height="1067" /></p> <p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Contemplative" border="0" alt="Contemplative" src="http://lh3.ggpht.com/_MOmDLu4Rm5Y/TbwcqL-CD9I/AAAAAAAAHc0/gXC5p_hXlPM/Bruno_Strandkorb_1085%5B21%5D.jpg?imgmax=800" width="800" height="1065" /></p> <p><img style="background-image: none; border-right-width: 0px; margin: 6px 12px 6px 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Power Nap" border="0" alt="Power Nap" src="http://lh5.ggpht.com/_MOmDLu4Rm5Y/TbwcqrYSuiI/AAAAAAAAHc4/t6nSkXWGJYA/Bruno_Zimmer_Sylt_2009_1121%5B13%5D.jpg?imgmax=800" width="800" height="601" /></p> <p><img style="background-image: none; border-right-width: 0px; margin: 6px 12px 6px 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Bruno is watching you!" border="0" alt="Bruno is watching you!" src="http://lh5.ggpht.com/_MOmDLu4Rm5Y/TbwcrHIoOVI/AAAAAAAAHc8/eoCoJGZWPuI/Bruno_Liege_S%C3%BCrdring%5B14%5D.jpg?imgmax=800" width="800" height="601" /></p> <p><img style="background-image: none; border-right-width: 0px; margin: 6px 12px 6px 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Let sleeping dogs lie!" border="0" alt="Let sleeping dogs lie!" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEio1fF9KNW7r9Rmi9-1TZdWfhHuwv9w9hSQeQySKz7yx3Xov9zIAfqremfRQ2-DEVKZM0fTDfhMqTRl_sLz-ETItIJu9-qmEcMcNxnUpcNi12lKorvsJbFp5nPwLk7scOynuhU_/?imgmax=800" width="800" height="601" /></p> <p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="How to leash a dog" border="0" alt="How to leash a dog" src="http://lh6.ggpht.com/_MOmDLu4Rm5Y/TbwcsQHU1mI/AAAAAAAAHdE/2au3_FuT5GI/Bruno_Petra_Bl%C3%BChender_Baum%5B12%5D.jpg?imgmax=800" width="800" height="601" /></p> <p><img style="background-image: none; border-right-width: 0px; margin: 6px 12px 6px 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Baby you can drive my car" border="0" alt="Baby you can drive my car" src="http://lh4.ggpht.com/_MOmDLu4Rm5Y/Tbwcszf8s3I/AAAAAAAAHdI/IKkGQOTjuDA/Bruno_Petra_im_Beetle%5B12%5D.jpg?imgmax=800" width="800" height="600" /></p> <hr /> <p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Previous Entry" border="0" alt="Previous Entry" src="http://lh6.ggpht.com/_MOmDLu4Rm5Y/Tbwg_o2j1CI/AAAAAAAAHeQ/_E2U0Cj3TH0/NavBack_48_RGBA%5B5%5D.png?imgmax=800" width="48" height="64" /><a title="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-miscellaneous-diverse.html" href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-miscellaneous-diverse.html"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Miscellaneous Home (TOC)" border="0" alt="Miscellaneous Home (TOC)" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5iZu4ZyKu5iPiYLcVbeh1ijTKSDCDlIGLFfQA8yOUnnQ8dfe8BZ3xegf1pui2huOSBcBuHDHpMmNmUmZzQu7SDbCXEdLe-50grllC39GSs7p_hJ-38HdsubWceRpyhyphenhyphen0VmDFS/?imgmax=800" width="48" height="64" /></a><a title="http://myvfpblog.blogspot.com/2008/02/got-seek-you-v6-installed.html" href="http://myvfpblog.blogspot.com/2008/02/got-seek-you-v6-installed.html"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Next Entry" border="0" alt="Next Entry" src="http://lh6.ggpht.com/_MOmDLu4Rm5Y/TbwhANBN8TI/AAAAAAAAHeY/C1inG7N_wig/NavForward_48_RGBA%5B6%5D.png?imgmax=800" width="48" height="64" /></a></p> Burkhardhttp://www.blogger.com/profile/11631168041975170500noreply@blogger.com0tag:blogger.com,1999:blog-26167158.post-85918553531094391042011-04-29T22:10:00.000+02:002014-07-23T19:20:17.623+02:00<p><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-toolbox-in-this-section.html"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Toolbox Home" border="0" alt="Toolbox Home" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNUuzRWdo17aAIgpXNrroXdClNuO_wbO9Ak9mKtrNggEdhuEB4gbDbxrKATY9MEHThEi0Tq-JEauSOblCUeHwpgZxN7bv-NNS2tp0aBzHySnTALLFcC7fv1Jy2hXLZGDClWu_c/?imgmax=800" width="32" height="43" /></a><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-complex-controls-no.html"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Complex Controls Home" border="0" alt="Complex Controls Home" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGhfWbEyIBJgMKvelCE_wZKDM7XIzwJC4es_nRlinZFL7mo1zVSIXr0Qcv5Nq14bNkNy8xx0M3QA7sN5UQhyphenhyphenc3tSbSi-iSJci0wumsYIsFbCYYUUMmdr8HEdTBlF8TqVQBXUs0/?imgmax=800" width="48" height="64" /></a><a href="http://myvfpblog.blogspot.com/2009/09/neat-solutions-home.html"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Neat Solutions Home" border="0" alt="Neat Solutions Home" src="http://lh6.ggpht.com/_MOmDLu4Rm5Y/SsIFgnbJ5SI/AAAAAAAACAw/Yu_ZfEIrkkI/Home_64_RGBA%5B1%5D.png?imgmax=800" width="64" height="85" /></a><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-foxtools.html"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Foxtools Home" border="0" alt="Foxtools Home" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1-QL57-IkA9mbUPawjOmcZhkjYP56Ypr5PNF5r22f896yREuMKBqn0KgABCmqQc74lrFu9mT011TrAFTs-KPE1sio1hRnJ7eJUdbCJqNHQ6JntehlGDHNtvzn4K0Y7fJ2fgvZ/?imgmax=800" width="72" height="96" /></a><a href="http://myvfpblog.blogspot.com/2009/09/foxquill-more-than-framework-foxquill.html"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="FoxQuill Home" border="0" alt="FoxQuill Home" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjftiuvGAjTbt4oCsxjU0CtiqgARwpvOHDI0rFj3CAitaC-XaoHHHcupZsqMEMIyUjAPF0AqllhsnuNkT9XazFdoKJM7ixTbzz9IHLvJtsUtMEbBvII0ig8IbsoapNKLuBzyaWk/?imgmax=800" width="96" height="128" /></a><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="VFPX Projects Home" border="0" alt="VFPX Projects Home" src="http://lh3.ggpht.com/_MOmDLu4Rm5Y/SsIFiGBYjpI/AAAAAAAAC1o/MlTG0eXB_s4/Home_128_RGBA%5B1%5D.png?imgmax=800" width="160" height="160" /><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-miscellaneous-diverse.html"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Miscellaneous Home" border="0" alt="Miscellaneous Home" src="http://lh6.ggpht.com/_MOmDLu4Rm5Y/SsIFiRZqzSI/AAAAAAAAB7w/aHFU_ny9ZiQ/Home_96_RGBA%5B4%5D.png?imgmax=800" width="96" height="128" /></a><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-windows-api-calling.html"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Windows API Home" border="0" alt="Windows API Home" src="http://lh5.ggpht.com/_MOmDLu4Rm5Y/SsIFirxEoVI/AAAAAAAAB70/LEfWHlE0J1g/Home_72_RGBA%5B4%5D.png?imgmax=800" width="72" height="96" /></a><a href="http://myvfpblog.blogspot.com/2009/09/latest-news-this-section-of-my-vfp-blog.html"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="News Home" border="0" alt="News Home" src="http://lh5.ggpht.com/_MOmDLu4Rm5Y/SsIFjNraTEI/AAAAAAAAB74/LBFAxy7dsVo/Home_64_RGBA%5B4%5D.png?imgmax=800" width="64" height="85" /></a><a href="http://myvfpblog.blogspot.com/2009/09/basics-home.html"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Basics Home" border="0" alt="Basics Home" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPnizox6c8x8C_-iZRy9smcCFQYgmjarLVZUc3CeU7llt7hiTGfqQQBVWF125MD1OaQzP15MbsBvmpX979-HGjEA-dzkfxc3eiHBC2CNjsjf8Jc93wJfETuzS7caiy1xfcVZTx/?imgmax=800" width="48" height="64" /></a><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-tips-tricks-in-this.html"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Tips&Tricks Home" border="0" alt="Tips&Tricks Home" src="http://lh6.ggpht.com/_MOmDLu4Rm5Y/SsIFjvKBMgI/AAAAAAAAB8A/J3QAF9BpzsA/Home_32_RGBA%5B4%5D.png?imgmax=800" width="32" height="43" /></a></p> <hr /> <h1><strong><font color="#ee2d14"><a title="http://vfpx.codeplex.com/" href="http://vfpx.codeplex.com/" target="_blank"><img style="border-right-width: 0px; margin: 0px 5px 0px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" align="left" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3WEF0MkkvdZLKtjdPHaX2SlRF4h6ViWKwmXeJumlJA1yKbapVouaSFqbs3uuqq6QpnyVuksr6UvoLDTDIZj1IJxjDhcneXxyXsWidVXCRAzwLvp4auoJI1o-fQBDH2IP70VFm/s214/vfpxbanner.gif" width="243" height="106" /></a>VFPX Projects</font></strong></h1> <h4><strong><font color="#ff0000">This section holds topics dealing with VFPX projects – existing and maybe some future ones…</font></strong></h4> <p>There are very cool tools, add-ons and other smart gizmos written in VFP (or even using C/C++) to enhance Visual FoxPro available for free download on <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="OffSiteLink" border="0" alt="OffSiteLink" src="http://lh4.ggpht.com/_MOmDLu4Rm5Y/TbsQ7naGFjI/AAAAAAAAHbI/IYsyDF0POPc/OffSiteLink%5B2%5D.gif?imgmax=800" width="11" height="7" /> <a title="http://vfpx.codeplex.com/" href="http://vfpx.codeplex.com/" rel="nofollow" target="_blank">VFPX</a>. The VFP community is still alive and agile! Some of the cool tools are designed to speed up development, others can be built into one’s own applications to add some sophisticated functionality at runtime. What’s still missing is some kind of an overall picture – a path to follow while designing and implementing all kind of VFPX add-ons, either design-time, or run-time related ones! I’m not the guru who can tell the one and only truth about such a “mission to mars”; I don’t even come close! In addition, I must admit that some years passed by since I tried to use some VFPX add-ons in my own applications the last time. What I do have instead is, enough experience what’s best not to do with VFP  <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Zwinkerndes Smiley" src="http://lh5.ggpht.com/_MOmDLu4Rm5Y/TbsQ8NsdxzI/AAAAAAAAHbM/0Ci2xgptErA/wlEmoticon-winkingsmile%5B2%5D.png?imgmax=800" /></p> <p> <br />This section will be the place to read about VFPX projects I was working with and, sometimes, contributed to. As usual I start without a precisely predefined layout. I hope, some fine day a golden thread will appear of its own volition ;-)</p> <p> </p> <p><img style="background-image: none; border-right-width: 0px; margin: 0px 6px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Home_24_RGBA" border="0" alt="Home_24_RGBA" align="left" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtRSblTRS1632RYYwUJ7rdKiJVVSMC4fWrU_4_YEf0Ab2kwrO7-LX4slq4Yixq2xmupF_JnUKWsT-mbSE6EcPr5tuGTpLfeU0QS9ti9pXLReSW75QIaE5JHe_W-LaE-trrthVh/?imgmax=800" width="28" height="28" /></p> <p><font color="#ff0000" size="4"><strong>Table of Contents</strong></font></p> <hr /> <p><strong></strong></p> <p><strong><a title="http://myvfpblog.blogspot.com/2011/04/vfpx-help-file-corrected-supported-and.html" href="http://myvfpblog.blogspot.com/2011/04/vfpx-help-file-corrected-supported-and.html"><img style="background-image: none; border-right-width: 0px; margin: 6px 10px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="VFPX – VFP 9 SP2 Help File" border="0" alt="VFPX – VFP 9 SP2 Help File" align="left" src="http://lh3.ggpht.com/_MOmDLu4Rm5Y/TbsQ8wlU6-I/AAAAAAAAHb0/IjKf2wavr6c/Doc_Full_1%5B3%5D.png?imgmax=800" width="54" height="89" /></a></strong></p> <p><font style="font-weight: bold" color="#ff0000" size="4">VFPX – VFP 9 SP2 Help File <a href="http://vfpx.codeplex.com/wikipage?title=VFP%209%20SP2%20Help%20File&referringTitle=Home" rel="nofollow" target="_blank"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="VFPX – VFP 9 SP2 Help File" border="0" alt="VFPX – VFP 9 SP2 Help File" src="http://lh5.ggpht.com/_MOmDLu4Rm5Y/TbsQ9NKZM5I/AAAAAAAAHbc/2j1-d-xWZlU/external%5B19%5D.png?imgmax=800" width="17" height="17" /></a></font></p> <p><b>The Visual FoxPro 9 SP2 Help file corrected, supported, and enhanced</b><strong><font color="#000000">.</font></strong></p> <p> <br /> <hr /></p> <p><a title="http://myvfpblog.blogspot.com/2014/07/vfpxfoxunit.html" href="http://myvfpblog.blogspot.com/2014/07/vfpxfoxunit.html"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 6px 10px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top: 0px; border-right: 0px; padding-top: 0px" title="VFPX - FoxUnit" border="0" alt="VFPX - FoxUnit" align="left" src="http://lh5.ggpht.com/-91ZxGkKvwY8/U8_ndBtdZPI/AAAAAAAAIHM/57x7wRU32G4/Doc_Full_2%25255B6%25255D.png?imgmax=800" width="54" height="89" /></a><font style="font-weight: bold" color="#ff0000" size="4">VFPX – FoxUnit <a href="https://vfpx.codeplex.com/wikipage?title=FoxUnit&referringTitle=Home" rel="nofollow" target="_blank"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="VFPX – FoxUnit" border="0" alt="VFPX – FoxUnit" src="http://lh5.ggpht.com/_MOmDLu4Rm5Y/TbsQ9NKZM5I/AAAAAAAAHbc/2j1-d-xWZlU/external%5B19%5D.png?imgmax=800" width="17" height="17" /></a></font></p> <p><strong><font color="#000000">A tool to facilitate using unit tests for your Visual FoxPro code base.</font></strong></p> <p> <br /> <hr /></p> Burkhardhttp://www.blogger.com/profile/11631168041975170500noreply@blogger.comtag:blogger.com,1999:blog-26167158.post-73124443122377108762011-04-29T22:07:00.000+02:002014-07-23T19:21:31.309+02:00VFPX - Help file corrected, supported, and enhanced<p><strong><font color="#ff8040">Version: 0.01.11 - last update: Wednesday, July 23, 2014, 19:17:00</font></strong> </p> <p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Previous Entry" border="0" alt="Previous Entry" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifmH349Ex1EsZ6vneindwdvL-uVYheslWnthcM7gjPFiunzpQKEmiYOEwCtyQZcD0bX2OkKog4GyHXlOR2WtQeWJtFwRY1Ysxg446PE4Lu7ZoLX2X-2PVaLsKeySETOAFND_Ee/?imgmax=800" width="48" height="64" /><a title="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-vfpx-projects-this.html" href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-vfpx-projects-this.html"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="VFPX Projects Home (TOC)" border="0" alt="VFPX Projects Home (TOC)" src="http://lh6.ggpht.com/_MOmDLu4Rm5Y/Tbsa0b_F6HI/AAAAAAAAHbw/mkRtHqLnNA0/NavHome_48_RGBA%5B3%5D.png?imgmax=800" width="48" height="64" /></a><a title="http://myvfpblog.blogspot.com/2014/07/vfpxfoxunit.html" href="http://myvfpblog.blogspot.com/2014/07/vfpxfoxunit.html"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="VFPX–FoxUnit" border="0" alt="VFPX–FoxUnit" src="http://lh3.ggpht.com/-CfBSN0J4xGo/U8_vFy-435I/AAAAAAAAIHY/aFIN-pwHlmc/NavForward_48_RGBA%25255B5%25255D.png?imgmax=800" width="48" height="64" /></a> </p> <hr /><font color="#000080"> <h4><b><font color="#800000">Get a refurbished and enhanced Visual FoxPro Help file.</font></b></h4> <p><font color="#000000">I downloaded a copy of the latest VFP9 SP2 help file (dv_foxhelp_vfp9sp2.exe) today. </font></p> <p><font color="#000000">I contributed the <font face="Courier New"><strong>LOADPICTURE()</strong></font> help page. </font><font color="#000000"> <br /><img style="background-image: none; border-right-width: 0px; margin: 6px 12px 6px 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="New LOADPICTURE() Help" border="0" alt="New LOADPICTURE() Help" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDY6lrKavawGVLSxP-rQk8i414Den4PoT4uoxwZmT3oo2jbN1alIiIy9zK9Eh7Bf2-dg9hyJKZcxG7XrwLS2wQ7HPnSXXQUxPWOF3qEQqAbzDjyKYeYtmMhZkCOJfplH8VKU8J/?imgmax=800" width="532" height="147" /></font></p> <p><font color="#000000">At the end of this help page my example #4 is now missing. <br /></font><font color="#000000">It had to be dropped because otherwise the whole page would have been to long. </font></p> <p><font style="background-color: #ffff00" color="#000000">No problem, you can get the whole story (and even more) directly from <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="external" border="0" alt="external" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaspFX_wQQrm-HJ-gZVXXxEQhiDGTH-E09I_G0Qge54EeVG9pTstaPMk9xgZgFdXXpR3dmTywhFWg8kUDrSbJTWIVILanY4Chh6CsCN6mMfudUNEsJLbL7vSS04EMTVe8fs8iW/?imgmax=800" width="10" height="10" /> </font><a title="Loadpicture() function - Some Myths Revealed" href="http://myvfpblog.blogspot.com/2011/04/loadpicture-functionsome-myths-revealed.html"><font style="background-color: #ffff00" color="#000000">here</font></a><font color="#000000"><font style="background-color: #ffff00">.</font> </font></p> <p><strong><font color="#800000">Do not forget to get your own copy of the latest VFP Help file! </font></strong></p> <p><font color="#000000"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="OffSiteLink" border="0" alt="OffSiteLink" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgp1x94OgcsxG73CJM9R1WqJ2JAOo8tYPFJ2LpE0BZw3TS0VkI8T8IdAGk-mNwBrjCLYxgyiKhlz-p3HnaPKLV-xeakeSV3iJ1pE0MxdDjgWgNTug7UXy7biikQnfTTaoHUEnO1/?imgmax=800" width="11" height="7" /> <a title="http://www.codeplex.com/site/users/view/Faure" href="http://www.codeplex.com/site/users/view/Faure" rel="nofollow" target="_blank">Francis Faure</a> who is the project manager is doing a really great job! <br />It is hard to keep track of all the little and large oddities that need <br />to be corrected – a time-consuming and sometimes nerving task!</font></p> </font> <p>Thanks Francis!</p> Burkhardhttp://www.blogger.com/profile/11631168041975170500noreply@blogger.com2tag:blogger.com,1999:blog-26167158.post-12043012789748817302011-04-29T17:20:00.000+02:002011-04-30T02:12:04.076+02:00The Future of FoxQuill<span style="font-family: "Trebuchet MS","sans-serif"; mso-fareast-font-family: 'Times New Roman'"></span><shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></path><lock aspectratio="t" v:ext="edit"></lock></shapetype> <h4><font size="2"><font style="font-weight: bold" color="#f79646">Version: 1.11.01 - last update: Saturday, April 30, 2011, 02:10:00</font></font></h4> <p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Previous Chapter" border="0" alt="Previous Chapter" src="http://lh4.ggpht.com/_MOmDLu4Rm5Y/Tbrf8zQ2XfI/AAAAAAAAHak/6ZIyGVNViEc/NavBack_48_RGBA%5B3%5D.png?imgmax=800" width="48" height="64" /><a title="http://myvfpblog.blogspot.com/2009/09/foxquill-more-than-framework-foxquill.html" href="http://myvfpblog.blogspot.com/2009/09/foxquill-more-than-framework-foxquill.html"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="FoxQuill.Net Home (TOC)" border="0" alt="FoxQuill.Net Home (TOC)" src="http://lh5.ggpht.com/_MOmDLu4Rm5Y/Tbrf9fA9QII/AAAAAAAAHao/9NF_5TceFMo/NavHome_48_RGBA%5B3%5D.png?imgmax=800" width="48" height="64" /></a><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Next Chapter" border="0" alt="Next Chapter" src="http://lh6.ggpht.com/_MOmDLu4Rm5Y/Tbrf9nKFCnI/AAAAAAAAHas/xH2cPPxNSak/NavForward_48_RGBA%5B3%5D.png?imgmax=800" width="48" height="64" />  <hr /></p> <h4><font style="font-weight: bold" color="#9b00d3">FoxQuill will become FoxQuill.NET</font></h4> <h1><b><span style="font-family: "Trebuchet MS","sans-serif"; color: #9b00d3; mso-fareast-font-family: 'Times New Roman'">VFP’s Future</span></b><span style="font-family: "Trebuchet MS","sans-serif"; mso-fareast-font-family: 'Times New Roman'"> </span></h1> <p class="MsoNormal"><span style="font-family: "Trebuchet MS","sans-serif"; font-size: 10.5pt; mso-fareast-font-family: 'Times New Roman'">Visual FoxPro will not die abruptly – neither tomorrow, nor next week! There is enough work left to be done for smart and experienced VFP developers – okay, maybe with additional programming language skills. I am sure, migrating VFP/XBase based legacy-systems to C# or any other language will become a pretty remarkable line of business in the future. </span></p> <h2><b><span style="font-family: "Trebuchet MS","sans-serif"; color: #9b00d3; mso-fareast-font-family: 'Times New Roman'"><b><span style="font-family: 'Trebuchet MS','sans-serif'; color: #9b00d3; mso-fareast-font-family: 'Times New Roman'"><img style="background-image: none; border-right-width: 0px; margin: 6px 12px 6px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="FQ_Framework_TV" border="0" alt="FQ_Framework_TV" align="left" src="http://lh6.ggpht.com/_MOmDLu4Rm5Y/TbtN9L6iitI/AAAAAAAAHcQ/M6K1JESBBzM/FQ_Framework_TV%5B12%5D.png?imgmax=800" width="316" height="637" /></span></b>The Future of FoxQuill</span></b><span style="font-family: "Trebuchet MS","sans-serif"; mso-fareast-font-family: 'Times New Roman'"> </span></h2> <p class="MsoNormal"><span style="font-family: "Trebuchet MS","sans-serif"; font-size: 10.5pt; mso-fareast-font-family: 'Times New Roman'">Microsoft’s initial release of the NET framework was on 13. February 2002. During the past decade countless books were written touching almost every NET-related aspect. <em><span style="font-family: "Trebuchet MS","sans-serif"">Why should one think about doing another one?</span></em> Well, first of all, I think this is a universal question, which also is true for other businesses: “<em><span style="font-family: "Trebuchet MS","sans-serif"">Why should we build another new type of car? Don’t we have enough to choose from?”</span></em> I believe, one possible answer is: “As long as we can make something better, we should go for it!” Another good answer: “As long as we can re-sharpen something to become more precise, we should do that, too!” <br /></span><shape style="z-index: 2; position: absolute; margin-top: 0px; width: 54pt; height: 85.5pt; visibility: visible; margin-left: 0px; mso-wrap-style: square; mso-wrap-distance-left: 0; mso-wrap-distance-top: 0; mso-wrap-distance-right: 0; mso-wrap-distance-bottom: 0; mso-position-horizontal: left; mso-position-horizontal-relative: text; mso-position-vertical: absolute; mso-position-vertical-relative: line" id="Bild_x0020_3" title=""The book is here on Amazon.com"" o:button="t" o:allowoverlap="f" target=""_blank"" href="http://www.amazon.com/What-Would-Google-Jeff-Jarvis/dp/0061709719/ref=ntt_at_ep_dpi_1/187-5903716-4665321" o:spid="_x0000_s1026" alt="Book link to Amazon.com" type="#_x0000_t75"><imagedata o:href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhf57sWhpP8IqB8xYHoxKVyXnTvK5cN2_W5eAs-pfbYCngbwDO6yq2aHyc82XYoVtlvV5is4K6nd7yWcqOaIIpNIdnRpoYl22jnYCG8h9M7aLP04z7nSc5sxl7dWAsh5TR0z6Sy/?imgmax=800" src="file:///C:\DOKUME~1\PETRAU~1\LOKALE~1\Temp\msohtmlclip1\01\clip_image004.png"></imagedata><wrap type="square" anchory="line"></wrap></shape><span style="font-family: "Trebuchet MS","sans-serif"; font-size: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-no-proof: yes"></span><span style="font-family: "Trebuchet MS","sans-serif"; font-size: 10.5pt; mso-fareast-font-family: 'Times New Roman'"> <br />But there is more to mediate on! Lately, I read <a title="Read more about the author..." href="http://en.wikipedia.org/wiki/Jeff_Jarvis" target="_blank">Jeff Jarvis</a>’ book <strong><span style="font-family: "Trebuchet MS","sans-serif"; color: black">What would Google Do?</span></strong><strong><span style="font-family: "Trebuchet MS","sans-serif""> I <u>do recommend</u> reading it!</span></strong> Amongst many other things, I learned that the Internet brought a big change in the global market: Yesterday we had some (few) big companies; earning big bucks was only possible for these mainstream players. Today, with the help of the internet, there are much more small-sized companies. <em><span style="font-family: "Trebuchet MS","sans-serif"">Specialization</span></em> is the buss word today! Do not try to capture all potential customers in your country, but only a small group that you’ve tailored your perfect fitting offer for. With the help of the internet, your customer base will be multiplied for sure. Now, the whole world has become your country! <br />My strategy is to niche a market with <strong><span style="font-family: "Trebuchet MS","sans-serif"; color: #9b00d3">FoxQuill.Net</span></strong> in a special way. The experience I’ve made learning C# on the .NET platform, I will publish as an <em><span style="font-family: "Trebuchet MS","sans-serif"">open-source book</span></em>. In addition, I will publish parts of <strong><span style="font-family: "Trebuchet MS","sans-serif"; color: #9b00d3">FoxQuill</span></strong> also as an open-source project. I just started to add and refactor some of my old FoxQuill classes. My intention is to make them “look and feel” more like their counterparts in my C#-based <strong><span style="font-family: "Trebuchet MS","sans-serif"; color: #9b00d3">FoxQuill.Net</span></strong> version. An effort that will pay back when finally migrating to the .Net platform one fine day. Finally, <strong><span style="font-family: "Trebuchet MS","sans-serif"; color: #9b00d3">FoxQuill.Net</span></strong> will be an open-source project as well! I would never presume to create a 100% compatible VFP.NET clone (see below). When Microsoft buried VB6 and published VB.NET they must have had good reasons not to recreate a 100% backwards compatible VB.Net version! </span></p> <h2><b><span style="font-family: "Trebuchet MS","sans-serif"; color: #9b00d3; mso-fareast-font-family: 'Times New Roman'">Good Starting Points</span></b><span style="font-family: "Trebuchet MS","sans-serif"; mso-fareast-font-family: 'Times New Roman'"> </span></h2> <p class="MsoNormal"><span style="font-family: "Trebuchet MS","sans-serif"; font-size: 10.5pt; mso-fareast-font-family: 'Times New Roman'">Most VFP developers seriously interested in the .NET platform know about the </span><a title=""Read more about the author..." t " href="http://en.wikipedia.org/wiki/Jeff_Jarvis"><span style="font-family: "Trebuchet MS","sans-serif"; font-size: 10.5pt; text-decoration: none; mso-fareast-font-family: 'Times New Roman'; mso-no-proof: yes; text-underline: none"><shape style="width: 8.25pt; height: 5.25pt; visibility: visible" id="_x0000_i1032" title=""Read more about the author..."" alt="OffSiteLink" type="#_x0000_t75"><imagedata o:href="http://lh5.ggpht.com/_MOmDLu4Rm5Y/TaZMFBG2uLI/AAAAAAAAHWc/smuZhgAkPWw/OffSiteLink%5b10%5d.gif?imgmax=800" src="file:///C:\DOKUME~1\PETRAU~1\LOKALE~1\Temp\msohtmlclip1\01\clip_image003.gif"></imagedata></shape></span></a><span style="font-family: "Trebuchet MS","sans-serif"; font-size: 10.5pt; mso-fareast-font-family: 'Times New Roman'"><a title="http://foxcentral.net/microsoft/VFPToolkitNET.htm" href="http://foxcentral.net/microsoft/VFPToolkitNET.htm" target="_blank">Visual FoxPro Toolkit for .NET</a>. I believe, a closer look at it gives you a good starting point. But, it is not my intention to trample down that trail again. I believe, that most of the authors of .NET books first learned C#, or VB.NET thoroughly and gained experience while working with Visual Studio. They all started writing after they have been there, done it, got the T-shirts :-) I will start now, immediately writing about what I am learning. Even better, writing about what I am missing and what is hard to understand, because there is counterpart within VFP. The best way to learn C#/VB.NET seen from my VFP-biased point of view surely differs from the mainstream. Voilà: there the niche is :-)  </span></p> <h2><b><span style="font-family: "Trebuchet MS","sans-serif"; color: #9b00d3; mso-fareast-font-family: 'Times New Roman'">VFP.NET the Unborn ‘Flatliner’</span></b><span style="font-family: "Trebuchet MS","sans-serif"; mso-fareast-font-family: 'Times New Roman'"> </span></h2> <p class="MsoNormal"><span style="font-family: "Trebuchet MS","sans-serif"; font-size: 10.5pt; mso-fareast-font-family: 'Times New Roman'">Lately I followed a thread on Google groups </span><a title=""Read more about the author..." t " href="http://en.wikipedia.org/wiki/Jeff_Jarvis"><span style="font-family: "Trebuchet MS","sans-serif"; font-size: 10.5pt; text-decoration: none; mso-fareast-font-family: 'Times New Roman'; mso-no-proof: yes; text-underline: none"><shape style="width: 8.25pt; height: 5.25pt; visibility: visible" id="_x0000_i1031" title=""Read more about the author..."" alt="OffSiteLink" type="#_x0000_t75"><imagedata o:href="http://lh6.ggpht.com/_MOmDLu4Rm5Y/TaZMF0e4DaI/AAAAAAAAHWg/blx8cb_FPNE/OffSiteLink%5b18%5d.gif?imgmax=800" src="file:///C:\DOKUME~1\PETRAU~1\LOKALE~1\Temp\msohtmlclip1\01\clip_image003.gif"></imagedata></shape></span></a><span style="font-family: "Trebuchet MS","sans-serif"; font-size: 10.5pt; mso-fareast-font-family: 'Times New Roman'"> <a title="Go to this Google group" href="https://groups.google.com/group/vfpnet-compiler-community-support-group" target="_blank">VFP.Net Compiler Community Support Group</a>. In a nutshell: There is (or was?) a company named </span><a title=""Read more about the author..." t " href="http://en.wikipedia.org/wiki/Jeff_Jarvis"><span style="font-family: "Trebuchet MS","sans-serif"; font-size: 10.5pt; text-decoration: none; mso-fareast-font-family: 'Times New Roman'; mso-no-proof: yes; text-underline: none"><shape style="width: 8.25pt; height: 5.25pt; visibility: visible" id="_x0000_i1030" title=""Read more about the author..."" alt="OffSiteLink" type="#_x0000_t75"><imagedata o:href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMvmisW7A_PbvdVDUHubFEnpRvsN74HKtSm42l2pvv5aHEI4f2tsVJnMSq3NXiGYXE49tkk5Iw4lagOMuRzG-Lh935ftBUZoerhELaM_GeZpbV__T1uPWXoYGrSzsHKVEqM8yd/?imgmax=800" src="file:///C:\DOKUME~1\PETRAU~1\LOKALE~1\Temp\msohtmlclip1\01\clip_image003.gif"></imagedata></shape></span></a><span style="font-family: "Trebuchet MS","sans-serif"; font-size: 10.5pt; mso-fareast-font-family: 'Times New Roman'"> <a title="http://www.etecnologia.net/" href="http://www.etecnologia.net/" target="_blank">eTecnologia</a>. They sell (or sold?)  </span><a title=""Read more about the author..." t " href="http://en.wikipedia.org/wiki/Jeff_Jarvis"><span style="font-family: "Trebuchet MS","sans-serif"; font-size: 10.5pt; text-decoration: none; mso-fareast-font-family: 'Times New Roman'; mso-no-proof: yes; text-underline: none"><shape style="width: 8.25pt; height: 5.25pt; visibility: visible" id="_x0000_i1029" title=""Read more about the author..."" alt="OffSiteLink" type="#_x0000_t75"><imagedata o:href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh61yreugbPL5JF8XBASyZCJMNOcbct7sW5MqReIyDfNnGOFeiOqwVOyWV7enptwH6AIqJ1504MrcyUsoSOGgV9l_FcQgm2t4YpD2XESsNjPPhoXNhivjjppY9nXAHhH9gekLNn/?imgmax=800" src="file:///C:\DOKUME~1\PETRAU~1\LOKALE~1\Temp\msohtmlclip1\01\clip_image003.gif"></imagedata></shape></span></a><span style="font-family: "Trebuchet MS","sans-serif"; font-size: 10.5pt; mso-fareast-font-family: 'Times New Roman'">a <a title="http://www.etecnologia.net/Products/CLRExtender/CLRExtender-index.htm" href="http://www.etecnologia.net/Products/CLRExtender/CLRExtender-index.htm" target="_blank">Net Extender for VFP</a>. This tool was intended to be a VFP wrapper that lets us access all the cool .NET functionality flawlessly. But the wrapper was very instable and thus, almost good for nothing! Next they told us, that pretty soon they would come up with a </span><a title=""Read more about the author..." t " href="http://en.wikipedia.org/wiki/Jeff_Jarvis"><span style="font-family: "Trebuchet MS","sans-serif"; font-size: 10.5pt; text-decoration: none; mso-fareast-font-family: 'Times New Roman'; mso-no-proof: yes; text-underline: none"><shape style="width: 8.25pt; height: 5.25pt; visibility: visible" id="_x0000_i1028" title=""Read more about the author..."" alt="OffSiteLink" type="#_x0000_t75"><imagedata o:href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWl3c4rjqOmQkurSNk3RnxsIilSfi76-F6CsoqMYz8hf7bCsAyIyhXC3GUBKsH74OdOF0jvbQ4GvNcKPPAQHLtKlw0koynZ4JnFjYO7beaLJq4D1831XyhBNagoDuhKe953-tk/?imgmax=800" src="file:///C:\DOKUME~1\PETRAU~1\LOKALE~1\Temp\msohtmlclip1\01\clip_image003.gif"></imagedata></shape></span></a><span style="font-family: "Trebuchet MS","sans-serif"; font-size: 10.5pt; mso-fareast-font-family: 'Times New Roman'"><a title="http://www.etecnologia.net/Products/VFPCompiler/VFPDeveloperStudio.html" href="http://www.etecnologia.net/Products/VFPCompiler/VFPDeveloperStudio.html" target="_blank">VFP Developer Studio</a> – a complete VFP 9 port to the .NET platform! Still it is not much more than an alpha version, even today (April 2011).  <br /><em><b><span style="font-family: "Trebuchet MS","sans-serif"; color: #9b00d3">IMOH:</span></b></em><em><b><span style="font-family: "Trebuchet MS","sans-serif""> Today, no small (even no mid-sized) company is able to allow itself the luxury of doing a full-featured (100% compatible) VFP 9 to VFP.NET port! Maybe they might be able to implement 95% of VFP’s overall functionality in the first half of their “migration-game”. But, for the remaining 5% of VFP’s functionality ( – believe me –) they will need much more than a second half!</span></b></em> </span></p> <h2><b><span style="font-family: "Trebuchet MS","sans-serif"; color: #9b00d3; mso-fareast-font-family: 'Times New Roman'">FoxQuill.Net Another Unborn Successor</span></b><span style="font-family: "Trebuchet MS","sans-serif"; mso-fareast-font-family: 'Times New Roman'"> </span></h2> <p class="MsoNormal"><span style="font-family: "Trebuchet MS","sans-serif"; font-size: 10.5pt; mso-fareast-font-family: 'Times New Roman'">The future of Visual FoxPro, better <em><span style="font-family: "Trebuchet MS","sans-serif"">the spirit of VFP,</span></em> must no longer be controlled by <em><span style="font-family: "Trebuchet MS","sans-serif"">bigger brothers</span></em>. Today, it is possible to form developer teams loosely coupled worldwide from <em><span style="font-family: "Trebuchet MS","sans-serif"">small herds</span></em> to <em><span style="font-family: "Trebuchet MS","sans-serif"">large swarms :-)</span></em> Today, we are able to create a new VFP.NET implementation by our joint efforts from scratch. The outcome may not be <em><span style="font-family: "Trebuchet MS","sans-serif"">the real thing</span></em> compared to VFP 9, but it will definitely be an enhanced development environment that re-enables us to write bullet-proof, stable running, paramount apps for modern operation systems in the shortest possible time! We must not waist our money on compatibility issues! Let’s learn from the past, but do not lose time to repeat it unsuccessfully! Of course, backward compatibility is a “nice to have”-feature, especially if one owes a lot of old sources written in VFP, or even in FPW (or even better in FoxPro for DOS/MAC/UNIX :-)  <br />Most cardinal errors made in the past stem from <em><span style="font-family: "Trebuchet MS","sans-serif"">how program logic was implemented</span></em>! The logic (the coded behavior) of a program was bound to the programming language much too tight. Every time you have to rewrite parts (or all) of your code during migration, you encounter this flaw. Look at good old macro substitution for example which is a very VFP/XBase - specific feature. Doing an automated port of a PRG that is heavily using macro substitution to C#  is next to impossible! </span></p> <h2><b><span style="font-family: "Trebuchet MS","sans-serif"; color: #9b00d3; mso-fareast-font-family: 'Times New Roman'">Revert Backward Compatibility to Forward Compatibility!</span></b><span style="font-family: "Trebuchet MS","sans-serif"; mso-fareast-font-family: 'Times New Roman'"> </span></h2> <p class="MsoNormal"><span style="font-family: "Trebuchet MS","sans-serif"; font-size: 10.5pt; mso-fareast-font-family: 'Times New Roman'">Let us face some of the troubles a <em><strong>T<span style="font-family: "Trebuchet MS","sans-serif"">omorrow VFP Developer</span></strong></em> may ran into: </span></p> <ul type="disc"> <li style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-list: l0 level1 lfo1; tab-stops: list 36.0pt" class="MsoNormal"><span style="font-family: "Trebuchet MS","sans-serif"; font-size: 10.5pt; mso-fareast-font-family: 'Times New Roman'">Microsoft stopped supporting and maintaining VFP. </span></li> <li style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-list: l0 level1 lfo1; tab-stops: list 36.0pt" class="MsoNormal"><span style="font-family: "Trebuchet MS","sans-serif"; font-size: 10.5pt; mso-fareast-font-family: 'Times New Roman'">VFP will no longer be compatible with Win 8, 9 or 10. </span></li> <li style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-list: l0 level1 lfo1; tab-stops: list 36.0pt" class="MsoNormal"><span style="font-family: "Trebuchet MS","sans-serif"; font-size: 10.5pt; mso-fareast-font-family: 'Times New Roman'">No raising generation of VFP developers any more. </span></li> <li style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-list: l0 level1 lfo1; tab-stops: list 36.0pt" class="MsoNormal"><span style="font-family: "Trebuchet MS","sans-serif"; font-size: 10.5pt; mso-fareast-font-family: 'Times New Roman'">Tons of NET programmers with neither XBase knowledge, nor any sympathy. </span></li> <li style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-list: l0 level1 lfo1; tab-stops: list 36.0pt" class="MsoNormal"><span style="font-family: "Trebuchet MS","sans-serif"; font-size: 10.5pt; mso-fareast-font-family: 'Times New Roman'">Many companies wish to upsize/migrate their legacy VFP systems to .NET (but only <strong><span style="font-family: "Trebuchet MS","sans-serif"">for little fees, please</span></strong>!) </span></li> <li style="mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-list: l0 level1 lfo1; tab-stops: list 36.0pt" class="MsoNormal"><span style="font-family: "Trebuchet MS","sans-serif"; font-size: 10.5pt; mso-fareast-font-family: 'Times New Roman'">Missing migration tools will hinder you, because you are to expensive! </span></li> </ul> <p style="margin-bottom: 12pt" class="MsoNormal"><span style="font-family: "Trebuchet MS","sans-serif"; font-size: 10.5pt; mso-fareast-font-family: 'Times New Roman'">The business landscape described above is closer than one might think! A .NET developer always advises any CEO during an in-depth consultation to migrate to the .NET language that meet his skills! No .NET developer would phone you up and ask for you assistance because of your prominent VFP skills – never ever! At the utmost, they may need your expertise during migration of their VFP tables. Upsizing dbf content to any kind of SQL Server instance might spawn subtle errors, as we know! The rest of the plot is very simple: all legacy VFP source code gets dropped. A complete rewrite will be done, because with some very clever NET tools this can be realized very fast and very cheap by someone with less .NET-skills than yours! <br /><strong><span style="font-family: "Trebuchet MS","sans-serif"; color: #9b00d3">Now, how could we revert compatibility to always point </span></strong><em><b><span style="font-family: "Trebuchet MS","sans-serif"; color: #9b00d3">forward</span></b></em><strong><span style="font-family: "Trebuchet MS","sans-serif"; color: #9b00d3"> to our latest, most powerful implementations? </span></strong>The answer is astonishingly simple: We have to GENERATE all of our source code by using a program and not by hacking in each line manually! Code that was generated by a machine can be maintained by a machine as well. Automatic maintenance finally leads to computer-based upgrading, upsizing and, if necessary, migration. All we have to do is <strong><span style="font-family: "Trebuchet MS","sans-serif"; color: black">decouple</span></strong> <em><span style="font-family: "Trebuchet MS","sans-serif"">user interface design</span></em> and <em><span style="font-family: "Trebuchet MS","sans-serif"">program logic definition</span></em> from the process of creating the corresponding source code. Look at Microsoft’s WPF and you know what I mean when I’m taking about decoupling the user interface design. This technology is already there! Decoupling program logic (the entire application behavior) from generating the corresponding source code can be realized in almost the same way. <em><b><span style="font-family: "Trebuchet MS","sans-serif"">Believe me!</span></b></em> <br />Using my (future:-) <strong><span style="font-family: "Trebuchet MS","sans-serif"; color: #9b00d3">FoxQuill.Net</span></strong> development system, resembles the way we create internet pages in an WYSIWYG editor, today. Yes, it still will be possible to manually write and add source code, but that’s generally not necessary in 95% of all business cases. Even my so called ‘micro-workflows’ can easily be assembled by selecting the appropriate building blocks from context sensitive lists. Dropping them on a design form afterwards and finally arrange/configure them is all that has to be done. I like to point you to Google’s </span><a title=""Read more about the author..." t " href="http://en.wikipedia.org/wiki/Jeff_Jarvis"><span style="font-family: "Trebuchet MS","sans-serif"; font-size: 10.5pt; text-decoration: none; mso-fareast-font-family: 'Times New Roman'; mso-no-proof: yes; text-underline: none"><shape style="width: 8.25pt; height: 5.25pt; visibility: visible" id="_x0000_i1027" title=""Read more about the author..."" alt="OffSiteLink" type="#_x0000_t75"><imagedata o:href="http://lh3.ggpht.com/_MOmDLu4Rm5Y/TaZMGySxznI/AAAAAAAAHWw/_YGDHSrT1p4/OffSiteLink%5b34%5d.gif?imgmax=800" src="file:///C:\DOKUME~1\PETRAU~1\LOKALE~1\Temp\msohtmlclip1\01\clip_image003.gif"></imagedata></shape></span></a><span style="font-family: "Trebuchet MS","sans-serif"; font-size: 10.5pt; mso-fareast-font-family: 'Times New Roman'"><a title="http://appinventor.googlelabs.com/about/" href="http://appinventor.googlelabs.com/about/" target="_blank">App Inventor for Android</a> where you can watch some short YouTube demos and tutorials. Especially the blocks editor user interface looks very promising (see below)! </span></p> <p style="margin-bottom: 12pt" class="MsoNormal"><a title="http://appinventor.googlelabs.com/about/moreinfo/" href="http://appinventor.googlelabs.com/about/moreinfo/" rel="nofollow" target="_blank"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 6px 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="http://appinventor.googlelabs.com/about/moreinfo/" border="0" alt="http://appinventor.googlelabs.com/about/moreinfo/" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwJPquPNcYn3lVrNnB-oe6Tx8MzVO9lGxHaYGCrulrSL8fHv0IgGvjXH7_AmhMVWblv3bQjgeKk1ArLt12-HNyd77hBielzr4dd8FGqVNo2PCDyilc-Qb6ZsTL3319Uheq7V9T/?imgmax=800" width="619" height="170" /></a></p> <p style="text-align: center" class="MsoNormal" align="center"><a title=""Watch the movie on YouTube" t " href="http://www.youtube.com/watch?v=Iq9KkAbhxQg&feature=player_embedded"><span style="font-family: "Trebuchet MS","sans-serif"; font-size: 10.5pt; text-decoration: none; mso-fareast-font-family: 'Times New Roman'; mso-no-proof: yes; text-underline: none"><shape style="width: 556.5pt; height: 411pt; visibility: visible" id="_x0000_i1026" title=""Watch the movie on YouTube"" alt="blocks editor user interface " type="#_x0000_t75"><imagedata o:href="http://lh4.ggpht.com/_MOmDLu4Rm5Y/TaZMHh6vnjI/AAAAAAAAHW0/YhUDmpbAG4Y/12%5b9%5d.png?imgmax=800" src="file:///C:\DOKUME~1\PETRAU~1\LOKALE~1\Temp\msohtmlclip1\01\clip_image006.png"></imagedata></shape></span></a><span style="font-family: "Trebuchet MS","sans-serif"; font-size: 10.5pt; mso-fareast-font-family: 'Times New Roman'"></span></p> <p class="MsoNormal"><span style="font-family: "Trebuchet MS","sans-serif"; font-size: 10.5pt; mso-fareast-font-family: 'Times New Roman'">Google still is some development-miles away from having the perfect App generator, but we all know that they will have one in the near future :-) <br />GUI layout, workflows, messaging, data-storage, -manipulation and -transport, as well as event-handling and system configuration; all these things are aspects that can be configured using universal XML-based schemas. Any <strong><span style="font-family: "Trebuchet MS","sans-serif"; color: #9b00d3">FoxQuill.NET</span></strong> editor (just like Google’s Block-Editor shown above partially) emits XML-based data which belongs to the additional abstraction/separation layer I mentioned earlier in this post. Thus, what we are creating during our future development with FoxQuill.NET is neither .NET’s IL code, nor C#/VB.NET source code, but XML files representing a concrete DESIGN; e.g. some GUI layout, or a process workflow, maybe an inter-object messaging specification, or some storage structure definition, or a details system configuration definition, to name only a few possibilities. </span></p> <h2><b><span style="font-family: "Trebuchet MS","sans-serif"; color: #9b00d3; mso-fareast-font-family: 'Times New Roman'">Pros & Cons</span></b><span style="font-family: "Trebuchet MS","sans-serif"; mso-fareast-font-family: 'Times New Roman'"> </span></h2> <p style="margin-bottom: 12pt" class="MsoNormal"><span style="font-family: "Trebuchet MS","sans-serif"; font-size: 10.5pt; mso-fareast-font-family: 'Times New Roman'">At the beginning, as long as adequate tools are rare, there is less interactivity compared to VFP. VFP’s command window is a very unique and useful feature, for example. Such pervasive interactivity normally requires an interpretative language driving the system like </span><a title=""Read more about the author..." t " href="http://en.wikipedia.org/wiki/Jeff_Jarvis"><span style="font-family: "Trebuchet MS","sans-serif"; font-size: 10.5pt; text-decoration: none; mso-fareast-font-family: 'Times New Roman'; mso-no-proof: yes; text-underline: none"><shape style="width: 8.25pt; height: 5.25pt; visibility: visible" id="_x0000_i1025" title=""Read more about the author..."" alt="OffSiteLink" type="#_x0000_t75"><imagedata o:href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgVf7d4gVEb4-l1SBqoMnKxNO66eGXxNrqAE4FjbQmkkO3OUZih2qSFl-R3wbYnqaDRIVmxY6Z4Ld5V4KRwLOIj2CF8oIoYQCGprzSfj_99JVkzdSthgSBs_npcURoRZD2S4Bt/?imgmax=800" src="file:///C:\DOKUME~1\PETRAU~1\LOKALE~1\Temp\msohtmlclip1\01\clip_image003.gif"></imagedata></shape></span></a><span style="font-family: "Trebuchet MS","sans-serif"; font-size: 10.5pt; mso-fareast-font-family: 'Times New Roman'">Python.  Luckily, there are much more Pros than Cons! <br />Every XML output generated by a designer can be preprocessed and/or redirected before the target generator starts it’s code generation. This enables dynamic workflows: we will be able to enhance/add, modify or delete parts of the XML data on the fly based on external conditions. Another big plus is, that the designer tools themselves will be able to pre-check the user-input. With these client-site validations enabled (available only in a local workstation mode) it is possible to catch potential errors at a very early state (still in the designer), which helps to eliminate unnecessary development round-trips. <br />The XML files generated by the different designers can be interchanged over the internet. The generation site can be a remote one. Thus, someone may build some very specialized  generator, or a much better version than the original one provided by FoxQuill.NET. The developer of such a super-generator tool then may publish the availability of her advanced functionality so that the community knows about it. After that, she can offer access to the (remote) service for free, or associated with a certain pricing plan. Because a generation service outputs text files only (e.g. C# source code), such a distributed remote source code generation is secure and can be packed and encrypted in addition.</span></p> <p style="margin-bottom: 12pt" class="MsoNormal"><span style="font-family: "Trebuchet MS","sans-serif"; font-size: 10.5pt; mso-fareast-font-family: 'Times New Roman'"><font color="#f79646" size="2"><strong><em><to be continued…></em></strong></font></span></p> <hr /> <h3><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Previous Chapter" border="0" alt="Previous Chapter" src="http://lh4.ggpht.com/_MOmDLu4Rm5Y/Tbrf91eKrKI/AAAAAAAAHaw/-3tSkpezDpI/NavBack_48_RGBA%5B7%5D.png?imgmax=800" width="48" height="64" /><a title="http://myvfpblog.blogspot.com/2009/09/foxquill-more-than-framework-foxquill.html" href="http://myvfpblog.blogspot.com/2009/09/foxquill-more-than-framework-foxquill.html"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="FoxQuill.Net Home (TOC)" border="0" alt="FoxQuill.Net Home (TOC)" src="http://lh5.ggpht.com/_MOmDLu4Rm5Y/Tbrf-F9S5wI/AAAAAAAAHa0/ZtRPz-8P4pQ/NavHome_48_RGBA%5B7%5D.png?imgmax=800" width="48" height="64" /></a><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Next Chapter" border="0" alt="Next Chapter" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivQ-FhirMpy7ScsWhQC8AEeujnpBLsq6T__pgcaPsH2ucxuUi9Kt_-nixVOKLv_xKccybPguiOsTVLRj4xDkAw785D1cBql69hQlxF4LhrgUPxvy2RwBPU5_Feb6NizkaK7bd5/?imgmax=800" width="48" height="64" /></h3> Burkhardhttp://www.blogger.com/profile/11631168041975170500noreply@blogger.com6tag:blogger.com,1999:blog-26167158.post-72818602360884251412011-04-25T19:21:00.000+02:002011-05-03T03:48:28.592+02:00The LOADPICTURE() Function – (Some) ALL Myths Revealed!<p><strong><font color="#ff8040">Version: 0.02.02 - last update: Thursday, April 26, 2011, 14:35:00</font></strong> </p> <p><a title="http://myvfpblog.blogspot.com/2009/09/design-time-references-monitor-designer.html" href="http://myvfpblog.blogspot.com/2009/09/design-time-references-monitor-designer.html"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Previous Entry" border="0" alt="Previous Entry" src="http://lh3.ggpht.com/_MOmDLu4Rm5Y/TbWxElzvv5I/AAAAAAAAHhA/26-c47w72Gc/NavBack_48_RGBA5%5B1%5D.png?imgmax=800" width="48" height="64" /></a><a title="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-tips-tricks-in-this.html" href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-tips-tricks-in-this.html"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Tips & Tricks Home (TOC)" border="0" alt="Tips & Tricks Home (TOC)" src="http://lh4.ggpht.com/_MOmDLu4Rm5Y/TbWxFPKGLQI/AAAAAAAAHXU/6PVUdp4S3jA/NavHome_48_RGBA5%5B3%5D.png?imgmax=800" width="48" height="64" /></a><a title="http://myvfpblog.blogspot.com/2011/05/hierarchical-table-order-part-i.html" href="http://myvfpblog.blogspot.com/2011/05/hierarchical-table-order-part-i.html"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Next Entry" border="0" alt="Next Entry" src="http://lh4.ggpht.com/_MOmDLu4Rm5Y/Tb9e5jpq3II/AAAAAAAAHhE/CXkhhet64Zc/NavForward_48_RGBA%5B10%5D.png?imgmax=800" width="48" height="64" /></a>  </p> <hr /> <h4><strong><font color="#000080">All you have to know about VFP’s LOADPICTURE() function </font></strong></h4> <p><font color="#d80e55"><strong></strong></font></p> <h1><font color="#000080">Intro</font></h1> <p>VFP’s LOADPICTURE() creates a COM picture object and returns a fancy ‘crippled’ interface reference! VFP’s <b>LOADPICTURE()</b><b> </b>function is nothing more than a wrapper around the Windows API function called <b>OleCreatePictureIndirect()</b>, which in turn creates a COM picture object. These COM–wrapped objects are used by many ActiveX controls. You can find out more about <em>OleCreatePictureIndirect()</em> <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="OffSiteLink" border="0" alt="OffSiteLink" src="http://lh4.ggpht.com/_MOmDLu4Rm5Y/TbWxF_B3EnI/AAAAAAAAHXc/etBIxAEPdzs/OffSiteLink%5B2%5D.gif?imgmax=800" width="11" height="7" /> <a title="http://msdn.microsoft.com/en-us/library/ms694511(v=vs.85).aspx" href="http://msdn.microsoft.com/en-us/library/ms694511(v=vs.85).aspx" rel="nofollow" target="_blank">here</a>. There are some VERY GOOD reasons to use VFP’s LOADPICTURE() functionality! After all, carelessly using COM image objects created by VFP’s LOADPICTURE() function in conjunction with VFP’s native Image controls will introduce some almost non-trappable very tricky malfunctions! If you want to get the best out of it, without spending hours on debugging what seems to be impossible, read the rest of this post!</p> <p>This is the syntax of the API call wrapped by VFP’s LOADPICTURE() function:</p> <pre><font size="2"><strong>OleCreatePictureIndirect(pPictDesc,; <span style="color: #008000">&& Pointer to the structure of parameters for picture</span>
Riid ,;<span style="color: #008000">&& Reference to the identifier of the interface</span>
fOwn ,;<span style="color: #008000">&& Whether the picture is to be destroyed</span>
ppvObj <span style="color: #008000">&& Address of output variable that receives the </span>
<span style="color: #008000">&& Interface pointer requested in riid</span></strong>
</font></pre>
<p><font size="2"></font></p>
<p>As we all know, the right way to call a COM object’s implementation (inside a DLL) is using one of its interfaces. To figure out the interfaces that are available within a picture COM object, use VFP’s <font color="#000000"><strong>Object Browser</strong></font>. You can load either the “StdTypes” DLL itself (at <windir>\SYSTEM32\OLEPRO32.DLL), or its type library file (<windir>\SYSTEM32\STDOLE2.TLB).</p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="ObjectBrowser_StdType" border="0" alt="ObjectBrowser_StdType" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1zp3Z9i1LE3-ye3J6rTIkFEZgCyJMnHlP276Ziy3ZXl4t7Lgwzpz0QbuaM1vp-gmer7qJ8_DCrDtt-GvzTXyRfnpbBR2HUJBWCtoZuV6n9r_KyQN4AM9PPMCc8PSiGNO2IhER/?imgmax=800" width="456" height="398" /></p>
<h2><font color="#000080">COM Interfaces</font></h2>
<p><strong><font color="#ffc000" size="3"><em></em></font></strong></p>
<p>As you can see, in VFP’s Object Browser the interface called “PICTURE” is VFP’s default interface that is returned each time we are using some command like:</p>
<pre><strong><font size="3">oPicture = <span style="color: #0000ff">LOADPICTURE</span>(GETPIC())<br /></font></strong>
<img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="ObjectBrowser_TLB" border="0" alt="ObjectBrowser_TLB" src="http://lh5.ggpht.com/_MOmDLu4Rm5Y/TbXh4XMSEbI/AAAAAAAAHZw/FNXoVCvlojw/ObjectBrowser_TLB%5B1%5D.png?imgmax=800" width="560" height="435" /></pre>
<p>The <em>oPicture</em> reference above is a COM object reference of an interface named “Picture” through which we can access our image’s properties and methods. </p>
<p>Let VFP’s IntelliSense help us and type <strong><em><font color="#0000ff" face="Courier New">opicture.</font></em></strong> into the command window after we created a picture instance like shown above. IntelliSense shows us a list of five properties and one method accessible through this primary interface. BTW: The same popup can be shown within your debugger:</p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="IntelliDebugger" border="0" alt="IntelliDebugger" src="http://lh4.ggpht.com/_MOmDLu4Rm5Y/TbXh4tUU5qI/AAAAAAAAHZ0/HtoDz8gqJ1Q/IntelliDebugger%5B1%5D.png?imgmax=800" width="587" height="290" /></p>
<p>This <strong><em>Picture</em></strong> interface is suitable in cases where we only want to pass a COM object reference to another ActiveX control, or we want to display the image using VFP’s own native image class like this:</p>
<pre><font size="3"><strong><span style="color: #0000ff">_Screen</span>.<span style="color: #0000ff">AddObject</span>("<span style="background-color: #ffff00; color: red">oImage</span>","<span style="background-color: #ffff00; color: red">IMAGE</span>")
oPicture = <span style="color: #0000ff">LOADPICTURE</span>(GETPIC())
<span style="color: #0000ff">_SCREEN</span>.oImage.<span style="color: #0000ff">PictureVal</span> = m.oPicture
<span style="color: #0000ff">_SCREEN</span>.oImage.<span style="color: #0000ff">Visible</span> = .T.</strong></font></pre>
<p>However, if we try to use the COM object’s <strong><em>render()</em></strong> method directly, bypassing the use of VFP’s  <strong><em>Image</em></strong> object, we will only receive an OLE error complaining about non-optional parameters. </p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="OleErrorDialog" border="0" alt="OleErrorDialog" src="http://lh6.ggpht.com/_MOmDLu4Rm5Y/TbXh5Lv4jvI/AAAAAAAAHZ4/_1MA1lbRttk/OleErrorDialog%5B1%5D.png?imgmax=800" width="388" height="137" /></p>
<p><strong>Without any further investigations, we are stuck at this point!</strong></p>
<h3><font color="#000080">By The Way 1,2,3</font></h3>
<ol>
<li><b></b>There is a BUG in the VFP online documentation for the image object’s <strong><em>PictureVal</em></strong> property! Actual writing reads: “<font color="#c0504d"><strong>If eExpression is an object, the object must be in an IPicture interface format. The IPicture interface format is the same format returned by the LOADPICTURE( ) Function.</strong>”</font> <font style="background-color: #ffff00">This is wrong!</font> It should be “<font color="#008040"><strong>If eExpression is an object, the object must implement one of the following interfaces: “Picture” OR “iPicture”, which both _*do*_ work! The Picture interface is the same returned by VFP’s <em>LOADPICTURE()</em> function. If you need the iPicture-interface, you can retrieve it by the help of VFP’s <em>GETINTERFACE()</em> function</strong>.</font>”
<br /></li>
<li>VFP’s <font color="#0000ff" face="Courier New"><strong>SAVEPICTURE()</strong></font> function is nothing more than a wrapper around the <em><strong>SaveAsFile()</strong></em> function of the COM picture object (accessible by VFP through the <strong><em>iPicture</em> </strong>interface)!
<br /></li>
<li><b></b>You can read one sentence in VFP’s online help about the <strong><em>LOADPICTURE()</em></strong> function: „If cFileName is omitted, the <b>null picture</b> is returned“. This sounds Greek. However, as you can read <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="OffSiteLink" border="0" alt="OffSiteLink" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhK-fmkYXGjVA6DdGOlT6EiA7qf-ndX_YDbICgJOcCFO4EaZfbSS6K6d3ygj0qJe9qMuu_S-ncqeTTIV63F2EIY115JZuX6qZqftczSPEzV9CceH5_tQXw1XgH_9cJtf8pLnz69/?imgmax=800" width="11" height="7" /> <a title="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/html/fb021348-07d4-4974-a71e-abb1b8d760c4.asp" href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/html/fb021348-07d4-4974-a71e-abb1b8d760c4.asp" rel="nofollow" target="_blank">here</a>, it is nothing more than a parameterization option defined in the <strong><em>OleCreatePictureIndirect()</em></strong> function of the underlying Windows API. The NULL-Picture-Object is nothing else, but an uninitialized object which can initialize itself through the <em>Load()</em> method of its <i>IPersistStream</i> interface. Got it? No? Do not hesitate – nothing we have to deal with (in the next future:-)
<br /></li>
</ol>
<h2><font color="#000080">To make a long story short</font></h2>
<p>… Let me show you how to get the darn thing work. As you should have guessed, we <b>must not</b> use the <strong><em>Picture</em></strong> interface that we get back using the <strong><em>LOADPICTURE()</em></strong> function, but the other (hidden) interface: <b><i>IPicture</i></b> is the right one to use! And this is how to get the right COM-Object reference:</p>
<pre><font size="3"><strong>oPicture = <span style="color: #0000ff">LOADPICTURE</span>(GETPIC())
oIPicture = <span style="color: #0000ff">GETINTERFACE</span>(oPicture, “iPicture”)</strong></font></pre>
<p>Typing in the first line in VFP’s command window, you will get some similar <font color="#0000ff" face="Courier New"><strong>GETPIC()</strong></font> dialogue like below:</p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="OpenPicture Dialog" border="0" alt="OpenPicture Dialog" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgH-Drf2roZ7mTb8gbArBjYyF7lBvksNLU0NnXyh2b8G4GxywpNbgZo23aVsNPY4K_5lJLUKRNsqRg9zhCx6lPP8bvQeS71uVQedHwQux_tPc_AKgKsf9BWwRudSSDhuFFoR89S/?imgmax=800" width="726" height="419" /></p>
<p>I have a little image on my disk called “tree.jpg” – a 100 x 100 pixels JPEG file that I will use during this walkthrough. Now, if we are using VFP’s Intellisense on <strong><em>oIPicture</em></strong> it shows us a longer list of properties and methods (see Object Browser screen shot below). The biggest point is that we now can use our COM object’s <strong><em>render()</em></strong> method directly!</p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="ObjectBrowser_Interfaces" border="0" alt="ObjectBrowser_Interfaces" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-ZhZFACrRV1K2mjsj_WCrAeWpAsBRD6BY3HIZWFSWXO_0punFQIFjpI6hEBcY9cQ3w7GwKsby-ChIltwvEJQxCMU7RRvE0yISn9BAmw10afXzdC1G3DrWgR_HVnhdd4KIP8Tw/?imgmax=800" width="728" height="678" /></p>
<p> </p>
<h3><font color="#000080">The COM Object’s Render() Method</font></h3>
<p>This is how the <strong><em>render()</em></strong> method’s signature reads in VFP’s <strong>Object Browser</strong> followed by a short description of each parameter:</p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="IntelliRender" border="0" alt="IntelliRender" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGMSZp-s1ORE8f0t8wb3BXOFldvgfgdl0nuw9ScrjBjmGIdmBifjb7VX-Mp3HMgJrHYMQQGHGGe-9E3_H5lbkqFKDOnUcfRTFdxGmDcs3_PspZiFNlGTiGcjkk_U-rgdXt6ihp/?imgmax=800" width="763" height="167" /></p>
<p><font color="#0000ff" size="3" face="Courier New"><strong>Render(hdc As Integer, x As Long, y As Long, cx As Long, cy As Long, xSrc As Long, ySrc As Long, cxSrc As Long, cySrc As Long, lprcWBounds As Void) As H Result</strong></font></p>
<p><font size="2">[target] <strong>hdc</strong> := the device context handle (a pointer to something like a canvas)
<br />There are two Windows API functions to retrieve a handle to an existing device context: <strong>GetDC()</strong> and <strong>GetWindowDC().</strong></font></p>
<p><font size="2">[target] x:= left-property of output-rectangle (top left corner’s X-coordinate)</font></p>
<p><font size="2">[target] y:= top-property of output-rectangle (top left corner’s Y-coordinate)</font></p>
<p><font size="2">[target] cx:= width-property of output-rectangle (the width of output)</font></p>
<p><font size="2">[target] cy:= height-property of output-rectangle (the height of output)</font></p>
<p><font size="2">Up to this point all coordinates are measured in pixel (we VFP developers are used to use) and could be mapped
<br />to LEFT, TOP, WIDTH and HEIGHT properties of an imaginary VFP image object.</font></p>
<p><font size="2">[source] xSrc:= X-offset into image source (from where column-copy starts)</font></p>
<p><font size="2">[source] ySrc:= Y-offset into image source (from where line-copy starts)</font></p>
<p><font size="2">[source] cxSrc:= Width of each line to copy (#no of columns)</font></p>
<p><font size="2">[source] cySrc:= Height of each column to copy (#no of lines)</font></p>
<h4><font color="#000080">HiMetric</font></h4>
<p>To make things a little bit more “interesting” one have decided to use <b><i>HiMetric</i></b> units for <u>some</u> of the COM object’s properties (those dealing with the image source dimensions). <font color="#000080"><strong>That is why a 100x100 pixels image loaded from disk ends up in our internal COM in-memory representation having 2646 x 2646 units!</strong></font></p>
<h4><font color="#000080">Coordinates</font></h4>
<p>“HiMetric” scaling must have been not difficult enough for some of <i><strong>them</strong></i>, someone decided to move the coordinate-origin (0, 0-point) from the top-left corner of the COM-Image source to the lower-left corner (maybe to spice things up ;-)</p>
<h4><font color="#000080">Some manual testing</font></h4>
<p>Let’s have a look at my original source image:</p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Testbild" border="0" alt="Testbild" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHrDCMYZ5owDRdNrFFMUjf3gtTg8ruiecZjW2ZQTg0AwOLtRFu4p5RGsUtmZtLsyvBifMEgeQrFCiq9K503ZGAqei8D6hVC5pZNH1HxZwcqN2xlFbt5QVpbomi7frWjPs9Q4Vl/?imgmax=800" width="100" height="100" /></p>
<p>Let us now assume, that we already have a valid handle to a device context to render our image on. The following call to render() </p>
<pre><strong><font size="3"><span style="color: #0000ff">WITH</span> oIPic
= .Render(m.hDC, 0, 0, 100, 100, 0, 0, .<span style="color: #0000ff">Width</span>, .<span style="color: #0000ff">Height</span>, <span style="color: #0000ff">NULL</span>)
<span style="color: #0000ff">ENDWITH</span></font></strong></pre>
<p>would then produce the following output:</p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="ComTestbild" border="0" alt="ComTestbild" src="http://lh4.ggpht.com/_MOmDLu4Rm5Y/TbXh7QZRTdI/AAAAAAAAHZI/zFyIYET9Y7U/ComTestbild%5B3%5D.jpg?imgmax=800" width="100" height="100" /></p>
<p>The origin of the COM coordinate system is somehow rotated in memory by 180° After some wild guesses one may find out that the following code produces the expected output:
<br />
<br /><font size="3"><strong><font face="Courier New"><span style="color: #0000ff">WITH</span> oIPic
<br />   = .Render(m.hDC ,;
<br />             0,    0   ,   100 ,   100     ,;
<br />             0, <font color="#0000ff">.<span style="color: #0000ff">Height</span>, .<span style="color: #0000ff">Width</span>, .<span style="color: #0000ff">Height</span></font><span style="color: #008000"><font color="#ff0000">*-1</font><font color="#000000">,;</font></span>
<br /><span style="color: #0000ff">             NULL</span>)
<br /><span style="color: #0000ff">ENDWITH</span></font></strong></font></p>
<p>We have to understand what’s going on internally to see things a little bit clearer! The image loaded into memory is nothing more than a memory block filled with pixel related color values. This memory block can be abstractly treated as a rectangle. During rendering, which internally is the process of transferring data from the source rectangle to the destination rectangle, our COM object uses different values which are passed in through parameter #6 to #9 (the [source] parameters) to control the process:</p>
<ol>
<li>The origin of the source rectangle, one could name “copy starting point”. </li>
<li>The width and the height of the source rectangle to support cases when we do not want to render out a source image completely! </li>
<li>The direction in which to “read-out” the source data (bytes). </li>
</ol>
<p>It is important to know, that the very first source pixel (the one that is the origin of the source rectangle) always gets rendered out at position 1,1 of the target rectangle. The second source pixel (what exact pixel will be copied next depends on the read-out direction) gets renders out at position 2,1 and so on. Thus, by selecting the appropriate origin to start from, it is possible to render a mirrored image into the destination device context.</p>
<h5><font color="#000080">The xSrc und ySrc Parameter</font></h5>
<p>The 6th and 7th parameter value of the <strong><em>render()</em></strong> function determine where the starting point of the copy process within the image source lays. One of the 4 corners of the source rectangle will become the origin. Below, we can see the memory based COM – image with a given source rectangle (the red frame). In this case the source rectangle’s size matches the whole image. The coordinate pairs of all four valid xSrc/ySrc – combinations are also depicted. The values shown reflect HiMetric scaling (a 100x100 pixels square on a 96 dpi device context)</p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Nullpunkte" border="0" alt="Nullpunkte" src="http://lh6.ggpht.com/_MOmDLu4Rm5Y/TbXh7uzWFKI/AAAAAAAAHZM/81jT8wJlb7Q/Nullpunkte%5B6%5D.png?imgmax=800" width="291" height="214" /></p>
<p>Through determining the origin of where to start reading out the source pixel values, we also determine the direction of read out indirectly! The direction of read out is established by the sign of the last two input parameters (<em>cxSrc</em> and <em>cySrc</em>) of the <em>render()</em> method. (Don’t be surprised, just take it as read :-)</p>
<h5><b><font color="#000080">The cxSrc und cySrc Parameter</font></b></h5>
<p>On the one hand, the 8th und 9th parameter determine width and height of the source rectangle, on the other hand they also determine the read direction during the rendering data transfer. The absolute values  <span style="color: #0000ff">ABS</span>(cxSrc) and <span style="color: #0000ff">ABS</span>(cySrc) define the width and height of the source rectangle, the sign of both values (+/-) the direction of read out. The picture below might help to shed some light on that:  </p>
<pre><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Ausleserichtung" border="0" alt="Ausleserichtung" src="http://lh4.ggpht.com/_MOmDLu4Rm5Y/TbXh7--rglI/AAAAAAAAHZQ/ZTM1mCdIAC0/Ausleserichtung%5B1%5D.png?imgmax=800" width="557" height="153" /></pre>
<p>The [source] coordinate parameters of the <font color="#0000ff" size="2" face="Courier New"><strong>oIPic.Render()</strong></font> call (see above) tell us: “Position the ‘copy from – origin’ at x = 0, y=2646 (see 2nd pic from the left within the image just above) and start the line-wise transfer from there. Each transferred line in <strong><font color="#ff0000">–> </font><font color="#ff0000">x</font></strong> direction with a pixel-width defined by <strong>ABS(<i>HiMetric-Units</i>)</strong> of the <strong><em>cxSrc</em></strong> parameter. Proceed with next line in <strong><font color="#ff0000">-</font><font color="#ff0000">y</font></strong> direction. Loop until as much pixel lines were transferred as defined in <strong>ABS(<i>HiMetric-Units</i>)</strong> of the <strong><em>cySrc</em></strong> parameter. Now, we are able to mirror any image during rendering along both axis:</p>
<p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Spiegelungen" border="0" alt="Spiegelungen" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_2aWynLMSZdsnl24ZSBNq1AW9pGpbgmUzcgxU2yXYMM4LbLwEl5QGxfin2wHlMfs8rRXs3fWYLBBx5cva2u1qREuH0uO82bFgRwj6n7t9p688yXxNAySguEADsM4MWNHIolML/?imgmax=800" width="361" height="357" /></p>
<h4><font color="#000080">Solving the Hourglass Problem</font></h4>
<p><font size="3">There is another weird VFP behavior most of us already encountered in the past: the “hourglass problem”! Sometimes, we want VFP to refresh some form content which results in a cascading refresh. Controls that have to be refreshed sometimes have images assigned to their .Picture properties. Such image references always point to a file on the disk (or the app/exe which makes no difference). In other words, VFP has to access the disk in one way or another. If these disk accesses last more than a few milliseconds, then the operating system changes the mouse cursor to an hourglass! And sometimes VFP isn’t aware of that change. As long as the user doesn’t touch the mouse, VFP doesn’t refresh (reset) the mouse cursor symbol. Thus, for the user it seems like VFP still is busy. With the help of VFP’s <strong><em>LOADPICTURE()</em></strong> function (and the newly introduced <strong><em>.PictureVal</em></strong> property) it is now possible to avoid a wrong hourglass cursor display. Using code like the following one</font></p>
<pre><strong><font size="3"><span style="color: #0000ff">_Screen</span>.<span style="color: #0000ff">AddObject</span>("<span style="background-color: #ffff00; color: red">oImage</span>","<span style="background-color: #ffff00; color: red">IMAGE</span>")
oPicture = <span style="color: #0000ff">LOADPICTURE</span>(GETPIC())
<span style="color: #0000ff">_SCREEN</span>.oImage.<span style="color: #0000ff">PictureVal</span> = m.oPicture
<span style="color: #0000ff">_SCREEN</span>.oImage.<span style="color: #0000ff">Visible</span> = .T.</font></strong></pre>
<p><font size="3">never ever again will display the wrong hourglass mouse cursor, because there no longer is any disk access! Before you now shout: “That’s COOL!”, read on; there is a severe drawback caused by a VFP bug!</font></p>
<h4><font color="#000080">Solving the PictureVal Bug</font></h4>
<p><font size="3">This is a short excerpt taken from one of my elder VFP projects. First, the INIT() of one of my VFP Image classes is the place where I load the COM-Images</font></p>
<pre><strong><font size="2"><span style="color: #0000ff">LOCAL</span> lcPicture <span style="color: #0000ff">AS</span> <span style="color: #0000ff">String</span>
<span style="color: #0000ff">WITH</span> <span style="color: #0000ff">THIS</span>
<span style="color: #0000ff"><font color="#000000"> </font>IF</span> .EnableMultiStatePictures
<span style="color: #008000">*\\ reassure we have pictures to display </span>
lcPicture = <span style="color: #0000ff">JUSTFNAME</span>(.<span style="color: #0000ff">Picture</span>)
<span style="color: #0000ff">IF</span> <span style="color: #0000ff">EMPTY</span>(.PictureEnabled)
.PictureEnabled = m.lcPicture
<span style="color: #0000ff">ENDIF</span>
<span style="color: #0000ff">IF</span> <span style="color: #0000ff">EMPTY</span>(.PictureDisabled)
.PictureDisabled = m.lcPicture
<span style="color: #0000ff">ENDIF</span>
<span style="color: #0000ff">IF</span> <span style="color: #0000ff">EMPTY</span>(.PictureMouseOver)
.PictureMouseOver = m.lcPicture
<span style="color: #0000ff">ENDIF</span>
<span style="color: #0000ff">IF</span> <span style="color: #0000ff">EMPTY</span>(.PicturePressed)
.PicturePressed = .PictureMouseOver
<span style="color: #0000ff">ENDIF</span>
<span style="color: #0000ff">IF</span> <span style="color: #0000ff">EMPTY</span>(.PictureSelected)
.PictureSelected = .PicturePressed
<span style="color: #0000ff">ENDIF</span>
<span style="color: #008000">*\\ set basic state</span>
.ImageState = <span style="color: #0000ff">IIF</span>(.<span style="color: #0000ff">Enabled</span>, 1, 0)
<span style="color: #008000">*//</span>
<span style="color: #0000ff"> ENDIF</span>
<span style="color: #0000ff"><font color="#000000"> </font>IF</span> .EnableComPictureHandling
<span style="color: #008000">*\\ The reason for using COM instances of JPG-images in conjunction with Image.PictureVal properties</span>
<span style="color: #008000">*\\ is, that we no longer have disk access. Thus, the hourglas mouse cursor never appears when</span>
<span style="color: #008000">*\\ clicking or hovering in/out on an image (refreshing it). BUT we have to be very carefully NOT</span>
<span style="color: #008000">*\\ to assign the same COM interface to THIS.PictureVal _twice_in_a_row!!! Doing so, will result in</span>
<span style="color: #008000">*\\ VFP looses the COM-reference to that picture object randomly. For more details see</span>
<span style="color: #008000">*\\ THIS._old_oPictureDisabled_Access() method.</span>
.PictureEnabled = <span style="color: #0000ff">LOADPICTURE</span>(<span style="color: #0000ff">LOCFILE</span>(<span style="color: #0000ff">JUSTSTEM</span>(.PictureEnabled),<span style="color: #0000ff">JUSTEXT</span>(.PictureEnabled),"<span style="background-color: #ffff00; color: red">Locate image</span>"))
.PictureDisabled = <span style="color: #0000ff">LOADPICTURE</span>(<span style="color: #0000ff">LOCFILE</span>(<span style="color: #0000ff">JUSTSTEM</span>(.PictureDisabled),<span style="color: #0000ff">JUSTEXT</span>(.PictureDisabled),"<span style="background-color: #ffff00; color: red">Locate image</span>"))
.PictureMouseOver = <span style="color: #0000ff">LOADPICTURE</span>(<span style="color: #0000ff">LOCFILE</span>(<span style="color: #0000ff">JUSTSTEM</span>(.PictureMouseOver),<span style="color: #0000ff">JUSTEXT</span>(.PictureMouseOver),"<span style="background-color: #ffff00; color: red">Locate image</span>"))
.PicturePressed = <span style="color: #0000ff">LOADPICTURE</span>(<span style="color: #0000ff">LOCFILE</span>(<span style="color: #0000ff">JUSTSTEM</span>(.PicturePressed),<span style="color: #0000ff">JUSTEXT</span>(.PicturePressed),"<span style="background-color: #ffff00; color: red">Locate image</span>"))
.PictureSelected = <span style="color: #0000ff">LOADPICTURE</span>(<span style="color: #0000ff">LOCFILE</span>(<span style="color: #0000ff">JUSTSTEM</span>(.PictureSelected),<span style="color: #0000ff">JUSTEXT</span>(.PictureSelected),"<span style="background-color: #ffff00; color: red">Locate image</span>"))
<span style="color: #0000ff"><font color="#000000"> </font>ENDIF</span>
<span style="color: #0000ff">ENDWITH</span></font></strong></pre>
<p>This is the content of the _old_oPictureDisabled_Access() method:</p>
<pre><strong><font size="3"><span style="color: #008000">*\\ It took me hours to find out what was going wrong! </span>
<span style="color: #008000">*\\ These are my findings:</span>
<span style="color: #008000">*\\ Assigning an interface reference of a COM-ImageObject </span>
<span style="color: #008000">*\\ (created using VFP's LOADPICTURE() function) to </span>
<span style="color: #008000">*\\ This.PictureVal property will work properly as long as </span>
<span style="color: #008000">*\\ you do not *reassign* the same reference to .PictureVal again!!</span>
<span style="color: #008000">*\\ Reassignment may work many times flawlessly, but (and that's for sure!) </span>
<span style="color: #008000">*\\ eventually VFP looses its internal COM reference completely </span>
<span style="color: #008000">*\\ after a reassignment! Apart from the fact that reassignments</span>
<span style="color: #008000">*\\ aren't necessary at all (coz the picture already is shown), </span>
<span style="color: #008000">*\\ they might occur, especially if one had coded COM-image reference </span>
<span style="color: #008000">*\\ assignments to .PictureVal properties all over the place generously </span>
<span style="color: #008000">*\\ without knowing about this issue!</span>
<span style="color: #008000">*//</span>
<pre><span style="color: #008000">*\\ My solution now is to use a new integer property <.ImageState> </span>
<span style="color: #008000">*\\ that may hold one of the following values: 0=Disabled; 1=Enabled; </span>
<span style="color: #008000">*\\ 2=MouseOver; 4=Pressed; 8=Selected (a bit field). This property tells </span>
<span style="color: #008000">*\\ me exactly which COM-ImageObject reference is assigned to </span>
<span style="color: #008000">*\\ the .PictureVal property at any moment. In all places where I </span>
<span style="color: #008000">*\\ have to assign another COM-Image reference, I carefully test </span>
<span style="color: #008000">*\\ against the <.ImageState> property value before assigning the </span>
<span style="color: #008000">*\\ new reference to eliminate reassignments completely!</span>
</pre></font></strong><p><font size="3"><font face="Calibri">The bottom line is: <strong><font color="#ff0000">THIS IS A VFP BUG</font></strong>! <br />But, luckily, a solution (a workaround) is pretty easy to implement. In fact, it may even help to speed up your executable/application. </font><font face="Calibri">I have to stress it here once more: The buggy behavior does only appear if one is reassigning the same COM interface reference to an image-object’s PictureVal property more than once in a row! </font></font></p><p><font size="3" face="Calibri">The the first loop of following code works flawlessly:</font> </p><pre><strong><font size="3"><span style="color: #0000ff">LOCAL</span> lnLoop <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>, oComPic1 <span style="color: #0000ff">AS</span> olePic
oComPic1 = <span style="color: #0000ff">LOADPICTURE</span>(<span style="color: #0000ff">GETFILE</span>())
oComPic2 = <span style="color: #0000ff">LOADPICTURE</span>(<span style="color: #0000ff">GETFILE</span>())
<span style="color: #0000ff">TRY</span>
<span style="color: #0000ff">_Screen</span>.<span style="color: #0000ff">Addobject</span>("<span style="background-color: #ffff00; color: red">oImage</span>","<span style="background-color: #ffff00; color: red">IMAGE</span>")
<span style="color: #0000ff">CATCH</span>
<span style="color: #0000ff">FINALLY</span>
<span style="color: #0000ff">_Screen</span>.oImage.<span style="color: #0000ff">Visible</span> = .T.
ENDTRY
<span style="color: #0000ff">FOR</span> lnLoop = 1 <span style="color: #0000ff">to</span> 100
<span style="color: #0000ff">_Screen</span>.oImage.<span style="color: #0000ff">PictureVal</span> = m.oComPic1
<span style="color: #0000ff">_Screen</span>.oImage.<span style="color: #0000ff">PictureVal</span> = m.oComPic2
<span style="color: #0000ff">NEXT</span>
<span style="color: #008000">*//</span></font></strong></pre><pre><strong><font size="3"><span style="color: #008000">*\\ whereas the next loop will break somewhere down the road:</span>
<span style="color: #0000ff">FOR</span> lnLoop = 1 <span style="color: #0000ff">to</span> 100
<span style="color: #0000ff">_Screen</span>.oImage.<span style="color: #0000ff">PictureVal</span> = m.oComPic1
<span style="color: #0000ff">_Screen</span>.oImage.<span style="color: #0000ff">PictureVal</span> = m.oComPic1
<span style="color: #0000ff">_Screen</span>.oImage.<span style="color: #0000ff">PictureVal</span> = m.oComPic2
<span style="color: #0000ff">_Screen</span>.oImage.<span style="color: #0000ff">PictureVal</span> = m.oComPic2
<span style="color: #0000ff">NEXT</span></font></strong></pre><p><font size="3" face="Calibri">You will receive the following error, leaving you with a superficially valid COM object!</font></p><p><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="1" border="0" alt="1" src="http://lh6.ggpht.com/_MOmDLu4Rm5Y/TbbQyxLwMWI/AAAAAAAAHaY/P7oqVlhTyFk/1%5B6%5D.png?imgmax=800" width="476" height="159" /></p><p><font color="#000000" size="3" face="Calibri"><strong>Believe me, that’s no fun to debug! <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-sadsmile" alt="Trauriges Smiley" src="http://lh5.ggpht.com/_MOmDLu4Rm5Y/TbbQzLf6g0I/AAAAAAAAHac/FMJQH88HHvg/wlEmoticon-sadsmile%5B2%5D.png?imgmax=800" /></strong></font></p></pre>
<h4><font color="#000080">ToDOs</font></h4>
<p><font size="3">Now, we really have some work to do before displaying our COM images directly:</font></p>
<ul>
<li><font size="3">We have to get a device context handle </font></li>
<li><font size="3">We have to get our current display resolution (DPI) </font></li>
<li><font size="3">We have to know all about “dots per inch” and <i>HiMetric</i> units </font></li>
<li><font size="3">We have to convert pixels to <i>HiMetric</i> units and vice versa (before we can use them) </font></li>
</ul>
<p><font color="#000080" size="3"></font></p>
<p><font color="#0000ff" size="4"><strong>The rest of this post is the content of my <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="OffSiteLink" border="0" alt="OffSiteLink" src="http://lh5.ggpht.com/_MOmDLu4Rm5Y/TbX_M2WsnpI/AAAAAAAAHaU/l-fMgq3n4XE/OffSiteLink%5B2%5D.gif?imgmax=800" width="22" height="14" /> </strong></font><a title="http://vfpx.codeplex.com/wikipage?title=VFP%209%20SP2%20Help%20File&referringTitle=Home" href="http://vfpx.codeplex.com/wikipage?title=VFP%209%20SP2%20Help%20File&referringTitle=Home" rel="nofollow" target="_blank"><font color="#9b00d3" size="4"><strong>VFPX Help file project</strong></font></a><font color="#0000ff" size="4"><strong> contribution.</strong></font></p>
<h2>LOADPICTURE([cFileName])</h2>
<h3><font color="#000080">Parameters</font></h3>
<p><b><i>cFileName
<br /></i></b>Specifies the image file on disk for which an object is created. The following image types are supported:
<table border="1" cellspacing="0" cellpadding="5" width="638"><tbody>
<tr>
<td style="background-color: #6633ff; color: #ffffff" width="325">
<p align="center"><b><font size="2">Image Type Groups</font></b></p>
</td>
<td style="background-color: #6633ff; color: #ffffff" width="311">
<p align="center"><b><font size="2">Filename Extensions</font></b></p>
</td>
</tr>
<tr>
<td valign="top" width="331">
<p>bitmaps</p>
</td>
<td valign="top" width="314">
<p>.bmp, .jpg, .jpeg, .jpe, .jfif, .gif, .giff, .gfa</p>
</td>
</tr>
<tr>
<td valign="top" width="332">
<p>icons</p>
</td>
<td valign="top" width="316">
<p>.ico</p>
</td>
</tr>
<tr>
<td valign="top" width="331">
<p>windows metafiles</p>
</td>
<td valign="top" width="317">
<p>.wmf</p>
</td>
</tr>
<tr>
<td valign="top" width="331">
<p>windows enhanced metafiles</p>
</td>
<td valign="top" width="317">
<p>.emf</p>
</td>
</tr>
<tr>
<td valign="top" width="331">
<p>cursor</p>
</td>
<td valign="top" width="317">
<p>.cur</p>
</td>
</tr>
</tbody></table>
<strong>Table 1 Supported Image Types</strong></p>
<p>The following restrictions (tested with VFP 9 SP2 and OlePro32.dll Version 6.0.6002.18005) exist:
<table border="1" cellspacing="0" cellpadding="5" width="649"><tbody>
<tr>
<td style="background-color: #6633ff; color: #ffffff" width="284">
<p align="center"><b><font size="2">Image Type Groups</font></b></p>
</td>
<td style="background-color: #6633ff; color: #ffffff" width="363">
<p align="center"><b><font size="2">Restrictions & Issues</font></b></p>
</td>
</tr>
<tr>
<td valign="top" width="285">
<p>bitmaps</p>
</td>
<td valign="top" width="363">
<p>Loading <b>.tif</b> and <b>.png</b> formats will cause an OLE error.</p>
</td>
</tr>
<tr>
<td valign="top" width="285">
<p>icons</p>
</td>
<td valign="top" width="363">
<p>Icons are allowed with sizes up to 128x128 and must not have more than 256 colors. Even if there is more than one icon stored in the icon file, always only the smallest icon gets displayed. The icon file may contain much more icons - even with more colors and larger sizes - as long as there is at least one that complies with the rules above, then no exception is thrown.</p>
</td>
</tr>
<tr>
<td valign="top" width="285">
<p>cursor</p>
</td>
<td valign="top" width="363">
<p>Cursor files must not have more than 1K of file size, otherwise an OLE error is generated. Cursor files containing 16 color cursors can be loaded flawlessly, but only monochrome output is supported. Loading an animated cursor (.ani) causes an OLE error to be raised.</p>
</td>
</tr>
</tbody></table>
</p>
<p><strong>Table 2 Known Limitations</strong></p>
<h4><font color="#000080">Null Picture Support</font></h4>
<p><b></b>If <i>cFileName</i> is omitted, an uninitialized “<b>null picture”</b> object is returned. </p>
<p>You can include GETPICT( ) as <i>cFileName</i> to display the Open dialog from which you can choose a bitmap file.<b>
<br /></b></p>
<h3><font color="#000080">Return Value</font></h3>
<p>VFP’s <i>LOADPICTURE()</i> function returns a <b><i>Picture</i></b> type COM object reference that can be assigned to ActiveX controls and VFP’s Image object’s <i>PictureVal</i> property. However, the real primary interface <b><i>iPicture</i></b> only can be retrieved using code like this:
<br /></p>
<pre><strong><font size="3">oIPicture = <span style="color: #0000ff">GETINTERFACE</span>(<span style="color: #0000ff">LOADPICTURE</span>(<span style="color: #0000ff">GETPICT</span>()), "<span style="background-color: #ffff00; color: red">iPicture</span>")
</font></strong></pre>
<h3><font color="#000080">Remarks</font></h3>
<p>Picture objects provide a language-neutral abstraction for bitmaps, icons, and metafiles. As with the standard font object, the system provides a standard implementation of the picture object. Its primary interfaces are <strong><i>i</i></strong><strong><i>Picture</i></strong> and <strong><i>iPictureDisp</i></strong>. A picture object is created with <strong><i>OleCreatePictureIndirect</i></strong> and supports both the <strong><i>iPicture</i></strong> and the <strong><i>iPctureDisp</i></strong> interfaces. The OLE-provided picture object implements the complete semantics of the <strong><i>iPcture</i></strong> and <strong><i>iPictureDisp</i></strong> interfaces. In other words, there’s no need to use another interface than <b><i>iPicture</i></b>!</p>
<p>VFP’s <i>LOADPICTURE()</i> function internally wraps the <b><i>OleCreatePictureIndirect()</i></b> function implemented in <b><i>OleAut32.dll</i></b>. Thus, all you can read about that function (above and online) is also true for VFP’s <i>LOADPICTURE()</i> function. <i>LOADPICTURE ()</i> was added to VFP’s vocabulary to make it easier to load images with COM interfaces that many presentation properties of ActiveX controls require for their settings. For example, the <i>ActiveX Outline control</i> has a <i>PictureOpen</i> property that requires a COM object image reference for its setting.</p>
<p>The COM object returned by VFP’s <i>LOADPICTURE()</i> function hides its primary interface <b><i>iPicture</i></b>. In contrast to the reference<b><i> </i></b>returnd by VFP’s <i>LOADPICTURE()</i>, the OLE-image’s primary <b><i>iPicture</i></b> interface is the only fully functional one. In other words, only <b><i>iPicture</i></b> can be used in VFP programms without generating any OLE errors. Because <b><i>iPicture</i></b> is a superset of <b><i>Picture</i></b> it may be, better, <i>it should be</i> used everywhere instead of the one returnd by <i>LOADPICTURE()</i> ! <b>Example #1</b> in the examples section below proves that it makes no difference which OLE image interface gets assigned to a VFP <i>oIMAGE.PICTUREVAL</i> property. </p>
<p>The IID of the <b><i>iPicture</i></b> interface is defined as “{7BF80980-BF32-101A-8BBB-00AA00300CAB}”. Thus, the following two lines of code both create a <b><i>null picture OLE image object</i></b>:
<br /></p>
<pre><strong><font size="3">oIPicture1 = <span style="color: #0000ff">GETINTERFACE</span>(<span style="color: #0000ff">LOADPICTURE</span>(<span style="color: #0000ff">GETPICT</span>()), "<span style="background-color: #ffff00; color: red">iPicture</span>")
oIPicture2 = <span style="color: #0000ff">CREATEOBJECTEX</span>("<span style="background-color: #ffff00; color: red">StdPicture</span>","<span style="background-color: #ffff00; color: red"></span>","<span style="background-color: #ffff00; color: red">{7BF80980-BF32-101A-8BBB-00AA00300CAB}</span>")</font></strong></pre>
<p><strong>
<br /><font size="3"></font></strong></p>
<p><strong><font size="3"></font></strong></p>
<h3><font color="#000080">Interface Members</font></h3>
<p>The following table summarizes the PEMs (with prefix P: = property, M: = method) of the <b><i>iPicture</i></b> interface. ‘Green’ PEMs are read/writable, all others are readonly.
<table border="1" cellspacing="0" cellpadding="5" width="650"><tbody>
<tr>
<td style="background-color: #6633ff; color: #ffffff" width="201">
<p align="center"><b><font size="2">PEM</font></b></p>
</td>
<td style="background-color: #6633ff; color: #ffffff" width="242">
<p align="center"><b><font size="2">Used for</font></b></p>
</td>
<td style="background-color: #6633ff; color: #ffffff" width="205">
<p align="center"><b><font size="2">ValueType</font></b></p>
</td>
</tr>
<tr>
<td width="201">
<p><b>P: Attributes</b></p>
</td>
<td valign="top" width="242">
<p>The current set of the picture's bit attributes.</p>
</td>
<td width="205">
<p>DWORD (int)</p>
</td>
</tr>
<tr>
<td width="201">
<p><b>P: CurDC</b></p>
</td>
<td valign="top" width="242">
<p>The current device context into which this picture is selected.</p>
</td>
<td width="205">
<p>HDC (long)</p>
</td>
</tr>
<tr>
<td width="201">
<p><b>P: Handle</b></p>
</td>
<td valign="top" width="242">
<p>Handle to the picture managed within this picture object.</p>
</td>
<td width="205">
<p>OLE_Handle (int)</p>
</td>
</tr>
<tr>
<td width="201">
<p><b>P: Height</b></p>
</td>
<td valign="top" width="242">
<p>The current height of the picture in the picture object.</p>
</td>
<td width="205">
<p>OLE_XSIZE_HIMETRIC (long)</p>
</td>
</tr>
<tr>
<td width="201">
<p><b>P: hPal</b></p>
</td>
<td valign="top" width="242">
<p>The current palette of the picture (if any).</p>
</td>
<td width="205">
<p>OLE_Handle (int)</p>
</td>
</tr>
<tr>
<td width="201">
<p><b>P: KeepOriginalFormat</b></p>
</td>
<td valign="top" width="242">
<p>The current value of the picture object's <i>KeepOriginalFormat</i> property.</p>
</td>
<td width="205">
<p>Bool</p>
</td>
</tr>
<tr>
<td width="201">
<p><b>P: Type</b></p>
</td>
<td valign="top" width="242">
<p>The current type of the picture.</p>
</td>
<td width="205">
<p>Short (int)</p>
</td>
</tr>
<tr>
<td width="201">
<p><b>P: Width</b></p>
</td>
<td valign="top" width="242">
<p>The current width of the picture in the picture object.</p>
</td>
<td width="205">
<p>OLE_XSIZE_HIMETRIC (long)</p>
</td>
</tr>
<tr>
<td width="201">
<p><b>M: PictureChanged</b></p>
</td>
<td valign="top" width="242">
<p>Notifies the picture object that its picture resource changed.</p>
</td>
<td width="205"> </td>
</tr>
<tr>
<td width="201">
<p><b>M: Render</b></p>
</td>
<td valign="top" width="242">
<p>Draws the specified portion of the picture onto the specified device context, positioned at the specified location.</p>
</td>
<td width="205"> </td>
</tr>
<tr>
<td width="201">
<p><b>M: SaveAS File</b></p>
</td>
<td valign="top" width="242">
<p>Saves the picture's data into a stream in the same format that it would save itself into a file.</p>
</td>
<td width="205"> </td>
</tr>
<tr>
<td width="201">
<p><b>M: SelectPicture</b></p>
</td>
<td valign="top" width="266">
<p>Selects a bitmap picture into a given device context, returning the device context in which the picture was previously selected as well as the picture's handle.</p>
</td>
<td width="263"> </td>
</tr>
</tbody></table>
</p>
<p><strong>Table 3 iPicture Interface Members</strong></p>
<p>The <i>Attributes</i> property is said to hold the picture’s bit attributes. Actually, there are only two, which can be set alone, or additive. The following table lists both possible values:
<table border="1" cellspacing="0" cellpadding="0"><tbody>
<tr>
<td style="background-color: #6633ff; color: #ffffff" width="168">
<p align="center"><b><font size="2">Constant </font></b></p>
</td>
<td style="background-color: #6633ff; color: #ffffff" width="378">
<p align="center"><b><font size="2">Description</font></b></p>
</td>
<td style="background-color: #6633ff; color: #ffffff" width="57">
<p align="center"><b><font size="2">Value</font></b></p>
</td>
</tr>
<tr>
<td width="168">
<p align="center"><b>PICTURE_SCALABLE</b></p>
</td>
<td valign="top" width="378">
<p>The picture object is scalable, such that it can be redrawn with a different size than was used to create the picture originally. Metafile-based pictures are considered scalable; icon and bitmap pictures, while they can be scaled, do not express this attribute because both involve bitmap stretching instead of true scaling.</p>
</td>
<td width="57">
<p>1</p>
</td>
</tr>
<tr>
<td width="168">
<p><b>PICTURE_TRANSPARENT</b></p>
</td>
<td valign="top" width="378">
<p>The picture object contains an image that has transparent areas, such that drawing the picture will not necessarily fill in all the spaces in the rectangle it occupies. Metafile and icon pictures have this attribute; bitmap pictures do not.</p>
</td>
<td width="57">
<p>2</p>
</td>
</tr>
</tbody></table>
</p>
<p><strong>Table 4 PictureAttributes Enumeration</strong></p>
<p>The following table lists all possible values of the <i>iPicture.Type</i> property:
<table border="1" cellspacing="0" cellpadding="0"><tbody>
<tr>
<td style="background-color: #6633ff; color: #ffffff" width="145">
<p align="center"><b><font size="2">Constant </font></b></p>
</td>
<td style="background-color: #6633ff; color: #ffffff" width="306">
<p align="center"><b><font size="2">Description</font></b></p>
</td>
<td style="background-color: #6633ff; color: #ffffff" width="151">
<p align="center"><b><font size="2">Value</font></b></p>
</td>
</tr>
<tr>
<td width="145">
<p align="center"><b>PICTYPE_UNINITIALIZED</b></p>
</td>
<td valign="top" width="306">
<p>The picture object is currently uninitialized. <b>This value will never be returned within VFP</b>!</p>
</td>
<td valign="top" width="151">
<p>-1</p>
</td>
</tr>
<tr>
<td width="145">
<p><b>PICTYPE_NONE</b></p>
</td>
<td valign="top" width="306">
<p>A new picture object is to be created without an initialized state. <b>This value is returned from VFP if LoadPicture() is used without a parameter</b>.</p>
</td>
<td valign="top" width="151">
<p>0</p>
</td>
</tr>
<tr>
<td width="145">
<p><b>PICTYPE_BITMAP</b></p>
</td>
<td valign="top" width="306">
<p>The picture type is a bitmap.</p>
</td>
<td valign="top" width="151">
<p>1</p>
</td>
</tr>
<tr>
<td width="145">
<p><b>PICTYPE_METAFILE</b></p>
</td>
<td valign="top" width="306">
<p>The picture type is a metafile.</p>
</td>
<td valign="top" width="151">
<p>2</p>
</td>
</tr>
<tr>
<td width="145">
<p><b>PICTYPE_ICON</b></p>
</td>
<td valign="top" width="306">
<p>The picture type is an icon.</p>
</td>
<td valign="top" width="151">
<p>3</p>
</td>
</tr>
<tr>
<td width="145">
<p><b>PICTYPE_ENHMETAFILE</b></p>
</td>
<td valign="top" width="306">
<p>The picture type is an enhanced metafile.</p>
</td>
<td valign="top" width="151">
<p>4</p>
</td>
</tr>
</tbody></table>
</p>
<p><strong>Table 5 Type Property Values</strong></p>
<p>The most interesting method of the COM image object’s <b><i>iPicture</i></b> interface ist <b><i>render()</i></b> which also works flawlessly only when called on the <b><i>iPicture</i></b> interface. The following table summarises the parameters of the <b><i>render()</i></b> method:
<table border="1" cellspacing="0" cellpadding="0"><tbody>
<tr>
<td style="background-color: #6633ff; color: #ffffff" width="95">
<p align="center"><b><font size="2">Parameter</font></b></p>
</td>
<td style="background-color: #6633ff; color: #ffffff" width="416">
<p align="center"><b><font size="2">Used for</font></b></p>
</td>
<td style="background-color: #6633ff; color: #ffffff" width="90">
<p align="center"><b><font size="2">Scale Unit</font></b></p>
</td>
</tr>
<tr>
<td width="95">
<p align="left"><b>hdc</b></p>
</td>
<td valign="top" width="416">
<p align="left">A handle of the device context on which to render the image.</p>
</td>
<td valign="top" width="90">
<p>------</p>
</td>
</tr>
<tr>
<td width="95">
<p><b>x</b></p>
</td>
<td valign="top" width="416">
<p>The horizontal coordinate in <em>hdc</em> at which to place the rendered image (X-position of upper left corner of output rectangle).</p>
</td>
<td valign="top" width="90">
<p>pixel</p>
</td>
</tr>
<tr>
<td width="95">
<p><b>y</b></p>
</td>
<td valign="top" width="416">
<p>The vertical coordinate in <em>hdc</em> at which to place the rendered image (X-position of upper left corner of output rectangle).</p>
</td>
<td valign="top" width="90">
<p>pixel</p>
</td>
</tr>
<tr>
<td width="95">
<p><b>cx</b></p>
</td>
<td valign="top" width="416">
<p>The horizontal dimension (width) of the destination rectangle (with of output rectangle).</p>
</td>
<td valign="top" width="90">
<p>pixel</p>
</td>
</tr>
<tr>
<td width="95">
<p><b>cy</b></p>
</td>
<td valign="top" width="416">
<p>The vertical dimension (height) of the destination rectangle (height of output rectangle).</p>
</td>
<td valign="top" width="90">
<p>pixel</p>
</td>
</tr>
<tr>
<td width="95">
<p><b>xSrc</b></p>
</td>
<td valign="top" width="416">
<p>The horizontal offset in the source picture from which to start copying.</p>
</td>
<td valign="top" width="90">
<p>HiMetric</p>
</td>
</tr>
<tr>
<td width="95">
<p><b>ySrc</b></p>
</td>
<td valign="top" width="416">
<p>The vertical offset in the source picture from which to start copying.</p>
</td>
<td valign="top" width="90">
<p>HiMetric</p>
</td>
</tr>
<tr>
<td width="95">
<p><b>cxSrc</b></p>
</td>
<td valign="top" width="416">
<p>The horizontal extent to copy from the source picture (width of image source’s clipping region AND direction of readout).</p>
</td>
<td valign="top" width="90">
<p>HiMetric</p>
</td>
</tr>
<tr>
<td width="95">
<p><b>cySrc</b></p>
</td>
<td valign="top" width="416">
<p>The vertical extent to copy from the source picture (height of image source’s clipping region AND direction of readout).</p>
</td>
<td valign="top" width="90">
<p>HiMetric</p>
</td>
</tr>
<tr>
<td width="95">
<p><b>lprcWBounds</b></p>
</td>
<td valign="top" width="416">
<p>If <i>hdc</i> is a metafile device context, the lprcWBounds parameter points to a <i>RECTL</i> structure specifying the bounding rectangle in the underlying metafile. The rectangle structure contains the window extent and window origin. These values are useful for drawing metafiles. The rectangle indicated by lprcBounds is nested inside this lprcWBounds rectangle; they are in the same coordinate space. If hdcDraw is not a metafile device context, lprcWBounds will be NULL. If hdcDraw is a metafile device context, lprcWBounds cannot be NULL!</p>
</td>
<td valign="top" width="90">
<p>------</p>
</td>
</tr>
</tbody></table>
</p>
<p><strong>Table 6 Render() Parameter Galore</strong></p>
<p>The method returns standard values like E_FAIL, E_INVALIDARG and E_OUTOFMEMORY, as well as S_OK, E_POINTER and CTL_E_INVALIDPROPERTYVALUE. These values are described on <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="OffSiteLink" border="0" alt="OffSiteLink" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIBQjtqB3XXBvZMUjOcPNGpnjuzSzLSux6ZLZX9orbZHEQU_bsg-xNMGP-Bopphl7LwPK1xsnEqgBP9gIwpMvENLnYXK0qpzGareCC0ns-M0hp4jEayTHDhPjuUK88CYn9sIIq/?imgmax=800" width="11" height="7" /> <a title="http://msdn.microsoft.com/de-de/library/ms644512(v=VS.100).aspx" href="http://msdn.microsoft.com/de-de/library/ms644512(v=VS.100).aspx" target="_blank">MSDN</a>.</p>
<h3><font color="#000080">Applications</font></h3>
<p><b>The render function has plenty of parameters</b>. Some of them passing in pixel values, others HiMetric values. <b>Example #3</b> has some useful conversions as well as other supporting functions and definitions. To figure out how <b><i>render()</i></b> works try the VFP code below; type it in line by line into VFP’s command window:</p>
<pre><font size="3"><strong><span style="color: #008000">* locate an image with round about 100 x 100 pixels </span>
goPic = <span style="color: #0000ff">LOADPICTURE</span>(<span style="color: #0000ff">GETPICT</span>())
gIP = <span style="color: #0000ff">GETINTERFACE</span>(m.goPic, "<span style="background-color: #ffff00; color: red">iPicture</span>")
goForm = <span style="color: #0000ff">CREATEOBJECT</span>("<span style="background-color: #ffff00; color: red">Form</span>")
goForm.<span style="color: #0000ff">Show</span>()
<span style="color: #008000">* declare access to the _client_area_ of a window </span>
<span style="color: #0000ff">DECLARE</span> <span style="color: #0000ff">Integer</span> GetDC <span style="color: #0000ff">IN</span> USER32 <span style="color: #0000ff">integer</span> <span style="color: #0000ff">HWnd</span>
<span style="color: #008000">* hDC should be <> 0 (otherwise that's an error)! </span>
hDC = GetDC(goForm.<span style="color: #0000ff">HWnd</span>)
<span style="color: #008000">* render your image directly onto form's client area </span>
gIP.Render(m.hDC,0,0,100,100,0,gIP.<span style="color: #0000ff">Height</span>,gIP.<span style="color: #0000ff">Width</span>,- gIP.<span style="color: #0000ff">Height</span>,<span style="color: #0000ff">NULL</span>)
<span style="color: #008000">* declare release function </span>
<span style="color: #0000ff">DECLARE</span> <span style="color: #0000ff">Integer</span> ReleaseDC <span style="color: #0000ff">IN</span> USER32 <span style="color: #0000ff">integer</span> <span style="color: #0000ff">HWnd</span>, <span style="color: #0000ff">integer</span> hDC
<span style="color: #008000">* next line should print 1 on the form's background >> "Okay" </span>
? ReleaseDC(m.goForm.<span style="color: #0000ff">HWnd</span>, m.hDC)
<span style="color: #008000">* declare access to the _whole_ window </span>
<span style="color: #0000ff">DECLARE</span> <span style="color: #0000ff">Integer</span> GetWindowDC <span style="color: #0000ff">IN</span> USER32 <span style="color: #0000ff">integer</span> <span style="color: #0000ff">HWnd</span>
<span style="color: #008000">* hDC now references form's caption an border areas as well! </span>
hDC = GetWindowDC(goForm.<span style="color: #0000ff">HWnd</span>)
<span style="color: #008000">* render out partially overwriting form's border and caption </span>
gIP.Render(m.hDC,0,0,100,100,0,gIP.<span style="color: #0000ff">Height</span>,gIP.<span style="color: #0000ff">Width</span>,- gIP.<span style="color: #0000ff">Height</span>,<span style="color: #0000ff">NULL</span>)
<span style="color: #008000">* never forget to free an allocated device context </span>
? ReleaseDC(m.goForm.<span style="color: #0000ff">HWnd</span>, m.hDC)
</strong></font></pre>
<p><strong>Direct input into VFP’s command window</strong></p>
<p><b><i>iPicture.Render()</i></b> qualifies for painting on otherwise unreachable form regions, like titlebar or borders. Another interesting application for direct rendering stems from the fact that no VFP object reference is necessary for painting. The <b><i>render()</i></b> method solely uses a common windows handle. Thus, one can render on any known device context.</p>
<h3><font color="#000080">Drawback</font></h3>
<p><b><i>iPicture.Render()</i></b> does its work outside of - and unnoticed by – the VFP engine itself. That’s why VFP has no idea of what was painted “between the lines”. Each time VFP refreshes the form’s area (we’ve just rendered our picture onto), will clear out our image. To make rendered output persistent measures have to be taken against VFP wiping it out! </p>
<h3><font color="#000080">Examples</font></h3>
<h4>Example #1</h4>
<p>The following example shows that both interfaces (<b><i>Picture</i></b> and <b><i>IPicture</i></b>) of a COM image instance can be assigned to VFP’s <b><i>Image.PictureVal</i></b> property:<b></b></p>
<pre><strong><font size="3"><span style="color: #0000ff">PUBLIC</span> goPic <span style="color: #0000ff">AS</span> Object, goIPic <span style="color: #0000ff">AS</span> Object
goPic = <span style="color: #0000ff">LOADPICTURE</span>(<span style="color: #0000ff">GETPICT</span>())
goIPic = <span style="color: #0000ff">GETINTERFACE</span>(m.goPic, "<span style="background-color: #ffff00; color: red">iPicture</span>")
<span style="color: #0000ff">_SCREEN</span>.<span style="color: #0000ff">AddObject</span>("<span style="background-color: #ffff00; color: red">oPic1</span>","<span style="background-color: #ffff00; color: red">IMAGE</span>")
<span style="color: #0000ff">_SCREEN</span>.<span style="color: #0000ff">AddObject</span>("<span style="background-color: #ffff00; color: red">oPic2</span>","<span style="background-color: #ffff00; color: red">IMAGE</span>")
<span style="color: #0000ff">WITH</span> <span style="color: #0000ff">_SCREEN</span>.oPic1
.<span style="color: #0000ff">VISIBLE</span> = .T.
.<span style="color: #0000ff">PICTUREVAL</span> = m.goPic <span style="color: #008000">&& "Picture"-Interface </span>
<span style="color: #0000ff">ENDWITH</span>
<span style="color: #0000ff">WITH</span> <span style="color: #0000ff">_SCREEN</span>.oPic2
.<span style="color: #0000ff">LEFT</span> = 110
.<span style="color: #0000ff">VISIBLE</span> = .T.
.<span style="color: #0000ff">PICTUREVAL</span> = m.goIPic <span style="color: #008000">&& "IPicture"-Interface</span>
<span style="color: #0000ff">ENDWITH</span>
<span style="color: #0000ff">HIDE</span> <span style="color: #0000ff">WINDOWS</span> <span style="color: #0000ff">ALL</span>
<span style="color: #0000ff">WAIT</span> <span style="color: #0000ff">WINDOW</span> "<span style="background-color: #ffff00; color: red">Press any key...</span>"
<span style="color: #0000ff">_SCREEN</span>.<span style="color: #0000ff">RemoveObject</span>("<span style="background-color: #ffff00; color: red">oPic1</span>")
<span style="color: #0000ff">_SCREEN</span>.<span style="color: #0000ff">RemoveObject</span>("<span style="background-color: #ffff00; color: red">oPic2</span>")
<span style="color: #0000ff">STORE</span> <span style="color: #0000ff">NULL</span> <span style="color: #0000ff">TO</span> goPic, goIPic
<span style="color: #0000ff">CLEAR</span>
<span style="color: #0000ff">SHOW</span> <span style="color: #0000ff">WINDOWS</span> <span style="color: #0000ff">ALL</span> </font></strong></pre>
<h4>Example #2</h4>
<p>The following example shows how to query the <b><i>iPicture</i></b> interface of a COM image instance. Intentionally, there are no Try…Catch…Endtry sections in this demo code, so that OLE errors may occur. You have to run the code snippet multiple times with different image types to see them.</p>
<pre><strong><font size="3">goPic = <span style="color: #0000ff">LOADPICTURE</span>(<span style="color: #0000ff">GETPICT</span>())
<span style="color: #0000ff">IF</span> <span style="color: #0000ff">VARTYPE</span>(m.goPic) == "<span style="background-color: #ffff00; color: red">O</span>"
goIPic = <span style="color: #0000ff">GETINTERFACE</span>(m.goPic, "<span style="background-color: #ffff00; color: red">iPicture</span>")
<span style="color: #0000ff">IF</span> <span style="color: #0000ff">VARTYPE</span>(m.goIPic) == "<span style="background-color: #ffff00; color: red">O</span>"
<span style="color: #0000ff">CLEAR</span> <span style="color: #008000">&& just some informal output: </span>
<span style="color: #0000ff">WITH</span> m.goIPic
?
? "<span style="background-color: #ffff00; color: red">Properties of 'IPicture'-Interface:</span>"
? "<span style="background-color: #ffff00; color: red">Attributes</span>" ,.<span style="color: #0000ff">Attributes</span>
<span style="color: #008000">*\\ next line will fail if an ICOn loaded </span>
? "<span style="background-color: #ffff00; color: red">CurDC</span>" ,.CurDC
? "<span style="background-color: #ffff00; color: red">Handle</span>" ,.Handle
? "<span style="background-color: #ffff00; color: red">Height</span>" ,.<span style="color: #0000ff">Height</span>
<span style="color: #008000">*\\ next line will fail if an ICOn loaded </span>
? "<span style="background-color: #ffff00; color: red">hPal</span>" ,.hPal
? "<span style="background-color: #ffff00; color: red">KeepOriginalFormat</span>",.KeepOriginalFormat
? "<span style="background-color: #ffff00; color: red">Type</span>" ,.<span style="color: #0000ff">Type</span>
? "<span style="background-color: #ffff00; color: red">Width</span>" ,.<span style="color: #0000ff">Width</span>
?
<span style="color: #0000ff">ENDWITH</span>
<span style="color: #0000ff">ENDIF</span>
<span style="color: #0000ff">ENDIF</span> </font></strong></pre>
<h4><a name="_Hlk291204454"><font color="#000000">Example #3</font></a></h4>
<a name="_Hlk291204454"></a>
<p><a name="_Hlk291204454"><b></b></a>The following code is a collection of supporting functions and declarations that come in handy while programming OLE image objects. </p>
<pre><strong><font size="3"><span style="color: #008000">* Supporting Functions & DEFINEs</span>
#<span style="color: #0000ff">DEFINE</span> INCH2MILLIMETER 25.4 <span style="color: #008000">&& 1 Inch = 25.4 millimeters</span>
#<span style="color: #0000ff">DEFINE</span> INCH2HIMETRICS (INCH2MILLIMETER <span style="color: #008000">* 100) && 1 HIMETRIC = 0.01</span>
<span style="color: #0000ff">FUNCTION</span> PXL2HIME(tnPixel <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>) <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>
<span style="color: #008000">* Pixel to HiMetric conversion</span>
<span style="color: #0000ff">LOCAL</span> lnPixelsOnOneHiMetricUnit <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>
lnPixelsOnOneHiMetricUnit = INCH2HIMETRICS / GetDPI()
<span style="color: #0000ff">RETURN</span> <span style="color: #0000ff">ROUND</span>(lnPixelsOnOneHiMetricUnit <span style="color: #008000">* m.tnPixel, 0)</span>
<span style="color: #0000ff">ENDFUNC</span>
<span style="color: #0000ff">FUNCTION</span> HIME2PXL(tnHimetric <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>) <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>
<span style="color: #008000">* HiMetric to Pixel conversion</span>
<span style="color: #0000ff">LOCAL</span> lnPixelsOnOneHiMetricUnit <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>
lnPixelsOnOneHiMetricUnit = INCH2HIMETRICS / GetDPI()
<span style="color: #0000ff">RETURN</span> <span style="color: #0000ff">ROUND</span>(m.tnHimetric / m.lnPixelsOnOneHiMetricUnit, 0)
<span style="color: #0000ff">ENDFUNC</span>
<span style="color: #0000ff">FUNCTION</span> GetDPI(tnHDC <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>) <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>
<span style="color: #008000">* retrieve dots per inch resolution </span>
<span style="color: #008000">* for VFP's _SCREEN device context</span>
<span style="color: #0000ff">DECLARE</span> <span style="color: #0000ff">Integer</span> GetDeviceCaps <span style="color: #0000ff">IN</span> GDI32 <span style="color: #0000ff">integer</span> hdc, <span style="color: #0000ff">integer</span> nIndex
<span style="color: #0000ff">DECLARE</span> <span style="color: #0000ff">Integer</span> GetWindowDC <span style="color: #0000ff">IN</span> USER32 <span style="color: #0000ff">integer</span> <span style="color: #0000ff">HWnd</span>
<span style="color: #0000ff">DECLARE</span> <span style="color: #0000ff">Integer</span> ReleaseDC <span style="color: #0000ff">IN</span> USER32 <span style="color: #0000ff">integer</span> <span style="color: #0000ff">HWnd</span>, <span style="color: #0000ff">integer</span> hDC
<span style="color: #008000">* For simplicity, we assume X- and Y- dimensions </span>
<span style="color: #008000">* using the same DPI resolution.</span>
#<span style="color: #0000ff">DEFINE</span> LOGPIXELSX 88 <span style="color: #008000">&& Logical pixels/inch in X </span>
#<span style="color: #0000ff">DEFINE</span> LOGPIXELSY 90 <span style="color: #008000">&& Logical pixels/inch in Y</span>
<span style="color: #008000">* Get VFP's _Screen-hDC to calculate resolution:</span>
<span style="color: #0000ff">LOCAL</span> lhDC <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>, lnDPI <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>
<span style="color: #0000ff">STORE</span> 0 <span style="color: #0000ff">TO</span> lhDC, lnDPI
lhDC = GetWindowDC(<span style="color: #0000ff">_Screen</span>.<span style="color: #0000ff">HWnd</span>)
<span style="color: #0000ff">IF</span> NOT m.lhDC = 0
lnDPI = GetDeviceCaps(m.lhDC, LOGPIXELSX)
<span style="color: #0000ff">ELSE</span>
lnDPI = 96 <span style="color: #008000">&& default to 96 DPI</span>
<span style="color: #0000ff">ENDIF</span>
<span style="color: #008000">* Free device context</span>
= ReleaseDC(<span style="color: #0000ff">_Screen</span>.<span style="color: #0000ff">HWnd</span>, m.lhDC)
<span style="color: #0000ff">RETURN</span> m.lnDPI
<span style="color: #0000ff">ENDFUNC</span>
<span style="color: #0000ff">FUNCTION</span> GetCanvas(tnHWND <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>, tlChild <span style="color: #0000ff">AS</span> Boolean) <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>
<span style="color: #008000">* Retrieve hDC (handle DeviceContext) of window handle</span>
<span style="color: #008000">* tlChild = TRUE := Use GetDC()</span>
<span style="color: #008000">* tlChild = FALSE := Use GetWindowDC()</span>
<span style="color: #0000ff">DECLARE</span> <span style="color: #0000ff">Integer</span> GetDC <span style="color: #0000ff">IN</span> USER32 <span style="color: #0000ff">integer</span> <span style="color: #0000ff">HWnd</span>
<span style="color: #0000ff">DECLARE</span> <span style="color: #0000ff">Integer</span> GetWindowDC <span style="color: #0000ff">IN</span> USER32 <span style="color: #0000ff">integer</span> <span style="color: #0000ff">HWnd</span>
<span style="color: #0000ff">LOCAL</span> lnHDC <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>
<span style="color: #0000ff">IF</span> m.tlChild
lnHDC = GetDC(m.tnHWND)
<span style="color: #0000ff">ELSE</span>
lnHDC = GetWindowDC(m.tnHWND)
<span style="color: #0000ff">ENDIF</span>
<span style="color: #0000ff">RETURN</span> m.lnHDC
<span style="color: #0000ff">ENDFUNC</span>
<span style="color: #0000ff">FUNCTION</span> ReleaseCanvas(tnHWND <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>, tnHDC <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>) <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>
<span style="color: #008000">* Releases a borrowed hDC</span>
<span style="color: #0000ff">DECLARE</span> <span style="color: #0000ff">Integer</span> ReleaseDC <span style="color: #0000ff">IN</span> USER32 <span style="color: #0000ff">integer</span> <span style="color: #0000ff">HWnd</span>, <span style="color: #0000ff">integer</span> hDC
<span style="color: #0000ff">RETURN</span> ReleaseDC(m.tnHWND, m.tnHDC)
<span style="color: #0000ff">ENDFUNC</span>
<span style="color: #008000"><font color="#ff0000">* The following function is not bullet-proof, as it fails on forms with scrollbars ;<br /> </font></span></font></strong><strong><font size="3"><font color="#ff0000"><span style="color: #008000"><font color="#ff0000">(oForm.Scrollbars > 0) See Example #4 for a working solution!</font></span>
</font><span style="color: #0000ff">FUNCTION</span> GetChildAreaCanvas(tnhWnd <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>) <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>
<span style="color: #008000">* VFP ‘TopLevelForms’ (oForm.ShowWindow = 2) have</span>
<span style="color: #008000">* a secondary window inside the outer one.</span>
<span style="color: #008000">* This is also true for forms showing scrollbars!</span>
<span style="color: #0000ff">LOCAL</span> lnVfpHANDLE <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>, lnClienthWnd <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>, lnHDC <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>
<span style="color: #008000">* Convert the given Windows hWnd to an internal VFP WHANDLE</span>
lnVfpHANDLE = <span style="color: #0000ff">SYS</span>(2326, m.tnhWnd)
<span style="color: #008000">* Retrieve the Windows hWnd for a client window </span>
<span style="color: #008000">* (WCLIENTWINDOW) of a specified Visual FoxPro parent window</span>
lnClienthWnd = <span style="color: #0000ff">SYS</span>(2325, m.lnVfpHANDLE)
<span style="color: #008000">* Check if there is a WCLIENTWINDOW</span>
<span style="color: #0000ff">IF</span> lnClienthWnd = lnVfpHANDLE
<span style="color: #008000">* No such WCLIENTWINDOW, return child’s client area</span>
lnHDC = GetCanvas(m.tnhWnd, .T.)
<span style="color: #0000ff">ELSE</span>
<span style="color: #008000">* There IS a WCLIENTWINDOW!</span>
<span style="color: #008000">* Get the device context handle for the </span>
<span style="color: #008000">* whole client area of that window:</span>
lnHDC = GetCanvas(lnClienthWnd)
<span style="color: #0000ff">ENDIF</span>
<span style="color: #0000ff">RETURN</span> m.lnHDC
<span style="color: #0000ff">ENDFUNC</span>
</font></strong></pre>
<h4><font color="#000080">Example #4</font></h4>
<p>The following example demonstrates how to render an image on different types of forms. Copy the code to a PRG file, then compile and run it. </p>
<p>The first section of the program can be seen as a testing setup. You will be asked four times to select a picture from your local disk. Then, a form will be created and the chosen picture will be rendered inside it. The MyForm class definition holds all functionality. At the end of this listing there are three supporting subclasses of <em>MyForm</em> called <i><strong>MyScrollableForm</strong>, <strong>MyDockableForm</strong>, </i>and<i> <strong>MyTopLevelForm</strong></i> which gets instantiated to test all kinds of form types. You may want to run the demo several times while changing/varying the base form’s (MyForm) <b>Scrollbars</b> and <b>MDIForm</b> property values. In addition to that you may uncomment the DEBUGOUT lines in <i>MyForm.HandleWinMsg1()</i> and <i>HandleWinMsg2()</i> to watch WinMessages in your debugger. The method <b><i>MyForm.ImageAttribs()</i></b><i> </i>is called at the end of <b><i>MyForm.RetrievePicture()</i></b><i> </i>method. If you like to see additional information about the loaded image, uncomment the invocation there.</p>
<span style="color: #0000ff"></span>
<pre><strong><font size="2"><span style="color: #0000ff">CLEAR</span>
<span style="color: #008000">*** SET STEP ON </span>
<span style="color: #0000ff">RELEASE</span> <span style="color: #0000ff">ALL</span> <span style="color: #0000ff">LIKE</span> goForm<span style="color: #008000">*</span>
<span style="color: #0000ff">PUBLIC</span> goForm1, goForm2, goForm3, goForm4
<span style="color: #008000">*//</span>
<span style="color: #008000">*\\ Try rendering on a form in SCREEN</span>
goForm1 = <span style="color: #0000ff">CREATEOBJECT</span>("<span style="background-color: #ffff00; color: red">MyForm</span>") <span style="color: #008000">&& IN_SCREEN (MDIForm = .T.)</span>
<span style="color: #0000ff">IF</span> <span style="color: #0000ff">VARTYPE</span>(m.goForm1) == "<span style="background-color: #ffff00; color: red">O</span>"
goForm1.<span style="color: #0000ff">Show</span>()
goForm1.<span style="color: #0000ff">Caption</span> = "<span style="background-color: #ffff00; color: red">goForm1 => IN_SCREEN (MDIForm = .T.)</span>"
goForm1.<span style="color: #0000ff">Name</span> = "<span style="background-color: #ffff00; color: red">goForm1</span>"
<span style="color: #0000ff">ENDIF</span>
<span style="color: #008000">*//</span>
<span style="color: #008000">* SET STEP ON</span>
<span style="color: #008000">*\\ Try rendering on a dockable form</span>
goForm2 = <span style="color: #0000ff">CREATEOBJECT</span>("<span style="background-color: #ffff00; color: red">MyDockableForm</span>") <span style="color: #008000">&& IN_SCREEN (dockable = 1)</span>
<span style="color: #0000ff">IF</span> <span style="color: #0000ff">VARTYPE</span>(m.goForm2) == "<span style="background-color: #ffff00; color: red">O</span>"
goForm2.<span style="color: #0000ff">Show</span>()
goForm2.<span style="color: #0000ff">Caption</span> = "<span style="background-color: #ffff00; color: red">goForm2 => IN_SCREEN (dockable = 1)</span>"
goForm2.<span style="color: #0000ff">Name</span> = "<span style="background-color: #ffff00; color: red">goForm2</span>"
<span style="color: #0000ff">ENDIF</span>
<span style="color: #008000">*//</span>
<span style="color: #008000">* SET STEP ON </span>
<span style="color: #008000">*\\ Try rendering on a TopLevelForm (TLF)</span>
goForm3 = <span style="color: #0000ff">CREATEOBJECT</span>("<span style="background-color: #ffff00; color: red">MyTopLevelForm</span>") <span style="color: #008000">&& AS_TOPLEVEL_FORM</span>
<span style="color: #0000ff">IF</span> <span style="color: #0000ff">VARTYPE</span>(m.goForm3) == "<span style="background-color: #ffff00; color: red">O</span>"
goForm3.<span style="color: #0000ff">Show</span>()
goForm3.<span style="color: #0000ff">Caption</span> = "<span style="background-color: #ffff00; color: red">goForm3 => AS_TOPLEVEL_FORM</span>"
goForm3.<span style="color: #0000ff">Name</span> = "<span style="background-color: #ffff00; color: red">goForm3</span>"
<span style="color: #0000ff">ENDIF</span>
<span style="color: #008000">*//</span>
<span style="color: #008000">* SET STEP ON </span>
<span style="color: #008000">*\\ Try rendering on a regular (child) form (with scrollbars)</span>
goForm4 = <span style="color: #0000ff">CREATEOBJECT</span>("<span style="background-color: #ffff00; color: red">MyScrollableForm</span>") <span style="color: #008000">&& IN_SCREEN (scrollbars = 3)</span>
<span style="color: #0000ff">IF</span> <span style="color: #0000ff">VARTYPE</span>(m.goForm4) == "<span style="background-color: #ffff00; color: red">O</span>"
goForm4.<span style="color: #0000ff">Show</span>()
goForm4.<span style="color: #0000ff">Caption</span> = "<span style="background-color: #ffff00; color: red">goForm4 => IN_SCREEN (scrollbars = 3)</span>"
goForm4.<span style="color: #0000ff">Name</span> = "<span style="background-color: #ffff00; color: red">goForm4</span>"
<span style="color: #0000ff">ENDIF</span>
<span style="color: #008000">*//</span>
<span style="color: #0000ff">RETURN</span> <span style="color: #008000">&& >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Bye, bye!</span>
<span style="color: #008000">***********************************************************</span>
<span style="color: #008000">*** SYS(602,0) && set off-screen bitmaps to "OFF"</span>
<span style="color: #008000">*\\ setting of off-screen bitmaps may have some impact</span>
<span style="color: #008000">*\\ but only, if one does not take care of all oddities.</span>
<span style="color: #008000">*\\ !!!!! This demo program is side effect free !!!!!</span>
<span style="color: #008000">*** SYS(602,1) && set off-screen bitmaps to "ON"</span>
<span style="color: #008000">***********************************************************</span>
<span style="color: #0000ff">DEFINE</span> <span style="color: #0000ff">CLASS</span> MyForm <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Form</span>
<span style="color: #008000">*\\ ----------------------------------</span>
<span style="color: #0000ff">AllowOutput</span> = .F. <span style="color: #008000">&& ? will be echoed on form while active</span>
<span style="color: #0000ff">ShowWindow</span> = 0 <span style="color: #008000">&& 0 := In Screen, 1 := In TLF, 2:= AS TLF</span>
<span style="color: #0000ff">Scrollbars</span> = 0 <span style="color: #008000">&& 0 : = None, 1 := horizontal, 2:= vertical, 3 := both</span>
<span style="color: #0000ff">MDIForm</span> = .T. <span style="color: #008000">&& .T. := form is a MDI form</span>
<span style="color: #008000">*\\ user defined ---------------------</span>
oPic = <span style="color: #0000ff">NULL</span> <span style="color: #008000">&& VFP's LOADPICTURE() COM object reference</span>
oIPic = <span style="color: #0000ff">NULL</span> <span style="color: #008000">&& promary iPicture interface reference</span>
cPicturePath = "<span style="background-color: #ffff00; color: red"></span>" <span style="color: #008000">&& full qualified DOS path to image</span>
lEventsBound = .F.<span style="color: #008000">&& flag</span>
nhDC = -1 <span style="color: #008000">&& device context to render the image on</span>
nHwnd = 0 <span style="color: #008000">&& window handle of rendering device context (.nhDC)</span>
<span style="color: #008000">*** HWnd = .... && thisform's native window handle which must not always</span>
<span style="color: #008000">&& be the window handle of the rendering device context!</span>
xDPI = 0 <span style="color: #008000">&& VFP's _SCREEN X-Resolution</span>
yDPI = 0 <span style="color: #008000">&& VFP's _SCREEN Y-Resolution</span>
iWindowProc1 = 0 <span style="color: #008000">&& Buffer </span>
iWindowProc2 = 0 <span style="color: #008000">&& Buffer</span>
nWidth = 0 <span style="color: #008000">&& Ole-Image property: Image width (pixels)</span>
nHeight = 0 <span style="color: #008000">&& dito : Image height (pixels)</span>
nTop = 0 <span style="color: #008000">&& dito : Image top position (pixels)</span>
nLeft = 0 <span style="color: #008000">&& dito : Image left position (pixels)</span>
nXOffset = 0 <span style="color: #008000">&& dito : Horiz.Offset in source (where copying starts)</span>
nYOffset = 0 <span style="color: #008000">&& dito : Vert.Offset in source (where copying starts)</span>
nCopyWidth = 0 <span style="color: #008000">&& dito : Horiz.Extend to copy from + readout direction</span>
nCopyHeight = 0 <span style="color: #008000">&& dito : Vert.Extend to copy from + readout direction</span>
<span style="color: #008000">*// ----------------------------------</span>
<span style="color: #0000ff">PROTECTED</span> <span style="color: #0000ff">FUNCTION</span> <span style="color: #0000ff">INIT</span>() <span style="color: #0000ff">AS</span> BOOLEAN
<span style="color: #008000">*\\ call public implementation</span>
<span style="color: #0000ff">THIS</span>.INITIALIZE()
<span style="color: #008000">*// </span>
<span style="color: #0000ff">RETURN</span> .T. <span style="color: #008000">&& always allow form to stay in memory</span>
<span style="color: #0000ff">ENDFUNC</span>
<span style="color: #0000ff">PROCEDURE</span> INITIALIZE() <span style="color: #0000ff">AS</span> VOID
<span style="color: #0000ff">WITH</span> <span style="color: #0000ff">THIS</span>
<span style="color: #008000">*\\</span>
.DeclareWinAPI()
.RetrieveDPI()
.RetrieveWinHandle()
.RetrieveWinProcs()
.RetrieveHandleDC()
.RetrievePicture()
.DoBind()
<span style="color: #008000">*//</span>
<span style="color: #0000ff">ENDWITH</span>
<span style="color: #0000ff">ENDFUNC</span>
<span style="color: #0000ff">PROCEDURE</span> <span style="color: #0000ff">PAINT</span>() <span style="color: #0000ff">AS</span> VOID
<span style="color: #008000">*\\ common entry point to render our COM pictures</span>
<span style="color: #0000ff">THIS</span>.RenderImages()
<span style="color: #008000">*// Secondary entry points (even more important) see HandleWinMsg1 & 2</span>
<span style="color: #0000ff">ENDPROC</span>
<span style="color: #0000ff">PROTECTED</span> <span style="color: #0000ff">PROCEDURE</span> <span style="color: #0000ff">DESTROY</span>() <span style="color: #0000ff">AS</span> VOID
<span style="color: #0000ff">WITH</span> <span style="color: #0000ff">THIS</span>
.UnbindAll()
.ResetAll()
.ReleaseDeviceContext()
<span style="color: #008000">*\\ release the public variable</span>
<span style="color: #0000ff">_SHELL</span> = "<span style="background-color: #ffff00; color: red">RELEASE </span>" + .<span style="color: #0000ff">Name</span>
<span style="color: #0000ff">ENDWITH</span>
<span style="color: #0000ff">ENDPROC</span>
<span style="color: #0000ff">PROTECTED</span> <span style="color: #0000ff">PROCEDURE</span> UnbindAll() <span style="color: #0000ff">AS</span> VOID
<span style="color: #0000ff">UNBINDEVENTS</span>(<span style="color: #0000ff">THIS</span>)
<span style="color: #0000ff">WITH</span> <span style="color: #0000ff">THIS</span>
<span style="color: #0000ff">IF</span> .lEventsBound
<span style="color: #008000">*\\ restore form's message loop</span>
<span style="color: #0000ff">UNBINDEVENTS</span>(.<span style="color: #0000ff">HWnd</span>)
<span style="color: #0000ff">UNBINDEVENTS</span>(.nHWnd)
<span style="color: #008000">*\\ .T. when BINDEVENT(hWnd,...) was successful</span>
.lEventsBound = .F.
<span style="color: #0000ff">ENDIF</span>
<span style="color: #0000ff">ENDWITH</span>
<span style="color: #0000ff">ENDPROC</span>
<span style="color: #0000ff">PROTECTED</span> <span style="color: #0000ff">PROCEDURE</span> ResetAll() <span style="color: #0000ff">AS</span> VOID
<span style="color: #0000ff">WITH</span> <span style="color: #0000ff">THIS</span>
.oPic = <span style="color: #0000ff">NULL</span>
.oIPic = <span style="color: #0000ff">NULL</span>
.cPicturePath = "<span style="background-color: #ffff00; color: red"></span>"
.nHwnd = 0
.xDPI = 0
.yDPI = 0
.iWindowProc1 = 0
.iWindowProc2 = 0
<span style="color: #008000">*\\ parameter for oIPic.Render()</span>
.nWidth = 0
.nHeight = 0
.nTop = 0
.nLeft = 0
.nXOffset = 0
.nYOffset = 0
.nCopyWidth = 0
.nCopyHeight = 0
<span style="color: #008000">*//</span>
<span style="color: #0000ff">ENDWITH</span>
<span style="color: #0000ff">ENDPROC</span>
<span style="color: #0000ff">PROTECTED</span> <span style="color: #0000ff">PROCEDURE</span> ReleaseDeviceContext() <span style="color: #0000ff">AS</span> VOID
<span style="color: #008000">*\\ Release .nHDC</span>
<span style="color: #0000ff">WITH</span> <span style="color: #0000ff">THIS</span>
<span style="color: #0000ff">IF</span> .nHDC <> 0 <span style="color: #008000">&& handle of device context</span>
ReleaseDC(.nHWnd, .nHDC)
.nHDC = 0
<span style="color: #0000ff">ENDIF</span>
<span style="color: #0000ff">ENDWITH</span>
<span style="color: #0000ff">ENDPROC</span>
<span style="color: #0000ff">PROTECTED</span> <span style="color: #0000ff">PROCEDURE</span> DeclareWinAPI() <span style="color: #0000ff">AS</span> VOID
<span style="color: #008000">*\\ Register WINAPI declarations</span>
<span style="color: #008000">*\\ WIN32API: Kernel32.dll, Gdi32.dll, User32.dll, Mpr.dll, and Advapi32.dll</span>
<span style="color: #0000ff">DECLARE</span> <span style="color: #0000ff">INTEGER</span> CallWindowProc <span style="color: #0000ff">IN</span> WIN32API <span style="color: #0000ff">INTEGER</span> lpPrevWndFunc, <span style="color: #0000ff">INTEGER</span> <span style="color: #0000ff">HWND</span>,<span style="color: #0000ff">INTEGER</span> Msg, <span style="color: #0000ff">INTEGER</span> wParam, <span style="color: #0000ff">INTEGER</span> LPARAM
<span style="color: #0000ff">DECLARE</span> <span style="color: #0000ff">INTEGER</span> GetDC <span style="color: #0000ff">IN</span> WIN32API <span style="color: #0000ff">INTEGER</span> <span style="color: #0000ff">HWND</span>
<span style="color: #0000ff">DECLARE</span> <span style="color: #0000ff">INTEGER</span> GetDeviceCaps <span style="color: #0000ff">IN</span> WIN32API <span style="color: #0000ff">INTEGER</span> hDC, <span style="color: #0000ff">INTEGER</span> nIndex
<span style="color: #0000ff">DECLARE</span> <span style="color: #0000ff">INTEGER</span> GetWindow <span style="color: #0000ff">IN</span> WIN32API <span style="color: #0000ff">INTEGER</span> <span style="color: #0000ff">HWND</span>, <span style="color: #0000ff">INTEGER</span> wFlag
<span style="color: #0000ff">DECLARE</span> <span style="color: #0000ff">INTEGER</span> GetWindowDC <span style="color: #0000ff">IN</span> WIN32API <span style="color: #0000ff">INTEGER</span> <span style="color: #0000ff">HWND</span>
<span style="color: #0000ff">DECLARE</span> <span style="color: #0000ff">INTEGER</span> GetWindowLong <span style="color: #0000ff">IN</span> WIN32API <span style="color: #0000ff">INTEGER</span> <span style="color: #0000ff">HWND</span>, <span style="color: #0000ff">INTEGER</span> nIndex
<span style="color: #0000ff">DECLARE</span> <span style="color: #0000ff">INTEGER</span> ReleaseDC <span style="color: #0000ff">IN</span> WIN32API <span style="color: #0000ff">INTEGER</span> <span style="color: #0000ff">HWND</span>, <span style="color: #0000ff">INTEGER</span> hDC
<span style="color: #008000">*// some more unused (but useful) at the end of this listing</span>
<span style="color: #0000ff">ENDPROC</span>
<span style="color: #0000ff">PROTECTED</span> <span style="color: #0000ff">PROCEDURE</span> RetrieveDPI() <span style="color: #0000ff">AS</span> VOID
<span style="color: #008000">*\\ calculate X/Y _screen resolutions</span>
<span style="color: #008000">*\\ retrieves dots per inch resolution for VFP's _SCREEN device context</span>
#<span style="color: #0000ff">DEFINE</span> LOGPIXELSX 88 <span style="color: #008000">&& Logical pixels/inch in X</span>
#<span style="color: #0000ff">DEFINE</span> LOGPIXELSY 90 <span style="color: #008000">&& Logical pixels/inch in Y</span>
<span style="color: #008000">*// </span>
<span style="color: #0000ff">LOCAL</span> lhDC <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>, lnDPI <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>
lhDC = GetWindowDC(<span style="color: #0000ff">_Screen</span>.<span style="color: #0000ff">HWnd</span>)
<span style="color: #0000ff">IF</span> m.lhDC <> 0
<span style="color: #0000ff">THIS</span>.xDPI = GetDeviceCaps(m.lhDC, LOGPIXELSX)
<span style="color: #0000ff">THIS</span>.yDPI = GetDeviceCaps(m.lhDC, LOGPIXELSY)
= ReleaseDC(<span style="color: #0000ff">_Screen</span>.<span style="color: #0000ff">HWnd</span>, m.lhDC)
<span style="color: #0000ff">ELSE</span>
<span style="color: #008000">*\\ fallback defaults</span>
<span style="color: #0000ff">STORE</span> 96 <span style="color: #0000ff">TO</span> ._xDPI, ._yDPI
<span style="color: #0000ff">ENDIF</span>
<span style="color: #0000ff">ENDPROC</span>
<span style="color: #0000ff">PROTECTED</span> <span style="color: #0000ff">PROCEDURE</span> RetrieveWinHandle() <span style="color: #0000ff">AS</span> VOID
#<span style="color: #0000ff">DEFINE</span> GW_CHILD 5
<span style="color: #0000ff">WITH</span> <span style="color: #0000ff">THIS</span>
<span style="color: #008000">*\\ default: THISFOEM.HWnd</span>
.nHWnd = .<span style="color: #0000ff">hWnd</span>
<span style="color: #008000">*//</span>
<span style="color: #008000">*\\ handle different scenarios:</span>
<span style="color: #0000ff">DO</span> <span style="color: #0000ff">CASE</span>
<span style="color: #0000ff">CASE</span> .<span style="color: #0000ff">Dockable</span> > 0
<span style="color: #008000">*\\ dockable forms do not have any child windows</span>
<span style="color: #0000ff">CASE</span> .<span style="color: #0000ff">ShowWindow</span> = 2
<span style="color: #008000">*\\ If the parent form is a TopLevelForm then</span>
<span style="color: #008000">*\\ there must be another child window, thus</span>
<span style="color: #008000">*\\ drill down to get inner-most child</span>
.nhWnd = GetWindow(.nHWnd, GW_CHILD)
<span style="color: #008000">*\\ TopLevelWindow with additional scroll bars</span>
<span style="color: #0000ff">IF</span> .<span style="color: #0000ff">Scrollbars</span> > 0
<span style="color: #008000">*\\IF there are scrollbars enabled, there is </span>
<span style="color: #008000">*\\an additional view port window. Thus,</span>
<span style="color: #008000">*\\drill down and get this window's handle</span>
.nhWnd = GetWindow(.nHWnd, GW_CHILD)
<span style="color: #008000">*//</span>
<span style="color: #0000ff">ENDIF</span>
<span style="color: #0000ff">CASE</span> .<span style="color: #0000ff">Scrollbars</span> > 0
<span style="color: #008000">*\\ Regular VFP form with scroll bars enabled</span>
.nhWnd = GetWindow(.nHWnd, GW_CHILD)
<span style="color: #0000ff">ENDCASE</span>
<span style="color: #0000ff">ENDWITH</span>
<span style="color: #0000ff">ENDPROC</span>
<span style="color: #0000ff">PROTECTED</span> <span style="color: #0000ff">PROCEDURE</span> RetrieveWinProcs() <span style="color: #0000ff">AS</span> VOID
#<span style="color: #0000ff">DEFINE</span> GWL_WNDPROC (-4)
<span style="color: #008000">*\\ retrieves the WIN Message handler ID for a given window </span>
<span style="color: #008000">*\\ which defaults to THISFORM</span>
<span style="color: #0000ff">WITH</span> <span style="color: #0000ff">THIS</span>
<span style="color: #0000ff">THIS</span>.iWindowProc1 = GetWindowLong(.<span style="color: #0000ff">Hwnd</span>, GWL_WNDPROC)
<span style="color: #0000ff">THIS</span>.iWindowProc2 = GetWindowLong(.nHwnd, GWL_WNDPROC)
<span style="color: #0000ff">ENDWITH</span>
<span style="color: #008000">*//</span>
<span style="color: #0000ff">ENDPROC</span>
<span style="color: #0000ff">PROTECTED</span> <span style="color: #0000ff">PROCEDURE</span> RetrieveHandleDC(tlAll <span style="color: #0000ff">AS</span> Boolean) <span style="color: #0000ff">AS</span> VOID
<span style="color: #0000ff">WITH</span> <span style="color: #0000ff">THIS</span>
<span style="color: #008000">*\\ force parameter default to boolean FALSE</span>
<span style="color: #0000ff">IF</span> NOT <span style="color: #0000ff">VARTYPE</span>(m.tlAll) == "<span style="background-color: #ffff00; color: red">L</span>"
tlAll = .F.
<span style="color: #0000ff">ENDIF</span>
<span style="color: #008000">*//</span>
<span style="color: #0000ff">IF</span> m.tlAll
<span style="color: #008000">*\\ the full window device context</span>
.nHDC = GetWindowDC(.nHwnd)
<span style="color: #0000ff">ELSE</span>
<span style="color: #008000">*\\ the child area device context</span>
.nHDC = GetDC(.nHwnd)
<span style="color: #0000ff">ENDIF</span>
<span style="color: #0000ff">ENDWITH</span>
<span style="color: #0000ff">ENDFUNC</span>
<span style="color: #0000ff">PROCEDURE</span> RetrievePicture(tcFileName <span style="color: #0000ff">AS</span> <span style="color: #0000ff">String</span>) <span style="color: #0000ff">AS</span> VOID
<span style="color: #008000">*\\ Load picture from disk.</span>
<span style="color: #008000">*\\ Initializes .oPIC and .oIPIC</span>
<span style="color: #0000ff">IF</span> (NOT <span style="color: #0000ff">VARTYPE</span>(m.tcFileName) == "<span style="background-color: #ffff00; color: red">C</span>")
tcFileName = "<span style="background-color: #ffff00; color: red"></span>"
<span style="color: #0000ff">ELSE</span>
tcFileName = <span style="color: #0000ff">ALLTRIM</span>(<span style="color: #0000ff">UPPER</span>(m.tcFileName))
<span style="color: #0000ff">ENDIF</span>
<span style="color: #0000ff">IF</span> <span style="color: #0000ff">EMPTY</span>(m.tcFileName)
<span style="color: #008000">*\\ prompt user</span>
m.tcFileName = <span style="color: #0000ff">GETPICT</span>("<span style="background-color: #ffff00; color: red">windows bitmap files:bmp;</span>"+;
"<span style="background-color: #ffff00; color: red">windows icon files:ico;</span>"+;
"<span style="background-color: #ffff00; color: red">run-length encoded files:rle;</span>"+;
"<span style="background-color: #ffff00; color: red">metafiles:wmf;</span>"+;
"<span style="background-color: #ffff00; color: red">enhanced metafiles:emf;</span>"+;
"<span style="background-color: #ffff00; color: red">JPEG files:jpg,jpeg</span>",;
"<span style="background-color: #ffff00; color: red">Render from file:</span>", "<span style="background-color: #ffff00; color: red">Load</span>" )
<span style="color: #0000ff">ENDIF</span>
<span style="color: #008000">*\\ load the picture</span>
<span style="color: #0000ff">TRY</span>
loPic = <span style="color: #0000ff">LOADPICTURE</span>(<span style="color: #0000ff">IIF</span>(<span style="color: #0000ff">EMPTY</span>(m.tcFileName), <span style="color: #0000ff">THIS</span>.cPicturePath, m.tcFileName))
<span style="color: #0000ff">CATCH</span>
loPic = <span style="color: #0000ff">NULL</span>
ENDTRY
<span style="color: #008000">*//</span>
<span style="color: #0000ff">IF</span> <span style="color: #0000ff">VARTYPE</span>(m.loPic) == "<span style="background-color: #ffff00; color: red">O</span>"
<span style="color: #0000ff">WITH</span> <span style="color: #0000ff">THIS</span>
<span style="color: #008000">*\\ save VFP's COM ref.</span>
.oPic = m.loPic
<span style="color: #008000">*\\ save pimary COM pic ref</span>
.oIPic = <span style="color: #0000ff">GETINTERFACE</span>(m.loPic, "<span style="background-color: #ffff00; color: red">IPicture</span>")
<span style="color: #008000">*//</span>
<span style="color: #008000">*\\ calculate pixel based width and height</span>
.nWidth = .HIME2PXL(.oIPic.<span style="color: #0000ff">Width</span>, "<span style="background-color: #ffff00; color: red">X</span>")
.nHeight = .HIME2PXL(.oIPic.<span style="color: #0000ff">Height</span>, "<span style="background-color: #ffff00; color: red">Y</span>")
.nTop = 0
.nLeft = 0
<span style="color: #008000">*//</span>
<span style="color: #008000">*\\ Next section positions a 1x1 pixel line object on the form</span>
<span style="color: #008000">*\\ at lower right corner of the rendered image. Scrollbars</span>
<span style="color: #008000">*\\ will appear if form is smaller than the picture loaded</span>
<span style="color: #0000ff">IF</span> .<span style="color: #0000ff">Scrollbars</span> > 0
<span style="color: #008000">*\\ Make the scrollbars appear if secessary</span>
<span style="color: #0000ff">IF</span> (.nWidth + .nLeft > .<span style="color: #0000ff">WIDTH</span>) AND <span style="color: #0000ff">BITTEST</span>(.<span style="color: #0000ff">Scrollbars</span>, 0) OR ;
(.nHeight + .nTop > .<span style="color: #0000ff">HEIGHT</span>) AND <span style="color: #0000ff">BITTEST</span>(.<span style="color: #0000ff">Scrollbars</span>, 1)
<span style="color: #0000ff">IF</span> NOT PEMSTATUS(<span style="color: #0000ff">this</span>,"<span style="background-color: #ffff00; color: red">_oPixel</span>",5)
.<span style="color: #0000ff">AddObject</span>("<span style="background-color: #ffff00; color: red">_oPixel</span>","<span style="background-color: #ffff00; color: red">LINE</span>")
._oPixel.<span style="color: #0000ff">top</span> = .nHeight + .nTop
._oPixel.<span style="color: #0000ff">left</span> = .nWidth + .nLeft
._oPixel.<span style="color: #0000ff">DrawMode</span> = 11 <span style="color: #008000">&& NOP: In effect, this setting turns drawing off</span>
._oPixel.<span style="color: #0000ff">Visible</span> = .T. <span style="color: #008000">&& Must be set visible! Due to .DrawMode it is not rendered!</span>
<span style="color: #0000ff">ENDIF</span>
<span style="color: #0000ff">ENDIF</span>
<span style="color: #008000">*//</span>
<span style="color: #0000ff">ENDIF</span>
<span style="color: #008000">*//</span>
<span style="color: #008000">*\\ Want to echo some of the extended COM attributes?</span>
<span style="color: #008000">*\\ Uncomment next line (will echo to VFP's desktop)</span>
<span style="color: #008000">*** .ImageAttribs()</span>
<span style="color: #008000">*//</span>
<span style="color: #008000">*\\ finally render new image the 1st time</span>
.RenderImages()
<span style="color: #008000">*//</span>
<span style="color: #0000ff">ENDWITH</span>
<span style="color: #0000ff">ENDIF</span>
<span style="color: #0000ff">ENDPROC</span>
<span style="color: #0000ff">PROTECTED</span> <span style="color: #0000ff">PROCEDURE</span> DoBind() <span style="color: #0000ff">AS</span> VOID
#<span style="color: #0000ff">DEFINE</span> WM_ERASEBKGND 0x0014
<span style="color: #008000">*\\ Bind to WIN-Messages</span>
<span style="color: #0000ff">WITH</span> <span style="color: #0000ff">THIS</span>
<span style="color: #008000">*\\ the regular case: simple VFP form IN SCREEN</span>
<span style="color: #0000ff">BINDEVENT</span>(.nhWnd, WM_ERASEBKGND, <span style="color: #0000ff">THIS</span>, "<span style="background-color: #ffff00; color: red">HandleWinMsg2</span>", 4)
<span style="color: #008000">*//</span>
<span style="color: #008000">*\\ TopLevel form -or- simple form with scrollbars -or-</span>
<span style="color: #008000">*\\ a combination of both</span>
<span style="color: #0000ff">IF</span> .<span style="color: #0000ff">ShowWindow</span> = 2
<span style="color: #008000">*\\ Some VFP forms receive "erase_background" message</span>
<span style="color: #008000">*\\ at their "outer" window</span>
<span style="color: #0000ff">BINDEVENT</span>(.<span style="color: #0000ff">hWnd</span>, WM_ERASEBKGND, <span style="color: #0000ff">THIS</span>, "<span style="background-color: #ffff00; color: red">HandleWinMsg1</span>", 4)
<span style="color: #008000">*//</span>
<span style="color: #0000ff">ENDIF</span>
.lEventsBound = .T.
<span style="color: #0000ff">ENDWITH</span>
<span style="color: #0000ff">ENDPROC</span>
<span style="color: #0000ff">FUNCTION</span> HandleWinMsg1(tnHWnd <span style="color: #0000ff">AS</span> <span style="color: #0000ff">INTEGER</span>, tnMsg <span style="color: #0000ff">AS</span> <span style="color: #0000ff">INTEGER</span>, tnWPARAM <span style="color: #0000ff">AS</span> <span style="color: #0000ff">INTEGER</span>, tnLPARAM <span style="color: #0000ff">AS</span> <span style="color: #0000ff">INTEGER</span>) <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>
<span style="color: #008000">**** DEBUGOUT "HandleWinMsg1 - WM_ERASEBKGND WPARAM = " + TRANSFORM(m.tnWPARAM) + " | LPARAM = "+ TRANSFORM(m.tnLPARAM)</span>
<span style="color: #008000">*//</span>
<span style="color: #008000">*\\ 1st Windows Message handler (either bound to outer TLF window or</span>
<span style="color: #008000">*\\ to the 'one & only' window handle >>> thisform.hwnd)</span>
<span style="color: #0000ff">LOCAL</span> nRetvalue
<span style="color: #008000">*\\ This routine gets called on Windows "EraseBackground" messages. </span>
<span style="color: #008000">*\\ Thus, first forward the message (which will wipe out the background)...</span>
nRetvalue = CallWindowProc(<span style="color: #0000ff">THIS</span>.iWindowProc1, m.tnHWnd, m.tnMsg, m.tnWPARAM, m.tnLPARAM)
<span style="color: #008000">*\\ ... and finally, render our image(s) again</span>
<span style="color: #0000ff">THIS</span>.RenderImages()
<span style="color: #008000">*//</span>
<span style="color: #0000ff">RETURN</span> m.nRetvalue
<span style="color: #0000ff">ENDFUNC</span>
<span style="color: #0000ff">FUNCTION</span> HandleWinMsg2(tnHWnd <span style="color: #0000ff">AS</span> <span style="color: #0000ff">INTEGER</span>, tnMsg <span style="color: #0000ff">AS</span> <span style="color: #0000ff">INTEGER</span>, tnWPARAM <span style="color: #0000ff">AS</span> <span style="color: #0000ff">INTEGER</span>, tnLPARAM <span style="color: #0000ff">AS</span> <span style="color: #0000ff">INTEGER</span>) <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>
<span style="color: #008000">*** DEBUGOUT "HandleWinMsg2 - WM_ERASEBKGND WPARAM = " + TRANSFORM(m.tnWPARAM) + " | LPARAM = "+ TRANSFORM(m.tnLPARAM)</span>
<span style="color: #008000">*//</span>
<span style="color: #008000">*\\ 2nd Windows Message handler (bound to any inner window, if such one exists)</span>
<span style="color: #0000ff">LOCAL</span> nRetvalue
nRetvalue = CallWindowProc(<span style="color: #0000ff">THIS</span>.iWindowProc2, m.tnHWnd, m.tnMsg, m.tnWPARAM, m.tnLPARAM)
<span style="color: #0000ff">THIS</span>.RenderImages()
<span style="color: #008000">*//</span>
<span style="color: #0000ff">RETURN</span> m.nRetvalue
<span style="color: #0000ff">ENDFUNC</span>
<span style="color: #0000ff">PROTECTED</span> <span style="color: #0000ff">PROCEDURE</span> RenderImages() <span style="color: #0000ff">AS</span> VOID
<span style="color: #008000">*\\ output loaded COM image (4 times to demonstrate FXs)</span>
<span style="color: #0000ff">WITH</span> <span style="color: #0000ff">THIS</span>
<span style="color: #008000">*\\ errors may rise during INIT() and DESTROY()</span>
<span style="color: #008000">*\\ it makes not much sense to catch them separately.</span>
<span style="color: #008000">*\\ Thus, just wrap all rendering with TRY...CATCH here</span>
<span style="color: #0000ff">TRY</span>
<span style="color: #008000">*\\ render the loaded picture 4 times:</span>
<span style="color: #008000">*\\ 1st: upper left one >>> normal output</span>
.oIPic.Render(.nhDC, 0, 0, .nWidth, .nHeight, 0,;
.oIPic.<span style="color: #0000ff">Height</span>, .oIPic.<span style="color: #0000ff">Width</span>, - .oIPic.<span style="color: #0000ff">Height</span>, <span style="color: #0000ff">NULL</span>)
<span style="color: #008000">*//</span>
<span style="color: #008000">*\\ 2nd: upper right one >>> mirrored vertically</span>
.oIPic.Render(.nhDC, .nWidth+10, 0, .nWidth, .nHeight, .oIPic.<span style="color: #0000ff">Width</span>,;
.oIPic.<span style="color: #0000ff">Height</span>, - .oIPic.<span style="color: #0000ff">Width</span>, - .oIPic.<span style="color: #0000ff">Height</span>, <span style="color: #0000ff">NULL</span>)
<span style="color: #008000">*//</span>
<span style="color: #008000">*\\ lower left one >>> mirrored horizontally</span>
.oIPic.Render(.nhDC, 0, .nHeight+10, .nWidth, .nHeight,;
0, 0, .oIPic.<span style="color: #0000ff">Width</span>, .oIPic.<span style="color: #0000ff">Height</span>, <span style="color: #0000ff">NULL</span>)
<span style="color: #008000">*//</span>
<span style="color: #008000">*\\ lower right one >>> mirrored horizontally + vertically</span>
.oIPic.Render(.nhDC, .nWidth+10, .nHeight+10, .nWidth, .nHeight, .oIPic.<span style="color: #0000ff">Width</span>, 0,;
- .oIPic.<span style="color: #0000ff">Width</span>, .oIPic.<span style="color: #0000ff">Height</span>, <span style="color: #0000ff">NULL</span>)
<span style="color: #008000">*//</span>
<span style="color: #0000ff">CATCH</span>
<span style="color: #008000">*\\ eat all rendering errors</span>
ENDTRY
<span style="color: #008000">*//</span>
<span style="color: #0000ff">ENDWITH</span>
<span style="color: #0000ff">ENDPROC</span>
<span style="color: #0000ff">PROCEDURE</span> ImageAttribs() <span style="color: #0000ff">AS</span> VOID
<span style="color: #008000">*\\ only for testing</span>
<span style="color: #0000ff">WITH</span> <span style="color: #0000ff">THIS</span>
<span style="color: #0000ff">IF</span> <span style="color: #0000ff">VARTYPE</span>(.oIPic) == "<span style="background-color: #ffff00; color: red">O</span>"
<span style="color: #008000">*\\ Output some interesting(?) things</span>
<span style="color: #0000ff">WITH</span> .oIPic
?
? "<span style="background-color: #ffff00; color: red">Eigenschaften des 'IPicture'-Interface:</span>"
? "<span style="background-color: #ffff00; color: red">Attributes</span>",.<span style="color: #0000ff">Attributes</span>
<span style="color: #0000ff">TRY</span>
? "<span style="background-color: #ffff00; color: red">CurDC</span>",.CurDC
<span style="color: #0000ff">CATCH</span>
? "<span style="background-color: #ffff00; color: red">No CurDC</span>" <span style="color: #008000">&& .ICO file</span>
ENDTRY
? "<span style="background-color: #ffff00; color: red">Handle</span>",.Handle
? "<span style="background-color: #ffff00; color: red">Height</span>",.<span style="color: #0000ff">Height</span>
<span style="color: #0000ff">TRY</span>
? "<span style="background-color: #ffff00; color: red">hPal</span>",.hPal
<span style="color: #0000ff">CATCH</span>
? "<span style="background-color: #ffff00; color: red">No hPal</span>"
ENDTRY
? "<span style="background-color: #ffff00; color: red">KeepOriginalFormat</span>" ,.KeepOriginalFormat
? "<span style="background-color: #ffff00; color: red">Type</span>" ,.<span style="color: #0000ff">Type</span>
? "<span style="background-color: #ffff00; color: red">Width</span>" ,.<span style="color: #0000ff">Width</span>
?
<span style="color: #0000ff">ENDWITH</span>
<span style="color: #008000">*//</span>
<span style="color: #0000ff">ENDIF</span>
<span style="color: #0000ff">ENDWITH</span>
<span style="color: #0000ff">ENDPROC</span>
#<span style="color: #0000ff">DEFINE</span> INCH2MILLIMETER 25.4 <span style="color: #008000">&& 1 Inch (German: 'Zoll') = 25.4 millimeters</span>
#<span style="color: #0000ff">DEFINE</span> INCH2HIMETRICS (INCH2MILLIMETER <span style="color: #008000">* 100) && 1 HIMETRIC = 0.01 </span>
<span style="color: #0000ff">FUNCTION</span> PXL2HIME(tnPixel <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>, tcDimension <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Character</span> ) <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>
<span style="color: #0000ff">LOCAL</span> lnPixelsOnOneHiMetricUnit <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>
lnPixelsOnOneHiMetricUnit = INCH2HIMETRICS / <span style="color: #0000ff">IIF</span>(m.tcDimension== "<span style="background-color: #ffff00; color: red">X</span>", <span style="color: #0000ff">THIS</span>.xDPI,<span style="color: #0000ff">THIS</span>.yDPI)
<span style="color: #008000">*\\</span>
<span style="color: #0000ff">RETURN</span> <span style="color: #0000ff">ROUND</span>(lnPixelsOnOneHiMetricUnit <span style="color: #008000">* m.tnPixel, 0)</span>
<span style="color: #008000">*//</span>
<span style="color: #0000ff">ENDFUNC</span>
<span style="color: #0000ff">FUNCTION</span> HIME2PXL(tnHimetric <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>, tcDimension <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Character</span> ) <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>
<span style="color: #0000ff">LOCAL</span> lnPixelsOnOneHiMetricUnit <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>
lnPixelsOnOneHiMetricUnit = INCH2HIMETRICS / <span style="color: #0000ff">IIF</span>(m.tcDimension== "<span style="background-color: #ffff00; color: red">X</span>", <span style="color: #0000ff">THIS</span>.xDPI,<span style="color: #0000ff">THIS</span>.yDPI)
<span style="color: #008000">*\\</span>
<span style="color: #0000ff">RETURN</span> <span style="color: #0000ff">ROUND</span>(m.tnHimetric / m.lnPixelsOnOneHiMetricUnit, 0)
<span style="color: #008000">*//</span>
<span style="color: #0000ff">ENDFUNC</span>
<span style="color: #0000ff">FUNCTION</span> buf2dword(m.tcBuffer <span style="color: #0000ff">AS</span> <span style="color: #0000ff">String</span>) <span style="color: #0000ff">AS</span> <span style="color: #0000ff">Integer</span>
<span style="color: #0000ff">RETURN</span> <span style="color: #0000ff">CTOBIN</span>(m.tcBuffer, "<span style="background-color: #ffff00; color: red">4rs</span>")
<span style="color: #0000ff">ENDFUNC</span>
<span style="color: #008000">*//</span>
<span style="color: #0000ff">ENDDEFINE</span>
<span style="color: #0000ff">DEFINE</span> <span style="color: #0000ff">CLASS</span> MyDockableForm <span style="color: #0000ff">AS</span> MyForm
<span style="color: #0000ff">Dockable</span> = 1
<span style="color: #0000ff">MDIForm</span> = .F.
<span style="color: #0000ff">ENDDEFINE</span>
<span style="color: #0000ff">DEFINE</span> <span style="color: #0000ff">CLASS</span> MyScrollableForm <span style="color: #0000ff">AS</span> MyForm
<span style="color: #0000ff">Scrollbars</span> = 3
<span style="color: #0000ff">MDIForm</span> = .F.
<span style="color: #0000ff">ENDDEFINE</span>
<span style="color: #0000ff">DEFINE</span> <span style="color: #0000ff">CLASS</span> MyTopLevelForm <span style="color: #0000ff">AS</span> MyForm
<span style="color: #0000ff">ShowWindow</span> = 2
<span style="color: #0000ff">MDIForm</span> = .F.
<span style="color: #0000ff">ENDDEFINE</span>
<span style="color: #008000">*\\ unused defines and other useful declarations</span>
<span style="color: #008000">*** #define WM_USER 0x0400</span>
<span style="color: #008000">*** #define WM_KILLFOCUS 0x0008</span>
<span style="color: #008000">*** #define WM_PAINT 0x000F</span>
<span style="color: #008000">*\\ Unused, but useful WIN32API DECLAEs</span>
<span style="color: #008000">* DECLARE INTEGER IsWindowVisible IN WIN32API INTEGER HWND</span>
<span style="color: #008000">* DECLARE INTEGER DefWindowProc IN WIN32API INTEGER HWND, INTEGER Msg,INTEGER wParam, INTEGER LPARAM</span>
<span style="color: #008000">* DECLARE INTEGER FindWindowEx IN WIN32API INTEGER hWndParent, INTEGER hwndChildAfter, STRING lpszClass, STRING lpszWindow</span>
<span style="color: #008000">* DECLARE INTEGER GetClassName IN WIN32API INTEGER HWND, STRING lpClassName, INTEGER nMaxCount</span>
<span style="color: #008000">* DECLARE INTEGER GetDesktopWindow IN WIN32API</span>
<span style="color: #008000">* DECLARE INTEGER GetWindowRect IN WIN32API INTEGER HWND, STRING @lpRect</span>
<span style="color: #008000">* DECLARE INTEGER GetWindowInfo IN WIN32API INTEGER HWND, STRING @ pwindowinfo</span>
<span style="color: #008000">* DECLARE INTEGER GetWindowText IN WIN32API INTEGER HWND, STRING @szText, INTEGER nLen</span></font></strong></pre>
<p> </p>
<hr />
<p><a title="http://myvfpblog.blogspot.com/2009/09/design-time-references-monitor-designer.html" href="http://myvfpblog.blogspot.com/2009/09/design-time-references-monitor-designer.html"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Previous Entry" border="0" alt="Previous Entry" src="http://lh4.ggpht.com/_MOmDLu4Rm5Y/Tb9e6FJYUrI/AAAAAAAAHhI/VHJTjE2UL1Y/NavBack_48_RGBA%5B3%5D.png?imgmax=800" width="48" height="64" /></a><a title="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-tips-tricks-in-this.html" href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-tips-tricks-in-this.html"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Tips & Tricks Home (TOC)" border="0" alt="Tips & Tricks Home (TOC)" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKpc3Alzlw1jQ4GRs7-KP3KXKqp0ktSfrwasB7GO9FhukHeKmpbXvpxSx_6cdpcjyBRMGNi71LMDqfsa6nfHOfCgt4oVFrWT5NJLm4bZtdIRCV7_V-7aBYzEdCnEEflG1VQO9i/?imgmax=800" width="48" height="64" /></a><a title="http://myvfpblog.blogspot.com/2011/05/hierarchical-table-order-part-i.html" href="http://myvfpblog.blogspot.com/2011/05/hierarchical-table-order-part-i.html"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Next Entry" border="0" alt="Next Entry" src="http://lh6.ggpht.com/_MOmDLu4Rm5Y/Tb9e6t8gluI/AAAAAAAAHhQ/AJ1j6yCQtT0/NavForward_48_RGBA%5B9%5D.png?imgmax=800" width="48" height="64" /></a></p> Burkhardhttp://www.blogger.com/profile/11631168041975170500noreply@blogger.com6tag:blogger.com,1999:blog-26167158.post-48768269882009541302011-04-15T01:16:00.000+02:002014-03-08T02:52:53.839+01:00<div style="text-align: left" dir="ltr" trbidi="on"><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-tips-tricks-in-this.html"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Tips&Tricks Home" border="0" alt="Tips&Tricks Home" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRf3axohp-uniVzluTGpy39pZFKk5sH3NNcArMBu7BcuXnwMH2prsJT0x_-ZytdlQ-hyGHZLUCscei-At6WVXjaDB2z2D1Yp6zSjsGP7HrsebZLZNAyQi2EQjQ01V6Wo92HTsP/?imgmax=800" width="32" height="43" /></a><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-toolbox-in-this-section.html"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Toolbox Home" border="0" alt="Toolbox Home" src="http://lh6.ggpht.com/_MOmDLu4Rm5Y/SsIJOHKX86I/AAAAAAAAB8I/zfJDi12jTTM/Home_48_RGBA%5B9%5D.png?imgmax=800" width="48" height="64" /></a><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-complex-controls-no.html"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Complex Controls Home" border="0" alt="Complex Controls Home" src="http://lh3.ggpht.com/_MOmDLu4Rm5Y/SsIJOk1KNRI/AAAAAAAAB8M/bM3B2LPiS-Y/Home_64_RGBA%5B9%5D.png?imgmax=800" width="64" height="85" /></a><a href="http://myvfpblog.blogspot.com/2009/09/neat-solutions-home.html"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Neat Solutions Home" border="0" alt="Neat Solutions Home" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_1f4zfr4vuAockbqMuHpu_M_IAmcQ9VIrlEacTEPYBf01cOG14_wwMlKZA2954Yk2hOufYMy2zDmkbbrmB86F6mx-mI-LnZA4aFLvvyIHETzcAxSouoOF8suR5tgQlZ-nWy1J/?imgmax=800" width="72" height="96" /></a><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-foxtools.html"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Foxtools Home" border="0" alt="Foxtools Home" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_LF9dRY4J1dcPzx6FlukTdUUORGRGIHLZuyxCFT22SGN-wdB7goiX8hqW1pzej94wA9T5En72mzjv1RYMhGKS3L6eDmQO73Mqu7-ssU52xR2GnDATtS9JJHDBkti02iFWWRua/?imgmax=800" width="96" height="128" /></a><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="FoxQuill Home" border="0" alt="FoxQuill Home" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheUsQkLn6eppJnCPJ76k5NU_yNSESIn1hsSiG-34GNupNWKaEZn_AQH8Lcc9mSlRjJvYNvLVwdPdoJ9bPBkZjNJdaMGUozIn8aTz-8bJ9LmhnPu19bzmxcJ1RIM5TxlZUhQLGK/?imgmax=800" width="160" height="160" /><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-vfpx-projects-this.html"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="VFPX Projects Home" border="0" alt="VFPX Projects Home" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipI8uzT8GMv0dvkMwOOG2AiusxDc5mpdP1o9umq2psduH5LJ2-70qHw2qj3jJottjrBpB903lxd-TngDHikia6zbmLQwrJa6hBR2FAVVj925PLjbbFlU5EufQQt4-OWnxWsPGl/?imgmax=800" width="96" height="128" /></a><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-miscellaneous-diverse.html"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Miscellaneous Home" border="0" alt="Miscellaneous Home" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYaI0RXv7VbPaLZ2XXjJZJN2XbFqz0Vv7-F_4d7nIWFuWAyUNPEwYePiFaE_uE9RvtO3po8gHEuN7iWsCWZCTWT4FtdtbrqbugCqSzZsD3OdN6TqhrhZzu-i9Ib5OGvNynmPDX/?imgmax=800" width="72" height="96" /></a><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-windows-api-calling.html"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Windows API Home" border="0" alt="Windows API Home" src="http://lh3.ggpht.com/_MOmDLu4Rm5Y/SsIJQ0VhPfI/AAAAAAAAB8k/r6zeroghEC8/Home_64_RGBA%5B4%5D.png?imgmax=800" width="64" height="85" /></a><a href="http://myvfpblog.blogspot.com/2009/09/latest-news-this-section-of-my-vfp-blog.html"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="News Home" border="0" alt="News Home" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgVDU4dfVokTHvLGk0gZlVfLIkat6lJSNdJ4AB7sX8N6tqGxl4eGHm-AN7BZKL1tTZsER-KJVVq7S5iFF1O5DEGiWPgbs7AmkQ41zLCUL2pBeCOMFs0wLmsgvwrNIPEVPDMDcq/?imgmax=800" width="48" height="64" /></a><a href="http://myvfpblog.blogspot.com/2009/09/basics-home.html"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Basics Home" border="0" alt="Basics Home" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbMbsq6Ns7MVilKmorLdwhm3aCM9hPYHbWrOflw47h2L5oglxfopoxIpWPcqDx7GJVbWL2mbkoYixzDKdVWzFo1LskehrHzoAJpXL60uuU0Mo3O5fKUT4NDLAUYcSpKhmvKNAL/?imgmax=800" width="32" height="43" /></a>  <hr /></div> <h1 style="text-align: left" dir="ltr" trbidi="on"><img style="background-image: none; border-right-width: 0px; margin: 0px 12px 6px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="FoxQuill another VFP Framework" border="0" alt="FoxQuill 2011" align="left" src="http://lh3.ggpht.com/_MOmDLu4Rm5Y/TaZMEjqKKmI/AAAAAAAAHWQ/DZZSOkVQ_Yc/image%5B198%5D.png?imgmax=800" width="134" height="120" /><strong><span style="color: #a618d9"><em>FoxQuill</em> another VFP Framework</span></strong></h1> <div style="text-align: left" dir="ltr" trbidi="on"><span style="color: #5e0c78"><em><font color="#000000">FoxQuill</font></em></span> is my homegrown framework I am working with amongst others. Within the next months (from March, 2014 on) I will expose some very interesting insights here. Starting with some challenging <em>FoxQuill Base Classes</em> I will show you the whys and wherefores of my design. Be warned, <u>this will <strong>not</strong> be a VFP beginner's lecture</u> but I'm afraid, there won't be much of them still out there today…</div> <div style="text-align: left" dir="ltr" trbidi="on"> </div> <hr /> <br /> <div style="text-align: left" dir="ltr" trbidi="on"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Table of Content" border="0" alt="Table of Content" align="left" src="http://lh6.ggpht.com/_MOmDLu4Rm5Y/Tbrga_kYJfI/AAAAAAAAHa8/3KlEsQ307SA/Home_24_RGBA%5B3%5D.png?imgmax=800" width="28" height="28" />  <font style="font-weight: bold" color="#9b00d3" size="4">Table of Content</font></div> <div style="text-align: left" dir="ltr" trbidi="on"> </div> <div style="text-align: left" dir="ltr" trbidi="on"><strong><font color="#9b00d3" size="4"></font></strong></div> <div style="text-align: left" dir="ltr" trbidi="on"><a href="http://myvfpblog.blogspot.com/2014/03/foxquill-overview.html"><img style="background-image: none; border-right-width: 0px; margin: 3px 5px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="click to follow the link..." border="0" alt="FoxQuill an Overview " align="left" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsPdB0uTYYnXgXaiWp4__SBNXePz0B-1E5rjfnvqsPWOf2pe8gtUdoc2PyeJmCTJG5KU3zAYbaeI9lVmQde46efgKSDs2MmM3PScJoeDB2jV2vwi4i81YQZB8ro3nEzlgTABBW/?imgmax=800" width="54" height="89" /></a></div> <h3><font color="#9b00d3">FoxQuill an Overview</font></h3> <div style="text-align: left" dir="ltr" trbidi="on">This is a short introduction of what we are going to talk about in this section of my blog. This is no "all about another VFP framework" but what is so special about the <em>FoxQuill framework</em> and why I decided to do it just that way. <br /></div> <div style="text-align: left" dir="ltr" trbidi="on"> </div> <div style="text-align: left" dir="ltr" trbidi="on"> </div> <div style="text-align: left" dir="ltr" trbidi="on"><a href="http://myvfpblog.blogspot.com/2014/03/core-components.html"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 3px 5px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top: 0px; border-right: 0px; padding-top: 0px" title="click to follow the link..." border="0" alt="Core Components" align="left" src="http://lh6.ggpht.com/-SVWOBgHqcCw/Uxp39JavVrI/AAAAAAAAIAc/59OaSXWGSnM/Doc_Full_1%25255B4%25255D.png?imgmax=800" width="54" height="89" /></a></div> <h3><font color="#9b00d3">Core Components</font></h3> <div style="text-align: left" dir="ltr" trbidi="on">I will overview the <strong><font color="#9b00d3">Core Components</font></strong> of <em>FoxQuill</em> which will be discussed in detail in my upcoming posts. You will find a lot of them being helpful examples for the statements I posted a long time ago (<a href="http://myvfpblog.blogspot.com/2008/04/vfp-editor-code-rtf2html-part-6.html" target="_blank">22 OOP Design Rules</a>). <br /></div> <div style="text-align: left" dir="ltr" trbidi="on"> </div> <div style="text-align: left" dir="ltr" trbidi="on"> </div> <div style="text-align: left" dir="ltr" trbidi="on"><img style="background-image: none; border-right-width: 0px; margin: 3px 5px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="still to be written..." border="0" alt="The Factory" align="left" src="http://lh5.ggpht.com/-Hl-e9OiMf1w/UxjNCdFDh8I/AAAAAAAAH6c/Crw1fA0msVY/Doc_Grey_2%25255B4%25255D.png?imgmax=800" width="54" height="89" /></div> <h3><font color="#9b00d3">The Factory</font></h3> <div style="text-align: left" dir="ltr" trbidi="on"><em>FoxQuill</em> is a data-driven framework, so is the <strong><font color="#9b00d3">The </font><font color="#9b00d3">Factory</font></strong> component! The Factory belongs to <em>FoxQuill's Core Components</em> ensuring highest flexibility in object creation even at runtime!</div> <div style="text-align: left" dir="ltr" trbidi="on"> </div> <div style="text-align: left" dir="ltr" trbidi="on"> </div> <div style="text-align: left" dir="ltr" trbidi="on"><img style="background-image: none; border-right-width: 0px; margin: 3px 5px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="still to be written..." border="0" alt="The GPStore" align="left" src="http://lh3.ggpht.com/-cq0BQXxak4o/UxjNDhJklMI/AAAAAAAAH6k/8Js6aGiBRgg/Doc_Grey_3%25255B4%25255D.png?imgmax=800" width="54" height="89" /><font color="#9b00d3"></font></div> <h3><font color="#9b00d3">The GPStore</font></h3> <div style="text-align: left" dir="ltr" trbidi="on">Data-driving an application, or an application framework, needs a lot of tables! <strong><font color="#9b00d3">The </font><font color="#9b00d3"><font color="#9b00d3">General</font> Purpose Store</font></strong> belongs to <em>FoxQuill's Core Components</em> simplifying the handling of meta data used by all other Core Components like the Factory, the Workflow, and the Matrix, just to name a few of them. The GPStore radically simplifies data handling of application related (meta-)data!</div> <div style="text-align: left" dir="ltr" trbidi="on"> </div> <div style="text-align: left" dir="ltr" trbidi="on"><font color="#9b00d3"><img style="background-image: none; border-right-width: 0px; margin: 3px 5px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="still to be written..." border="0" alt="The Construct" align="left" src="http://lh4.ggpht.com/-3b-25oO-CI4/UxjNE8OIpgI/AAAAAAAAH6s/q5e_Ob4MhYk/Doc_Grey_4%25255B4%25255D.png?imgmax=800" width="54" height="89" /></font></div> <h3><font color="#9b00d3">The Construct</font></h3> <div style="text-align: left" dir="ltr" trbidi="on">Object-Pooling is nothing new. <em>FoxQuill's</em> Object-Manager called <strong><font color="#9b00d3">The Construct</font></strong> raises application-internal object hosting and maintenance to the next level. With the aid of<em> The </em><em>Construct </em>developers are able to change any application aspect dynamically (even at runtime!) without re-coding!</div> <div style="text-align: left" dir="ltr" trbidi="on"> </div> <div style="text-align: left" dir="ltr" trbidi="on"><img style="background-image: none; border-right-width: 0px; margin: 3px 5px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="still to be written..." border="0" alt="The Matrix" align="left" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhea6AxOGta4Y7uHVwJrOSpx0WkTd8rWxBs0GIS4eBrJt5tIZC3cmVgNhRi13hq_KRIvMs1f7vIokJiwPoiIF91VABQqkVnagD4Z0rTYr64G1VVKbEzM6n86U30MrLVKhnbkfnU/?imgmax=800" width="54" height="89" /></div> <h3><font color="#9b00d3">The Matrix</font></h3> <div style="text-align: left" dir="ltr" trbidi="on"><em>FoxQuill</em> supports dynamic, table-driven object creation and composition at runtime. Thus, <em>FoxQuill</em> has to support dynamic messaging, too! <em>FoxQuill's</em> <em>Unified Object Messaging</em> system is called <strong><font color="#9b00d3">The Matrix</font></strong> which enables the developer to control any aspect of object collaboration even at runtime!</div> <div style="text-align: left" dir="ltr" trbidi="on"> </div> <div style="text-align: left" dir="ltr" trbidi="on"><img style="background-image: none; border-right-width: 0px; margin: 3px 5px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="still to be written..." border="0" alt="The Workflow" align="left" src="http://lh4.ggpht.com/-OXhJK-EQ4q0/UxjNHe7G_QI/AAAAAAAAH68/nnDjEIPIY_I/Doc_Grey_6%25255B4%25255D.png?imgmax=800" width="54" height="89" /></div> <h3><font color="#9b00d3">The Workflow</font></h3> <div style="text-align: left" dir="ltr" trbidi="on"><em>FoxQuill</em> supports dynamic, table-driven behavior not only at the class-instance level but also at the application level. "Hot gluing" all framework components together at runtime and controlling them is the business of <strong><font color="#9b00d3">The Workflow</font></strong> engine. Naturally, the <font color="#000000"><em>Workflow</em></font> also is completely table-driven and supports the concept of <em>task-oriented application design</em>.</div> <div style="text-align: left" dir="ltr" trbidi="on"> </div> <div style="text-align: left" dir="ltr" trbidi="on"><img style="background-image: none; border-right-width: 0px; margin: 3px 5px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="still to be written..." border="0" alt="The Kernel" align="left" src="http://lh4.ggpht.com/-3zYqYCXQ0GU/UxjNI-CkFkI/AAAAAAAAH7E/eL-WnLUKH4o/Doc_Grey_7%25255B4%25255D.png?imgmax=800" width="54" height="89" /></div> <h3><font color="#9b00d3">The Kernel</font></h3> <div style="text-align: left" dir="ltr" trbidi="on">Bringing all <em>Core Components</em> together is realized by <strong><font color="#9b00d3">The Kernel</font></strong>. The Kernel component also is called <em>the FoxQuill Core.</em> It can be compared to an electric control cabinet in the real world, or the program kernel of UNIX operating systems. The re-using developer will not change any Kernel aspect programmatically, but through simple table-based configuration, if at all. Compiling the Kernel into an VFP App/Exe, then starting it, will lead to some kind of <em>application hosting service</em> running. This <em>App-Host Instance</em> can then be commanded to load and execute any kind of further APPs/EXEs that were build upon <em>FoxQuill's Base Classes.</em></div> <div style="text-align: left" dir="ltr" trbidi="on"> </div> <div style="text-align: left" dir="ltr" trbidi="on"><img style="background-image: none; border-right-width: 0px; margin: 3px 5px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="still to be written..." border="0" alt="Libraries & Tools" align="left" src="http://lh6.ggpht.com/-JFW5Vv9Spvs/UxjNJ4cGe0I/AAAAAAAAH7M/l1L-4HsHHNk/Doc_Grey_8%25255B4%25255D.png?imgmax=800" width="54" height="89" /></div> <h3><font color="#9b00d3">Libraries & Tools</font></h3> <div style="text-align: left" dir="ltr" trbidi="on">All of the above things are build upon a rock-solid bunch of framework classes called <strong><font color="#9b00d3">The FoxQuill Libs</font></strong>. Nobody should feel forced to use them but may stay with the own set of base classes. As I said before, this blog is no advertisement that wants to lead you to buy my system. Quite the contrary, it would be more satisfying if it would lead you to re-think and re-work <u><em>your own</em></u> classes. The <em>FoxQuill Libs</em> went a long way through everlasting refactoring. At the moment they will be refactored a last time to become <em>My Final VFP Version</em>. The classes in the final <em>FoxQuill Libs</em> will be ready to be migrated to other languages pretty easily (using special tools for that job).</div> <div style="text-align: left" dir="ltr" trbidi="on"> </div> <div style="text-align: left" dir="ltr" trbidi="on"><font color="#9b00d3"></font></div> <div style="text-align: left" dir="ltr" trbidi="on"><font color="#9b00d3"></font></div> <div style="text-align: left" dir="ltr" trbidi="on"><font style="font-weight: bold" color="#9b00d3"><a href="http://myvfpblog.blogspot.de/2011/04/foxquill-becomes-foxquillnet.html"><img style="background-image: none; border-right-width: 0px; margin: 3px 5px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="click to follow this link..." border="0" alt="FoxQuill will become FoxQuill.NET" align="left" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhatUSvW0Tc8_sN-j7vzmhNR1-fn0qd90BlKWcwSaO8ZcEkuoktZq2w-ETiyQmzE-idvNq-ZD1MDw6UERWWe59dhXIs-y9unoBYMy6q5HwfOWyQc9mlFiKlBV40yrgzo-Y5Ggpo/?imgmax=800" width="54" height="89" /></a></font></div> <h3><font color="#9b00d3">FoxQuill will become FoxQuill.NET</font></h3> <p>Some thoughts and insights dealing with my VFP framework (<img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="OffSiteLink" border="0" alt="OffSiteLink" src="http://lh4.ggpht.com/_MOmDLu4Rm5Y/TaZMEh0ff_I/AAAAAAAAHWU/tRUHGle8uY4/OffSiteLink%5B2%5D.gif?imgmax=800" width="11" height="7" /> <a href="http://www.foxquill.de">www.foxquill.de</a> still not available today) and its future transition into the .NET world. At the moment I’m enhancing and trying to migrate it to the .NET platform. At the same time I am learning C# – <strong>what a mess :-)</strong> Sometimes I think I am to old to start all over again learning another programming language. On the other hand, I do believe that this challenge will also be a damn good chance to create very interesting things for todays 'melting' VFP community…</p> Burkhardhttp://www.blogger.com/profile/11631168041975170500noreply@blogger.com8tag:blogger.com,1999:blog-26167158.post-91706101498598480912011-04-12T12:26:00.000+02:002011-04-30T16:45:26.810+02:00How To Re-Enable Blogger Comments (From Windows Live Writer)<p><strong><font color="#ff8040">Version: 1.13.01 - last update: Wednesday, April 13, 2011, 11:55:00</font></strong></p> <p><strong><a title="http://myvfpblog.blogspot.com/2011/04/bruno-my-rr-rhodesian-ridgeback.html" href="http://myvfpblog.blogspot.com/2011/04/bruno-my-rr-rhodesian-ridgeback.html"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Previous Entry" border="0" alt="Previous Entry" src="http://lh5.ggpht.com/_MOmDLu4Rm5Y/TaVzCDSP6fI/AAAAAAAAHds/LJ9jUisaNq4/NavBack_48_RGBA%5B3%5D.png?imgmax=800" width="48" height="64" /></a><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-miscellaneous-diverse.html"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Miscellaneous Home (TOC)" border="0" alt="Miscellaneous Home (TOC)" src="http://lh6.ggpht.com/_MOmDLu4Rm5Y/SsX0eSObFhI/AAAAAAAAHdw/kOSLM8XWr9s/NavHome_48_RGBA%5B1%5D.png?imgmax=800" width="48" height="64" /></a><a href="http://myvfpblog.blogspot.com/2008/05/humour-3_19.html"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Next Entry" border="0" alt="Next Entry" src="http://lh5.ggpht.com/_MOmDLu4Rm5Y/SsX0em0JRuI/AAAAAAAAHd0/baGwj0xwKi0/NavForward_48_RGBA1.png?imgmax=800" width="48" height="64" /></a></strong>  <hr /></p> <h1><font color="#000080"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="error" border="0" alt="error" src="http://lh3.ggpht.com/_MOmDLu4Rm5Y/TaVzDbtw8KI/AAAAAAAAHVo/b7VwS4KKIsI/error%5B3%5D.png?imgmax=800" width="83" height="61" /> WWW <= What Went Wrong :-)</font></h1> <p>I create & maintain this blog using Microsoft’s <img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="OffSiteLink" border="0" alt="OffSiteLink" src="http://lh4.ggpht.com/_MOmDLu4Rm5Y/TaRIE0WYinI/AAAAAAAAHR4/TBOHzFiWS5E/OffSiteLink2.gif?imgmax=800" width="11" height="7" /> <a title="http://explore.live.com/windows-live-writer?os=other" href="http://explore.live.com/windows-live-writer?os=other" target="_blank">Windows Live Writer</a>. Lately I was checking in some cool new sidebar gadgets for my blog space. During the update of my blogger template I must have changed a setting dealing with the display of comments at the bottom of each page. </p> <h3><strong><font color="#000080">How to reproduce</font></strong></h3> <p>If you like to follow me, just do the steps below:</p> <ol> <li>Check into your account </li> <li>Click “Design” in the upper right corner of your blogger bar at top of the page (showing … <your login> [New Post] [<u>Design</u>] [Sign Out] ) </li> <li><span style="font-family: arial">Select the “Settings” tab and below click the “Comments” link. </span></li> <li><span style="font-family: arial">All this brings you to the page shown below:</span> </li> </ol> <p><a href="http://lh6.ggpht.com/_MOmDLu4Rm5Y/TaRIFM4pyDI/AAAAAAAAHR8/OMG8scp5Xhg/s1600-h/image10.png" target="_blank"><img style="display: block; float: none; margin-left: auto; margin-right: auto" title="Disables Comments for New Posts" alt="Disables Comments for New Posts" src="http://lh3.ggpht.com/_MOmDLu4Rm5Y/TaRIF8272tI/AAAAAAAAHSA/4BJbP_ccoDg/image_thumb1.png?imgmax=800" width="472" height="497" /></a> </p> <p align="center"><span style="font-family: arial"><strong>Img #1.) Be careful with the “Comments Default for Posts” entry!</strong></span></p> <p><span style="font-family: arial">The combo box in question allows you to disable the display of the <strong><u>0 Comments</u></strong> link in the footer section of every new post. Setting this option to “New Posts Do Not Have Comments” will disable the whole commenting feature for every blog entry you will publish in the future!</span></p> <h3><strong><font color="#000080">Live Writer never knows</font></strong></h3> <p>Sadly, our Live Writer is not aware of the fact, that comments are disabled. Thus, there is no way to correct the missing commenting option with the help of Microsoft’s tool. In addition, Google stores some kind of “comments-disabled” flag value inside of every post you make. Thus, you may re-visit your blogger’s settings page (shown above) and reset your wrong choice to “New Post Have Comments” like shown in the next screenshot:</p> <p><img style="display: block; float: none; margin-left: auto; margin-right: auto" title="Allow Comments on Posts" alt="Allow Comments on Posts" src="http://lh6.ggpht.com/_MOmDLu4Rm5Y/TaRIGK0BeiI/AAAAAAAAHUE/dL7mnn7U_zk/8%5B8%5D.png?imgmax=800" width="485" height="77" /></p> <p>But, this will not affect any page you posted while your wrong “…No Comments”-selection was active! Only your <strong>next new post</strong> will show the <strong><u>0 Comments</u></strong> link again. Okay, you may consult Google’s help pages. There are a lot of FAQ entries dealing with “missing comments links”. Alas, that makes it not easier to find the right answer to solve your homegrown problem :-) Many times missing comments links resulting from some corrupted blogger template. There are plenty of suggestions how to manually fix broken templates. Maybe someone dares to follow them, but not me!</p> <h3><strong><font color="#000080">The RTFM Solution</font></strong></h3> <p><strong><font color="#000080">There is a simple native way (only some clicks away!) to let the “Comments” link reappear in your post’s footer.</font></strong> I found it while reading some Google’s online help pages dealing with blogger settings, etc. If you like to follow me, just do the steps below:</p> <ol> <li>Check into your account </li> <li>Click “Design” in the upper right corner of your blogger bar at top of the page (showing … <your login> [New Post] [<u>Design</u>] [Sign Out] ) </li> <li><span style="font-family: arial">Select the “Posting” tab and below click the “Edit Posts” link. </span></li> <li><span style="font-family: arial">All this brings you to the page shown below:</span> </li> </ol> <p align="center"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5sqmjl5g8Vj736feond_cNwkp6_W81mzsDa3Rm7cAQkHSuzveSeOUEs1M_3I0iXy-X3yoMuzqif4CTviC2lejqPb8znZnpb9lsNz3WM2P8_APnwNLLRiTN5REC4E2bMJXcXy5/s1600-h/image34.png" target="_blank"><img style="display: inline" title="Select Post with Comments disabled" alt="Select Post with Comments disabled" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgcNqihpr1e4KS4IjReOCq1Ch1U_ePm_PT3b5zoQGy8z2awwFj9EvQJjRsYYtfwPY656mmuETdG_j-E7yL8MKsFILw4OUlUTAYIaH-QzG0DGMlKl3NiheMUgnmeffLDkCq5ia6/?imgmax=800" width="483" height="428" /></a>  <br /><span style="font-family: arial"><strong>Img #2.) Select an entry with disabled Comments link!</strong></span></p> <p><span style="font-family: arial">Now, go and click “Edit” to switch a post with missing “Comments” link into edit mode. Google starts a web editor session for you like shown below:</span></p> <p align="center"><a href="http://lh6.ggpht.com/_MOmDLu4Rm5Y/TaRIHsinLlI/AAAAAAAAHSQ/p0Rgfhl-JY8/s1600-h/image25.png" target="_blank"><img style="display: inline" title="Expand Post Options" alt="Expand Post Options" src="http://lh4.ggpht.com/_MOmDLu4Rm5Y/TaRIIETf5II/AAAAAAAAHSU/jTBYTRPRvHg/image_thumb8.png?imgmax=800" width="481" height="326" /></a> <br /><span style="font-family: arial"><strong>Img #3.) Watch out the “Post Options” link in the bottom left corner!</strong></span></p> <p><span style="font-family: arial">There is an easy to oversee switch “<strong><font color="#800080">Post Options</font></strong>” in the lower left corner of the online editor. Click that link-button and the editor window expands a region showing you a whole bunch of additional post related options, like shown below:</span></p> <p align="center"><a href="http://lh3.ggpht.com/_MOmDLu4Rm5Y/TaRIIsToGVI/AAAAAAAAHSY/zcwBok_tMhA/s1600-h/image33.png" target="_blank"><img style="display: inline" title="Reset Reader Comments to "Allow"" alt="Reset Reader Comments to "Allow"" src="http://lh5.ggpht.com/_MOmDLu4Rm5Y/TaRIJOgg7pI/AAAAAAAAHSc/inUEa1rWctg/image_thumb12.png?imgmax=800" width="476" height="467" /></a> <br /><span style="font-family: arial"><strong>Img #4.) Choose “Allow” to re-enable “Comments”</strong></span></p> <p><span style="font-family: arial">Re-select “Allow” in the “Reader comments” option group and after saving your post shows up with <strong><u>n Comments</u></strong> link in it’s footer, again – <strong>f</strong></span><span style="font-family: arial"><strong>inally</strong> ;-)</span></p> <p><span style="font-family: arial">Repeat the last steps for every post with hidden/disabled “Comments” link – et nous voilà arrivés!</span></p> <p><span style="font-family: arial"><strong><font color="#800040">BTW.: The option used above (the way to change settings on a per-post basis) is well described somewhere on one of the many, many Google online help pages:-) We all know the shortcut “RTFM“, don’t we? ;-)</font></strong></span></p> <p><span style="font-family: arial">That's all for now, <br />   </span><span style="font-family: arial">CU guys!</span></p> <hr /> <p><strong><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Previous Entry" border="0" alt="Previous Entry" src="http://lh5.ggpht.com/_MOmDLu4Rm5Y/TaVzCDSP6fI/AAAAAAAAHd4/fywh3_ngm_g/NavBack_48_RGBA2.png?imgmax=800" width="48" height="64" /><a href="http://myvfpblog.blogspot.com/2009/09/visual-foxpro-miscellaneous-diverse.html"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Miscellaneous Home (TOC)" border="0" alt="Miscellaneous Home (TOC)" src="http://lh6.ggpht.com/_MOmDLu4Rm5Y/SsX0eSObFhI/AAAAAAAAHd8/mClqMrpS0_g/NavHome_48_RGBA5.png?imgmax=800" width="48" height="64" /></a><a href="http://myvfpblog.blogspot.com/2008/05/humour-3_19.html"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Next Entry" border="0" alt="Next Entry" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3lrCJsNa-Q7UNQDcD8OxWfJp66dqk4FEe-daH_JpSKLa4kEM2ZUxXheE9ZAiBZm4TscjWI5pczxYaI9zoUyGi4CtB2A_i9MO-h2KzFShrHC9JRBBaBKFgXaR2zB54Hm-Ytb23/?imgmax=800" width="48" height="64" /></a></strong></p> Burkhardhttp://www.blogger.com/profile/11631168041975170500noreply@blogger.com0