Navigation


VFPConversion Blog

This blog is dedicate to the adoption of technologies such as Microsoft .NET or SQL Server in addition to Visual FoxPro. Expect posts on this blog to be fairly technical, as this blog is geared towards developers, testers, and technical decision makers.

Content Area Footer

Monday, June 27, 2005
COM Interop: VFP COM objects and ASP.NET

Many VFP developers face the need of consuming VFP COM components in either ASP.NET Web Applications or Web Services. That’s normally a good way to reuse business logic you’ve built over time in VFP. However, when dealing with VFP business logic accessed as a COM component, one must also deal with security. This represents a common pitfall. 

Let’s say you create a VFP COM component that exposes the business logic you want to consume from .NET. In that case, a .NET web application tries to instantiate this object (going through the COM Callable Wrapper, or CCW, for short). This commonly causes a “System.AnauthorizedAccessException” exception, because the "user" (the web application) doesn’t have access rights to the folder where the COM component is physically located.

Normally, users accessing a web application (without any specific authentication specified) get logged in using the generic ASPNET user, which has very limited rights on the computer. In order for the application to work, the ASPNET user must have read rights to the folder the COM component is located in. Therefore, to provide access to the VFP COM component from within .NET, make sure that the ASPNET user account is granted read access to that folder. Also, make sure you do NOT grant write-access to the folder. In general, you want to set the access rights for that account as low as possible to prevent hacking attacks. Also, only assign read rights as specifically as possible. Do not (for instance) allow read access to an entire harddrive!

There also is a way to avoid the nastiness of messing with the ASPNET user account altogether: VFP COM components can be registered in COM+ (a task that only requires a few clicks and no programming changes). In COM+, one can specify a specific user account that is used to run the component. This way, one can create a special user account and use it for the purpose of interop only. As long as that account has access to the component, no other changes in the security system are required, and the ASPNET user account remains locked down, and therefore limits the attack surface hackers have to work with. The downside of this approach is the overhead that gets introduced, both in terms of administration and performance. Nevertheless, this is the recommended approach.



Posted @ 3:52 PM by Lassala, Claudio (lassala@foxbrasil.com.br) -
Comments (6)


Sunday, June 19, 2005
Static Code Analysis

Creating code of high quality is difficult. For this reason, software projects need a very good process that concerns itself with code quality. Developers are testing, testers are testing, code reviews take place, automated tests are performed on the UI, database, and object levels, and - in environments like .NET - a new technique known as "Static Analysis" is used. So what is this "Static Analysis" exactly?

Static Analysis basically refers to automated code reviews. Consider this simple example for instance:

o=CREATEOBJECT("wwIPStuff")
o.cMailServer="mail.yourmailserver.net"
o.cSenderEmail="
rstrahl@west-wind.com"
o.cSenderName="Rick Strahl"
o.cRecipient="
somebody@sweat.com,another@bust.com"
o.cSubject="wwIPStuff Test Message"
o.cMessage="Who said this had to be difficult?"
o.SendMail()

This sends an email from VFP using West Wind's IPStuff (www.west-wind.com). It is a relatively simple object to use, and is very powerful at the same time. However, people tend to have some problems with this, because unless the object is used correctly, it does not work. People often forget to send the email server setting, or set it incorrectly.

Of course, this is something that can be handled with code reviews, where the person in charge of the code review can verify, that "mail.yourmailserver.net" is in fact the correct server to use. Static Analysis does the same thing, but instead of having someone in charge of that code review, there is software that does this. The question is: How can this be done reliably?

Static Analysis really only works well with strongly typed languages. In the example above, it is extremely difficult to write an algorithm that loads thousands of files of source code and reliably analyze what "o.cMailServer" is and what it should it be set to. However, if "o" is stronly typed, it is very easy to look at it through strongly typed technologies such as ".NET Reflection" or ".NET Introspection", where it is easy to ensure that "o" really refers to "wwIPStuff", and create a simple set of rules that define how wwIPStuff is to be used, and what the rules are for the "cMailServer" property. (Note that in addition to strong typing, this also requires another technology that supports the parsing aspect...)

In Visual Studio, up to version 2003, Static Analysis is done through a tool known as FxCop (www.gotdotnet.com/team/fxcop). FxCop ships with thousands of rules right out of the box, and it can be enhanced with different rules of your own (in fact, our own Claudio Lassala is presenting a session about this very topic at this week's DevTeach conference - www.devteach.com). Starting with Visual Studio 2005, Static Analysis will be integrated right into the Visual Studio environment.

The advantages of Static Analysis are clear: One can perform very advanced code reviews that do not overlook problems and at the same time include massive amounts of code. In fact, with Static Analysis, one can code-review 100% of all source code (in fact, rules can be defined that only allow code to be checked into source control if all static analysis rules were passed). Of course, there are always special cases that need to be reviewed manually, but with Static Analysis, that becomes a much more approachable problem.

The increase in quality achieved through static analysis are amazing! Best practices and rules can be easily enforced and communicated. Much more so than training ever could. Also, the simple fact that every line of source code written will be analyzed causes most developers to write much cleaner code to begin with.



Posted @ 2:41 PM by Egger, Markus (megger@eps-software.com) -
Comments (2)


Tuesday, June 14, 2005
Live from DevCon 2005, Las Vegas

After the opening session presented by Microsoft's Ken Levy and Randy Brown last night, DevCon is now in full swing with it's first full day of sessions today.

The keynote last night was interesting, especially since Microsoft just posted the new VFP Roadmap, and attendees were eager to learn more about how to interpret the announcements. In particular, people have come to Las Vegas to learn more about the "Sedna" project, which is scheduled for release in 2007. What exactly is Sedna? Will it be called VFP10? What does the future hold?

After the keynote and the first day of the conference, some of these questions have been answered to a certain extent, but it is also clear that even Microsoft has yet to make a lot of decisions in the next 2 years before the project is brought to completion. However, at this point the interpretation that seems to emerge (and that Microsoft seems to be guiding attendees to) is that Sedna can be seen either as an Add-On to VFP9, or as VFP9 - Service Pack 2. The core engine of the product will not be modified in Sedna (except for bug-fixing perhaps) and the focus is clearly on .NET and Windows Longhorn adoption for VFP developers.

This certainly does not mean that VFP is not a viable product anymore. It simply means that there are other technologies that VFP developers should also be thinking about in the future. VFP will remain a Win32 product, and will not be migrated to the Managed Platform or 64-bit. While for some scenarios, Win32 may still be a viable solution, other projects may require a more up-to-date implementation and VFP developer should plan accordingly in the long term (or possibly even in the near future... depending on the project).

Most of the keynote demos focused on early ideas for Sedna, with presentations including anything from relatively simple interop scenarios, to an early demo of Avalon UIs using .NET WinForms components, which in turn used FoxPro data.

Sadly, attendance at this year's DevCon is a little down from last year's. (Official numbers have not been announced, but several attendees seem to have been busy trying to count attendees themselves, and guesses range from 160 to 200 attendees). Unfortunately, many of the old Fox Gang members are not attending DevCon anymore. However, those who are still active and many of them are now blogging. For more information on the conference, check out David Stevenson's Talking Fox Blog, or Alex Feldstein's Blog.

The conference content is good as always. Many of the regular conference sessions deal with features new to VFP9, or with .NET adoption for VFP developers. The conference overall is a pretty good deal for attendees, since all attendees are free to attend other conferences that are held here at the same time, such as a SharePoint conference, and Access conference, a .NET conference, and an SQL Server conference.

If you have missed this conference however, there still is time to get into the next event of similar nature: DevTeach (www.DevTeach.com) in Montreal is just around the corner!



Posted @ 1:37 AM by Egger, Markus (megger@eps-software.com) -
Comments (2)


Friday, June 10, 2005
Going to DevCon...

Advisor's Visual FoxPro DevCon 2005 is just around the corner!

This weekend, several people associated with VFPConversion.com will be heading to Las Vegas to present: Claudio Lassala, Rick Strahl, Kevin McNeish, Rod Paddock, and myself (Markus) will all be presenting. Feel free so seek us out at the conference and chat about technology (or other topics).

After recent Microsoft announcements, the keynote is highly anticipated. Expect some posts right from the conference over the next few days.

For details, visit http://advisorevents.com/cmt0506p.nsf/w/main-cmx

If you missed DevCon, you can still sign up for the next conference with FoxPro content: DevTeach in Montreal (www.DevTeach.com).



Posted @ 9:48 AM by Egger, Markus (megger@eps-software.com) -
Comments (7)


Thursday, June 09, 2005
Declarative UI Development: Is it new for VFP Developers?

With WinFX, Microsoft introduces a completely new UI technology called "Avalon", and with it, a completely new way of defining these UIs (among other things) called "XAML" (pronounced "zamel"). (Note: I will be teaching a session about Avalon at the upcoming DevTeach conference in Montreal - www.DevTeach.com). XAML is a way to define UIs "declaratively". What does that mean? It means that rather than using traditional programming techniques, one simply "declares" what the UI looks like. An example explains what it means:

In Visual FoxPro, we would create a form with controls on it like so:

oForm = CreateObject("Form")
oForm.AddObject("btn1","CommandButton")
oForm.btn1.Top = 10
oForm.btn1.Left = 10
oForm.btn1.Caption = "Hello World"

oForm.AddObject("txt1","TextBox")
oForm.txt1.Top = 30
oForm.txt1.Left = 10

And so forth. In Avalon on the other hand, one can declare the same thing like so:

<Window> 
    <Button ID="btn1" Top="10" Left="10">Hello World</Button> 
    <TextBox ID="txt1" Top="30" Left="10"/>
</Window>

This is a slightly simplified version of the real Avalon syntax, but you get the idea. (Of course Avalon still also supports programmatic declaration of the UI similar to how its done in VFP of WinForms today).

If you are interested in more information about the declarative programming concept, check out my recent CoDe Magazine eColumn: http://www.code-magazine.com/Article.aspx?quickid=050053.

All this declarative programming is a hot new thing for WinForms developer, and in many ways rightfully so, since it provides a number of advantages (see my article for some details). However, when I talk to VFP developers, they often seem to be sceptical about the whole concept. I am not really sure why. I understand that the syntax is different from what we are used to, but is the concept really new? Give this a try:

USE (HOME(2)+"Solution\forms\Launch.scx")
cXml = ""
CursorToXml("Launch","cXml")
? cXml

As you will see, this conceptually is very similar to what Avalon does. Sure, the syntax is a bit different, but the concept is the same. Creating a form in an SCX or VCX is really very close in concept to declarative programming. Much closer than it is to traditional programmatic development. The main different is that VFP stores the declaration of the UI in DBF files, while Avalon uses XML. But that's mainly a storage mechanism and has little influence on the concept.

Some may say "but I am never exposed to the DBF structure of a form when I create it", and that's true! But guess what: So far, Microsoft has not shown any visual editors for XAML, but there is no doubt that there will be. In fact, third parties have already presented such editors (see www.erain.com for an example).

Does that mean that there is little difference between Avalon and VFP forms? No! Avalon is a much more powerful UI technology than any of the current windows UI packages can provide. It is a 3D-based, fully graphics accelerated UI geared towards highly professional and highly polished user interfaces. But I find it interesting to see that a fundamental concept introduced in FoxPro 15 (or more) years ago, still provides great value today!



Posted @ 10:04 AM by Egger, Markus (megger@eps-software.com) -
Comments (1)


Wednesday, June 08, 2005
Passing Arrays to a .NET COM object from Visual FoxPro

A number of people have asked me about passing arrays to .NET functions from Visual FoxPro applications. The problem here is that Visual FoxPro arrays are not formatted the right way to just be called to a .NET COM object by default. VFP arrays are 1 based while in general COM objects expect arrays to be 0 based so you need to fix up arrays to make this happen. .NET arrays are always 0 based unless explicitly declared otherwise.

Assume you have a method in a .NET COM object that looks like this:

 

[ClassInterface(ClassInterfaceType.AutoDual)]

[ProgId("DotNetCom.DotNetComPublisher")] 

public class DotNetComPublisher

public string PassArray(object[] Objects )

{

  string Output = "";

  foreach(object Customer in Objects)

  {

      // *** Must access array by using Reflection

      Output += ComUtils.GetProperty(Customer,"Name") + " " +    

          ComUtils.GetProperty(Customer,"Name") + "\r\n";

  }

  return Output;

}
}

 

And you want to pass an object like this:

 

loAddr = CREATEOBJECT("EMPTY")

ADDPROPERTY(loAddr,"Name","Rick Strahl")

ADDPROPERTY(loAddr,"Company","West Wind")

ADDPROPERTY(loAddr,"Date",DATETIME())

 

loAddr2 = CREATEOBJECT("EMPTY")

ADDPROPERTY(loAddr2,"Name","Rick Strahl")

ADDPROPERTY(loAddr2,"Company","West Wind")

ADDPROPERTY(loAddr2,"Date",DATETIME())

 

DIMENSION loAddrArray[2]

loAddrArray[1] = loAddr

loAddrArray[2] = loAddr2

 

To .NET. Your first try likely looks like this:

 

LOCAL loNet as DotNetCom.DotNetComPublisher

loNet = CREATEOBJECT('DotNetCom.DotNetComPublisher')

? loNet.PassArray(@loAddrArray)

 

which will fail with Invalid Parameter type.

 

The key to make this work is to use the COMARRAY() function in VFP to mark the array as 0 based and passed by reference:

 

LOCAL loNet as DotNetCom.DotNetComPublisher

 

loNet = CREATEOBJECT('DotNetCom.DotNetComPublisher')

COMARRAY(loNet,10)

? loNet.PassArray(@loAddrArray)

 

And this works correctly passing the objects to .NET.

 

To return arrays works as well. Take the following .NET method:

 

public Customer[] ReturnArray(int Count)

{

      Customer[] Customers = new Customer[Count];

      for (int x= 0;x < Count; x++)

      {

            Customers[x] = new Customer();

            Customers[x].Company = "West Wind " + DateTime.Now.ToString();

            Customers[x].oAddress.StreetAddress = DateTime.Now.ToString();

      }

      return Customers;

}

 

Which you can retrieve like this in FoxPro:

 

LOCAL loNet as DotNetCom.DotNetComPublisher

loNet = CREATEOBJECT('DotNetCom.DotNetComPublisher')

loArray =loNet.ReturnArray(3)

 

lnCount = ALEN(loArray,1)

 

FOR x=1 TO lnCount

   loCust = loArray[x]

   ? loCust.Company

   ? loCust.oAddress.StreetAddress

ENDFOR

RETURN

 

Note that you are not getting the Array object that .NET is returning. There’s no Length property for example, but rather VFP marshals this .NET array to a standard array. Actually .NET returns this array to COM as a COM compatible SafeArray and VFP picks that up and exposes the array as a VFP array object. You won't need to use COMARRAY() on the returned array.

 

A final option that I like to use in many situations is to not pass arrays as parameter or return types directly, but rather pass objects that contain arrays. The advantage is that you get more control over the data and you have a chance to potentially call COMARRAY() with other marshalling options.



Posted @ 2:02 PM by Strahl, Rick (rstrahl@west-wind.com) -
Comments (5)


Wednesday, June 08, 2005
Subclassing with Designer Support

Visual Studio has very fancy visual designers (such as the form designer). They are different from the designers in FoxPro in that they work directly of the source code file. For instance, when you add a button to the form and set the button's caption to "Hello World", the form designer creates the following source code snippet (or similar... this is a condensed version):

//
// button1
//
this.button1 = new System.Windows.Forms.Button();
this.button1.Location = new System.Drawing.Point(312, 128);
this.button1.Name = "button1";
this.button1.TabIndex = 2;
this.button1.Text = "Hello World!";

As you can see, the button gets created, and then all the required properties are set. The million-dollar-question is: Which properties are "required"? The simple answer would be: "All the properties that have changed". And this is the correct answer, except: How do we know which properties have changed? To know that, we also have to know what the propertie's default value is. In FoxPro, the designer can look in the VCX and find out. In .NET, things are not quite this simple.

The people writing the .NET designers have come up with the following solution. Each property can have an attribute attached that defines the default value. If we were to add a custom property, this could look like this example:

public class Xxx
{
    private string myCaption = "Hello";

    [DefaultValue("Hello")]
    public string Caption
    {
        get { return this.myCaption; }
        set { this.myCaption = value; }
    }
}

The attribute (red) allows the designer to figure out the default value for the Caption property. Therefore, whenever the caption is "Hello", no source code line will be created, since the default value is OK, but if the caption was set to something else, the designer would create the appropriate source code line.

The situation gets a bit tricky when we start subclassing controls. For instance, we might want to subclass the default label control and set AutoSize to true. Conceptually, this can be done very easily like so:

public class MyLabel : System.Windows.Forms.Label
{
    public MyLabel()
    {
        this.AutoSize = true;
    }
}

So far so simple. However, the AutoSize property has a DefaultValue attribute of false. Therefore, whenever the auto size of our new label is set to true (which would be the newly programmed standard value for the property), the designer thinks that according to the DefaultValue attribute, it is NOT the default, and thus creates a line of code the specifically sets the property to true again. This is redundant, but unless we change our class again, not a big problem. On the other hand, if we were to drop this label on a form and set its AutoSize property to false, the designer looks at the DefaultValue atttribute and says "cool... that's the default value anyway... no code needed" and does NOT create the line. Therefore the property can not be set to false anymore, which pretty much makes it useless. To fix the problem, we must not just change the propertie's value, but we must also override the property itself, so we can set the new attribute:

/// <summary>

/// Auto size
/// </summary>
[DefaultValue(true)]
public override bool AutoSize
{
    get { return base.AutoSize; }
    set { base.AutoSize = value; }
}

As you can see, the override itself only calls the base functionality without any other changes. We simply had to override to attach a new DefaultValue() property, which allows the designer to work right. Unfortunately, with this little trick, we may have lost some other functionality. The property description may not show up correctly anymore for instance, and we may have to duplicate the original Description() attribute as well.

This is probably one of the most annoying things in .NET OOP. I have been lobbying to get this changed for a while. Right now, we will have to deal with the situation. Luckily, the C# and VB.NET editors make it relatively easy to code all of this...



Posted @ 8:44 AM by Egger, Markus (megger@eps-software.com) -
Comments (1)


Tuesday, June 07, 2005
What exactly is an 'Inner Class'?

OK, some people had questions about the last blog entry. I mentioned that "inner classes" are stored in the same file as regular classes. So what exactly is an "inner class". So here's the deal:

In Visual FoxPro, there is basically one type of class. No differences, no strings attached. In .NET, there are many different types of classes. For instance, there is the standard "class", which is very similar to a class in VFP. Then, there is a "struct", which is rather similar to a class, but completely different in terms of internal handling (especially memory management). Then there are completely different types of classes, such as Delegates and Enums (those will probably be a topic of a future post).

Inner classes are classes that are defined in other classes. One would do this for classes that are only needed inside of another class. Consider this example:

public class Xxx
{
  
private Yyy internalDataStore = new Yyy();

  
publicvoid DoSomething()
  
{
     
this.internalDataStore.Something();
  
}
}

class
Yyy
{
  
publicvoid Something()
  
{
     
// Something
  
}
}

In this example, class Xxx uses class Yyy for internal purposes only. So why define class Yyy in a way that is visible to everyone and may confuse people? That's exactly where inner classes are important. The following example defines class Yyy within class Xxx and is thus only available to class Xxx.

public class Xxx
{
  
private Yyy internalDataStore = new Yyy();

  
publicvoid DoSomething()
  
{
     
this.internalDataStore.Something();
  
}

  
class Yyy
  
{
     
publicvoid Something()
     
{
        
// Something
     
}
  
}
}



Posted @ 9:14 PM by Egger, Markus (megger@eps-software.com) -
Comments


Monday, June 06, 2005
About Assemblies, Classes, VCXes, and how they all relate...

One of the things in .NET that seems to throw Fox developers for a loop, is how to organize their .NET classes in source files.

FoxPro developers are generally used to putting multiple classes in a single file, such as a .PRG or a .VCX file. As a result, many VFP developers end up putting several .NET classes in a single .VB or .CS file, thus treating it very much like a class library. In FoxPro, this makes sense, because a class library is a file that contains multiple classes, and in the Fox-world, that is generally a VCX file (or VCX plus VCT combination). In .NET however, the closest concept there is to a "class library" is an assembly. Assemblies are the compiled versions of a collection of classes and therefore very similar to class libraries (all classes in a project get compiled into a .DLL or .EXE assembly), although one can also see assemblies as applications (especially when they are compiled into EXEs).

In .NET, there are mostly downsides to putting a multiple classes into single source files: Source control gets tougher, editors can not handle multiple classes in a single assembly, .NET developers are generally not used to having multiple classes in a single file and therefore have a hard time navigating projects,...

As a rule-of-thumb, at EPS, we put each class in its own source file. There are very few exceptions to this rule. "Inner classes" for instance, are always in the same file. Sometimes, Enums or Delegates are in the same file as the class using them. But as a general rule, keep things separate, and your .NET life will be a lot smoother.



Posted @ 10:39 AM by Egger, Markus (megger@eps-software.com) -
Comments (4)


Monday, June 06, 2005
VFP-to-.NET Conversion Training - Montreal

DevTeach 2005 (www.DevTeach.com) is just around the corner, and with it, a 2-day VFPConversion.com pre-con seminar, presented by industry expert Kevin McNeish.

Topics include: C# and VB.NET primer, Object-Orientation in .NET, Data Access in .NET, Creating Windows Forms Applications, Creating Web Forms Applications, Best practices for porting Fox applications to .NET, and .NET to FoxPro Interop. All content is presented from a VFP perspective.

For further details and to sign up, visit http://www.eps-cs.com/VFPConversion/Training/Index.aspx.



Posted @ 10:28 AM by Egger, Markus (megger@eps-software.com) -
Comments (2)


Thursday, June 02, 2005
Microsoft announces Future-of-VFP Roadmap

Microsoft published a "Microsoft Visual FoxPro Roadmap" to help developers figure out the appropriate path forward. Details can be found at: http://msdn.microsoft.com/vfoxpro/roadmap/

The roadmap includes the first public announcement of "Sedna", the project the Microsoft VFP Team is currently working on. ("Sedna" is an object in our solar system beyond Pluto, the 9th planet...). Sedna will help VFP developers to make the move to .NET much more easily. Sedna is an add-on product to Visual FoxPro 9 and will ship sometime in the first half of 2007 (after the release of Windows "Longhorn"). Microsoft has not announced any plans for a new version of Visual FoxPro. Microsoft has also announced that Visual FoxPro will remain a Win32 product. It will of course continue to work in WinFX and 64bit scenarios, but only in compatibility mode.

For VFPConversion.com, this represents a new chapter in our existence. While initially, VFPConversion.com was even criticized by some as "stabbing Microsoft in the back", it has now become much clearer that VFPConversion.com is very much in line with Microsoft's plans for the future of Visual FoxPro.

For additional information, visit Ken Levy's blog at http://blogs.msdn.com/klevy/ (Ken is Microsoft's VS Data Product manager, and also the "public voice of Visual FoxPro).



Posted @ 7:05 AM by Egger, Markus (megger@eps-software.com) -
Comments (2)


Wednesday, June 01, 2005
Welcome to the VFPConversion Blog

Welcome to the brand-new VFPConversion.com blog! This blog is slightly different from regular blogs in that it is written not by a single person, but by an entire group of people who can provide valuable information about VFPConversion topics. Expect this blog to provide detailed technical information about Visual FoxPro and .NET and very little fluff that often plagues personal blogs.

We hope you will find this new feature useful, and are looking forward to your feedback! 

Sincerely,
Markus Egger

President and Chief Software Architect, EPS Software Corp. - www.eps-cs.com
Publisher, CoDe Magazine - www.code-magazine.com
www.eps-software.com - www.MarkusEgger.com



Posted @ 7:10 AM by Egger, Markus (megger@eps-software.com) -
Comments (15)


 

 

 

 

 

 

 

Syndication RSS 2.0 RSS 2.0

All My Blogs:
My personal blogs:
Dev and Publishing Dev and Publishing
Travel and Internat. Living Travel and Internat. Living
Other blogs I contribute to:
Milos Blog (US) Milos Blog (US)
VFPConv. Dev Blog (US) VFPConv. Dev Blog (US)
VFPConv. Dev Blog (DE) VFPConv. Dev Blog (DE)

 

Blog Archives
All Blog Posts

2009
    February (1)
2008
    November (1)
    October (2)
    April (1)
    March (1)
2007
    August (1)
    July (1)
    June (2)
    March (1)
    January (1)
2006
    December (1)
    November (2)
    October (1)
    September (1)
    August (1)
    April (3)
    March (2)
    February (1)
    January (1)
2005
    December (2)
    November (3)
    October (2)
    September (7)
    August (3)
    July (4)
    June (12)

 

 

 

This Blog is powered by MilosTM Collaboration Components.