Month: February 2025

  • Microsoft Visual FoxPro 9.0

    Microsoft Visual FoxPro 9.0

    Learn Microsoft Visual FoxPro 9.0

    • Article
    • 08/29/2016

    Microsoft® Visual FoxPro® database development system is a powerful tool for quickly creating high-performance desktop, rich client, distributed client, client/server, and Web database applications. Employ its powerful data engine to manage large volumes of data, its object-oriented programming to reuse components across applications, its XML Web services features for distributed applications, and its built-in XML support to quickly manipulate data.

    Visual FoxPro 6 Language Reference Book on Archive.Org

    Note that Visual FoxPro 9.0 is the last version and was published in 2007.


    Download Visual FoxPro 9.0 SP2

    Download Service Pack 2 for Microsoft Visual FoxPro 9.0. SP2 provides the latest updates to Visual FoxPro 9.0 combining various enhancements and stability improvements into one integrated package.

    Three Hotfixes for Visual FoxPro 9.0 SP2

    Visual FoxPro Samples and Updates

    Find code samples and product updates for Visual FoxPro.

    Visual FoxPro on MSDN Forums

    Join the conversation and get your questions answered on the Visual FoxPro Forum on MSDN.

    Visual FoxPro 9.0 Overview

    With its local cursor engine, tight coupling between language and data, and powerful features, Visual FoxPro 9.0 is a great tool for building database solutions of all sizes. Its data-centric, object-oriented language offers developers a robust set of tools for building database applications for the desktop, client-server environments, or the Web. Developers will have the necessary tools to manage data—from organizing tables of information, running queries, and creating an integrated relational database management system (DBMS) to programming a fully-developed data management application for end users.

    • Data-Handling and Interoperability. Create .NET compatible solutions with hierarchical XML and XML Web services. Exchange data with SQL Server through enhanced SQL language capabilities and newly supported data types.
    • Extensible Developer Productivity Tools. Enhance your user interfaces with dockable user forms, auto-anchoring of controls, and improved image support. Personalize the Properties Window with your favorite properties, custom editors, fonts, and color settings.
    • Flexibility to Build All Types of Database Solutions. Build and deploy stand-alone and remote applications for Windows based Tablet PCs. Create and access COM components and XML Web Services compatible with Microsoft .NET technology.
    • Reporting System Features. Extensible new output architecture provides precision control of report data output and formatting. Design with multiple detail banding, text rotation, and report chaining. Output reports supported include in XML, HTML, image formats, and customizable multi-page print preview window. Backward compatible with existing Visual FoxPro reports.

    Resources

    Visual FoxPro Downloads

    • Article
    • 08/29/2016

    Download samples, along with the final product updates including service packs for Visual FoxPro to ensure maximum productivity and performance from your Visual FoxPro development.

    Visual FoxPro 9.0 Updates

    • Visual FoxPro 9.0 Service Pack 2 (SP2)
      Download Service Pack 2 for Microsoft Visual FoxPro 9.0. SP2 provides the latest updates to Visual FoxPro 9.0 combining various enhancements and stability improvements into one integrated package.
    • Help Download for Visual FoxPro 9.0 SP2
      Download product documentation for Visual FoxPro 9.0 SP2.
    • GDI+ Update for Visual FoxPro 9.0 SP2
      Security update patch for Visual FoxPro 9.0 SP2 for fixing Buffer Overrun in JPEG Processing (GDI+).
    • GDI+ Update for Visual FoxPro 9.0 SP1
      Security update patch for Visual FoxPro 9.0 SP1 for fixing Buffer Overrun in JPEG Processing (GDI+). Note: We highly recommend that you install Service Pack 2, then apply the GDI+ SP2 update.
    • Visual FoxPro 9.0 ‘Sedna’ AddOns
      AddOn pack for Visual FoxPro 9.0. This download contains six components: VistaDialogs4COM, Upsizing Wizard, Data Explorer, NET4COM, MY for VFP and VS 2005 Extension for VFP.
    • XSource for Visual FoxPro 9.0 SP2
      Download XSource for Visual FoxPro 9.0 SP2. XSource.zip has its own license agreement for usage, modification, and distribution of the Xbase source files included.
    • Microsoft OLE DB Provider for Visual FoxPro 9.0 SP2
      The Visual FoxPro OLE DB Provider (VfpOleDB.dll) exposes OLE DB interfaces that you can use to access Visual FoxPro databases and tables from other programming languages and applications. The Visual FoxPro OLE DB Provider is supported by OLE DB System Components as provided by MDAC 2.6 or later. The requirements to run the Visual FoxPro OLE DB Provider are the same as for Visual FoxPro 9.0. Note: This version of the VFP OLE DB provider is the same version as the one included with Visual FoxPro 9.0 SP2.
    • VFPCOM Utility
      Extend Visual FoxPro interoperability with other COM and ADO components with the VFPCOM Utility. This utility is a COM server that provides additional functionality when you use ADO and access COM events with your Visual FoxPro 9.0 applications. For installation instructions and more details on the issues that have been addressed, consult the VFPCOM Utility readme.
    • Visual FoxPro ODBC Driver
      The VFPODBC driver is no longer supported. We strongly recommend using the Visual FoxPro OLE DB provider as a replacement. Please refer to the following article for more information and related links to issues when using the VFPODBC driver: https://support.microsoft.com/kb/277772.

    Visual FoxPro 8.0 Updates

    • Visual FoxPro 8.0 Service Pack 1Download Microsoft Visual FoxPro 8.0 Service Pack 1 (SP1), which provides the latest updates to Visual FoxPro 8.0. SP1 combines various enhancements and stability improvements into one integrated package. The download contains all the documentation for these updates. For installation instructions and more details on SP1, consult the Service Pack 1 readme.
    • GDI+ Update for Visual FoxPro 8.0 SP1Security update patch for Visual FoxPro 8.0 SP1 for fixing Buffer Overrun in JPEG Processing (GDI+).
    • Visual FoxPro 8.0 SP1 Task Pane Source CodeSource code for Task Pane Manager component included in SP1 for Visual FoxPro 8.0. SP1 for VFP 8.0 included an updated Task Pane Manager component as an .APP application file but did not contain the update source code files associated with the updated version.
    • Visual FoxPro 8.0 Localization Toolkit OverviewOverview document of the Localization Toolkit project results for making available various language versions of the design-time IDE DLL and help documentation as add-ons to the English version of Visual FoxPro 8.0.

    Visual FoxPro 7.0 Updates

    • Visual FoxPro 7.0 Service Pack 1Download Microsoft Visual FoxPro 7.0 Service Pack 1 (SP1), which provides the latest updates to Visual FoxPro 7.0. SP1 combines various enhancements and stability improvements into one integrated package. The download contains all the documentation for these updates. For installation instructions and more details on SP1, consult the Service Pack 1 readme.

    Code Samples

    • .NET Samples for Visual FoxPro DevelopersThis download contains different projects and source files which are designed to show how how some common Visual FoxPro functionally is created in Visual Basic .NET.
    • Visual FoxPro 8.0 SamplesThis download contains different projects which are designed to show how new features in Visual FoxPro 8.0 can be used. Each project is self-contained and can be run independently of any other. There is a readme text file contained in each project that describes each sample program.
    • Sample: Visual FoxPro DDEX Provider for Visual Studio 2005A Data Designer EXtension Provider allows a data source to integrate better with data tools in Visual Studio. Visual FoxPro “Sedna” included a sample for such a provider for VFP data.This is now available as a stand-alone download.

    System Requirements

    • Article
    • 08/29/2016

    To install Microsoft Visual FoxPro 9.0, you need:Expand table

    Minimum Requirements
    ProcessorPC with a Pentium-class processor
    Operating SystemMicrosoft Windows 2000 with Service Pack 3 or later operating systemMicrosoft Windows XP or laterMicrosoft Windows Server 2003 or later
    Memory64 MB of RAM minimum; 128 MB or higher recommended
    Hard Disk165 MB of available hard-disk space for typical installation; 20 MB of additional hard-disk space for Microsoft Visual FoxPro 9.0 Prerequisites
    DriveCD-ROM or DVD-ROM drive
    DisplaySuper VGA 800 X 600 or higher-resolution monitor with 256 colors
    MouseMicrosoft Mouse or compatible pointing device

    Frequently Asked Questions

    • Article
    • 08/29/2016

    Find answers to your frequently asked questions about Visual FoxPro.

    Q: What operating system is required for Visual FoxPro 9.0?

    Developing applications with Visual FoxPro 9.0 is supported only on Microsoft Windows 2000 Service Pack 3 or later, Windows XP, Windows Server 2003 and Windows Vista. You can create and distribute run-time applications for Windows 98, Windows Me, Windows 2000 Service Pack 3 or later, Windows XP, Windows Server 2003 and Windows Vista. Installation on Windows NT 4.0 Terminal Server Edition is not supported.

    Q: Will there be a Visual FoxPro 10.0?

    No. There will not be another major release of Visual FoxPro (see announcement: A message to the community, March 2007).

    Q: Will there be updates to Visual FoxPro?

    Yes. Visual FoxPro will continue to be supported as per the lifecyle policy (https://support.microsoft.com/lifecycle/?p1=7992). Visual FoxPro 9 will be supported until 2014. In support of these products we may release patch updates from time to time. These typically fix problems discovered either internally or by a customer and reported to our product support engineers.

    Q: Will there be a service pack 3 for Visual FoxPro 9?

    At this time there are no plans to release a service pack for Visual FoxPro. However if there arises a need to publish a collection of fixes we may release a service pack. We will make announcements on the Visual FoxPro home page.

    Q: What types of applications can I build with Visual FoxPro 9.0?

    With its local cursor engine, tight coupling between language and data, and powerful features, such as object-oriented programming, Visual FoxPro 9.0 is a great tool for building database solutions of all sizes, from desktop and client/server database applications to data-intensive COM components and XML Web services.

    Visual FoxPro 9.0 is an application development tool for building extremely powerful database applications and components. Its data-centric, object-oriented language offers developers a robust set of tools for building database applications on the desktop, client/server, or on the Web, through components and XML Web services. Developers will have the necessary tools to manage data from organizing tables of information, running queries, and creating an integrated relational database management system (DBMS) to programming a fully developed data management application for end users.

    Q: Can I use Visual FoxPro to build Web applications?

    Visual FoxPro COM components can be used with Internet Information Services (IIS) to build high-powered Internet database applications. This is because Visual FoxPro components can be called from Active Server Pages (ASP). Visual FoxPro is compatible with ASP but works even better in conjunction with the more modern ASP.NET. The components will retrieve and manipulate data, and will build some of the HTML returned to the user.

    Q: Can you consume XML Web services with Visual FoxPro?

    Yes, Visual FoxPro 9.0 makes it easy to consume XML Web services by integrating the SOAP Toolkit into the product.

    Q: Is Visual FoxPro a part of MSDN Subscriptions?

    Yes, Visual FoxPro 9.0 is included in the Professional, Enterprise, and Universal levels of MSDN Subscriptions. Visual FoxPro 9.0 is available for download to MSDN Subscribers via MSDN Subscriber downloads.

    Q: How long will Visual FoxPro be supported by Microsoft?

    Visual FoxPro 9.0 has standard support by Microsoft through January 2010 and extended support through January 2015 as per the developer tools lifecycle support policy.

    Q: How long will the SOAP Toolkit included in Visual FoxPro 9.0 be supported by Microsoft?

    Licensed users of Visual FoxPro 9.0 have a special lifecycle support plan for the SOAP Toolkit, supported by Microsoft on the same support plan as Visual FoxPro 8.0 which is through April 2008 and extended support through September 2013.

    Q: Is Visual FoxPro 9.0 compatible with Visual Studio 2005 and SQL Server 2005?

    Yes. We improved XML support and added new data types in Visual FoxPro 9.0 which improves .NET interop and SQL Server compatibility. Moreover the ‘Sedna’ add-on pack includes improvements to the Data Explorer and the Upsizing Wizard. These have significant improvements to support SQL Server 2005.

    Q: How does Visual FoxPro 9.0 compare to SQL Server?

    We do not contrast Visual FoxPro versus SQL Server. We position SQL Server as a database engine and Visual FoxPro as a developer tool. While Visual FoxPro has a database engine built-in, it is not positioned as a stand-alone database engine only. The trend is for an increasing amount of Visual FoxPro based applications to use SQL Server as the data storage in the solution. Of course, this is not required; it depends on the requirements of the solution. SQL Server offers security, reliability, replication, and many other features of a full relational database engine while the Visual FoxPro database system is an open file based DBF system that does not have many of those features. We leave it up to developers and companies to position and to compare various Microsoft products and technologies with each other and decide which ones are best for them to use when and how.

    Q: Are there plans to enhance the 2 GB database size limit in Visual FoxPro?

    The 2 GB limit is per table, not per database. We do not have any plans to extend the 2 GB table size limit in Visual FoxPro due to many reasons including the 32-bit architecture that already exists within the product. For large, scalable databases we recommend SQL Server 2008.

    Q: Is Visual FoxPro supported on Windows Vista?

    Yes. Visual FoxPro 9 Service Pack 2 is fully supported on Windows Vista.

    Q: Are there plans for Visual FoxPro to support 64-bit versions of the Windows operating system?

    No. While Visual FoxPro will remain 32-bit and not natively use 64-bit addressing; it will run in 32-bit compatibility mode. Visual Studio 2008 supports creating native 64-bit applications.

    Q: How do you position Visual FoxPro in relation to Microsoft Access?

    Microsoft Access, the database in Office, is the most broadly used and easiest-to-learn database tool that Microsoft offers. If you are new to databases, if you are building applications that take advantage of Microsoft Office, or if you want an interactive product with plenty of convenience, then choose Microsoft Access. Visual FoxPro is a powerful rapid application development (RAD) tool for creating relational database applications. If you are a database developer who builds applications for a living and you want ultimate speed and power, then choose Visual FoxPro.

    Q: Is Visual FoxPro part of Visual Studio .NET?

    No. Visual FoxPro 9.0 is a stand-alone database development tool which is compatible and evolutionary from previous versions of Visual FoxPro. Visual FoxPro 9.0 does not use or install the Windows .NET Framework. Visual FoxPro 9.0 is compatible with Visual Studio .NET the area of XML Web services, XML support, VFP OLE DB provider, and more. Visual FoxPro and Visual Studio are complimentary tools that work great together, such as Visual FoxPro 9.0 plus ASP.NET for adding WebForm front ends and mobile device front ends to Visual FoxPro applications.

    Q: What is Microsoft’s position on Visual FoxPro related to Visual Studio and .NET?

    We do not have plans to merge Visual FoxPro into Visual Studio and .NET, and there are no plans to create any sort of new Visual FoxPro .NET language. Instead, we are working on adding many of the great features found in Visual FoxPro into upcoming versions of Visual Studio, just like we’ve added great Visual Studio features into Visual FoxPro. If you want to do .NET programming, you should choose a .NET language with Visual Studio.

    A Message to the Community

    • Article
    • 08/29/2016

    March 2007

    We have been asked about our plans for a new version of VFP. We are announcing today that there will be no VFP 10. VFP9 will continue to be supported according to our existing policy with support through 2015 (https://support.microsoft.com/lifecycle/?p1=7992). We will be releasing SP2 for Visual FoxPro 9 this summer as planned, providing fixes and additional support for Windows Vista.

    Additionally, as you know, we’ve been working on a project codenamed Sedna for the past year or so. Sedna is built using the extensibility model of VFP9 and provides a number of new features including enhanced connectivity to SQL Server, integration with parts of the .NET framework, support for search using Windows Desktop Search and Windows Vista as well as enhanced access to VFP data from Visual Studio.

    Concurrently, the community has been using CodePlex (https://www.codeplex.com) to enhance VFP using these same capabilities in the VFPx project. Some of these community driven enhancements include:

    • Support for GDI+
    • An enhanced class browser
    • Support for Windows Desktop Alerts
    • An object oriented menu system
    • Integration with MSBuild
    • A rule-based code analysis tool similar to fxCop in Visual Studio
    • An Outlook Control Bar control

    To reiterate, today we are announcing that we are not planning on releasing a VFP 10 and will be releasing the completed Sedna work on CodePlex at no charge. The components written as part of Sedna will be placed in the community for further enhancement as part of our shared source initiative. You can expect to see the Sedna code on CodePlex sometime before the end of summer 2007.

    Visual FoxPro 6

    Technical Articles

    • Article
    • 06/30/2006

    ADO Jumpstart for Microsoft Visual FoxPro Developers

    Customizing Visual FoxPro 6.0 Application Framework Components

    Microsoft Transaction Serer for Visual FoxPro Developers

    The Microsoft Visual FoxPro 6.0 Component Gallery

    Microsoft Visual FoxPro 6.0 and Visual Studio Installer Tutorial

    Using Microsoft Visual Studio Installer for Distributing Visual FoxPro 6.0 Applications

    Using MSMQ with Microsoft Visual FoxPro 6.0

    The Visual FoxPro 6.0 Class Browser

    ADO Jumpstart for Microsoft Visual FoxPro Developers 

    • Article
    • 06/30/2006

    In this article

    1. Introduction
    2. What Are OLE DB and ADO?
    3. Why Incorporate ADO into a Visual FoxPro Application?
    4. ADO Object Model

    Show 2 more

    John V. Petersen

    April 1999

    Summary: Provides Microsoft Visual FoxPro developers with an overview of ActiveX Data Objects (ADO) and shows how to incorporate ADO into Visual FoxPro applications. Discusses the ADO object model and implementing Remote Data Services (RDS). (52 printed pages)

    Contents

    Introduction What are OLE DB and ADO? Why Incorporate ADO into a Visual FoxPro Application? ADO Object Model Remote Data Services Summary

    Introduction

    Microsoft®ActiveX® Data Objects (ADO) is perhaps the most exciting new Microsoft technology in quite some time. Because ADO is concerned with data, this new technology is of particular interest to Microsoft® Visual FoxPro® developers. Of course, you may ask, “Why do I need ADO? Visual FoxPro already has a high-performance local data engine.” It’s a good question.

    This paper provides the Visual FoxPro developer with a background of what ADO is and how to incorporate ADO into Visual FoxPro applications. After reading this paper, you should have enough information to readily answer the question: “Why do I need ADO?”

    A Brief Word About ADO Events

    One limitation of Visual FoxPro has been an inability to surface COM events. While Visual FoxPro can respond to events raised by ActiveX controls, objects created with the CreateObject function cannot. In Microsoft®Visual Basic®, COM Events are handled by using the WithEvents keyword. In Visual FoxPro, the new VFPCOM.DLL achieves the same results. The topics VFPCOM, ADO Events, and how to integrate ADO and Visual FoxPro will be discussed in another white paper. This paper is dedicated to providing the Visual FoxPro developer, with a comprehensive overview of ActiveX Data Objects, Remote Data Services (RDS), their respective objects, and how those objects work.

    This paper covers the following topics:

    • What are ADO and OLE DB?
    • Why incorporate ADO into a Visual FoxPro application?
    • The ADO object model
    • Remote Data Services

    What Are OLE DB and ADO?

    When discussing ADO, we are really talking about two distinct elements: the ActiveX data objects themselves and Microsoft Universal Data Access technology, more commonly known as OLE DB.

    OLE DB and Universal Data Access

    In simple terms, OLE DB is the succeeding technology to the Open Database Connectivity (ODBC) standard. OLE DB is a set of low-level interfaces that facilitate the Microsoft Universal Data Access strategy. ADO is a set of high-level interfaces for working with data.

    While both ODBC and OLE DB have the ability to make data available to a client, the capabilities of the two technologies are very different. ODBC is primarily designed for use on relational data. However, data exists in nonrelational as well as relational formats. In addition to new data formats, data resides in new places such as the Internet. Finally, the Microsoft Component Object Model (COM) framework requires better data access technology. Clearly, ODBC does not address these needs; a new technology is needed. That technology is OLE DB, and it is here to stay.

    The following graphic best illustrates how OLE DB and ADO work together. Clients can work directly with OLE DB or can work with OLE DB through the ADO interface (the latter is typically the case). Note that OLE DB can access SQL data either directly or through ODBC. An OLE DB provider provides direct access by OLE DB. Also note that OLE DB can also be used to access a variety of non-SQL data, as well as data that exists in mainframes. The ability to access data through a common interface, without regard to data location or structure, is the real power behind ADO and OLE DB.

    Whereas ODBC uses drivers, OLE DB uses providers. A provider is a software engine that provides a specific type of data that matches the OLE DB specification. Several OLE DB providers exist today, including those for Microsoft SQL Server™ and Oracle. Because there is such widespread use of ODBC, an OLE DB provider for ODBC has also been created in order to ease the migration from ODBC to OLE DB. Several nonrelational providers are currently under development. Perhaps the most anticipated of these is the OLE DB Provider for Microsoft Outlook®. A special provider, MS Remote, allows direct data access over the Internet. This brief list of providers shows the third-party community commitment to OLE DB, and many new providers are currently under development. For the latest news on available providers, refer to https://www.microsoft.com/data/.

    ADO Overview

    OLE DB is then a set of low-level interfaces that provide access to data in a variety of formats and locations. While powerful, OLE DB interfaces can be cumbersome to work with directly. Fortunately, ADO provides a set of high-level, developer-friendly interfaces that make working with OLE DB and universal data access a relatively simple task. Regardless of the programming environment you use, any Visual Studio® or Microsoft Office product such as Visual FoxPro, Visual Basic, Visual C++®, or Word, the interface you will use to access data remains constant. That interface is ADO, which in turn uses OLE DB.

    ADO itself is just a set of objects. By itself, ADO is not capable of anything. In order to provide any functionality, ADO needs the services of an OLE DB provider. The provider in turn uses the low-level OLE DB interface to access and work with data. One ADO connection may use a SQL Server OLE DB provider and another ADO connection may use an Oracle OLE DB provider. While the interface is constant, the capabilities may be very different because OLE DB providers are very different, which highlights the polymorphic nature of OLE DB.

    As developers, we crave consistency. ADO provides us with a consistent interface for our program code.

    ADO Version Summary

    The current version of ADO (2.1) is the fourth version of ADO to be released in less than two years. ADO 1.0 was primarily limited to working with Active Server pages. Only one OLE DB provider existed, the OLE DB Provider for ODBC Drivers.

    ADO (2.1)—Ships with the newest version of Microsoft Web browser, Internet Explorer 5.0. When discussing data or anything related to the Internet, it is almost impossible to do so without mentioning XML. XML, the Extensible Markup Language, is a mark-up language that allows users to create custom tags to describe data. XML is quickly becoming the universal format for storing and streaming data. The primary storage format in Office 2000 for document data will be XML. ADO (2.1) client-side recordsets can be saved as XML documents.

    ADO (2.0)—Represented a huge gain in functionality. One of the most notable new features was the ability to create client-side recordsets. To go along with this, also added were the abilities to create filters and indexes, and the ability to sort recordsets. These abilities are very much the same as those that exist with Visual FoxPro cursors. Finally, the ability to persist client-side recordsets was also added. In effect, data could be acquired from a server into a client-side recordset. The client-side recordset could then be saved as a file on the local hard-drive that could be opened at a later time without being connected to the network.

    ADO (1.5)—Introduced new capabilities and providers to ADO. Among the new providers was the OLE DB Provider for Jet (the JOLT Provider). The MS Remote Provider, which powers the Remote Data Services (RDS), was introduced as well. This version also introduced the ability to create disconnected recordsets.

    What You Need to Get Started

    In order to work through the examples presented in this paper, you will need the following:

    • Microsoft Visual FoxPro 6.0
    • Microsoft Data Access Components, which can be downloaded from https://www.microsoft.com/data/
    • SQL Server 6.5 or 7.0 with the sample Northwind database installed
    • A system DSN called TasTrade that points to the TasTrade Visual FoxPro Sample Database
    • A system DSN called Northwind that points to the SQL Server Northwind database

    Why Incorporate ADO into a Visual FoxPro Application?

    Have you ever wanted to pass a cursor as an argument to a function or class method? Or have you wanted to pass data to automation server applications such as Microsoft Word or Excel? Perhaps you have created a Visual FoxPro DLL and have needed a way to pass data from the user interface to a class method in the DLL. Maybe you have been looking for a way to stream data across the Web. If your answer is “yes” to at least one of these, ADO can help you today!

    Until now, the world of component-based development has lacked one thing: a method of effectively moving data between processes. Now, whether ADO is hosted by Visual FoxPro, Visual Basic, Excel, or Word, the interface is consistent. The new COM capabilities of Visual FoxPro 6.0 enable creating of ADO recordsets, populating them with data, and passing them to a variety of processes. This all goes to support the strategic positioning of Visual FoxPro, a creator of middle-tier components.

    Just about everything in Visual FoxPro is an object, except for reports, menus, and data. One of the biggest feature requests from Visual FoxPro developers has been the ability to work with data as a set of objects. Data objects provide several benefits, including an enhanced event model and the ability to overcome limitations of Visual FoxPro cursors. While many limitations are gone, many benefits of Visual FoxPro cursors have been retained. As you work with ADO, there’s good reason to think are many similarities to Visual FoxPro; ADO is based on the Visual FoxPro cursor engine. So, for those who have wanted data objects in Visual FoxPro, the wait is over with ADO.

    ADO is not a replacement for Visual FoxPro cursors. Rather, Visual FoxPro cursors and ADO are complementary. When used together, very powerful applications can result. The following pages detail the ADO object model and the common properties and methods you will work with, including:

    • Remote Data Services (RDS), technology which allows for the streaming of data over the Internet via HTTP.
    • VFPCOM.DLL, which enables the handling of COM events in Visual FoxPro.
    • ADO Integration into Visual FoxPro.

    This section has several comprehensive examples on strategies you may employ when integrating ADO into your Visual FoxPro Applications.

    ADO Object Model

    Connection Object

    ProgID: ADODB.Connection

    The purpose of the Connection object is to provide access to a data store. To illustrate, the following code creates an ADO Connection object:

    oConnection = CreateObject("adodb.connection")
    

    Once an ADO Connection object has been created, you can access its data store. An active connection can be established by providing a few pieces of key information and invoking the Open( ) method of the Connection object. The following code opens a connection to the Visual FoxPro TasTrade database:

    oConnection.Open("TasTrade")
    

    Alternatively, the following code accesses the SQL Server Northwind database:

    oConnection.Open("Northwind","sa","")
    

    These two examples work with the OLE DB Provider for ODBC drivers. Different OLE DB providers can be used as well. The following example sets some common properties of the Connection object and uses the OLE DB Provider for SQL Server:

    With oConnection
       .Provider = "SQLOLEDB.1"
       .ConnectionString = "Persist Security Info=False;User 
          ID=sa;Initial Catalog=Northwind;Data Source=JVP"
       .Open
    EndWith
    

    The syntax of the ConnectionString property appears complicated. Fortunately, you don’t have to code this by hand. When you install the Microsoft Data Access Components (MDAC), you can create a data link file.

    To create a data link file:

    1. Right-click your desktop and choose New\Microsoft Data Link from the pop-up menu.
    2. Specify a name for the file.
    3. Right-click and select Properties to modify the file properties.
    4. In the Properties dialog box, click the Provider tab, and choose a provider.
      The OLE DB Provider for ODBC is the default choice. For this example, select the OLE DB Provider for SQL Server.
    5. Click the Connection tab.
    6. Specify the name of the server, your user name and password, and the name of the database you wish to connect to.
    7. Open the UDL file in Notepad.Now, it is just a matter of copying and pasting the information. Alternatively, you can use the file itself:oConnection.Open(“File Name=c:\temp\test.udl”)

    ADO recognizes four arguments in the ConnectionString:

    • File Name: Specifies the name of a UDL file to use.
    • Provider: Specifies the name of an OLE DB provider to use.
    • Remote Provider: Specifies the name of a provider to use with Remote Data Services (RDS).
    • Remote Server: Specifies the server on which data resides when using Remote Data Services (RDS).

    Any additional arguments passed in the ConnectionString are passed through to the OLE DB provider being used.

    In addition to the Open method, the following are the common methods you are likely to use with the Connection object:

    • BeginTransCommiTrans, and RollBackTrans—These methods work like the Begin Transaction, End Transaction, and RollBack statements in Visual FoxPro. The Connection object controls all transaction processing. For more detail, see the section Transactions/Updating Data. Note that not all OLE DB providers support transaction processing.
    • Close—This method closes an open Connection object.
    • Execute—This method runs a SQL statement, stored procedure, or OLE DB provider-specific command. In reality, a Command object, which actually does the work of executing the command, is created on the fly. More on the Command object and the flat object hierarchy of ADO later in this paper.
    • OpenSchema—This method returns information regarding defined tables, fields, catalogs, and views into an ADO Recordset object. This method works like the DBGetProp( ) function in Visual FoxPro.

    Errors collection

    ADO does not trap errors, nor does it have an error handler. Instead, ADO can record the occasions when errors occur. It is up to the host application, Visual FoxPro in this case, to both trap and handle the error. ADO only reports what errors have occurred. Note that the error is actually reported by the specific OLE DB provider. ADO is merely a vehicle to report the error.

    The Errors collection is part of the Connection object and consists of zero or more Error objects. When an error occurs, an Error object is appended to the Errors collection. The following code illustrates how the Errors collection works. In this example, the name of the database has been misspelled purposely in order to generate an error:

    oConnection = CreateObject("adodb.connection")
    With oConnection
       .Provider = "SQLOLEDB.1"
       .ConnectionString = "Persist Security Info=False;User 
        ID=sa;Initial Catalog=Nothwind;Data Source=JVP"
       .Open
    EndWith
    */ At this point an error will occur – causing VFP's default error
    */ handler – or the active error handler to invoke
    */ At this point, we can query the Errors Collection of the
    */ Connection Object
    For Each Error In oConnection.Errors
       ?Error.Description,Error.Number
    Next Error
    

    Recordset Object

    ProgID: ADODB.Recordset

    Once you establish an ADO connection, you can open a recordset of data. The Recordset object is very much like a Visual FoxPro cursor. Like the Visual FoxPro cursor, an ADO recordset consists of rows of data. The recordset is the primary object that you will use while working with ADO. Like the Connection object, the Recordset object also provides an Open method. To illustrate, the following code opens the Customer table of the Visual FoxPro Tastrade database:

    oRecordSet = CreateObject("adodb.recordset")
    oRecordSet.Open("Select * From Customer",oConnection)
    

    The first argument of the Open method specifies the source of data. As you will see, the source can take on several forms. The second argument of the Open method specifies a connection to use for retrieving the data specified by the source. At a minimum, this is all you need to open a recordset. Additional examples will expand on the additional arguments the Open method accepts.

    With a Recordset object created, one of the most common actions you will perform is navigating through records. Depending on the type of ADO recordset that has been created, certain navigational capabilities may or may not be available. The different types of possible ADO recordsets will be discussed shortly. The following code illustrates how to navigate through an ADO recordset:

    Do While !oRecordSet.Eof
       oRecordset.MoveNext
    EndDo
    

    The following paragraphs briefly describe the most common recordset properties and pethods you are likely to use. It is by no means a replacement for the ADO documentation, which gives both a complete description of the properties and methods and complete descriptions of acceptable enumerated types and arguments. ADO is well documented in the Microsoft Data Access Components (MDAC) SDK. You can download the MDAC SDK from https://www.microsoft.com/data.

    In addition, I highly recommend ADO 2.0 Programmers Reference, by David Sussman and Alex Homer, from Wrox Press.

    RecordSet types

    You can create four types of recordsets in ADO:

    • Forward Only—This type of recordset can be navigated only in a forward direction. It is ideal when only one pass through a recordset is required. Examples include populating a List box or a Combo box. The RecordCount property is irrelevant with this type of recordset.
    • Keyset—This type of recordset keeps acquired data up to date. For example, if you retrieve 100 records, data modified by other users to those 100 records will be visible in your recordset. However, modifications regarding new or deleted records made by other users will not be visible in your recordset. Both forward and backward navigation are supported. The RecordCount property returns a valid value with this type of recordset.
    • Dynamic—With this type of recordset, all underlying data is visible to the Recordset object. Because the number of records in the underlying table can change, the RecordCount property is irrelevant with this type of cursor. However, forward and backward navigation are supported.
    • Static—Both the number of records and data are fixed at the time the Recordset object is created. The only way to get the latest version of data and all records is to explicitly invoke the Requery method. You can use the RecordCount property. In addition, both forward and backward navigation is permitted.

    RecordSet locations

    Recordset objects can exist in either of two locations, the server or the client:

    • Server—The most common examples of server-side ADO recordsets are those created through Active Server Pages (ASP).
    • Client—A recordset that resides on a workstation is useful when creating disconnected recordsets or recordsets on which you wish to apply filters, sorts, or indexes.

    The most common properties you are likely to use with ADO recordsets include the following:

    • ActiveCommand property—An object reference to the Command object that created the recordset.
    • ActiveConnection property—An object reference, to the Connection object, that provides the link to an underlying data source.
    • AbsolutePosition property—Specifies the relative position of a record in an ADO recordset. Unlike the Bookmark property, which does not change, the AbsolutePosition property can change depending on the active sort and filter.
    • Bookmark property—A unique record identifier that, like the record number in a Visual FoxPro cursor or a record number in Visual FoxPro, does not change during the life of a recordset.
    • BOF/EOF properties—Beginning of File and End of File, respectively, that work just like the BOF( ) and EOF( ) functions in Visual FoxPro.
    • EditMode property—Specifies the editing state of the current record in an ADO recordset.
    • Filter property—The string that represents the current filter expression. This property is like the SET FILTER statement in Visual FoxPro. Unlike the Find method, multiple expressions linked with AND or OR operators are allowed. This property is only applicable to client-side recordsets.
    • Sort property—A comma-delimited set of fields that specifies how the rows in an ADO recordset are sorted. This property is only applicable to client-side recordsets.
    • State property—Specifies the state of an ADO recordset. Valid State properties are closed, open, connecting, executing, or fetching.
    • Status property—Specifies the editing status of the current record. Valid Status properties include unmodified, modified, new, and deleted. This property can be any one of the values contained in RecordStatusEnum.
    • MarshalOptions property—Specifies how records are returned (marshaled) to the server. Either all or only modified records can be returned. This property is only applicable to client-side disconnected recordsets
    • MaxRecords property—Specifies the total number of records to fetch from a data source.
    • RecordCount property—Specifies the number of records in a recordset. This property is like the Recc( ) function in Visual FoxPro.
    • Source property—Specifies the command or SQL statement that provides data for the recordset.

    Note   The type and location of a cursor as well as the OLE DB provider you select will affect the recordset properties that are available.

    Use the following table as a guide to help you make the right recordset type and location decision:

    Table 1. PropertiesExpand table

    TypeBookmarkRecordCountSortFilterMarshalOptions
    Forward Only     
    Key Set44   
    Dynamic     
    Static: Client44444
    Static: Server44   

    Only client-side recordsets can be sorted and filtered. If the CursorLocation property of ForwardOnlyKeySet, and Dynamic recordset types is set to adUseClient, making them client-side cursors, the CursorType property is automatically coerced to the Static Cursor type.

    Note   This is the behavior of the OLE DB Provider for SQL Server. The OLE DB Provider for ODBC supports only ForwardOnly and Static recordsets, regardless of where the recordset resides.

    As with properties, method availability can also vary:

    Table 2. Available MethodsExpand table

    TypeMoveFirstMovePreviousMoveNextMoveLastResyncRequery
    Forward Only  4  4
    Key Set4444 4
    Dynamic4444 4
    Static – Client444444
    Static – Server4444 4

    The following list describes some of the common methods you will use in the ADO Recordset object:

    • MoveFirstMovePreviousMoveNextMoveLast, and Move methods—Navigational methods that work as their respective names imply. The Move method accepts two arguments, the number of records to move and the position from which to begin the move. The Move method is similar to the Go statement in Visual FoxPro. MoveFirst and MoveLast work like Go Top and Go Bottom, respectively. Finally, MovePrevious and MoveNext work like Skip 1 and Skip –1, respectively.
    • Find method—Accepts a criterion string as an argument and searches the recordset for a match. If a match is not found, depending on the search direction, either the BOF or EOF property will evaluate to true (.T.). This method works much the same way as the Seek and Locate statements in Visual FoxPro. Unlike the Filter property and the Seek and Locate statements in Visual FoxPro, the ADO Recordset object does not allow multiple search values joined by the And or the Or operator. Using anything other than a single search value will result in an error.
    • Open method—Opens an existing ADO Recordset object. This method accepts several arguments and is discussed in detail later in this section.
    • Close method—Closes an ADO Recordset object. Many properties, such as CursorType and LockType, although read/write, cannot be modified while the recordset is open. The Close method must be invoked before those and other properties are modified.
    • Update and UpdateBatch methods—Update writes changes for the current record to the underlying data source; UpdateBatch writes pending changes for all modified records to the underlying data source. The UpdateBatch method is only relevant when Optimistic Batch Locking is used.
    • Cancel and CancelBatch methods—The Cancel method cancels modifications made to the current record; the CancelBatch method cancels pending changes to all modified records.
    • Resync method—Refreshes the Recordset object with data from the underlying data source. Invoking this method does not rerun the underlying command. Options exist for which records are actually refreshed.
    • Requery method—Unlike the Resync method, reruns the underlying command, which causes any pending changes to be lost. In effect, issuing a Requery is like invoking the Close method then immediately invoking the Open method.
    • Supports method—Specifies whether or not the recordset supports a function, based on a passed argument. For example, you can use this method to specify whether a recordset supports bookmarks, or the addition or deletion of records, or the FindUpdate, and UpdateBatch methods, to name a few. Because what is supported is depends on the OLE DB provider used, it is a good idea to use this method to make sure a needed function is supported.
    • GetRows method—Returns a set of records into an array.
    • GetString method—Returns a set of records into a string.

    The moral of the story is that before relying on the existence of anything in ADO, know and understand the OLE DB provider you are using, because the capabilities available to you can vary dramatically.

    Lock types

    There are four different locking schemes in ADO recordsets. These locking schemes are similar to those in Visual FoxPro.

    • Read-Only—As the name indicates, the recordset is opened for read-only purposes only. When you don’t need to modify data, this is the best locking scheme to use from a performance standpoint. This scheme applies to both server and client-side recordsets.
    • Lock Pessimistic—In this scheme, a lock attempt is attempted as soon as an edit is performed. This locking scheme is not relevant for client-side recordsets. Pessimistic Locking in an ADO recordset is like Pessimistic Locking with Row Buffering in a Visual FoxPro cursor.
    • Lock Optimistic—In this scheme, a lock attempt is made when the Update method is invoked. This locking scheme applies to both server and client-side recordsets. Optimistic Locking in an ADO recordset is like Optimistic Locking with Row Buffering in a Visual FoxPro cursor.
    • Lock Batch Optimistic—This scheme is like the Lock Optimistic scheme, except that more than one row of data is involved. In this scheme, a lock is attempted on modified records when the UpdateBatch method is invoked. This scheme is like Optimistic Locking with Table Buffering in a Visual FoxPro cursor.

    The following table illustrates the availability of some common methods depending on the locking scheme used:

    Table 3. Method Availability (Depending on Lock Type)Expand table

    Lock TypeCancelCancelBatchUpdateUpdateBatch
    Read Only4   
    Pessimistic4444
    Optimistic4444
    Optimistic Batch4444

    With the concepts of cursor types, locations, and locking schemes out of the way, we can discuss the real abilities of ADO recordsets. The most notable of these abilities are updating, sorting, and filtering of data. Before undertaking that discussion, however, take a few moments to review the Fields Collection object.

    Fields collection object

    Associated with the Recordset object, is the Fields Collection object. The Fields Collection object contains zero or more Field objects. The following code enumerates through the Fields Collection of a Recordset object:

    For Each ofield In oRecordset.Fields
       With oField
          ?.Name,.Value,.Type,.DefinedSize
          ?.ActualSize,.NumericScale,.Precision
       EndWith
    Next oField
    

    The common Field properties you will work with:

    • Name—Specifies the name of the Field object. This corresponds to the name of the data element in the underlying data source. It is easy to define the name element as the name of the field in the underlying table. However, note that ADO and OLE DB work with both relational and nonrelational data. Given that, while you may be working with ADO, the underlying data may come from Outlook, Excel, Word, or Microsoft® Windows NT® Directory Services.
    • Value—Indicates the current value of the Field object.
    • OriginalValue—Indicates the Value property of the Field object before any modifications where made. The OriginalValue property returns the same value that would be returned by the OldVal( ) function in Visual FoxPro. When you invoke the Cancel or CancelUpdate methods of the Recordset object, the Value property of the Field object is replaced by the contents of the OriginalValue property. This behavior is similar to that exhibited when TableRevert( ) is issued against a Visual FoxPro cursor.
    • UnderlyingValue—Indicates the current value in the data source. This property corresponds most closely to the CurVal( ) function in Visual FoxPro. To populate the Value property of each Field object in the Fields collection, you need to invoke the Resync method of the Recordset object. With a client-side cursor, this property will return the same value as the OriginalValue property, since the recordset may or may not have an active connection.
    • Type—Indicates the data type of the Field object. The value of this property corresponds to a value contained in DataTypeEnum. Examples of values in DataTypeEnum are adBoolean, adInteger, and adVarChar.
    • Defined Size—Specifies the size of the field containing a data element in the data source. For example, in SQL Server, the Country field in the Customers table of the Northwind database is 15 characters long. Therefore, the DefinedSize property of the Country Field object is 15.
    • ActualSize—Represents the length of the actual data element in a datasource. To illustrate, consider the Country Field object again. In the case where the value is Germany, the ActualSize property is 7, while the DefinedSize property is still 15.
    • NumericScale—Specifies how many digits to the right of the decimal place are stored.
    • Precision—Specifies the maximum number of digits to be used for numeric values.

    In addition to these properties, GetChunk is one interesting method you are likely to use. This method allows you to progressively fetch portions of the contents of a field object. This method is very useful when dealing with large text fields. It can be used only on fields where the adFldLong Bit set of the Attributes property is set to true (.T.). See the next section for details on the Attributes property. Understand that fields of the type ADLongVarChar have the adFldLong Bit set. The Notes field of the Employees table is of the type adLongVarChar.

    The following code fetches data from the notes field in 10-byte chunks:

    Local nBytesRead,cChunkRead 
    nBytesRead = 0
    cChunkRead = Space(0)
    Do While .T.
       nBytesRead = nBytesRead + 10
       cChunkRead = oRecordset.Fields("notes").GetChunk(10)
       If IsNull(cChunkRead) Or;
        nBytesRead > oRecordset.Fields("notes").ActualSize
          Exit
       Else
          ?cChunkRead
       Endif   
    EndDo
    

    Successive calls to GetChunk continue where the previous call ended. The GetChunk method is very useful when you need to stream data or only need to see the first few characters of a large text field.

    Along with GetChunk, examine the AppendChunk method. The first time this method is called for a field, it overwrites any data in the field. Successive calls then append the data, until pending edits are cancelled or updated. The following code illustrates how this method works:

    For x = 1 To 100
       oRecordset.Fields("notes").AppendChunk(Str(x)+Chr(10)+Chr(13))
    Next x
    

    Both the GetChunk and AppendChunk methods are ideal for dealing with low memory scenarios.

    The Attributes property

    An attribute specifies the characteristics of something. As a person, you have many attributes, eye color, height, weight, and so forth. In the OOP world, objects have many attributes. Most of the time, attributes are exposed in the form of properties. A Visual FoxPro form has several properties such as WidthHeight, and BackColor, just to name a few. The same is true for objects in ADO. Sometimes, however, it is not convenient to have a one-to-one correspondence between attributes and properties. Often, you can pack large amounts of information into a smaller space through the power of setting bits. A bit is much like a switch. It is either on or off or 1 or 0. If you string these bits together, you gain the ability to store multiple values in a small space. This is how the Attributes property works.

    The ConnectionParameterField, and Property objects all have an Attributes property. If you have never worked with bit operations before, working with this property can be quite challenging. In some situations, as is the case with the GetChunk and AppendChunk methods, you will need to refer to the Attributes property of the Field object to determine whether those methods are available.

    Using the Field object to illustrate how the Attributes property works, you can associate the following attributes with a Field object and its associated binary values:

    • AdFldMayDefer—Indicates that the field contents are retrieved only when referenced—0x00000002
    • adFldupdateable—Indicates that the field can be updated—0x00000004
    • adFldUnkownupdateable—Indicates that the provider does not know whether the field is updateable—0x00000008
    • adFldFixed—Indicates that the field contains fixed length data—0x00000010
    • adFldIsNullable—Indicates that the field can accept a null value during a write operation—0x00000020
    • adFldMayBeNullable—Indiates that the field may contain a null value—0x00000040
    • adFldlong—Indicates that the field contains long binary data and that the GetChunk and AppendChunk methods can be used—0x00000080
    • adFldRowID—Indicates that the field contains a row ID and cannot be updated. This does not relate to a field that may contain the identity value or some other auto-incrementing value. Rather, it relates to a ROW ID that is unique across the database. Oracle has this feature—0x00000100
    • adFldRowVersion—Indicates whether the field indicates the version of the row. For example, a SQL TimeStamp field may have this attribute set—0x00000200
    • adFldCachedDeferred—Indicates that once this field has been read, future references will be read from the cache—0x00001000

    Usually, more than one of these attributes are present at any given time. Yet the Attributes property is a single value. Using the Employees table Notes field as an example, you will see that the Attributes property yields a value of 234. The value 234 represents the sum of the attributes for that field. For example, nullable and long attributes have decimal values of 32 and 128 respectively. This means that the Attributes property evaluates to 160. This works like the Windows Messagebox dialog box with regard to specifying the icon and types of buttons that are present.

    Knowing that the Attributes property is a sum of the attributes of a Field object does not help in determining whether a specific attribute is present. This is where understanding bit operations comes in handy. The first step is to convert the sum (such as 234, above) into a binary equivalent:

    11101010
    

    Working from right to left, (or from the least significant bit to the most significant)—and beginning with zero, see that bits 1, 3, 5, 6, and 7 are set, (indicated by their values of 1 in those positions). Bits 0, 2, and 4 are not set. The next step is to determine whether a field is “long.”

    To determine whether a field is a long field, we must first convert the adFldLong constant, which specifies which bit if set, indicates that the field is long. The adFldLong constant has a hex value of 0x00000080. This translates into a decimal value of 128. The following is the binary equivalent:

    10000000
    

    Converting a hex value to decimal in Visual FoxPro is simple. The following code illustrate how to convert hexadecimal values to decimal:

    x = 0x00000080
    ?x && 128
    

    And, if you ever need to convert back to hexadecimal:

    ?Transform(128,"@0") && 0x00000080 
    

    Using our original hex value, 11101010, and working from right to left and beginning with zero, see that the seventh bit is set. Therefore, the seventh bit of the Attributes property, if set, means the field is long. Going further, whatever attributes occupy bits 1, 3, 5, and 6, also apply to this field. The following table of field attributes should help to sort things out:

    Table 4. Field AttributesExpand table

    Hex ValueDecimal ValueField Attribute ConstantBit
    0x000000022AdFldMayDefer1
    0x000000044AdFldupdateable2
    0x000000088AdFldUnkownUpdateable3
    0x0000001016AdFldFixed4
    0x0000002032AdFldIsNullable5
    0x0000004064AdFldMayBeNull6
    0x00000080128AdFldLong7
    0x00000100256AdFldRowID8
    0x00000200512AdFldRowVersion9
    0x000010004096AdFldCacheDeferred12

    So, along with being a long field, the field is deferred, updateable, can have a null written to it, and it may also already contain a null value. Visually, this makes sense. How can you do this programmatically?

    If you refer to online examples (almost always programmed in Visual Basic), you will see code like this:

    If (oField.Attribute AND adFldLong) = adFldLong 
       ' The field is long
    End If
    

    This is pretty slick in that you can test for whether a specific attribute bit is set by using the AND operator with the attribute property and the constant. If you try this in Visual FoxPro, you will get data type mismatch errors. Fortunately, there is a way. Visual FoxPro contains a host of bit functions. One function, BITTEST, does as its name implies. It tests whether a specified bit in a passed argument is set. To review, we need to see if the seventh bit in the value 234 is set. The following Visual FoxPro code demonstrates how to use the BITTEST function:

    If BitTest(234,7)
       */ The Field is long
    Endif
    

    To find out if the field is nullable:

    If BitTest(234,5)
       */ The Field is long
    Endif
    

    The Attributes property of the ConnectionParameter, and Property objects works in the same manner as illustrated above. The differences are the names and quantity of attributes that are present.

    ADO and COM defined constants

    ADO and OLE DB, like any COM components, make extensive use of defined constants in the examples that document the usage of properties, events, and methods. Other development environments in Visual Studio such as Visual Basic and Visual Interdev provide IntelliSense technology, because of their respective abilities to interact directly with the type libraries of COM components. For these development environments, you can reference defined constants just as if they were a part of the native language. So, working with published examples is a fairly trivial task. On the other hand, in the Visual FoxPro development environment there is, in fact, a bit of a challenge. The question always seems to be “How can I use the Visual Basic samples in Visual FoxPro?” The biggest stumbling block is usually in finding the value of the defined constants. In Visual FoxPro, you need to use the #Define statement for each constant.

    One solution for obtaining the value of the ADO defined constants is to obtain the MDAC SDK from Microsoft. The MDAC SDK can be downloaded from https://www.microsoft.com/data/download.htm.

    Once you install the SDK, locate the Include\ADO directory. In that directory, you will find the ADOINT.H file, which contains all of the enumerated types and the values for the defined constants.

    A second, and perhaps easier, solution is to use the resources already installed on your machine. If you are working through the sample code in this paper, you already have the Microsoft Data Access Components installed on your workstation. The Visual Basic Development Environment (both the full Visual Basic IDE and the Visual Basic Editor in desktop applications like Word and Excel) has a great resource called the Object Browser. This could, in fact, be the most underutilized tool on the planet.

    To illustrate its functionality, open any desktop application that uses Visual Basic, such as Word or Excel. Or, if you have the Visual Basic Programming System installed, you can open that as well.

    If you opened a VBA application

    1. From the View menu, choose Toolbars.
    2. From the Toolbars menu, choose Visual Basic.
    3. On the Visual Basic toolbar, click Visual Basic Editor.
    4. From the Tools menu, choose References.
    5. Check the Microsoft Data Access Objects 2.x Library.

    If you opened the Visual Basic IDE

    1. Create an empty project.
    2. From the Project menu, select References.
    3. Check the Microsoft Data Access Objects 2.x Library.

    Now, whether you are in the VBA Editor or the VB IDE

    1. Press F2 to display the Object Browser.
    2. In the first combo box, select ADODB.
    3. In the second box, type ADVARCHAR.
    4. Press Search
      or
      Press Enter.

    Clearly, the Object Browser is a powerful tool for the developer who works with COM components. Not only are the defined properties, events, and methods accessible in the Object Browser, so also are the defined constants and their respective values. Notice the value of adVarChar in the lower pane of the Object Browser.

    Opening, sorting, and filtering data

    One of the big advantages of using a development platform such as Visual FoxPro is its local data engine. Not only does the engine provide superior query performance, but it also provides some very flexible capabilities when it comes to both working with and presenting data. There isn’t a Visual FoxPro application that fails to sort or filter data to some degree. In Visual FoxPro, sorting is accomplished by creating a set of index tags for a table. Filtering is accomplished by using the Set Filter command. Fortunately, ADO has these capabilities as well.

    You can see in the Field Attribute table that the availability of features depends on the location in which the recordset is created. It is clear that we must ensure that a client-side recordset is created.

    For example, create a Connection object to the TasTrade or SQL Server Northwind database. The following code assumes that the Connection object, oConnection, has been created before you open the Recordset object.

    First, we need to implement a few required #Defines:

    #Define adUseClient   3
    #Define adLockBatchOptimistic   4
    #Define adCmdTable   2
    

    For SQL Server:

    With oRecordset
       .Source = "Customers"
       .ActiveConnection = oConnection
       .CursorLocation = adUseClient
       .LockType = adLockBatchOptimistic
       .Open
    EndWith
    

    Or

    oRecordset.Open("Customers",;
                     oConnection,;
                     adUseClient,;
                     adLockBatchOptimistic)
    

    For Visual FoxPro:

    With oRecordset
       .ActiveConnection = oConnection
       .Source = "Customer"
       .CursorType = adOpenStatic
       .LockType = adLockReadOnly
       .CursorLocation = adUseClient
       .Open(,,,,adCmdtable)
    EndWith
    

    Or

    oRecordset.Open("Customer",;
                     oConnection,;
                     adUseClient,;
                     adLockBatchOptimistic,;
                     adCmdTable)
    

    Or

    With oRecordset
       .ActiveConnection = oConnection
       .Source = "Select * From Customer"
       .CursorType = adOpenStatic
       .LockType = adLockReadOnly
       .CursorLocation = adUseClient
       .Open
    EndWith
    

    Or

    oRecordset.Open("Select * From Customer",;
                     oConnection,;
                     adUseClient,;
                     adLockBatchOptimistic)
    

    SQL Server and Visual FoxPro open data differently. Remember that when using SQL Server, you are using the OLE DB Provider for SQL Server. When you access data in Visual FoxPro, use the OLE DB Provider for ODBC, since there is no native OLE DB provider for Visual FoxPro.

    The difference rests with the optional fifth argument of the Open method. The SQL Server OLE DB Provider is designed to recognize when you pass just a table name. With the ODBC OLE DB Provider, you must specify how it should interpret the Source property. By default, the ODBC OLE DB Provider expects a SQL statement. When you pass a SQL statement, there is no need to explicitly state how the provider should interpret things. The Visual FoxPro ODBC driver generates an “Unrecognized Command Verb” error message if you only specify a table name as the source and you fail to use the optional fifth argument. Note that if you use the ODBC OLE DB Provider to access SQL Server, you must employ the same technique that is needed for Visual FoxPro.

    Which method should you employ when you populate the properties individually before invoking the Open method or passing the arguments to the Open method? Once again, it is a matter of preference. Of the two, manually populating the properties makes for more readable code.

    Sorting and filtering data are just matters of manipulating the Sort and Filter properties respectively. The following code sorts the recordset created from TasTrade in the example above, by country, ascending, then by region, descending:

    oRecordset.Sort = "Country,Region Desc"
    

    The following code displays the sort and the functionality of the AbsolutePosition and Bookmark properties.

    oRecordset.MoveFirst
    Do While Not oRecordset.Eof
       With oRecordset
          ?.Fields("country").Value,;
           .Fields("region").Value,;
           .AbsolutePosition,;
           .Bookmark 
           .MoveNext
       EndWith
    EndDo
    

    Setting a filter is as easy as setting the sort. The following code filters for records where the country is Germany:

    oRecordset.Filter = "Country = 'Germany'"
    

    The Filter property also supports multiple values:

    oRecordset.Filter = "Country = 'Germany' Or Country = 'Mexico'"
    

    Finally, wild card characters are also supported:

    oRecordset.Filter = "Country Like 'U*'"
    

    To reset either the Filter or Sort properties, set them equal to an empty string:

    oRecordset.Sort = ""
    oRecordset.Filter = ""
    

    Finding data

    Another important capability of an ADO recordset is the ability to find records based on a search string. This capability works like searching for records in a Visual FoxPro cursor. Unlike the Seek or Locate statement in Visual FoxPro, the Find method provides control over the scope of records that are searched. The following code searches for a country that begins with the letter “B.”

    oRecordset.Find("country Like 'B%'")
    

    Although multiple criteria are not allowed, wild card searches are permitted:

    oRecordset.Find("country Like 'U*'")
    

    Searches for multiple criteria, such as the following, would result in an error:

    oRecordset.Find("country Like 'G*' Or country Like 'B*'")
    

    Transactions/updating data/conflict resolution

    Updating data in an ADO recordset is a fairly simple process. As in any environment, conflict resolution in multi-user environments is always an issue to be dealt with. This is where the Errors collection comes into play. Error trapping and handling needs to become an integral part of your ADO-related code. The following code samples employ a simple error handling scenario and use the Errors collection to determine whether conflicts have occurred. For a complete list and description of ADO error codes, consult the online documentation.

    When you update data, you can update either a single row, or several rows at a time in batch mode. These methods most closely correspond to row and table buffering, respectively, in Visual FoxPro. Building on the recordset already created, the lock type is Batch Optimistic. While updates are normally conducted in batches, you can also update one row at a time, just as in Visual FoxPro.

    The following code modifies the CompanyName field and attempts to update the SQL Server data source:

    oRecordset.Fields("companyname").Value = "Ace Tomato Company"
    oRecordset.Update
    

    Depending on a variety of scenarios, this code may or may not work. Perhaps a contention issue exists? Perhaps the user does not have rights to modify data. Hundreds of issues can cause an attempted update to fail. Therefore, anytime you attempt an update, you should employ error trapping. The following code expands the previous example and makes it a bit more robust:

    Local Err,cOldErr,oError
    cOldError = On("Error")
    On Error Err = .T.
    oRecordset.Fields("companyname").Value = "Ace Tomato Company"
    oRecordset.Update
    If Err
       For Each oError In oRecordset.ActiveConnection.Errors
          With oError
             ?.Number,.Description
          EndWith
       Next oError
    Endif
    On Error &cOldErr
    

    If you are thinking, “Hey, maybe I should write a wrapper class to better encapsulate and centralize code,” you’re on the right track. The following code creates a custom class that can serve as a starting point:

    Local oRecordsetHandler
    oRecordsetHandler = CreateObject("RecordsetHandler")
    oRecordset.Fields("companyname").Value = "Alfreds Futterkiste"
    If !oRecordsetHandler.Update(oRecordset)
       oRecordsetHandler.Cancel(oRecordset)
    Endif
    Define Class RecordsetHandler As Custom
       Protected oRecordset
       Protected ErrFlag
       
       Procedure Update(oRecordset)
          This.oRecordset = oRecordset
          oRecordset.UpdateBatch
          Return !This.ErrFlag
       EndProc
       Procedure Cancel(oRecordset)
          This.oRecordset = oRecordset
          oRecordset.Cancel
          Return !This.ErrFlag
       EndProc
       
       Procedure Error(nError, cMethod, nLine)
          Local oError
          For Each oError In This.oRecordset.ActiveConnection.Errors
             With oError
                ?.Number,.Description
             EndWith
          Next oError
          This.ErrFlag = .T.
       EndProc
    EndDefine
    

    There’s a better way to determine whether an update proceeded successfully. The preferred approach is to trap events that ADO fires. Visual FoxPro by itself does not surface COM Events. Fortunately, the new VFPCOM.DLL component provides this capability to Visual FoxPro. The previous example can be modified to show how using COM Events makes for more robust code and class design.

    Now we can improve the code of our example. Most of the time, for efficiency, you will want to batch your updates that comprise multiple records. Often, when you update multiple records, transaction processing is required. In other words, either updates to all records must succeed or none should occur. To illustrate, let’s say you must apply a 10 percent price increase to the products you sell. The prime requirement is that all records in the Products table need modification. Without transactional capabilities, the possibility exists that, for example, after the first 10 records are updated, an error generated on the eleventh record prevents a complete update. Transaction processing provides the ability to rollback changes.

    The following example incorporates error trapping and the three transaction methods of the Connection object:

    Local Err,cOldErr
    cOldErr = On("error")
    On Error Err = .T.
    oRecordset.ActiveConnection.BeginTrans
    Do While !oRecordset.Eof
       If Err
          Exit
       Else
          With oRecordset
             .Fields("unitprice").Value = ;
                .Fields("unitprice").Value * 1.1
             .Movenext
          EndWith   
       Endif
    EndDo
    oRecordSet.UpdateBatch
    If Err
       oRecordset.ActiveConnection.RollBackTrans
       oRecordset.CancelBatch
    Else
       oRecordset.ActiveConnection.CommitTrans
    Endif   
    On Error &cOldErr 
    

    Additional operations you are likely to employ with recordsets deal with adding new records and deleting existing records. Both of these processes are very simple. The following code adds a new record:

    oRecordset.AddNew
    

    As in Visual FoxPro, in ADO the new record becomes current. Once the AddNew method is invoked, the field can be populated and, depending on the LockType, you then invoke either the Update or UpdateBatch methods to modify the data source.

    Deleting records is just as easy. The following code deletes the current record:

    oRecordset.Delete
    

    Once again, after deleting the record, a call to Update or UpdateBatch will update the data source.

    SQL Server identity fields and parent/child relationships

    SQL Server, like most server RDBMSs and Microsoft® Access®, creates an auto-incrementing field that can serve as a primary key for a table. Typically, the data type for this field is Integer. In SQL Server, this type of field is called the Identity field. Fields of this type are read-only. It begs the question, “When adding records, how can one determine what these values are?” Knowing that the next generated value is a requirement for maintaining referential integrity when child tables are involved. The following example code shows a recordset in which the first field, ID, is the auto-incrementing field. After new field is added, checking the value of the ID field yields a character with a length of zero. Attempting to update the field results in an error. However, once the recordset is updated, checking the value again will yield a valid identity value.

    oRecordset.AddNew
    ?oRecordset.Fields("id").Value && empty string
    oRecordset.UpdateBatch
    ?oRecordset.Fields("id").Value && returns new identity value
    

    With the new identity value available, you can add records in child tables, using the identity value in the parent table as the foreign key in the child tables.

    But, what do you do in cases where you have disconnected recordsets?

    This section details an important capability in ADO—the ability to have recordsets without an active connection to the backend data source. At this point you can freely add new records to disconnected records. When the recordset is eventually reconnected, those newly added records are then sent to the backend data source. How do you know what the identity value will be in those cases? Simply put, you don’t know. At the same time, however, you still need to be able to add both parent and child records locally. You need some method that maintains the relationship locally, while at the same time, supporting the use of the identity value when the data is sent to the backend.

    The simplest solution to this problem is to include a field in each table that serves as the local ID. You need this extra field because the identity field will be read-only. On the client side, you can use several methods for producing an ID that is unique. One approach is to use the Windows API to fetch the next Global Unique Identifier (GUID). The following procedure outlines how the local process unfolds:

    1. Add a new parent record.
    2. Fetch the next GUID.
    3. Update the local primary key column with the GUID.
    4. Add a new child record.
    5. Update the local primary key column with the GUID.
    6. Update the foreign key column of the child with the GUID from its parent.

    At some point, you will reconnect to the server. The update process could be performed within the context of a transaction, done one row at a time by navigating through each record. Checking the recordset Status property, which indicates whether the current record has been newly created, modified, deleted, and so on, determines whether the current row should be sent back to the server. If the record should be sent back, the parent record can be updated via the UpdateBatch method. The UpdateBatch method accepts an optional argument that specifies that only the current record be updated. By default, UpdateBatch works on all records. If the value of one is passed—corresponding to the adAffectCurrent constant—only the current record is updated. Once the update occurs, the identity value generated by the server is available. This value would then be used to update the foreign key columns of any related children. Once that process is complete, the records for that parent would be sent back to the server as well. This same process would be used if grandchild and great-grandchild relationships also existed.

    The following Visual FoxPro code, from Visual FoxPro 6 Enterprise Development, by Rod Paddock, John V. Petersen, and Ron Talmage (Prima Publishing), illustrates how to generate a GUID:

    Local oGuid
    oGuid = CreateObject("guid")
    ?oGuid.GetNextGuid( )
    */ Class Definition
    Define Class guid AS Custom
      */ Create protected members to hold parts of GUID
      Protected data1
      Protected data2
      Protected data3
      Protected data4
      Procedure GetNextGuid
        */ The only public member. This method will return the next GUID
        Local cGuid
        cGuid = This.Export( )
        UuidCreate(@cGuid)         
        This.Import(cGuid)            
        cGuid = This.Convert(cGuid)
        Return cGuid
      EndProc
      Protected Procedure bintoHex(cBin)
        */ This method converts a binary value to Char by calling the Hextochar
    
        */ Method
        Local cChars, nBin
        cChars = ""
        For nDigit = 1 To Len(cBin)
          nBin = Asc(Substr(cBin, nDigit, 1))
          cChars = cChars + This.Hex2Char(Int(nBin/16)) + ;
            This.Hex2Char(Mod(nBin,16))
        EndFor
        Return(cChars)
      EndProc
      Protected Procedure hex2char(nHex)
        */ This method converts a hex value to  ASCII 
        Local nAsc
        Do Case
          Case Between(nHex,0,9)
            nAsc = 48 + nHex
          Case Between(nHex,10,15)
            nAsc = 65 + nHex - 10
        EndCase
        Return(Chr(nAsc))
      EndProc
      Procedure import(cString)
        */ This method takes the binary string and populates the 4 data
        */ properties
        With This
          .Data1 = Left(cString, Len(.Data1))
          cString = SubStr(cString, Len(.Data1)+1)
          .Data2 = Left(cString, Len(.Data2))
          cString = SubStr(cString, Len(.Data2)+1)
          .Data3 = Left(cString, Len(.Data3))
          cString = SubStr(cString, Len(.Data3)+1)
          .Data4 = Left(cString, Len(.Data4))
        EndWith
        Return cString
        EndProc
    
      Protected Procedure export
        */ This method creates the buffer to pass to the GUID API.
        With This
          .Data1 = Space(4)
          .Data2 = Space(2)
          .Data3 = Space(2)
          .Data4 = Space(8)
        EndWith
        Return(This.Data1 + This.Data2 + This.Data3 + This.Data4)
      EndProc
      Protected Procedure Convert(cGuid)
        */ This method makes the call to the BinToHex that 
        */ converts the data in the 4 data properties from 
        With This
          cGuid =  .BinToHex(.Data1) + "-" + .BinToHex(.Data2) + "-" + ;
            .BinToHex(.Data3) + "-" + .BinToHex(.Data4)
          Return cGuid
        Endwith 
        EndProc
      Procedure Init
        */ Declare the function in the DLL
        Declare Integer UuidCreate ;
          In C:\Winnt\System32\RPCRT4.DLL String @ UUID
        Return
      EndProc
    EndDefine
    

    Output is produced as follows:

    Disconnected/Persisted Recordsets

    One of the most powerful features of ADO is the ability to create both disconnected and persisted recordsets. A disconnected recordset is a client-side recordset that does not have a current ActiveConnection. SQL data sources, such as SQL Server, Oracle, and so on, are licensed according to the number of concurrent connections. For example, the number of people that using an application connected to SQL Server is 300. However, it has been determined that at any time, only 50 users actually use the services of a connection. A connection is needed only when data is being requested, updates are made, or a stored procedure on the database server is invoked. From a financial standpoint, it is far less expensive for a company to only purchase 50 licenses than to purchase 300. From a resource standpoint, performance should improve because the server only has the overhead of 50 connections instead of 300, of which 250 are idle at any time.

    Using the ADO recordset of customer data already created, the following code disconnects the client-side recordset:

    oRecordSet.ActiveConnection = Null
    

    If you attempt to do this with a server-side recordset, an error occurs stating that the operation is not allowed on an open recordset. Once the recordset is disconnected, you can continue to work with and modify records. The following code will work:

    oRecordset.MoveFirst
    Do While !oRecordset.Eof
       ?oRecordset.Fields("companyname").Value
       oRecordset.Fields("companyname").Value = ;
          Upper(oRecordset.Fields("companyname").Value)
       oRecordset.MoveNext 
    EndDo
    

    With modified records in a client-side recordset, three basic options exist.

    • Cancel local changes
    • Marshall local changes to the server
    • Save (persist) the recordset locally.

    You can save (persist) the recordset locally for both later use and, ultimately, for marshalling those persisted changes back to the server.

    The first choice is pretty simple to implement, since it takes one line of code:

    oRecordset.CancelBatch 
    

    The second choice is also simple to implement. Much of the work in updating multiple records and transactions has already been detailed. This procedure really involves two separate steps:

    1. Re-establish an active connection.
    2. Marshal modified records back to the data source.

    The following code re-establishes the connection:

    With oConnection
       .Provider = "SQLOLEDB.1"
       .ConnectionString = "Persist Security Info=False;User 
          ID=sa;Initial Catalog=Northwind;Data Source=JVP"
       .Open
    EndWith
    oRecordset.Activeconnection = oConnection
    

    Then the code marshals the records by attempting the updates

    Local Err,cOldErr
    cOldErr = On("error")
    On Error Err = .T.
    With oRecordset
       .ActiveConnection.BeginTrans
       .UpdateBatch
       If Err
          .ActiveConnection.RollBackTrans
          .CancelBatch
       Else
          .ActiveConnection.CommitTrans
       Endif
    EndWith   
       On Error &cOldErr
    

    Often, however, there’s a need to shut things down and then reopen the recordset at another time. To be effective, the recordset must reflect incremental changes. This cycle may repeat any number of times.

    To illustrate how to persist a recordset, consider again the following code that modifies records in a Recordset object:

    oRecordset.MoveFirst
    Do While !oRecordset.Eof
       ?oRecordset.Fields("companyname").Value
       oRecordset.Fields("companyname").Value = ;
          Upper(oRecordset.Fields("companyname").Value)
       oRecordset.MoveNext 
    EndDo
    

    Now you can invoke the Save method to persist the recordset:

    oRecordset.Save("c:\temp\customers.rs")
    

    At a later time, you can open the persisted recordset:

    oRecordset = CreateObject("adodb.recordset")
    oRecordset.Open("c:\temp\customers.rs")
    

    After the persisted recordset is reopened, you can use the same code, which establishes a connection to a disconnected recordset, to make additional modifications. You can marshal changes made in the persisted recordset to the underlying data source.

    Hierarchical/Shaped Recordsets

    Visual FoxPro not only provides the ability to work with local data, but also the ability to set up relations using the Set Relation command. When you move the record pointer in the parent table, the record pointer automatically moves in any child tables that exist. This makes working with and building interfaces for one to many relationships very simple in Visual FoxPro. Fortunately, the same capability exists in ADO, in the form of hierarchical recordsets, also referred to as shaped recordsets.

    There are two necessary components when creating and working with hierarchical recordsets:

    • The Microsoft DataShape OLE DB Provider, MSDataShape
    • The Shape language, a superset of the SQL syntax

    The first requirement is fairly easy to fulfill because it only entails setting the Provider property of the ADO Connection object to the proper value:

    oConnection.Provider = "MSDataShape"
    

    The second requirement, using the Data Shape language, is a bit more challenging. When you first see Data Shape language, it can be fairly intimidating, just as FoxPro may have been when you first worked with it. But like anything else, with a bit of practice and patience, Microsoft Data Shape language will become second nature.

    To examine Shape language, consider a parent-child common scenario of customers and orders. For each customer, zero or more orders can exist. In turn, each order can contain one or more line items. The following code employs Shape syntax to relate customers and orders in the SQL Server Northwind database:

    SHAPE {SELECT * FROM "dbo"."Customers"} AS Customers APPEND ({SELECT * 
    FROM "dbo"."Orders"} AS Orders RELATE "CustomerID" TO "CustomerID") AS 
    Orders
    

    If your first thought is, “Gee, this is like setting relations in Visual FoxPro,” you are indeed correct. It is exactly the same principle. If the Shape syntax is broken down, the task becomes manageable. The first clause in the code begins with the keyword SHAPE, to signify that what follows is not pure SQL, but rather, Data Shape language. The Data Shape language is a super-set of SQL, which is why you need to use MSDataShape as the OLE DB provider. MSDataShape can interpret and execute Shape commands. Finally, the last portion of the first command specifies that the results of the SQL statement are to be aliased as Customers.

    In the next set of commands, things get a bit complicated, especially when the hierarchy is nested an additional one or two levels (this is the case when order details are added, as we’ll do in the next example).

    You can interpret the keyword APPEND as “Append the results of the next SQL statement to the results of the previous SQL statement.” Of course, just appending records won’t suffice. Rather, you must provide a rule that specifies how the records are to be related. This is where the RELATE keyword comes into play.

    You can interpret the RELATE keyword as, “When appending records, do so based on these join fields.” In this case, the join is between the CustomerID column in the Customers table and the CustomerID column in the Orders table.

    Finally, we need to alias the data that was just appended as Orders. The following code sets up the objects and creates the hierarchical recordset:

    #Include adovfp.h
    Local oRecordset,oConnection,oCommand, cShpStr
    oRecordset = CreateObject("adodb.recordset")
    oConnection = CreateObject("adodb.connection")
    cShpStr = 'SHAPE {SELECT * FROM "dbo"."Customers"} AS Customers '
    cShpStr = cShpStr + 'APPEND ({SELECT * FROM "dbo"."Orders"} ;
      AS  Orders '
    cShpStr = cShpStr + 'RELATE "CustomerID" TO "CustomerID") AS Orders'
    With oConnection
       .Provider = "MSDataShape"
       .ConnectionString = "Data Provider=SQLOLEDB.1;Persist Security ;
        Info=False;User ID=sa;Initial Catalog=Northwind;Data Source=JVP"
       .Open
    EndWith
    With oRecordset
       .ActiveConnection = oConnection
       .Source = cShpStr
       .CursorType = adOpenStatic
       .LockType = adLockBatchOptimistic
       .CursorLocation = adUseClient
       .Open
    EndWith
    

    The question at this point is, “How is the data appended?” The technique is rather clever. When you append a recordset to another recordset, you do so through a Field object. If you query the Count property of the Fields collection, you discover that the value of 12 is returned. However, in SQL Server, you see that the Customers table only has 11 fields. The twelfth field, in this case, is actually a pointer to the Orders recordset. The rows in the Orders recordset for a given row in the Customers recordset are only those for that customer. The following code illustrates just how powerful hierarchical recordsets are:

    oRecordset.MoveFirst
    Do While !oRecordset.Eof
       With oRecordset
          ?.Fields("Customerid").Value,.Fields("CompanyName").Value
       EndWith
       oOrders = oRecordset.Fields("orders").Value
       Do While !oOrders.Eof
          With oOrders
          ?Chr(9),.Fields("Customerid").Value,.Fields("orderdate").Value
          .MoveNext
          EndWith   
       EndDo   
       oRecordset.MoveNext
    EndDo
    

    With the basics of hierarchical recordsets out of the way, we can turn our attention to a more complicated, real-life example. The following example adds several dimensions to the recordset.

    First, the Order Details table is appended to the Orders child recordset. In this case, a new field that will in turn point to the OrderDetails recordset, is added to the Orders recordset. The Products table is then appended to the OrderDetails recordset providing three levels of nesting. Appended to the Products recordset are two tables, Categories and Suppliers. Traversing up the hierarchy to the Orders recordset appends the Employees table.

    This list illustrates the hierarchy and shows all the tables involved as well as the nesting scheme. When creating reports, it is quite possible that you will need all of these tables. The ability to relate tables in this fashion and the ability to display the data in a user interface or a report have always been true powers of Visual FoxPro. Before ADO, attempting all this work outside Visual FoxPro was extremely difficult, sometimes bordering on the impossible.

    Customers
    
    Orders
    
    OrderDetails
       Products
          Categories
          Suppliers
    Employees
       EmployeeTerritories
          Territories
             Region
    Shippers
    
    

    The following is the Shape syntax to create the hierarchical recordset:

    SHAPE {SELECT * FROM "dbo"."Customers"} AS Customers APPEND (( SHAPE 
    {SELECT * FROM "dbo"."Orders"} AS Orders APPEND (( SHAPE {SELECT * FROM 
    "dbo"."Order Details"} AS OrderDetails APPEND (( SHAPE {SELECT * FROM 
    "dbo"."Products"} AS Products APPEND ({SELECT * FROM "dbo"."Categories"} 
    AS Categories RELATE 'CategoryID' TO 'CategoryID') AS Categories,({SELECT 
    * FROM "dbo"."Suppliers"} AS Suppliers RELATE 'SupplierID' TO 
    'SupplierID') AS Suppliers) AS Products RELATE 'ProductID' TO 
    'ProductID') AS Products) AS OrderDetails RELATE 'OrderID' TO 'OrderID') 
    AS OrderDetails,(( SHAPE {SELECT * FROM "dbo"."Employees"} AS Employees 
    APPEND (( SHAPE {SELECT * FROM "dbo"."EmployeeTerritories"} AS 
    EmployeeTerritories APPEND (( SHAPE {SELECT * FROM "dbo"."Territories"} 
    AS Territories APPEND ({SELECT * FROM "dbo"."Region"} AS Region RELATE 
    'RegionID' TO 'RegionID') AS Region) AS Territories RELATE 'TerritoryID' 
    TO 'TerritoryID') AS Territories) AS EmployeeTerritories RELATE 
    'EmployeeID' TO 'EmployeeID') AS EmployeeTerritories) AS Employees RELATE 
    'EmployeeID' TO 'EmployeeID') AS Employees,({SELECT * FROM 
    "dbo"."Shippers"} AS Shippers RELATE 'ShipVia' TO 'ShipperID') AS 
    Shippers) AS Orders RELATE 'CustomerID' TO 'CustomerID') AS Orders
    

    This is just about as complicated as it gets. Nobody in their right mind would want to hammer this code out manually. Fortunately, there is a visual way to build this code. The DataEnvironment designer that ships with Visual Basic allows you to visually design ADO connections, recordsets, and hierarchical recordsets. The following illustrates how this hierarchical recordset appears in the designer:

    The extensive Shape syntax can be copied and pasted into Visual FoxPro, or any other environment that can host ADO. For complete details on how to use the DataEnvironment designer, consult the Visual Basic documentation on the MSDN CDs that ship with Visual Studio.

    The following Visual FoxPro code traverses the hierarchical recordset and displays the data:

    #Include adovfp.h
    oRecordset = CreateObject("adodb.recordset")
    oConnection = CreateObject("adodb.connection")
    cShpStr = 'SHAPE {SELECT * FROM "dbo"."Customers"}  AS Customers APPEND'
    cShpStr = cShpStr + '(( SHAPE {SELECT * FROM "dbo"."Orders"}  AS Orders '
    cShpStr = cShpStr  + 'APPEND (( SHAPE {SELECT * FROM "dbo"."Order 
    Details"}  AS OrderDetails '
    cShpStr = cShpStr  + 'APPEND (( SHAPE {SELECT * FROM "dbo"."Products"}  
    AS Products '
    cShpStr = cShpStr  + 'APPEND ({SELECT * FROM "dbo"."Categories"}  AS 
    Categories '
    cShpStr = cShpStr  + 'RELATE "CategoryID" TO "CategoryID") AS 
    Categories,'
    cShpStr = cShpStr  + '({SELECT * FROM "dbo"."Suppliers"}  AS Suppliers '
    cShpStr = cShpStr  + 'RELATE "SupplierID" TO "SupplierID") AS Suppliers) 
    AS Products '
    cShpStr = cShpStr  + 'RELATE "ProductID" TO "ProductID") AS Products) AS 
    OrderDetails '
    cShpStr = cShpStr  + 'RELATE "OrderID" TO "OrderID") AS OrderDetails,'
    cShpStr = cShpStr  + '(( SHAPE {SELECT * FROM "dbo"."Employees"}  AS 
    Employees '
    cShpStr = cShpStr  + 'APPEND (( SHAPE {SELECT * FROM 
    "dbo"."EmployeeTerritories"}  AS EmployeeTerritories '
    cShpStr = cShpStr  + 'APPEND (( SHAPE {SELECT * FROM "dbo"."Territories"}  AS Territories '
    cShpStr = cShpStr  + 'APPEND ({SELECT * FROM "dbo"."Region"}  AS Region '
    cShpStr = cShpStr  + 'RELATE "RegionID" TO "RegionID") AS Region) AS 
    Territories '
    cShpStr = cShpStr  + 'RELATE "TerritoryID" TO "TerritoryID") AS 
    Territories) AS EmployeeTerritories '
    cShpStr = cShpStr  + 'RELATE "EmployeeID" TO "EmployeeID") AS 
    EmployeeTerritories) AS Employees '
    cShpStr = cShpStr  + 'RELATE "EmployeeID" TO "EmployeeID") AS Employees,'
    cShpStr = cShpStr  + '({SELECT * FROM "dbo"."Shippers"}  AS Shippers '
    cShpStr = cShpStr  + 'RELATE "ShipVia" TO "ShipperID") AS Shippers) AS 
    Orders '
    cShpStr = cShpStr  + 'RELATE "CustomerID" TO "CustomerID") AS Orders '
    With oConnection
       .Provider = "MSDataShape"
       .ConnectionString = "Data Provider=SQLOLEDB.1;Persist Security 
    Info=False;User ID=sa;Initial Catalog=Northwind;Data Source=JVP"
       .Open
    EndWith
    With oRecordset
       .ActiveConnection = oConnection
       .Source = cShpStr
       .CursorType = adOpenStatic
       .LockType = adLockBatchOptimistic
       .CursorLocation = adUseClient
       .Open
    EndWith
    Do While !oRecordset.Eof
       With oRecordset
          ?.Fields("CustomerID").Value,.Fields("CompanyName").Value
       EndWith
       oOrders =  oRecordset.Fields("orders").Value
       Do While !oOrders.Eof
          oShippers = oOrders.Fields("shippers").Value
          oEmployee = oOrders.Fields("employees").Value
          oEmployeeTerritories = 
    oEmployee.Fields("employeeterritories").Value
          oTerritories = oEmployeeTerritories.Fields("territories").Value
          oRegion = oTerritories.Fields("region").Value
          ?"Order ID:  ",oOrders.Fields("orderid").Value,;
          "Order Date:  ",oOrders.Fields("orderdate").Value
          oOrderDetails = oOrders.Fields("orderdetails").Value
          ?"Territory:  ", 
    oTerritories.Fields("territorydescription").Value,;
          "Region:  ",oRegion.Fields("RegionDescription").Value
          ?"Shipper: ",oShippers.Fields("companyname").Value
          oEmployee = oOrders.Fields("employees").Value
          With oEmployee
             ?"Employee: ",.Fields("employeeid").Value,;
             .Fields("firstname").Value + " " + .Fields("lastname").Value
          EndWith   
          ?"Order Details:  "
          Do While !oOrderDetails.Eof
             oProducts = oOrderDetails.Fields("Products").Value
             oCategories = oProducts.Fields("categories").Value
             oSuppliers = oProducts.Fields("suppliers").Value
             ?Chr(9),;
              oProducts.Fields("productname").Value,;
              oSuppliers.Fields("companyname").Value,;
              oCategories.Fields("categoryname").Value,;
              oOrderDetails.Fields("Quantity").Value,;
              oOrderDetails.Fields("UnitPrice").Value
              oOrderDetails.MoveNext
          EndDo
          oOrders.MoveNext
       EndDo   
       oRecordset.MoveNext
    EndDo
    

    The output appears as follows:

    Because a hierarchy exists, the ability to create drill-down interfaces becomes a fairly simple task. The preceding Visual FoxPro code illustrates how to traverse the hierarchy.

    Perhaps you want to use Microsoft Word or Excel as a reporting tool. With a combination of Visual FoxPro COM servers, ADO, and Automation, the process becomes manageable. The first and third parts of the solution have been around. However, only now that a set of COM objects exists to handle and work with data as Visual FoxPro does natively can the solution become a reality.

    Hierarchical recordsets and recursive relationships

    One of the nice features of SQL Server, and of most other server back ends is provision for recursive relations. The following is the SQL Server 7.0 database diagram for the Northwind database:

    In the Northwind database, the Employees table employs recursion to support a manager/staff relationship. Both managers and staff are employees. In some cases, it happens that some employees report to other employees. In Visual FoxPro, you can create the same sort of relation by opening a table twice using two different aliases. In ADO, the task is totally supported and is quite easy to implement. The following is the Shape syntax:

    SHAPE {SELECT * FROM "dbo"."Employees"}  AS Managers APPEND ({SELECT * 
    FROM "dbo"."Employees"}  AS Staff RELATE 'EmployeeID' TO 'ReportsTo') AS 
    Staff
    

    The following Visual FoxPro code displays a list of managers and the staff that reports to each manager:

    #Include adovfp.h
    oRecordset = CreateObject("adodb.recordset")
    oConnection = CreateObject("adodb.connection")
    cShpStr = 'SHAPE {SELECT * FROM "dbo"."Employees"}  AS Managers '
    cShpStr = cShpStr + 'APPEND ({SELECT * FROM "dbo"."Employees"} AS Staff '
    cShpStr = cShpStr + 'RELATE "EmployeeID" TO "ReportsTo") AS Staff '
    With oConnection
       .Provider = "MSDataShape"
       .ConnectionString = "Data Provider=SQLOLEDB.1;Persist Security 
    Info=False;User ID=sa;Initial Catalog=Northwind;Data Source=JVP"
       .Open
    EndWith
    With oRecordset
       .ActiveConnection = oConnection
       .Source = cShpStr
       .CursorType = adOpenStatic
       .LockType = adLockBatchOptimistic
       .CursorLocation = adUseClient
       .Open
    EndWith
    Do While !oRecordset.Eof
       oStaff = oRecordset.Fields("staff").Value
       If oStaff.Recordcount > 0
          With oRecordset
             ?.Fields("firstname").Value + " " + ;
             .Fields("lastname").Value ,;
             .Fields("Title").Value
             Do While !oStaff.Eof
                With oStaff
                   ?Chr(9),;
                   .Fields("firstname").Value + " " + ;
                   .Fields("lastname").Value ,;
                   .Fields("Title").Value
                EndWith
                oStaff.MoveNext
             EndDo
          EndWith
       Endif
       oRecordset.MoveNext
    EndDo
    

    The output appears as follows:

    Finally, note that hierarchical recordsets are updateable. The following code expands the previous example to illustrate how to make a simple update:

    Do While !oRecordset.Eof
       oStaff = oRecordset.Fields("staff").Value
       If oStaff.Recordcount > 0
          With oRecordset
             Do While !oStaff.Eof
                With oStaff
                   .Fields("firstname").Value = ;
                      Upper(.Fields("firstname").Value)
                   .Fields("lastname").Value = ;
                      Upper(.Fields("lastname").Value)
                   .Fields("Title").Value = ;
                      Upper(.Fields("Title").Value)
                EndWith
                oStaff.MoveNext
             EndDo
             */ Write changes to Staff recordset
             oStaff.UpdateBatch
          EndWith
       Endif
       oRecordset.MoveNext
    EndDo
    

    The ability to view related records, coupled with the ability to make updates, places the ADO hierarchical recordset capability on par with similar capabilities in Visual FoxPro.

    Multiple recordsets

    Use of hierarchical recordsets represents only one method for returning data from multiple recordsets in one object. For starters, building hierarchical recordsets is not the most straightforward of propositions. In many cases, a simpler alternative may be all that is required.

    Consider the case where you need a specific customer record and the orders for that customer. Yes, you could use a hierarchical recordset. But, there is a simpler way: run two SQL statements.

    Some OLE DB providers can process multiple SQL Statements. The OLE DB Provider for SQL Server has this capability. Attempting to do this with Visual FoxPro tables via the OLE DB Provider for ODBC will not work.

    When using this technique, you have two choices on where the logic exists to perform the task. One choice is to build the SQL on the client and pass it to the server through a Command object. The other choice is to invoke a stored procedure on the database server through a Command object. I’ll illustrate both techniques. The Command object will be discussed in detail later in this paper.

    To illustrate the stored procedure method, the following stored procedure must be created on the SQL Server Northwind database:

    CREATE  PROCEDURE CustomerAndOrders @CustomerID nchar(5)
    AS
    Select * From Customers Where Customers.CustomerID = @CustomerID
    Select * From Orders Where Orders.CustomerID = @CustomerID 
    

    With the stored procedure created, the following code will create the recordset:

    #Include adovfp.h
    oConnection = CreateObject("adodb.connection")
    oCommand = CreateObject("adodb.command")
    With oConnection
       .Provider = "SQLOLEDB.1"
       .ConnectionString = ;
          "Persist Security Info=False;User ID=sa;Initial
            Catalog=Northwind;Data Source=JVP"
       .Open
    EndWith
    With oCommand
       .CommandText = "CustomerAndOrders"
       .ActiveConnection = oConnection 
       .CommandType = adCmdStoredProc 
    EndWith
    oCommand.Parameters("@CustomerID").Value = "ALFKI"
    oRecordset = oCommand.Execute
    Do While !oRecordset.Eof
       ?oRecordset.Fields(1).Value
       oRecordset.MoveNext
    EndDo
    oRecordset = oRecordset.NextRecordset
    Do While !oRecordset.Eof
       ?oRecordset.Fields(0).Value
       oRecordset.MoveNext
    EndDo
    

    Like any recordset, the recordset just produced can be navigated. Once the first set of records from the Customers table have been navigated, the NextRecordset method is invoked. This causes the recordset produced by the second SQL statement to become available. Thus, the next set of commands loops through the records from the Orders table. This technique is ideal in those situations where you may need to populate Combo or ListBox controls.

    The previous example references a collection that has not been discussed yet, the Parameters collection. The Parameters collection and the individual Parameter objects that it contains serve several purposes. One purpose is to provide the capacity to create parameterized queries. Another purpose is to provide the ability to send arguments to, and return data from, a stored procedure. For more information on the Parameters collection, see the Command Object section of this paper.

    Alternatively, you can produce the SQL on the client if you wish. The following code illustrates the difference:

    With oCommand
       .CommandText = "Select * From Customers Where CustomerID =
          'ALFKI'" + Chr(13) + "Select * From Orders Where CustomerID =
          'ALFKI'"
       .ActiveConnection = oConnection 
       .CommandType = adCmdText 
    EndWith
    oRecordset = oCommand.Execute
    

    The same result is achieved. The difference lies in how the result is achieved.

    Which approach is better?

    It depends on what your requirements are. The first option, which uses stored procedures, is more secure; the code is set and you can assign permissions with regard to who can execute the stored procedure. The second option provides more flexibility, but less security.

    Fabricated recordsets

    Up to this point, recordset objects have been presented in the context of origination from an ADO connection. In many cases, you may want to create an ADO recordset with data that does not come from a data source, just as you may in some cases use the Create Cursor command in Visual FoxPro. For example, you may have an application that works with a small amount of data, such as an array or Visual FoxPro cursor. Perhaps you need to dynamically build a table structure. Whatever the reason, the ability to create ADO recordsets from scratch is powerful.

    To illustrate this capability, consider the need to fetch a list of files from a specified directory. In Visual FoxPro, a handy function, ADIR( ), performs this sort of task. However, what if you need to pass the data to another application? Or, perhaps you need to persist the list to a file on disk. While Visual FoxPro arrays are powerful, ADO recordsets provide a compelling alternative. The following code fetches a list of files from a specified directory, fabricates a recordset, and copies the values from the array into the newly created recordset:

    */GetFiles.prg
    #INCLUDE "adovfp.h"
    Local Array aFiles[1]
    Local nFiles,nField,nFile,oRS
    nFiles = Adir(aFiles,Getdir( )+"*.*")
    oRS=Createobject("adodb.recordset")
    With oRS
    .CursorLocation=ADUSECLIENT
    .LockType=ADLOCKOPTIMISTIC
    */ Adding new fields is a matter of appending
    */ new field objects to the Fields Collection. 
    .Fields.Append("File",ADCHAR,20)
    .Fields.Append("Size",ADDOUBLE,10)
    .Fields.Append("DateTime",ADDBTIME,8)
    .Fields.Append("Attributes",ADCHAR,10)
    .Open
    EndWith
    For nFile = 1 To nFiles
       */ Add a new record. This automatically makes
       */ the new record the current record - just
       */ like VFP.
       oRS.AddNew
       With ors
          .Fields("File").Value = aFiles[nFile,1]
          .Fields("Size").Value = aFiles[nFile,2]
          .Fields("DateTime").Value = ;
            Ctot(Dtoc(aFiles[nFile,3]) + " " + aFiles[nFile,4])
          .Fields("Attributes").Value = aFiles[nFile,5]
       EndWith
    Next nItem
    Return oRS
    

    With the new recordset created and populated, it can be navigated like any other recordset:

    oFiles = GetFiles ( )
    Do While !oFiles.Eof
       ?oFiles.Fields("File").Value
       oFiles.movenext
    EndDo
    

    ADO recordsets instead of arrays

    Referring to the previous example, let’s say that the list needs to be sorted by file size, descending. Arrays in Visual FoxPro can be sorted, when all columns in the array are of the same data type. In this case, there are three data types: Character, Numeric, and DateTime. With a client-side ADO recordset, the process becomes simple. The following code does the trick:

    oRS.Sort = "Size Desc"
    

    Sorts are not limited to just one column. Perhaps you need to sort by size, descending, and then by file, ascending:

    oRS.Sort = "Size Desc,File"
    

    And, when it comes to sorting, such properties as Bookmark and AbsolutePosition that have already been demonstrated are available here as well.

    Perhaps you need to find a specific value. The ASCAN( ) function in Visual FoxPro enables you to do this. However, it does not allow you to specify a particular column to search. Rather, once the first occurrence of a specified value is found, regardless of the column, the search is stopped. With ADO recordsets, more granular control is provided. The following code checks to see if a file called VFP6.EXE is in the recordset:

    oRS.Find("File Like 'VFP6.EXE'")
    If !oRS.Eof
       */ Found it
    Else
       */ Not found
    Endif
    

    Finally, you may wish to filter the list based on the file size being greater than a specified value:

    oRS.Filter = "size > 50000"
    

    When evaluating the tools at your disposal for local data handling, be sure to consider fabricated ADO recordsets. Also, if you find yourself running into obstacles with Visual FoxPro arrays, fabricated ADO recordsets may provide a sound alternative.

    Command Object

    ProgID: ADODB.Command

    The purpose of the Command object is just as the its name implies, to run commands. For example, you may need to run a SQL update against a SQL Server table. To illustrate, the following code applies a 10 percent increase in the UnitPrice field in the Products table of the SQL Server Northwind database:

    oCommand = CreateObject("adodb.command")
    With oCommand
       .ActiveConnection = oConnection
       .CommandText = "Update Products Set unitprice = unitprice * 1.1"
       .Execute
    EndWith
    

    The ActiveConnection property

    To review, both the Command object and Recordset object have the ActiveConnection property. A Command object needs to know what data source it is to execute commands against. A Recordset object needs to know what data source contains the data it is to retrieve. The way you accomplish this is by setting the ActiveConnection property.

    The ActiveConnection property presents a great opportunity to talk about the flexible nature of the ADO object model. The ADO object model is very flat, in that you do not have to create a series of objects in order to gain access to other objects. For example, the following is one way to create and open both a Connection and a Recordset object:

    oConnection = CreateObject(""adodb.connection"")
    oRecordset = CreateObject(""adodb.recordset"")
    With oConnection
       .Provider = ""SQLOLEDB.1""
       .ConnectionString = ""Persist Security Info=False;User 
        ID=sa;Initial Catalog=Nothwind;Data Source=JVP""
       .Open
    EndWith
    With oRecordset
       .ActiveConnection = oConnection
       .Source = ""Products""
       .Open
    EndWith
    

    Here is another way to create the two objects:

    oRecordset = CreateObject(""adodb.recordset"")
    With oRecordset
       .ActiveConnection = ""Provider=SQLOLEDB.1;Persist Security 
        Info=False;User ID=sa;Initial Catalog=Northwind;Data Source=JVP""
       .Source = ""Products""
       .Open
    EndWith
    

    Now, you can reference the Connection object because it has been implicitly created from the passed connection string:

    ?oRecordset.ActiveConnection.ConnectionString
    

    The same is true for the Command object. While a Command object was not explicitly created, a Command object was in fact created and actually did the work of creating the recordset. Using the recordset just created, the following command will yield “Products” as the CommandText:

    ?oRecordset.ActiveCommand.CommandText
    

    Which method should you use?

    It is really a matter of preference. The latter method, which uses only the RecordSet object, is somewhat overloaded. It carries the same overhead as the former method because you must still create a Connection object. The former method is probably a better way to go as it makes for more readable code.

    Parameters collection

    The Parameters collection works with the Command object. The primary use of the Parameters Collection is to both pass arguments to, and accept return values from stored procedures. To illustrate, consider the CustOrderHist stored procedure in the SQL Server Northwind database:

    CREATE PROCEDURE CustOrderHist @CustomerID nchar(5)
    AS
    SELECT ProductName, Total=SUM(Quantity)
    FROM Products P, [Order Details] OD, Orders O, Customers C
    WHERE C.CustomerID = @CustomerID
    AND C.CustomerID = O.CustomerID AND O.OrderID = OD.OrderID AND 
    OD.ProductID = P.ProductID
    GROUP BY ProductName
    

    To illustrate how the Parameters collection is used in conjunction with the Command object, consider the following comprehensive example:

    First, you need to establish a valid connection:

    oConnection = CreateObject("adodb.connection")
    

    Next, the connection needs to be opened.

    With oConnection
       .Provider = "SQLOLEDB.1"
       .ConnectionString = "Persist Security Info=False;User 
        ID=sa;Initial Catalog=Northwind;Data Source=JVP"
       .Open
    EndWith
    

    With a valid, open connection, a Command object can be prepared:

    With oCommand
       .ActiveConnection = oConnection 
       .CommandText = "CustOrderHist"
       .CommandType = adCmdStoredProc && adCmdStoredProc = 4
    EndWith
    

    At this point, information can be obtained from the Parameters collection:

    For Each Parameter in oCommand.Parameters
       ?Parameter.Name,Parameter.Size,Parameter.Type
    Next Parameter
    

    The first Parameter object is reserved for the value that the stored procedure may return. Regardless of whether the stored procedure explicitly returns a value, this Parameter object will be created. Examining the CustOrderHist stored procedure, note that a single argument, a customer ID, is accepted.

    With a Command object and Parameter object in place, the real work can begin. To get things rolling, a value needs to be assigned to the Parameter object that will in turn be passed to the stored procedure. In this case, a SQL statement is executed that totals the quantity, by product, that a specified customer has purchased. The following code provides a customer ID and executes the stored procedure:

    oCommand.Parameters("@CustomerID").Value = "ALFKI"
    oRecordset = oCommand.Execute
    

    Yet another way to produce a Recordset object is through the execution of a stored procedure. The resulting Recordset object contains two fields that correspond to the select statement in the CustOrderHist stored procedure. Need a different history? Just update the Value property of the Parameter object and invoke the Execute method of the Command object.

    The Parameters collection also comes into play in the area of parameterized queries. Consider the following SQL Statement:

    Select * ;
       From Customer ;
       Where country = ? And max_order_amt > ?
    

    As with views, either local or remote, in Visual FoxPro, so too can queries be parameterized in ADO. In ADO, the question mark acts as a placeholder for parameters. The following example illustrates how to put this all together.

    First, a connection and a Command object need to be created:

    oConnection = CreateObject("adodb.connection")
    oCommand = CreateObject("adodb.command")
    

    Next, the connection needs to be established:

    oConnection.Open("northwind","sa","")
    

    For illustration purposes, the OLE DB Provider for ODBC is used. The native OLE DB Provider for SQL Server could have been used as well.

    Next, the Command object needs to be prepared:

    With oCommand
       .ActiveConnection = oConnection
       .CommandText = "Select * From Customer Where country = ? 
    EndWith
    

    With the Command object ready to go, a parameter object needs to be created:

    oCountryParameter = ;
     oCommand.CreateParameter("country",adChar,adParamInput,1," "))
    

    The arguments for the CreateParameter method are as follows:

    • Name—The name of the parameter.
    • Type—The data type of the parameter. A list of valid values is contained in DataTypeEnum.
    • Direction—The direction of the parameter. Parameters sent to a command are input parameters. Arguments passed back from a command are output parameters. A list of valid values is contained in ParameterDirectionEnum.
    • Size—The length of the parameter.
    • Value—The initial value of the parameter.

    Alternatively, the parameter could have been created like this:

    OCountryParameter = CreateObject("adodb.parameter")
    With oCountryParameter
       .Name = "Country"
       .Type = adChar
       .Direction = adParamInput
       .Size = 1
       .Value = " "
    EndWith
    

    Once the parameter has been created, it needs to be appended into the Parameters collection of the Command object:

    oCommand.Parameters.Append(oCountryParameter)
    

    With the parameter in place, the value of the parameter can be set. In this case, the parameter will be set so that any country that begins with the letter U will be returned into a Recordset object:

    With oCountryParameter
       .Size = 2
       .Value = "U%"
    EndWith
    

    Now, a Recordset object can be created:

    oRecordset = oCommand.Execute
    

    A useful feature of specifying parameters is that this enforces characteristics such as size, data type, and so on. For example, the preceding parameter was defined as a character. If a value based on a different data type was assigned to the Value property of the Parameter object, an error would result. The same is true if the assigned value is greater in length than what has been specified by the Size property.

    Finally, if a list of customers in Mexico were required, the following code would complete the task:

    With oCommand
       .Parameters("country").Size = Len("Mexico")
       .Parameters("country").Value = "Mexico"
       oRecordSet = .Execute 
    EndWith
    

    Properties Collection

    Recall the earlier assertion that, by itself, ADO is incapable of doing anything? ADO in fact just provides an interface. OLE DB providers give ADO the ability to do anything. So then, what distinguishes one OLE DB provider from another? More specifically, how can you determine what an OLE DB provider can and cannot do, or what attributes it does or does not possess? Depending on the OLE DB provider you use, or the type of recordset you use (client or server), what is supported will likely differ.

    The Properties collection applies to the ConnectionRecordset, and Field objects. The Command object also has a Properties collection, which is identical to the Recordset object Properties collection.

    Multiple result sets provide a good example of varying OLE DB provider support. To determine if multiple result sets can be obtained, you can refer to the “Multiple Results” properties:

    If oConnection.Properties("Multiple Results").Value = 1
       */ Supports multiple result sets
    EndIf
    

    While the OLE DB providers for SQL Server and ODBC both support multiple results, the OLE DB provider for Jet does not. To illustrate, the following is valid syntax for SQL Server:

    oRecordset.Source="SELECT * FROM customers;"+"SELECT * FROM orders"
    oRecordset.Open
    ?oRecordSet.Fields.Count && number of fields in customers table
    oRecordset = oRecordset.NextRecordSet
    ?oRecordSet.Fields.Count && number of fields in orders table
    

    In this case, the OLE DB Provider for SQL Server can return multiple recordsets. If you attempt the same thing with the OLE DB Provider for ODBC, which you need to use when accessing Visual FoxPro data, you will receive an error message stating that the requested action is not supported by the OLE DB provider.

    Another example involves the way in which the Properties collection deals with the location of a Recordset object. Recordsets can either exist locally as client-side recordsets or they can exist remotely as server-side recordsets. Client-side recordsets, as will be discussed shortly, have several capabilities that server-side recordsets do not have. One of these abilities is to create indexes. The following code creates a client-side recordset:

    oRecordset = CreateObject("adodb.recordset")
    oConnection = CreateObject("adodb.connection")
    With oConnection
       .Provider = "SQLOLEDB.1"
       .ConnectionString = "Persist Security Info=False;User 
        ID=sa;Initial Catalog=Northwind;Data Source=JVP"
       .Open
    EndWith
    With oRecordset
       .Cursorlocation = adUseClient && adUseClient = 3
       .ActiveConnection = oConnection
       .Source = "Products"
       .Open 
    EndWith
    

    Now, lets create an index on the ProductName field using the following code:

    oRecordSet.Fields("productname").Properties("optimize").Value = .T.
    

    In the absence of a declaration of where a Recordset object should reside, the Recordset object, by default, resides on the server. Attempting to reference the Optimize property results in an error stating that the specified property could not be found in the collection.

    While the ADO interface is constant, depending on the provider you use, the capabilities may be very different. Be sure to consult your provider’s documentation.

    Remote Data Services

    One of the most powerful data access capabilities introduced by Microsoft is Remote Data Services (RDS). Although a separate set of objects exists for RDS, RDS is really just another component for use with ADO. There are two ways you can implement RDS.

    • Use the same ADO objects described in this paper
    • Use the RDS data control

    Let’s discuss the RDS data control option first, since it represents some uncharted territory.

    The RDS Data Control

    The following code creates an instance of the RDS data control:

    oRDSDataControl = Createobject("rds.datacontrol")
    

    Once the data control is created, only three properties need to be populated: ServerConnect, and SQL.

    With oRDSDataControl
       .Server = "http://jvp"
       .Connect = ;
        "Remote Provider=SQLOLEDB.1;database=northwind;User ID=sa;"
       .Sql = "Customers"
    EndWith
    

    Because we’re using the SQL Server OLE DB Provider, the SQL property can consist of just the table name. The following code retrieves the same recordset, but does so with the OLE DB provider for ODBC:

    With oRDSDataControl
       .Server = "http://jvp"
       .Connect = "dsn=northwind;uid=sa;pwd=;"
       .Sql = "Customers"
    EndWith
    

    Whenever possible, you should use a native OLE DB provider rather than the OLE DB provider for ODBC.

    With the RDS data control properties set, you can create a recordset. Invoke the Refresh method to accomplish this, as in the following code:

    oRDSDataControl.Refresh
    oRecordset = oRDSDataControl.Recordset
    

    From this point on, you can work with the recordset the same way you work with any other ADO client-side recordset:

    Do While !oRecordset.Eof
       orecordset.Fields(1).value = ;
          Proper(orecordset.Fields(1).value)
       oRecordset.Movenext
    EndDo
    oRecordset.Updatebatch
    

    Alternatively, you can replace the last line of code with a call to the SubmitChanges method of the RDS data control:

    oRDSDataControl.SubmitChanges
    

    Implementing RDS Through the ADO Interface

    You can invoke RDS by using the same ADO Connection object discussed above. As with hierarchical recordsets, the first step involves the selection of an OLE DB provider. In this case, the MSRemote provider is required. The following code sets up the Connection object:

    oConnection = CreateObject("adodb.connection")
    With oConnection
       .Provider = "MS Remote.1"
    
       .ConnectionString = "Remote Server=http://jvp;Remote 
             Provider=SQLOLEDB.1;database=northwind;User ID=sa;Pwd=;"
       .Open
    EndWith
    

    The ADO ConnectionString property supports only four arguments. The first two, Provider and File Name, have already been discussed. The third and fourth, Remote Provider and Remote Server, are used by the RDS in the example above. The Remote Provider is the same OLE DB provider used when you create local connections. The additional parameters that specify the database, user ID, and password are used by the OLE DB Provider for SQL Server that in turn is located on the remote server. The following code connects the Recordset object and Connection object and with one difference, is basically the same as the previous examples in this paper:

    With oRecordset
       .ActiveConnection = oConnection
       .Source = "Customers"
       .LockType = adLockBatchOptimistic
       .Open
    EndWith
    

    The only difference is that properties such as CursorLocation and CursorType are omitted since all recordsets created through RDS must exist on the client. Additionally, all client-side recordsets are static types. If you like, you can still specify the properties explicitly. Any incompatible properties will be coerced to a valid value. For example, if you specify the CursorType to be a ForwardOnly cursor and you specify the recordset exists on the client, when the Open method is fired, ADO forces the cursor type to be static. The same is true if you specify the CursorLocation to be on the server and you use the MSDataShape provider. Since all hierarchical pecordsets must exist on the client, the CursorLocation is coerced to the proper value.

    Summary

    The goal of this paper has been to provide you with a fairly comprehensive overview of both ADO and RDS from the perspective of Visual FoxPro applications. Note that ADO is not a replacement for the Visual FoxPro Cursor Engine. Rather, regard it as another tool at your disposal. Both Visual FoxPro cursors and ADO recordsets have their relative strengths and weaknesses.

    ADO is ideal in situations where your application is component based, or in situations where you need to pass data to other applications such as Excel in automation operations. Fabricated ADO recordsets can provide an interesting alternative to arrays when more robust data handling requirements are necessary.

    For most local data handling operations however, Visual FoxPro cursors will usually provide better results.

    John V. Petersen, MBA, is president of Main Line Software, Inc., based in Philadelphia, Pennsylvania. John’s firm specializes in custom software development and database design. He is a Microsoft Most Valuable Professional and has spoken at many developer events, including Visual FoxPro Developers Conference, FoxTeach, the Visual FoxExpress Developer’s Conference, DevDays, and TechEd. In addition, John has written numerous articles for FoxTalk and FoxPro Advisor. John is co-author of Visual FoxPro 6 Enterprise Development and Hands-on Visual Basic 6—Web Development, both from Prima Publishing. John’s latest project is the ADO Developer’s Handbook, from Sybex Publishing, due September 1999.

    Customizing Visual FoxPro 6.0 Application Framework Components 

    • Article
    • 06/30/2006

    In this article

    1. Overview
    2. Examining Framework Components
    3. Designating the Classes You Want
    4. Specifying Your Own Framework Components

    Show 7 more

    Lisa Slater Nicholls

    October 1998

    Summary: Describes how the Microsoft® Visual FoxPro® version 6.0 Application Framework, including the Application Wizard and Application Builder, can be used by the beginning developer to turn out polished applications and customized by the more experienced developer to create more detailed applications. (32 printed pages)

    Contents

    Overview Examining Framework Components Designating the Classes You Want Specifying Your Own Framework Components A Closer Look at the Standard Application Wizard A New Application Wizard A Few Parting Thoughts about Team Practices Appendix 1 Appendix 2 Appendix 3 Appendix 4Expand table

    Click to copy the appfrmwk sample application discussed in this article.

    Overview

    The Visual FoxPro 6.0 Application Framework offers a rapid development path for people with little experience in Visual FoxPro. With a few simple choices in the Application Wizard and the Application Builder, beginning developers can turn out polished and practical applications.

    Under the hood, however, the framework offers experienced developers and teams much more. This article shows you how to adapt the framework components so they fit your established Visual FoxPro requirements and practices.

    In the first section of this article you’ll learn about the files and components that support the framework and how they work together while you develop an application. This information is critical to moving beyond simply generating framework applications to experimenting with framework enhancements.

    The second section teaches you how to apply your experiences with the framework to multiple applications. After you’ve experimented with framework enhancements for a while, you will want to integrate your changes with the framework, for standard use by your development team. By customizing the files the Application Wizard uses to generate your application, you’ll make your revisions accessible to team members—without sacrificing the framework’s characteristic ease of use.

    Examining Framework Components

    This section shows where the framework gets its features and components, and how these application elements are automatically adjusted during your development process.

    Once you see how and where framework information is stored, you can begin to try different variations by editing the versions generated for a framework application. When you’re satisfied with your changes, you can use the techniques in the next section to migrate them to your team’s versions of the framework components.

    Note   Like most Visual FoxPro application development systems, the framework is composed of both object-oriented programming (OOP) class components and non-OOP files. This distinction is important because you adapt these two types of components in different ways; classes can be subclassed, while non-OOP files must be included as is or copied and pasted to get new versions for each application. The framework is minimally dependent on non-OOP files, as you’ll see here, but these files still exist.

    Throughout this article we’ll refer to the non-OOP framework files as templates, to distinguish these components from true classes.

    Framework Classes

    The Visual FoxPro 6.0 framework classes are of two types:

    1. Framework-specific classes. These classes have been written especially for the application framework and provide functionality specific to the framework. The standard versions of these classes are in the HOME( )+ Wizards folder, in the _FRAMEWK.VCX class library.
    2. Generic components. These features come from class libraries in the HOME( )+ FFC (Visual FoxPro Foundation Classes) folder.

    _FRAMEWK.VCX

    The _FRAMEWK.VCX class library (see Figure 1) contains all the classes written specifically to support the framework. Each framework application you create has an application-specific VCX containing subclasses of the _FRAMEWK.VCX components. The Application Wizard puts these subclasses in a class library named <Your projectname> plus a suffix to designate this library as one of the wizard-generated files. To distinguish these generated, empty subclasses, it adds a special prefix to the class names as well.

    Figure 1. _FRAMEWK.VCX framework-specific class library, as viewed in Class Browser, is found in the HOME( )+ Wizards folder.

    Framework superclass: _Application

    The _Application class is a required ancestor class, which means that this class or a subclass of this class is always required by the framework. This class provides application-wide manager services. For example, it manages a collection of modeless forms the user has opened.

    You designate a subclass of _Application simply by using CREATEOBJECT( ) or NEWOBJECT( ) to instantiate the subclass of your choice. (By default, the framework provides a main program to do this, but this PRG contains no required code.) When your designated _Application subclass has instantiated successfully, you call this object’s Show( ) method to start running the application.

    Note   In this article, we’ll refer to the object you instantiate from a subclass of _Application as the application object. We’ll continue to refer to “your subclass of _Application” to mean the class definition instantiating this object, which will be in a VCX belonging to your application (not _FRAMEWK.VCX). You’ll also see references to “_Application“, that refer specifically to code and properties you’ll find in the superclass located in _FRAMEWK.VCX.

    At run time, the application object instantiates other objects as necessary to fill all the roles represented by the other classes in _FRAMEWK.VCX except _Splash. The framework identifies these roles as important to various application functions, but, as you’ll see in this section, you have full control over how the roles are carried out.

    Note   The _Splash class is an anomaly in _FRAMEWK.VCX; it isn’t instantiated or used by the framework application directly. (If it were instantiated by the application object, your splash screen would appear too late to be useful.) Instead, _Splash merely provides a default splash screen with some of the same attributes as _Application (for example, your application name and copyright). The Application Builder transfers these attributes to your application’s subclass of _Splash at the same time it gives them to your application’s subclass of _Application, so they stay synchronized. The default main program delivered with a framework gives you one way to instantiate this splash screen before you instantiate your application object.

    You certainly don’t need to use the method shown in the default main program for your splash screen. In fact, many applications do not need a splash screen at all. For those that do, you may prefer to use the Visual FoxPro –b<file name> command-line switch, which displays a bitmap of your choice during startup, rather than a Visual FoxPro form of any description.

    Framework superclass: _FormMediator

    You’ll grasp most of the “roles” played by the subsidiary classes in _FRAMEWK.VCX easily, by reading their class names and descriptions. (If you can’t read the full class description when you examine _FRAMEWK.VCX classes in a project, try using the Class Browser.) However, you’ll notice a _FormMediator class whose purpose takes a little more explaining.

    You add an object descended from the _FormMediator custom class to any form or form class, to enable the form to communicate efficiently with the application object. This section will show you several reasons the form might want to use services of the application object. With a mediator, your form classes have access to these services, but the forms themselves remain free of complex framework-referencing code.

    The _FormMediator class is low-impact. It doesn’t use a lot of resources, and its presence will not prevent your forms from being used outside a framework application. Using this strategy, the framework can manage any forms or form classes your team prefers to use, without expecting them to have any special inheritance or features.

    Like _Application, _FormMediator class is a required ancestor class. You can create other mediator classes, as you can subclass _Application to suit your needs, but your mediators must descend from this ancestor.

    We’ll refer to _FormMediator and its descendents as the mediator object, because (strictly speaking) your forms will see it as the “application mediator” while the application object treats it as a “form mediator.”

    The Visual FoxPro 6.0 Form Wizards create forms designed to take advantage of mediators when the framework is available. You can see some simple examples of mediator use in the baseform class of HOME( )+ Wizards\WIZBASE.VCX.

    Examine _FormMediator‘s properties and methods, and you’ll see that you can do much more with the mediator in your own form classes. For example, the application object calls mediator methods and examines mediator properties during its DoTableOutput( ) method. (This method allows quick output based on tables in the current data session.) Your mediator for a specific form could:

    • SELECT a particular alias to be the focus of the output.
    • Prepare a query specifically for output purposes (and dispose of it after the output).
    • Inform the application object of specific classes and styles to be used by _GENHTML for this form.
    • Change the output dialog box caption to suit this form.

    The mediator also has methods and properties designed to specify context menus for the use of a particular form. If the application object receives this information from the mediator, it handles the management of this menu (sharing it between forms as necessary).

    You’ll find one example of mediator use in the ErrorLogViewer class. (This use is described in Appendix 1, which covers the options system.) A full discussion of the _FormMediator class is beyond the scope of this document. The more information you give a mediator or mediator subclass, however, the more fully your forms can use framework’s features, without making any significant changes to the forms themselves.

    Note   The _Application class includes a property, lEnableFormsAtRuntime (defaulting to .T.), which causes the application object to add mediators at run time to any form not having a mediator of its own. You can specify the mediator subclass that the application adds to a form at run time. Keep in mind, however, that mediators added at design time will have a more complete relationship with their form containers, because these forms can include code referencing their mediator members. During a form’s QueryUnload event, for example, the form can use the mediator to determine whether the form contains any unconfirmed changes. Without code in the form’s QueryUnload method, the mediator can’t intercede at this critical point.

    Additional _FRAMEWK.VCX classes

    The other classes in _FRAMEWK.VCX are all dialog box and toolbar classes to perform common functions within an application. None of these classes are required ancestors; you can substitute your own user interfaces and class hierarchies for these defaults at will. Two of them (_Dialog and _DocumentPicker) are abstract; that is, they are never instantiated directly, existing only to provide properties and methods to their descendent classes. Others will not instantiate unless you pick specific application characteristics. For example, if you don’t write “top form” applications (MDI applications in their own frames) you will never use _TopForm, the _FRAMEWK.VCX class that provides the MDI frame window object.

    Once you have examined these classes, and identified their roles, you will know which ones supply the types of services you need in applications you write—and, of these, you will identify the ones you wish to change.

    Designating the Classes You Want

    For each class role identified by the framework, the application object uses corresponding xxxClass and xxxClassLib properties to determine the classes you want. To change which class is instantiated for each role, you change the contents of these properties in your subclass of _Application.

    For example, _Application has cAboutBoxClass and cAboutBoxClassLib properties, and it uses these properties to decide what dialog box to show in its DoAboutBox( ) method (see Figure 2).

    Figure 2. Class and ClassLib property pairs in the _Application object

    If you fill out a class property but omit the matching Classlib property, _Application assumes that your designated class is in the same library as the _Application subclass you instantiated. If your _Application subclass is in the MyApplication.vcx and cAboutBoxClass has the value “MyAboutBox” but cAboutBoxClassLib is empty, a call to the Application object’s DoAboutBox( ) method instantiates a class called MyAboutBox in MyApplication.vcx.

    If you call the method instantiating one of the subsidiary classes when the matching class property is empty, _Application attempts to provide appropriate behavior to the specific situation. For example, if the cAboutBoxClass property is empty, DoAboutBox( ) will simply do nothing, because it has no alternative. By contrast, if the cErrorViewerClass property is empty, the _Application DisplayErrorLog( ) method will ask its cusError member object to use its default error log display instead.

    Except for the cMediatorClass and cMediatorClassLib properties, which must specify a class descending from _FormMediator in _FRAMEWK.VCX, remember that there are no restrictions on these dialog boxes and toolbars. You don’t have to subclass them from the classes in _FRAMEWK.VCX, or even follow their examples, in your own classes fulfilling these framework roles.

    Even when you design completely different classes, you will still benefit from investigating the defaults in _FRAMEWK.VCX, to see how they take advantage of their relationship with the framework. For example, all the classes descended from _Dialog have an ApplyAppAttributes( ) method. When the framework instantiates these classes, it checks for the existence of this method. If the ApplyAppAttributes( ) method exists, the application object passes a reference to itself to the form, using this method, before it calls the Show( ) method. In this way, the dialog box can derive any framework-specific information it needs before it becomes visible. For instance, the About Box dialog box might adjust its caption using the _Application.cCaption property.

    If the ApplyAppAttributes( ) method does not exist in yourcAboutBoxClass class, no harm is done. The _Application code still tries to harmonize your dialog box with its interface, in a limited way, by checking to see whether you’ve assigned any custom value to its Icon property. If you haven’t, _Application assigns the value in its cIcon property to your dialog box’s icon before calling its Show( ) method.

    Note   This strategy typifies the framework’s general behavior and goals:

    • It tries to make the best use of whatever material you include in the application.
    • When possible, it does not make restrictive assumptions about the nature of this material.
    • It avoids overriding any non-default behavior you may have specified.

    Investigating the default _Options dialog box class and _UserLogin default dialog boxes will also give you insight into the _Application options and user systems. While the dialog boxes themselves are not required, you will want to see how they interact with appropriate _Application properties and methods, so your own dialog boxes can take advantage of these framework features. In particular, the _Application options system has certain required elements, detailed in Appendix 1.

    FoxPro Foundation Generic Classes

    You may be surprised that _FRAMEWK.VCX contains only two required classes (the application and mediator objects), and in fact even when you add the other subsidiary classes, _FRAMEWK.VCX doesn’t contain much of the functionality you may expect in a Visual FoxPro application. You will not find code to perform table handling. You won’t find dialog boxes filling standard Visual FoxPro roles, such as a dialog box to select report destinations. You won’t find extensive error-handling code.

    _FRAMEWK.VCX doesn’t include this functionality because there is nothing framework-specific about these requirements. Instead, it makes use of several Visual FoxPro Foundation Classes libraries, useful to any framework or application, to perform these generic functions. The _Application superclass contains several members descending from FFC classes, and it instantiates objects from other FFC classes at run time as necessary. Then it wraps these objects, setting some of their properties and adding some specific code and behavior to make these instances of the FFC classes especially useful to the framework.

    For example, _Application relies on its cusError member, descended from the _Error object in FFC\_APP.VCX, to do most of its error handling, and to create an error log. However, as mentioned earlier, _Application code displays the error log using a framework-specific dialog box. The application object also sets the name and location of the error log table to match its own needs, rather than accepting _Error‘s default.

    The framework uses four FFC class libraries: _APP.VCX_TABLE.VCX_UI.VCX, and _REPORTS.VCX. Figure 3 shows these libraries in Class Browser views, as well as in a Classes tab for a framework application project.

    Figure 3. A framework application uses generic Visual FoxPro Foundation Classes, from HOME( )+ FFC folder, to supplement the framework-specific classes in _FRAMEWK.VCX.

    Unlike the subsidiary classes in _FRAMEWK.VCX, the FFC classes and their complex attributes are used directly by _Application, so you don’t specify alternative classes or class libraries for these objects. You can still specify your own copies of these class libraries, as you’ll see in the next section.

    If you examine the Project tab in Figure 3, or the project for any framework application, you’ll find this list of libraries built in. You’ll see _FRAMEWK.VCX, and there will be at least one class library containing the subclasses of _FRAMEWK.VCX for this application.

    You’ll see one more FFC library: _BASE.VCX, which contains the classes on which _FRAMEWK.VCX and all the FFC libraries are based. Your framework project must have access to a library called _BASE, containing all the classes found in _BASE. However, neither the framework nor the four FFC class libraries it uses require any specific behavior or attributes from these classes. You are free to create an entirely different _BASE.VCX with classes of the same name, perhaps descending from your team’s standard base library.

    Framework Templates

    The framework templates are of three types:

    1. Menu templates, a collection of Visual FoxPro menu definition files (.mnx and .mnt extensions)
    2. Metatable, an empty copy of the table the framework uses to store information about the documents (forms, reports, and labels) you use in your application
    3. Text, a collection of ASCII supporting files

    Unlike the .vcx files used by the framework, Visual FoxPro doesn’t deliver separate versions of these templates on disk. Because the templates are copied, rather than subclassed, for framework applications, the templates don’t need to be available to your project as separate files. Instead, these items are packed into a table, _FRAMEWK.DBF, found in the HOME( )+ Wizards folder. The Application Wizard unpacks the files when it generates your new application (see Figure 4).

    Figure 4. The Application Wizard copies template files from this _FRAMEWK.DBF table in HOME( )+ Wizards folder.

    Because the files don’t exist on disk, their template file names are largely irrelevant, except to the Application Wizard. Although we’ll use the template names here, keep in mind that their copies receive new names when the Wizard generates your application.

    Just as the framework identifies “dialog box roles” and supplies sample dialog boxes to fill those roles, it identifies some “menu roles,” and comes equipped with standard menus to meet these requirements. The roles are startup (the main menu for your application) and navigation (a context menu for those forms you identify as needing navigation on the menu).

    There are three template startup menus, each corresponding to one of the three application types described by the Application Builder as normaltop form, and moduleT_MAIN.MNX, is a standard “replace-style” Visual FoxPro menu. It’s used for normal-style applications, which take over the Visual FoxPro environment and replace _MSYSMENU with their own menu. T_TOP.MNX, for top form applications, looks identical to T_MAIN.MNX, but has some code changes important to a menu in an MDI frame. T_APPEND.MNX is an “append-style” menu, characteristic of modules, which are applications that add to the current environment rather than controlling it.

    There is one navigation menu template, T_GO.MNX. Its options correspond to the options available on the standard navigation toolbar (_NavToolbar in _FRAMEWK.VCX).

    Note   Because both T_GO.MNX and T_APPEND.MNX are “append-style” menus, they can exist as part of either _MSYSMENU or your top form menu. The Application Builder synchronizes your copy of T_GO.MNX to work with your normal- or topform-type application. However, if you change your application type manually rather than through the Application Builder, or if you want a module-type application that adds to an application in a top form, you may need to tell these menus which environment will hold them.

    You make this change in the General Options dialog box of the Menu Designer (select or clear the Top-Level Form check box). If you prefer, you can adjust the ObjType of the first record in the MNX programmatically, as the Application Builder does. See the UpdateMenu( ) method in HOME( )+ Wizards\APPBLDR.SCX for details.

    Like the document and toolbar classes in _FRAMEWK.VCX, the menu templates are not required. They simply provide good examples, and should give you a good start on learning how to use menus in a framework application.

    In particular, you’ll notice that the menus do not call procedural code directly, only application object methods. This practice ensures that the code is properly scoped, regardless of whether the MPR is built into an app, or whether the .app or .exe holding the MPR is still in scope when the menu option runs.

    Because Visual FoxPro menus are not object-oriented, they can’t easily hold a reference to the application object. To invoke application object methods, the menus use the object’s global public reference. This reference is #DEFINEd as APP_GLOBAL, in an application-specific header file, like this:

    #DEFINE APP_GLOBAL              goApp
    

    Here is an example menu command using the #DEFINEd constant (the Close option on the File menu):

    IIF(APP_GLOBAL.QueryDataSessionUnload( ),
      APP_GLOBAL.ReleaseForm( ),.T.)
    

    Each template menu header #INCLUDEs this header file. You can change the #DEFINE and recompile, and your menus will recognize the new application reference.

    Note   The application object can manage this public reference on its own (you don’t need to declare or release it). It knows which variable name to use by consulting its cReference property, which holds this name as a string. You can either assign the value in the program that instantiates your application object (as shown in the default main program) or you can assign this string to the cReference property of your _Application subclass at design time.

    The template menus are the only part of the framework using this global reference. If you wish, your forms and other objects can use the reference, too, but there are rarely good reasons to do this. Before you opt to use the global reference, think about ways you might pass and store a reference to the application object in your forms instead. If your forms have mediator objects, they have a built-in method to receive this reference any time they need it.

    Metatable Template

    _FRAMEWK.DBF contains records for T_META.DBF/FPT/CDX, the table holding information about documents for your application. Records in this table indicate whether a document should be treated as a “form” or “report”—and you can create other document types on your own.

    The document type designation is used by the framework dialog boxes descending from _DocumentPicker, to determine which documents are displayed to the user at run time. For example, the _ReportPicker dialog box will not display documents of “form” type, but the _FavoritePicker dialog box displays both forms and reports.

    However, document type as specified in the metatable does not dictate file type. A “report” type document might be a PRG, which called a query dialog box and then ran a report based on the results.

    The Application Builder creates and edits metatable records when you use the Builder to add forms and documents to the application. If you manually add a form or document to a framework project, the Project Hook object invokes the Builder to ask you for details about this document and fill out the metatable accordingly. Of course, you can also add records to the metatable manually.

    The Application Builder and the _FRAMEWK.VCX dialog boxes descending from _DocumentPicker rely on the default structure of this metatable. (You’ll find its structure detailed in**Appendix 2.) The dialog boxes derive from this table the information they need to invoke each type of document, including the options you’ve set in the Application Builder for each document. (Appendix 3 gives you a full list of _DocumentPicker subclasses and their assigned roles.)

    Just as you don’t have to use the _DocumentPicker dialog boxes, you don’t have to use the default metatable structure in a framework application. If you like the idea of the table, you could design a different structure and use it with dialog boxes with different logic to call the _Application methods that start forms and reports.

    Note   If you design a metatable with a different structure from the default, the application object can still take care of it for you. On startup, the metatable is validated for availability and appropriate structure. Once the metatable is validated, the application object holds the metatable name and location so this information is available to your application elements later, even though the application object makes no use of the metatable directly.

    Edit your _Application subclass’s ValidateMetatable( ) method to reflect your metatable structure if it differs from the default. No other changes to the standard _Application behavior should be necessary to accommodate your metatable strategy.

    You can also dispense entirely with a metatable in a framework application. No part of the framework, except the _DocumentPicker dialog boxes, expects the metatable to be present.

    For instance, you might have no need for the dialog boxes or data-driven document access in a simple application. In this case, you can eliminate the metatable and invoke all your reports and forms directly from menu options. Simply provide method calls such as APP_GLOBAL.DoForm( ) and APP_GLOBAL.DoReport( ) as menu bar options. Fill out the arguments in these methods directly in the command code for each menu option, according to the requirements of each form and report.

    Additional Text Templates

    _FRAMEWK.DBF holds copies of some additional text files copied for your application’s use.

    T_START.PRG is the template for the program that initializes your application object and shows the splash screen. Its behavior is well documented in comments you’ll find in the application-specific header file, described later. In addition, as just mentioned, it is not necessary. The program that creates your application object does not have to be the main program for your application, nor does it have to do any of the things that T_START.PRG does.

    For example, suppose your application is a “module type,” handling a particular type of chore for a larger application. Because it is a module, it does not issue a READ EVENTS line or disturb your larger application’s environment. It may or may not need to use the framework’s user log on capabilities; you may have set up a user logging system in the outer program. The outer application may be a framework application, or it may not. All these things will help you decide what kind of startup code you need for this application object.

    Let’s look at some sample code you might want to use for an accounting application. This .exe file is not a framework application, but it has a framework module added to it, which performs supervisor-level actions. Only some users are allowed to have access to this module. When your accounting application starts up, it may have an application manager object of its own, which performs its own login procedures. The method that decides whether to instantiate the framework module might look like this:

    IF THIS.UserIsSupervisor( )
       THIS.oSupervisorModule = ;
          NEWOBJECT(THIS.cMyFrameworkModuleSupervisorClass,;
                    THIS.cMySupervisorAppClassLib)
       IF VARTYPE(THIS.oSupervisorModule) = "O"
          * success
       ELSE
          * failure
       ENDIF
    ELSE
       IF VARTYPE(THIS.oSupervisorModule) = "O"
          * previous user was a supervisor
          THIS.oSupervisorModule.Release()
       ENDIF
    ENDIF
    

    This code does not handle the public reference variable, a splash screen, or any of the other items in T_START.PRG.

    You may not need the public reference variable at all because, in this example, your framework application is securely scoped to your larger application manager object. However, if your module application has menus that use the global reference to invoke your application object, you might assign the correct variable name to THIS.oSupervisorModule.cReference just above the first ELSE statement in the preceding sample code (where you see the “* success” comment). This is the strategy you see in T_START.PRG.

    Note   If many different outer applications will use this module, you will prefer to assign the appropriate cReference string in the class, rather than in this method (so you only need to do it once). You can assign this value to cReference either in the Properties window or in code during startup procedures for the application object. Either way, an assign method on the cReference property in _Application does the rest.

    T_META.H is the template name for the application-specific header file, just mentioned in the section on menu templates. Only the menus and T_START.PRG use this header file, so it is up to you whether you use it, and how you use it. In the preceding example, you might not use it at all, or you might use only its APP_GLOBAL define to set the application object’s global reference.

    The framework uses a few more text templates:

    • T_CONFIG.FPWNot surprisingly, provides a template for the config.fpw generated for your application. The template version gives new Visual FoxPro developers some ideas about what the config.fpw is for (it’s mostly comments); you will almost certainly wish to edit this file to meet your own standards.
    • T_LOG.TXTProvides a startup file for the “action log” the Project Hook will write during the life of your application to let you know what changes it has made to your application while you worked with the project.
    • T_HEAD.TXTProvides a standard header that the Application Wizard uses when generating your application-specific copies of framework templates. You might want to revise T_HEAD.TXT to include your own copyright notices, especially after you’ve edited the rest of the templates.

    Specifying Your Own Framework Components

    If you’ve done any development at all, you’ve undoubtedly experienced moments in which you identify something you wish to abstract from the process of developing a single application. You’ve done it too many times, you know how to do it, and now it’s time you figure out the best way to do it—so you never have to do it again.

    In OOP terms, this is the time to develop a superclass to handle this function, so you can reuse its features. In template terms, this is the time to edit the template you copy for each application’s use. In the Visual FoxPro 6.0 application framework’s mixed environment, as you know, we have both types of components.

    We’ll quickly review how these components are managed automatically by the Application Wizard and Builder during your development cycle. Then we’ll turn our attention to how you integrate your own superclasses and edited templates into this system.

    Framework Components During Your Application Lifecycle

    When you choose to create a new framework application, the Application Wizard takes your choices for a location and project name and generates a project file. If you select the Create project directory structure check box, the Application Wizard also creates a directory tree under the project directory. It adds _FRAMEWK.VCX and the required foundation class libraries to this project. It also adds a class library with appropriate application-specific subclasses of _FRAMEWK.VCX.

    The Application Wizard then adds template-generated, application-specific versions of all the non-OOP components the application needs. As you probably realize, the Application Wizard copies these files out of the memo fields in _FRAMEWK.DBF.

    _FRAMEWK.DBF contains two more records we haven’t mentioned yet: T_META.VCX and T_META.VCT. These records hold straight subclasses of the classes in _FRAMEWK.VCX, and they are copied out to disk to provide your application-specific class library.

    Note   T_META.VCX is not a template. It is just a convenient way for the Application Wizard to hold these subclasses, and is not part of your classes’ inheritance tree. Your subclasses descend directly from _FRAMEWK.VCX when the Application Wizard creates them, and thereafter will inherit directly from _FRAMEWK.VCX.

    Once your new framework project exists, the Application Wizard builds it for the first time. It also associates this project with a special Project Hook object, designed to invoke the Application Builder. The Application Wizard shows you the new project and invokes the Application Builder.

    At this point, the Application Builder takes over. The Application Builder provides an interface you can use to customize the framework aspects of any framework-enabled project, throughout the life of the project.

    You can use the Application Builder to customize various cosmetic features of the application object, such as its icon. When you make these choices, the Application Builder stores them in the appropriate properties of your _Application subclass. (In some cases, it also stores them in the matching _Splash subclass properties.)

    In addition, the Application Builder gives you a chance to identify data sources, forms, and reports you’d like to associate with this project. It gives you convenient access to the data, form, and report wizards as you work, in case you want to generate new data structures and documents. For inexperienced developers, the Application Builder provides a visual way to associate data structures directly with forms and reports, by providing options to invoke report and form wizards each time you add a new data source.

    Whether you choose to generate reports and forms using the wizards or to create your own, the Application Builder and its associated Project Hook object help you make decisions about framework-specific use of these documents. (Should a report show up in the Report Picker dialog box, or is it only for internal use? Should a form have a navigation toolbar?) It stores these decisions in your framework metatable.

    As you think about these automated elements of a framework development cycle, you’ll see a clear difference between the changes you can effect if you change the Application Wizard, or generation process, and the changes you can effect by editing the Application Builder and Project Hook. The files provided by the Wizard, in advance of development, represent your standard method of development. The changes made thereafter, through the Builder and Project Hook, represent customization you can do for this single application.

    The balance of this article concentrates on enhancing the Wizard to provide the appropriate framework components when you begin a new application. Once you have established how you want to enhance the startup components, you will think of many ways you can change the Builder and the Project Hook, to take advantage of your components’ special features, during the rest of the development cycle.

    Note   An important change in versions after Visual FoxPro 6.0 makes it easy for you to customize the Application Builder to match your style of framework use. Rather than directly invoking the default appbldr.scx, the default Application Builder in later versions is a PRG.

    The PRG makes some critical evaluations before it displays a Builder interface. For example, it checks to see whether the project has an associated Project Hook object, and whether this Project Hook object specifies a builder in its cBuilder property. See HOME( )+ Wizards\APPBLDR.PRG for details. You will find it easy to adopt this strategy, or to edit appbldr.prg to meet your own needs for displaying the Builder interface of your choice.

    A preview version of appbldr.prg is included with the source for this article. See appbldr.txt for instructions on making this new Application Builder available automatically from the VFP interface, similar to the new wizard components delivered as part of the document.

    A Closer Look at the Standard Application Wizard

    You’ll find the Visual FoxPro 6.0 Application Wizard files in your HOME( )+ Wizards folder. When you invoke the Application Wizard from the Tools menu, it calls appwiz.prg, which in turn invokes the dialog box in Figure 5, provided by appwiz.scx.

    Figure 5. The standard Visual FoxPro 6.0 Application Wizard dialog box provided by appwiz.scx

    When you choose a project name and location, appwiz.prg invokes HOME( )+ Wizards\WZAPP.APP, the Visual FoxPro 5.0 Application Wizard, with some special parameters.

    The older wizard contained in wzapp.app does most of the work of creating your new project files. The Visual FoxPro 5.0 Application Wizard determines that you are in a special automated mode from the object reference it receives as one parameter and does not show its original interface. It evaluates a set of preferences received from this object reference, and proceeds with the generation process.

    The standard implementation has a number of constraints:

    • Your application subclasses descend directly from _FRAMEWK.VCX. This prevents your adding superclass levels with your own enhancements to the framework, and you certainly can’t specify different superclasses when you generate different “styles” of applications.
    • Your copies of the ancestor classes, in _FRAMEWK.VCX and FFC libraries, are presumed to be in the HOME( )+ Wizards and HOME( )+ FFC directories. Because these ancestor classes are built into your framework applications, and therefore require recompilation during a build, you have to give all team members write privileges to these locations or they can’t use the Application Wizard to start new framework applications. In addition, the fixed locations hamper version control; you may wish to retain versions of ancestor classes specific to older framework applications, even when Microsoft delivers new FFC and Wizards folders.
    • Your non-OOP components are always generated out of HOME( )+ Wizards\_FRAMEWK.DBF. The templates are not easily accessible for editing. The assumed location of _FRAMEWK.DBF prevents you from using different customized template versions for different types of apps, and also presents the same location problems (write privileges and versioning) that affect your use of the framework class libraries. As with your application subclasses, you can’t designate different templates when you generate different types of applications.
    • You have no opportunity to assign a custom Project Hook to the project.

    To allow you to design and deploy customized framework components, a revised Application Wizard should, at minimum, address these points.

    You can make the required changes without major adjustment of the current Application Wizard code, but some additional architectural work provides more room for other enhancements later.

    A New Application Wizard

    If you DO NEWAPPWIZ.PRG, provided in the source code for this article, you will get a dialog box almost identical to Figure 5, and functionally equivalent to the original dialog box. The only difference you’ll notice is a request, on startup, asking you if you wish to register this wizard in your HOME( )+ Wizards\WIZARD.DBF table for future use (see Figure 6).

    Figure 6. The Newappwiz.prg wizard classes can be registered to HOME( )+ Wizards\WIZARD.DBF so you can choose them from the Tools Wizards menu later.

    Though your newly instantiated wizard class calls the old Visual FoxPro 5.0 Wizard code just as the original one did, its internal construction allows completely new generation code to replace this approach in a future version.

    You can call newappwiz.prg with a great deal of information packed into its second parameter, to indicate what wizard class should instantiate and what this wizard class should do once instantiated.

    Why the second parameter, rather than the first? Newappwiz.prg, like appwiz.prg, is designed with the standard wizard.app in mind. wizard.app, the application invoked by the Tools Wizards menu option for all wizard types, uses its registration table, HOME( )+ Wizards\WIZARD.DBF to find the appropriate wizard program to run. Wizard.app passes other information in its first parameter to the wizard program (in this case, newappwiz.prg). Wizard.app passes the contents of the Parms field of wizard.dbf, as the second parameter.

    If you choose Yes in the dialog box in Figure 6, the NewAppWizBaseBehavior class becomes a new choice in the registration table, and fills out its options in the Parms field. Additional NewAppWizBaseBehavior subclasses will do the same thing, registering their own subclasses as separate entries. Once a class is registered in wizard.dbf, you don’t have to call newappwiz.prg directly again.

    If you’ve chosen Yes in the dialog box in Figure 6 and also choose to register the wizard subclass we investigate in the next section, when you next choose the Application Wizard from the Tools menu, you’ll get a choice, as you can see in Figure 7.

    Figure 7. Select your Application Wizard du jour from the Tools Wizards option—once you have more than a single Application Wizard listed in your HOME( )+ Wizards\WIZARD.DBF table.

    An Extended Subclass of the New Wizard: AppWizReinherit

    With an enhanced architecture in place, we can address the issues of component-generation we’ve raised.

    Run newappwiz.prg again, this time with a second parameter indicating a different wizard subclass to instantiate:

      
    

    You should get another message box, similar to Figure 6, asking you if you want to register this subclass in the wizard.dbf table. When you’ve dismissed the message box, you see the dialog box in Figure 8.

    Figure 8. Re-inheritance Application Wizard, page 1

    The first page of this dialog box contains exactly the same options as the standard Application Wizard.

    Note   You’ll find all the visual classes used in the new wizards in newappwiz.vcx, as part of the source code for this article. The container you see on this page of the AppWizFormReinherit class is the same container class used in AppWizFormStandard. You can read more about these dialog box classes in Appendix 4.

    Each subsequent page of the dialog box addresses one of our concerns with the way the original Application Wizard delivers components, and includes some information about how it works. (Figure 9 shows you pages 2 and 3.) Each option defaults to the same behavior you’d get from the original Application Wizard—you don’t need to fill out information on all pages.

    Figure 9. Pages 2 and 3 of the Re-inherit App Wizard provide a layer of superclasses and the locations of your FFC and _FRAMEWK.VCX libraries for this framework application.

    If you change the parent VCX as suggested on the second page of the dialog box, you can have one or more layers of superclasses between your application’s subclasses of _FRAMEWK.VCX. You’ll create team-specific enhancements in these layers.

    Note   This version of the Application Wizard will create the initial classes for you, as subclasses of the components in _FRAMEWK.VCX, if you specify a VCX name that does not exist. Later, you can create more layers of subclasses from the one the Application Wizard derived from _FRAMEWK.VCX, and designate your subclass layer in this dialog box as appropriate. The VCX you designate on the second page of this dialog box should always conform to the following rules:

    • Be the immediate superclasses (parent classes) of the application-specific VCX for this application.–and–
    • Include all the required subclasses of _FRAMEWK.VCX, with the same names as the _FRAMEWK ancestor classes.

    You may want several different branches of your team-specific class levels, to match different types of framework applications you commonly create. For example, you could have one superclass set with your team’s options for a framework module and another one with your team’s topform custom attributes (including the class and classlibrary for your subclass of _topform to provide the correct frame).

    Note   These branches, or types, are not restricted to the “styles” or options you see represented in the Application Builder. They are just part of the normal process of subclassing and enhancing a class tree.

    For example, you may decide to create Active Documents as framework applications. To do so, you’ll need an _Application subclass that is aware of its hosted environment, and makes certain interface decisions accordingly. You’ll also need an ActiveDoc subclass that is aware of the framework’s capabilities and calls application object methods in response to browser-triggered events, just as the menu templates invoke framework behavior.

    Now that you can insert class levels between _FRAMEWK.VCX and your application-specific level, you can make the implementation of these features standard across applications.

    If you change the locations of the FFC and _FRAMEWK.VCX libraries on the “Ancestors” page, the Application Wizard will place appropriate copies of the required class libraries in your specified locations if they don’t exist. The Application Wizard also ensures that your copy of _FRAMEWK.VCX inherits from the proper version of FFC, and that your parent classes point to the proper version of _FRAMEWK.VCX.

    Note   As mentioned in the section “FoxPro Foundation Generic Classes,” your FFC location can include your own version of _BASE.VCX. Your _BASE.VCX does not have to have the same code or custom properties as the original _BASE.VCX, but like your parent classes, your _BASE must include classes descended from the same Visual FoxPro internal classes, with the same names, as the classes in the original _BASE.

    Other FFC libraries, not used in the framework and not described in this article, will not necessarily work with your own _BASE.VCX. For example, if your application uses _GENHTML, the _HTML.VCX library relies on code in the HOME( ) + FFC\_BASE.VCX library. If you use other FFC libraries in your framework application, you may have two _BASE.VCXs included in your project—this is perfectly normal.

    The Application Wizard then focuses on your template files on the next page of the dialog box. If you set a location for your template files, the Application Wizard will create fresh copies of these files (by copying them from the original _FRAMEWK.DBF), ready for you to edit.

    In each case, if the files are already in the locations you supply, the Application Wizard will use the ones you have.

    The last page of the dialog box allows you to pick a Project Hook. The original AppHook class in HOME( ) + Wizards\APPHOOK.VCX is the required ancestor class for a Project Hook designed to work with this application framework, but you can add a lot of team-specific features to your Project Hook subclass. The Application Wizard attempts to verify that the class you specify on this page descends from the appropriate AppHook class.

    When you generate your application, the Application Wizard will create a new set of straight subclasses from your parent VCX (or _FRAMEWK.VCX, if you haven’t changed the default on the “Parents” page). These subclasses become the new T_META.VCX/VCT records in _FRAMEWK.DBF. The Wizard appends new contents for all the other template records of _FRAMEWK.DBF from the template folder, if you’ve named one.

    Note   The first time you and the Application Wizard perform these tasks, it won’t make much difference to the final results. Once the Wizard gives you editable superclass layers and your own copies of the templates, however, you have all the architecture necessary to customize the framework for subsequent uses of the Application Wizard.

    Having replaced _FRAMEWK.DBF records, the Application Wizard proceeds to create your new application much as before, inserting information about your designated Project Hook class at the appropriate time.

    All the “enhanced” Wizard actions are tuned to respect the current setting of the lDelegateToOriginalAppWizard switch, which indicates whether the Visual FoxPro 5.0 Application Wizard code is running or if new code is creating the project. For example, because the original code only looks in the HOME( )+ Wizards folder for _FRAMEWK.DBF, if you have indicated a different place for your _FRAMEWK.DBF (on the “Templates” page) this table will be copied to HOME( )+Wizards before wzapp.app runs. (The first time this occurs, the new Wizard copies your original _FRAMEWK.DBF to a backup file in the HOME( ) + Wizards folder.) Presumably, newer code simply uses your templates table wherever you’ve placed it.

    When you use this Wizard to generate a framework application it saves information about your preferred parent classes, as well as the locations of your FFC and _FRAMEWK libraries and template files, to special _FRAMEWK.DBF records. You won’t need to enter this information, unless you wish to change it. This release of the Application Wizard doesn’t save information about the custom Project Hook subclass you may have specified. However, the next section will show you how to put this information into the Parms of wizard.dbf for default use.

    Note   Because the Application Wizard reads its stored information out of _FRAMEWK.DBF, it can’t get the location of _FRAMEWK.DBF from a stored record! However, you can put this information into the Parms field of wizard.dbf, as described in the next section, so all your developers use the proper version of _FRAMEWK.DBF without having to look for it.

    You may even decide to use a version of this Wizard class, or of its associated dialog box, that only allows some developers to change the “advanced” pages. Other team members can fill out standard information on Page 1, but they’ll still get your improved versions of all the framework components.

    Registering Additional Wizard Subclasses and Customized Records

    The new Application Wizard provides the opportunity to register each subclass of its superclass separately in the wizard.dbf table. The wizard stores its class name and location in the Parms field of its own wizard.dbf record.

    However, you can add more information in the Parms field. You can even store multiple entries in the wizard.dbf for a single subclass, with differently tuned Parms values. The Application Wizard, once instantiated, uses this additional information.

    Here’s the full list of nine options you can pass in the second parameter, or place in the Parms field, for use by NewAppWizBaseBehavior and its subclasses. All #DEFINEs mentioned in this list are in the newappwiz.h header file associated with newappwiz.prg:

    These three options instantiate the Wizard:

    • Wizard classMust descend from #DEFINEd APPWIZSUPERCLASS, defaults to NEWAPPWIZSUPERCLASS.
    • Wizard classlibLibrary containing wizard class, defaults to NEWAPPWIZ.PRG.
    • .App or .exe file nameOptional file, containing the wizard class library.

    These six options are used by the Application Wizard after it instantiates:

    • Wizard form classMust descend from #DEFINEd APPWIZFORMSUPERCLASS, defaults to #DEFINEd NEWAPPWIZFORMSTANDARD.
    • Wizard form classlibLibrary containing the form class, defaults to NEWAPPWIZ.VCX.
    • .App or .exe file nameOptional file containing the wizard form class library.
    • Project Hook classThe Project Hook class you want to associate with this project, if you don’t want to use the default Project Hook class associated with framework-enabled projects. This class should descend from the AppHook class in HOME( )+ “Wizards\APPHOOK.VXC”, so it includes the default functionality, but can include enhancements required by your team.
    • Project Hook classlibThe class library containing the Project Hook class you choose to associate with this project.
    • Template DBFHolding application components, defaults to HOME( )+ Wizards\_FRAMEWK.DBF (#DEFINED as APPWIZTEMPLATETABLE).

    Store these values delimited by commas or carriage returns in the Parms field of wizard.dbf. Similarly, if you call newappwiz.prg directly, you can pass all this information as the program’s second parameter, as a single string delimited with commas or carriage returns.

    After you’ve registered the AppWizReinherit class, the Parms field for this class’ record in wizard.dbf contains the following information:

    APPWIZREINHERIT,<fullpath>\newappwiz.fxp,,AppWizFormReinherit, <fullpath>\NEWAPPWIZ.VCX,,APPHOOK, <fullpath of HOME()+ "Wizards"> \APPHOOK.VCX, <fullpath of HOME()+ "Wizards"> _framewk.DBF
    

    You could run the NEWAPPWIZ program, passing the same string as its second parameter, to get AppWizReinherit‘s default behavior.

    Using our ActiveDoc example just shown, you could create a wizard.dbf entry that invokes the same Wizard class but defaults to a different parent VCX and different menu templates than the rest of your framework applications.

    To accomplish this, you’d edit the information in the ninth value for this row of the wizard.dbf table, which indicates Template DBF, by editing the Parms field.

    Your new row in the table contains the same string in the Parms field, except for the section following the last comma, which points to a new template table. Your special ActiveDoc copy of _FRAMEWK.DBF holds your special Active Document menu templates and superclass information.

    Next, suppose you decide that your ActiveDocument framework applications need a special Project Hook subclass, not just special superclasses and menu templates. You could specify this hook automatically, in the seventh and eighth sections of the Parms field. You might even subclass the AppWizFormReinherit dialog box, to disable the last page of this dialog box for ActiveDocument-type applications, by changing the fourth and fifth sections of the Parms field. (This way, your team members would always use the right Project Hook class when generating this type of framework application.)

    If you made all these changes, this new entry in the wizard.dbf table might have a Parms field that looked like this:

    APPWIZREINHERIT,<fullpath>\newappwiz.fxp,,MyAppWizActiveDocumentDialog, <fullpath>\MyAppWizDialogs.VCX,,MyActiveDocumentAppHookClass, <fullpath> \MyHooks.VCX, <fullpath>\MyTemplates.DBF

    You would also edit the Name field in wizard.dbf for this entry, perhaps to something like “Active Document Framework Application,” to distinguish this entry from your standard values for the AppWizReinherit class.

    When one of your team members accessed the Tools Wizards option from the system menu, “Active Document Framework Application” would now appear on the list of available Wizards, as part of the list you saw in Figure 7. The developer could automatically create the right type of framework application, without making any special choices.

    A Few Parting Thoughts about Team Practices

    You’ll notice a check box in the Reinheritance Wizard‘s dialog box, indicating that you can omit message boxes and generate your new application with no warning dialog boxes or user interaction. Although this is a helpful option once you’ve used this Wizard a few times, please be sure to read all the message boxes, and the information in the edit boxes on the various pages of this dialog box, at least once.

    Any developer’s tool, especially one that edits visual class libraries and other metafiles as extensively as this one does, can potentially cause problems if the system is low on resources. The Help text available within this Wizard attempts to point out its potential trouble spots, so you can close other applications as needed, and have a good idea of what to expect at each step. Other caveats, such as incompletely validated options in this preliminary version, are indicated in the Help text as well.

    You also see a More Info button, which provides an overview of the issues this class is meant to address, and how you can expect it to behave (see Figure 10).

    Figure 10. Wizard documentation under the More Info button

    Beyond its stated purpose to enhance the Application Wizard, AppWizReinherit and its dialog box class try to give you a good model for tool documentation, both at design and run time. The dialog box’s NewAppWiz_Documentation( )GetUserInfo( ), and DisplayDocumentation( ) methods should give you several ideas for implementation of run-time documentation. Newappwiz.prg has a demonstration procedure, BuilderGetDocumentation( ), which shows you how you can apply these ideas to design time documentation for Builders as well. A final demonstration procedure in newappwiz.prg, ReadDocs( ), shows you another aspect of this process.

    Each documentation idea demonstrated here is a variation on a theme: Text is held (using various methods) within the VCX, so it travels with the VCX and will not get lost no matter how widely you distribute the library.

    Whether you use these particular implementations is not important; in many cases you’ll be just as well off if you create a text file with documentation and use Visual FoxPro’s FileToString( ) method to read this information for display by the tool whenever necessary.

    No matter how you decide to implement it, documentation that helps your team better understand the intended use, extension possibilities, and limitations of the tools you build is critical to their adoption and successful use.

    A framework is, in itself, a kind of abstraction, a level above daily activities. Enhancements to a framework represent yet another level of abstraction. Your team will benefit from all the extra attention you can give to communicating your goals for this process.

    With any framework, you can efficiently prototype applications and build complete lightweight applications. With a framework set up the way your team operates, you can accomplish these goals without sacrificing quality, depth, or your normal habits of development. With a framework set to deliver your standard components and practices automatically, even new developers can make meaningful, rewarding contributions to your team effort.

    Appendix 1: The User Option System

    The framework employs a user-registration system based on a user table that is created by the application object if not found at run time. The application object uses the cUserTableName property to set the name and location of this table. If no path is supplied in this property, the location will be set by the cAppFolder property.

    Note    By default, the application object sets cAppFolder to the location of the APP or EXE that instantiated it. If, for some reason, the application object was instantiated outside a compiled APP or EXE container, cAppFolder contains the location of the application object’s VCX.

    If necessary, the application object creates this table in the appropriate location, using the following code (excerpted from the CreateUserTable( ) method):

    lcIDField = THIS.cUserTableIDField
    lcLevelField = THIS.cUserTableLevelField
    * names of two generic-requirement fields,
    * User ID and level, are specified by
    * _Application properties in case you
    * wish to match them to some existing system
    CREATE TABLE   (tcTable) ;
       ((lcIDField) C(60), ;
       (lcLevelField) I, ;
       UserPass  M NOCPTRANS, ;
       UserOpts  M NOCPTRANS, ;
       UserFave  M NOCPTRANS, ;
       UserMacro M NOCPTRANS, ;
       UserNotes M )
    INDEX ON PADR(ALLTR(&lcIDField.),60) TAG ID
    * create a case-sensitive, exact word match
    INDEX ON PADR(UPPER(ALLTR(&lcIDField.)),60) TAG ID_Upper
    * create a case-insensitive, exact word match
    INDEX ON DELETED( ) TAG IfDeleted
    

    If you don’t opt to have users log in and identify themselves in this application, this table is still created. In this case it supplies a default record, representing “all users,” so user macros, favorites, and options can still be stored in this table on an application-wide basis.

    Note   Because of their “global” nature in Visual FoxPro, user macro saving and setting features are only available to framework applications that issue READ EVENTS. Module applications are not allowed to edit the macro set.

    When a user logs in, his password is evaluated using the user table’s UserPass field. A SetUserPermissions( ) method, abstract in the base, is called at this time so the user’s level can be checked in order to make appropriate changes to the application and menu options as well.

    If the login is successful (or when the application starts up assuming no user login for this application), user name and level are stored in the cCurrentUser and iCurrentUserLevel properties.

    User macros, favorites, and options are set from the user’s record in the user table. The _Application code handling macros rely on standard Visual FoxPro abilities to SAVE and RESTORE macros to and from the UserMacro memo field. The favorites system uses an easy-to-read ASCII format in the UserFave memofield. However the options system and the UserOptions field deserve more explanation.

    The user table stores option information in its UserOptions memo field, by SAVEing the contents of a local array. This local array is RESTOREd and copied into a member array, aCurrentUserOpts, to establish user options when the current user is set.

    The array format is fixed, and yet extremely flexible in the types of user options that can be stored. The allowable options include SETs and member properties, and the options should be specified as being “global” to the application or private to a datasession. The array is laid out, to specify these attributes of each option, in four columns, as follows.Expand table

    User Option Array Column 1Column 2Column 3Column 4
    Item nameFor a SET command, the item you’re setting, same as what you’d pass to the SET( ) function.
    For an object, the property you wish to set. Can be the Member.Property you wish to set.
    Value for this itemProperty (.F.)
    or SET (.T.) ?
    Session (.F.)
    or Global (.T.) ?

    Each time a user logs in, the application method ApplyGlobalUserOptions( ) applies SET options and application object property values for all array rows with .T. in the fourth column. The mediator object has the responsibility to call the application method ApplyUserOptionsForSession( ), on your instructions, passing a reference to its parent form. This method applies SET options and form property values for all array rows with .F. in the fourth column.

    The _Options dialog box supplied in _FRAMEWK.VCX gives you examples of all the combinations that can be created for a user option using this array, although its contents are merely examples. It shows you how the user options stored in an array can be expressed as a user interface, giving the user a chance to make changes. It also shows how results of a user-option-setting can be “translated” back into the user options array for use during this login, or saved as defaults to the user preference table.

    You will note that, when the user options to apply changes to the current settings, the Options dialog box reinvokes ApplyGlobalUserOptions( ) and then iterates through the available forms, giving their mediators a chance to reapply session settings if they’re set to do so.

    In many cases, a “global” setting can transferred to forms as well. For example, the _ErrorLogViewer dialog box has a mediator that checks the application’s cTextDisplayFont setting. This is a global user option, because it provides a chance for the user to specify a text font across all the UI of an application. The mediator transfers the value of the cTextDisplayFont to a property of the same name belonging to its parent dialog box. An assign method on this property then applies the fontname value to all members of the dialog box that should reflect the setting.

    Appendix 2: The Default Metatable Structure

    This table shows you the default structure of the framework’s metatable. Appendix 3 shows you how the default _FRAMEWK.VCX dialog boxes use this information.Expand table

    FieldNameTypeUse
    Doc_typeCThis field contains a character to distinguish between document types. Currently, “F” is used for “forms” and “R” is used for “reports.” But this designation just determines how the document type is presented in the interface, not necessarily what type of Visual FoxPro source code file underlies the document. See Alt_Exec and Doc_wrap fields, below.More document types may be added. The framework already contains one extra type, “A,” specifically reserved for you to add application information. The framework will not use “A”-type metatable records in any way, so the reservation of this type simply allows you to use metatable records, or perhaps one metatable header record, as a convenient place for system storage. In most cases, you would want to transfer the contents of such a record to application properties on startup.
    Doc_descrCThe “caption” or long description you want to show up in document picker lists.
    Doc_execMThe name of the file to be run, usually an .scx or .frx file. In the case of a class to be instantiated, this is the .vcx file name.For Form-type documents, the file extension is assumed to be .scx unless this entry is marked “Doc_wrap” (see below) or the Doc_class field is filled out, in which case the extension is assumed to be .vcx.For Report-type documents, the file extension will default to .frx unless this entry is marked “Doc_wrap”. If no .frx file exists by that name, the application object looks for an .lbx file.In all cases, you may also fill out the file extension explicitly.In all cases, if you Include the file to be run in the project, you need not use paths in this field. If you wish to Exclude the file from the project, you may use path information. Assuming your applications install their subsidiary Excluded files to the appropriately located folder, relative pathing should work in the metatable, and is probably the best policy in this case!
    Doc_classMThe class to be instanced, where the Doc_exec is a .vcx file
    Doc_newLMark this .T. for a Form-type document you wish to show up in the FileNew list. When the application object instantiates a form from the FileNew list, it sets its own lAddingNewDocument property to .T. This practice gives the form a chance to choose between loading an existing document or a blank document during the form’s initialization procedures.In many cases, the form delegates this process to its mediator object. The mediator object saves this information for later use.If you do not use a mediator, you may wish to save this information to a form property; you can’t expect the application object’s lAddingNewDocument to reflect the status of any particular form except during the initialization process of that form.For a Report-type document, this field denotes an editable report (new report contents, or even a new report from a template). This capability isn’t currently implemented.
    Doc_openLMark this .T. for a Form-type document you wish to show up in the FileOpen list.For a Report-type document, this field denotes a runnable report or label and will place the item in the report picker list.
    Doc_singleLMark this .T. for a Form-type document that is modeless but should only have one instance. The application object will bring it forward, rather than create a second instance, if the user chooses it a second time.
    Doc_noshowLMark this .T. for a Form-type document that you wish to .Show( ) yourself after additional manipulation, rather than allowing the DoForm( ) method to perform the .Show( ).Note   You will have to manipulate the application’s forms collection or the current _SCREEN.Forms( ) contents to get a reference to this form, so you can manipulate the form and then .Show it when you are ready. If you need this reference immediately, the best place to get it is probably the application object’s aForms[] member array. At this moment, the application object’s last-instantiated form is the one for which you want the reference, and the application object’s nFormCount property has just been refreshed. Therefore, .aForms[THIS.nFormCount] gives you the reference you need when you’re in an application object method (in other code, replace THIS with a reference to the application object). You can see an example of this usage in the _Application‘s DoFormNoShow( ) method.You can create Doc_Wrap programs as described in the entry for the next field. Your wrapper program can take advantage of the DoFormNoShow( ) method, receive its return value (a reference to the form or formset object), and proceed to do whatever you want with it.
    Doc_wrapLIf this field is marked .T. indicating a “wrapped” document, the application’s DoProgram( ) method will run instead of its DoReport( )/DoLabel( ) or DoForm( ) method.If you omit the file extension, the DoProgram( ) method uses the standard Visual FoxPro extension hierarchy to figure out what file you wish to run (“.exe .app .fxp .prg”).
    Doc_goLIf this field is marked .T. and the document is “Form”-type, the form uses the framework’s standard Go context menu for navigation. The menu name is configurable using the application object’s cGoMenuFile property. This field is not used for report-type documents.
    Doc_navLIf this field is marked .T. and the document is “Form”-type, the form uses the framework’s standard navigation toolbar for navigation. The class is configurable using the application object’s cNavToolbarClass and cNavToolbarClassLib properties. This field is not used for report-type documents.
    Alt_execMIf this field is filled out, it takes precedence over the Doc_exec field just described. When the user makes a document choice, the _DocumentPicker’s ExecDocument( ) method converts the contents of this field into a string and runs that string as a macro.Your Alt_exec statement can be anything you choose, and it can use attributes of the metatable, including the Properties field (below) however you want. For example, you can choose to have the metatable editable (on disk) rather than included in the APP/EXE, and you can place information in the Properties field dynamically at run time. Your document would then be able to be “aware” of this information by examining the current contents of the Properties field.
    PropertiesMThis memo field is not used by the framework in any way. It’s for developer use, primarily in conjunction with the Alt_exec field.
    User_notesMThis memo field is not used by the framework in any way. It can be used for notes that would be displayed as Help text for a particular form or report, and so on.

    Appendix 3: Default Document- Management Elements of the Framework

    The framework accesses metatable information through the _DocumentPicker classes. _DocumentPicker is an abstract standard dialog box class, which contains a picklist and a couple of buttons. The working _DocumentPicker subclasses each have their own way of using the information in the metatable to perform two tasks:

    • Show the documents in the picklist.
    • Run the appropriate action when the user picks a document.

    Each subclass stores the relevant metatable fields into an array, which serves as the data source for the list box in the dialog box. The same array holds the metatable information that will eventually act on the user’s choice.

    The _DocumentPicker superclass has an abstract FillDocumentArray( ) method, designed to perform the first service during the dialog box Init( ), and another abstract method called ExecDocument( ), which is triggered whenever/however the user makes a selection from the document list.

    The _DocumentPicker class receives a parameter from the application object. Each subclass of _DocumentPicker uses the parameter to determine which of two states it is supposed to be in when it displays its document list and acts on the user’s choice of a document from the list. The _DocumentPicker superclass simply makes note of this logical value, leaving it to the subclasses to interpret it.

    The various _DocumentPicker’s FillDocumentArray( ) methods concentrate on different document types, and fill the array with the appropriate information for that type. Their ExecDocument( ) methods call different application object methods depending on their document type and the dialog box’s current state, sending information from the metatable from the array to method arguments as needed.

    The first two columns in the table below show you the names of these working classes and the document types that will appear in their lists, courtesy of their FillDocumentArray( ) method. The other columns show the application methods that call them, and the meaning assigned to their two states when ExecDocument( ) is triggered. Each application method listed here takes a logical parameter (defaulting to .F., State 1) to indicate for what purpose the class presents its document list.Expand table

    _DocumentPicker
    Subclass
    _Document typesAssociated _Application methodState 1
    action
    State 2
    action
    _NewOpenformsDoNewOpen( )EditAdd
    _ReportPickerreports and labelsDoReportPicker( )Run report/labelModify/Add not implemented
    in _Application superclass.
    _FavoritePickerdocuments and files of any typeDoStartupForm( )Run document/filePut document / file on Favorites menu for quick access.

    Appendix 4: Using the NEWAPPWIZ Visual Classes

    AppWizFormReinherit, the dialog box called by AppWizReinherit, and AppWizFormStandard, the default dialog box with the same interface as the original wizard, both descend from the same superclass, AppWizFormBaseBehavior (see Figure 11).

    Figure 11. Newappwiz.vcx in the Class Browser

    AppWizFormBaseBehavior is the required superclass for any dialog box provided as the UI of a NewAppWizBaseBehavior or its descendents. The Application Wizard superclass validates your dialog box class when it instantiates the dialog box as descending from this superclass dialog box.

    NewAppWizBaseBehavior contains only the very simple required behavior, no visible controls. It has three custom properties to represent required wizard information (project name, location, and whether or not the Wizard should generate project directory structure). It receives this information from an object reference the Wizard passes. It has a Finish( ) method which passes this information back to the Application Wizard.

    In your subclass of AppWizFormBaseBehavior, you simply databind the interface controls of your choice to these three custom properties. You create other controls and custom properties to represent your enhanced options. Your dialog box calls the Finish( ) method when you’re ready to generate. (Both AppWizFormReinherit and AppWizFormStandard use the OKButton class you see in Figure 11, which contains the call to its parent form’s Finish( ) method.)

    You can augment Finish( ) to pass more options from the dialog box back to your Wizard subclass as necessary.

    You’ll find more information in the NewAppWiz_Documentation method of the superclass. The default AppWizFormStandard subclass shows you a simple example of how to make it work

    Microsoft Transaction Server for Visual FoxPro Developers 

    • Article
    • 06/30/2006

    In this article

    1. Introduction
    2. What Is Microsoft Transaction Server?
    3. Why Is MTS Important for Visual FoxPro Developers?
    4. Creating Your First MTS Server

    Show 12 more

    Randy Brown
    Microsoft Corporation

    October 1998

    Summary: Discusses using Microsoft® Visual FoxPro® version 6.0 with MTS to develop three-tier applications. (36 printed pages).

    Contents

    Introduction What Is Microsoft Transaction Server? Why Is MTS Important for Visual FoxPro Developers? Creating Your First MTS Server Setting Up Security The Basic Features of MTS Just-In-Time Activation Transactions Programming Models Deployment Remote Deployment and Administration Security Shared Property Manager MTS Support for Internet Information Server Automating MTS Administration Tips and TricksExpand table

    Click to copy the sample files associated with this technical article.

    Introduction

    No doubt you’ve heard all about Microsoft Transaction Server (MTS) and how it will make your life easier to develop three-tier applications. This article offers a good primer on using Visual FoxPro 6.0 with MTS. We cover the basics of using MTS and then extend it to using with Visual FoxPro Component Object Model (COM) Components. This document is intended to be used with the Microsoft PowerPoint® slide show included with the Visual FoxPro sample files.

    MTS is a great environment for working with three-tier development. However, one should realize that it is simply not just a matter of dropping your Visual FoxPro servers into an MTS package and expecting miracles. While it is true that much of the work is already done for you, nothing comes for free. Performance and scalability are critical factors that require well-thought-out designs. Good MTS applications are designed with MTS in mind from the start!

    This article assumes that you have MTS already installed. It is available in the Microsoft Windows NT® version 4.0 Option Pack, available from the Microsoft Web site at https://www.microsoft.com/windows/downloads/default.asp.

    In addition, you should familiarize yourself with the basics of MTS. Information is available in the Help files provided with MTS when you install the Windows NT 4.0 Option Pack.

    What Is Microsoft Transaction Server?

    MTS is a component-based transaction processing system for building, deploying, and administering robust Internet and intranet server applications. In addition, MTS allows you to deploy and administer your MTS server applications with a rich graphical tool (MTS Explorer). MTS provides the following features:

    • The MTS run-time environment.
    • The MTS Explorer, a graphical user interface for deploying and managing application components.
    • Application programming interfaces (APIs) and resource dispensers for making applications scalable and robust. Resource dispensers are services that manage nondurable shared state on behalf of the application components within a process.

    The MTS programming model provides a framework for developing components that encapsulate business logic. The MTS run-time environment is a middle-tier platform for running these components. You can use the MTS Explorer to register and manage components executing in the MTS run-time environment.

    The three-tier programming model provides an opportunity for developers and administrators to move beyond the constraints of two-tier client/server applications. You have more flexibility for deploying and managing three-tier applications because:

    • The three-tier model emphasizes a logical architecture for applications, rather than a physical one. Any service may invoke any other service and may reside anywhere.
    • These applications are distributed, which means you can run the right components in the right places, benefiting users and optimizing use of network and computer resources.

    Why Is MTS Important for Visual FoxPro Developers?

    Microsoft is investing a great amount of resources in three-tier development because of a multitude of benefits derived from this architecture. As shown in Figure, Tier 2, the so-called “middle tier,” represents the layer where much of the Application Services/Business Logic is stored. Visual FoxPro COM components are ideally suited for this architecture and will play a key role in this tier for many years to come. This middle tier is also where MTS lives.

    Figure 1. Web-enabled three-tier architecture

    Future applications will consist of Web based front ends using a combination of HTML/XML. While Visual FoxPro data can be used as your database of choice for Tier 3, your applications should be written to communicate to a generic back end. This should be a test of your application’s extensibility. “How easy is it to swap back ends—let’s say Visual FoxPro database to Microsoft SQL Server™?” There are several options, including Open Database Connectivity (ODBC) and ActiveX® Data Objects (ADO), which provide generic interfaces to data. Remember, your application should be written knowing that any or all of the three tiers can be swapped out independent of each other.

    So why is MTS great for Visual FoxPro developers? It should be clear now that the ability to swap out tier components at will makes for a great reusability story. Microsoft has a concept called total cost of ownership (TCO), which means the collective cost of providing and maintaining corporate Information Services. The three-tier model goes a long way toward reducing TCO.

    Updating the Presentation layer is very easy because it merely involves one having to refresh his/her browser. Windows front ends consisting of Visual FoxPro/Visual Basic® forms offer more flexibility in user interface, but updating 150 sites can be time-consuming. In addition, one should expect improved UI options available in HTML.

    The back-end data is usually the tier that changes the least. Having data managed centrally also reduces costs. Remember that data can be distributed and still managed from one location. It doesn’t have to be stored centrally to be managed centrally.

    Finally, we get to Visual FoxPro’s role in the middle tier. Middle-tier components tend to change most often because they represent business rules, which change as the needs of the business changes. Traditional client/server and monolithic applications would often combine the first two layers into one. This was very inefficient because of the distribution costs in updating sites. Today, with browsers, much of this distribution problem goes away. However, business rules are often complex and can contain sensitive/secure information, so it’s not always wise to send these rules back with the HTML to a Web browser. In addition, it can impede performance.

    So, we end up with a dilemma. We want to limit the amount of information sent back to the client, but we also want to minimize the number of back and forth trips between client and server, because bandwidth is also a big consideration (more so with the Internet versus an intranet). The best solution is one involving a so-called “Smart Client.” Traditionally, the Web browser is thought of as an unintelligent client whose job is to merely display an entire static Web page. Each time something on the page changes, we need to refresh the entire Web page. With dynamic HTML (DHTML), you no longer need to do this. Only parts of the Web page affected need updating. In addition, some of the business rules can (and should) reside on the client, thus reducing round trips to the server. For example, you may want to have your client have simple data validation rules, such as one to ensure a value is not negative. It would be more efficient to perform these sorts of checks on the client. Most of the rules, especially sensitive ones, will exist on the server away from client eyes. It is also important to realize, however, that client-side business rules are subject to change almost as frequently as those on the server. The ATSWeb application (available at https://msdn.microsoft.com/vfoxpro/ats_alpha/default.htm) offers a great example of business rules being applied to both client and server.

    MTS provides an environment for hosting your Visual FoxPro middle-tier objects because it handles many of the common tasks, including resource and thread management, security, deployment, application robustness, and transactions. This leaves you, the developer, with only the responsibility of providing business logic specific to your application.

    Creating Your First MTS Server

    Let’s jump right in and create an MTS server, because it’s very simple if you already know how to create a Visual FoxPro COM component.

    Creating a Visual FoxPro COM Component

    1. Create a new project file called test1.pjx
    2. Create a new program file (PRG) called test1.prg
    3. Add the following code to this program:DEFINE CLASS server1 AS custom OLEPUBLIC PROCEDURE hello RETURN “Hello World” ENDPROC ENDDEFINE
    4. Build the server as a DLL (for example, test1.dll). All MTS components must be created as in-process DLL servers. You now have a server that can be tested directly in Visual FoxPro:x=create(“test1.server1”) ? x.hello()

    Adding the Visual FoxPro COM Component to an MTS Package

    A package is a collection of components that run in the same process. Packages define the boundaries for a server process running on a server computer. For example, if you group a Sales component and a Purchasing component in two different packages, these two components will run in separate processes with process isolation. Therefore, if one of the server processes terminates unexpectedly (for instance, because of an application fatal error), the other package can continue to execute in its separate process.

    This section describes the task of installing the Visual FoxPro server into the MTS environment.

    1. Launch MTS Explorer.
    2. In the left pane, navigate to the Computers item and select My Computer. You are now looking at the MTS environment.
    3. Click the Packages Installed node to view all default packages installed by MTS. You can think of a Package as a set of components that perform related application functions. For example, an Inventory package might consist of two DLLs, each performing a task related to checking product inventory for a customer order.
    4. Let’s create a new package now. Select the Action -> New -> Package menu item.
    5. Click the Create an empty package button. Type in a name for your new package (for example, Foxtest1).
    6. Click the Next button, and then click the Finish button. You should now see your new package added under the Packages Installed node.
    7. Click your new package node (for example, Foxtest1). You should now see two items. The Components folder is where you add new components such as the Visual FoxPro component you just created. The Roles folder is where you set up groups of users (roles) who all share similar access privileges (security). You do not need to add anything to the Roles folder in order to use your Visual FoxPro component with MTS.
    8. Click the Components folder and select the Action -> New -> Component menu item.
    9. Click the Install new component(s) button. This will bring up the Install Components dialog box. Click the Add files button and go to the location where you created your Visual FoxPro server (for example, test1.dll). Select both the .dll and .tlb files. The .tlb file is the type library file containing properties and methods of your server. After selecting these two files, you should see your OLEPUBLIC component listed in the lower panel. Click Finish and you should see your server added to this folder.
    10. At this point, your package is complete and ready to go. Later, we will talk about setting Transaction support. This can be done from the Properties dialog box of your server.

    Accessing Your Component

    You can now test your new MTS packaged component using a command similar to the one used to test Visual FoxPro after the DLL server was first created.

    x=create("test1.server1")
    ? x.hello()
    

    That’s all you need to do! If you go back into the MTS Explorer, you should see the component represented with a spinning icon. Click the Status View to see details about the state of the object.

    Figure 2. New component viewed in MTS Explorer

    If you release the object (RELEASE x), MTS releases its reference.

    Going Forward

    We’ve just discussed the basics of installing your Visual FoxPro server in MTS. Essentially, all we did was wrap the Visual FoxPro component inside an MTS process that manages security, transaction state, fault tolerance, and other common server responsibilities. All Visual FoxPro servers used with MTS are registered this way. The remainder of the article discusses how to take advantage of MTS-specific features such as security and transactions. You can write code in your components that talk directly to the MTS run-time environment. In addition, the above process can be entirely automated, because MTS exposes an administrative Automation interface.

    Setting Up Security

    So why are we starting out so early with security? Well, sooner or later, you’re going to fiddle with some sort of security switch and suddenly that MTS application of yours will no longer work. It’s important that you follow these instructions and refer to them later when you decide to add security to your applications.

    Note   MTS 2.0 security setup is described in the Readme document. If you have MTS installed on Microsoft Windows® 95, you can skip this section.

    Setting System Package Identity

    Before you do anything in MTS, it is a good idea to configure the system package for administrating security. When installing MTS, set the system package identity before creating any new packages as follows:

    1. Create a new local Windows NT group named “MTS Administrators” and a new local user named “MTS Administrator.”
    2. Add the “MTS Administrator” user to the “MTS Administrators” and “Administrators” groups.
    3. Set the identity of the system package to “MTS Administrator.” If this does not work, try setting this to the Administrator user.

    Note   You cannot set a package’s identity to a group.

    1. Shut down the system package so that it will be restarted with the new identity. You can do this by right-clicking the My Computer icon in MTS Explorer and selecting Shut Down Server Processes.

    Adding Security for MTS Packages

    You first need to determine whether you want all or just a few components in your Package to have security. Right-click the Package and select Properties. Next, click the Security tab. Then check the Enable authorization checking check box. To enable or disable security at a component level, right-click a component and display the Properties dialog box.

    If this is all you do, an “Access is denied” error message is generated when you try to access your component. You MUST associate a valid role with any component marked for security!

    Right-click the package’s Roles folder and select New Role. Type in a functional role such as Managers, Accountants, and so on.

    The new role is added as a subfolder. Right-click this folder to Add New User (you will get a dialog box to Add Users and Groups to Role). Select the user(s) that you want to add to your role. To finish, select the Role Membership folder under each component that is marked for security and add the new role created in step 3 by right-clicking the folder and selecting New Role.

    Note   You may still experience the “Access is denied” error message when running your components. There are a couple of possible solutions:

    • Sometimes adding a Group to a role does not work (step 3). You might try adding individual users instead.
    • The user rights for that user are not properly set. Make sure the user account for the identities of the system package and other MTS packages have the Windows NT “Log on as a service” user right. You can verify this by using the Windows NT User Manager:
    1. From the Policies menu, select User Rights.
    2. Click Show Advanced User Rights.

    Tips for Visual FoxPro Users

    Much of the security administration can easily be handled by Automation using the MTS Admin objects. You can set up Security administration in the AfterBuild event of a ProjectHook class you have tied to the project that generates your MTS COM DLL server. See the section “Using Visual FoxPro 6.0 Project Hooks” for examples.

    The Basic Features of MTS

    Before we jump right into using Visual FoxPro with MTS, let’s review some basic concepts that you need to know in order to make effective use of the MTS environment. For more detailed information, see MTS Help.

    Activity

    An activity is a collection of MTS objects that has a single distributed thread of logical execution. Each MTS object belongs to a single activity. This is a basic concept that describes how the middle-tier functions when confined to the MTS environment. In an MTS package, multiple clients can access objects, but only one object per client is running at a time on a single thread.

    Context

    Context is state that is implicitly associated with a given MTS object. Context contains information about the object’s execution environment, such as the identity of the object’s creator and, optionally, the transaction encompassing the work of the object. The MTS run-time environment manages a context for each object.

    As a developer, think of every Visual FoxPro object that is registered in an MTS package as having an associated Context object that is created every time you instantiate the Visual FoxPro object. So, each time you issue a CreateObject command, two objects are created—your server and its associated Context. In fact, you can return an object reference to this Context object directly in your code, as in the following example:

    #DEFINE MTX_CLASS   "MTXAS.APPSERVER.1"
    LOCAL oMTX,oContext
    oMtx = CREATEOBJECT(MTX_CLASS)
    oContext = oMtx.GetObjectContext()
    

    The Context object has the following properties and methods.Expand table

    CountCreateInstanceDisableCommit
    EnableCommitIsCallerInRoleIsInTransaction
    IsSecurityEnabledItemSecurity
    SetAbortSetComplete 

    As you can see, the properties, events, and methods (PEMs) are used to access information related to the object transaction and security context (see MTS Help for more details on specific syntax for these PEMs). It is important to understand that the Context state is inherited. An object in a package called from another object in the same package will inherit the state of its caller. Because Context is confined within the same process, state, such as security, is trusted. No object in a package needs to explicitly provide its own security. When your object is released, so is its Context.

    Package

    Packages, as we just described, are the building blocks of MTS. Think of them as mini applications—a set of components that perform related application functions. All components in a package run in the same MTS process.

    Remember, “Good MTS applications are designed with MTS in mind from the start.” You should design your Package contents with your entire application in mind. Each package runs in its own process, so try to design packages that don’t attempt to do more than they absolutely need to. There are performance advantages to maintaining many components within in a single package, but there may also be security constraints (roles) that dictate a different architecture.

    Packages are also the primary means of deployment. The MTS environment allows one to export the contents of a Package to a nice distributable setup (both client and server). We’ll discuss this in the “Deployment” section.

    Role

    A role is a symbolic name that defines a class of users for a set of components. Each role defines which users are allowed to invoke interfaces on a component. A role is the primary mechanism to enforce security. Role-based security is handled at the component level. It’s possible that this may be at the method level in a future version of MTS. Security cannot be enforced on the Windows 95 version of MTS.

    Roles are stored at the package level. Each component in a package can belong to one of more of the defined roles. For example, an Inventory package might contain a Visual FoxPro server whose responsibility is to handle inventory. There are two roles defined in this package: Managers and Clerks. These two roles are simply collections of Windows NT users/groups with a collective name that you provide. Your server is coded so that Clerks can access inventory data for normal order entries and reporting. Managers have additional power in that they can override inventory levels to make adjustments (for example, quarterly product shrinkage estimates).

    You can set up security so that it is automatically handled (for instance, users not in roles are given “Access is denied” error message), or you can manage it programmatically through code. The Context object’s IsCallerInRole method is ideal for this.

    Resource Dispensers

    A resource dispenser manages nondurable shared state on behalf of the application components within a process. Resource dispensers are similar to resource managers, but without the guarantee of durability. MTS provides two resource dispensers:

    • The ODBC resource dispenser
    • The Shared Property Manager

    Resources are shared within the same process—same process = same package. In the section “Shared Property Manager,” we discuss programmatically accessing shared properties. This is a really cool thing for Visual FoxPro developers because it allows multiple instances of objects to share state information. For example, you could have a counter that tracks the last ID number used by a database.

    ODBC resource dispenser

    The ODBC resource dispenser manages pools of database connections for MTS components that use the standard ODBC interfaces, allocating connections to objects quickly and efficiently. Connections are automatically enlisted on an object’s transactions and the resource dispenser can automatically reclaim and reuse connections. The ODBC 3.0 Driver Manager is the ODBC resource dispenser; the Driver Manager DLL is installed with MTS.

    Shared Property Manager

    The Shared Property Manager provides synchronized access to application-defined, process-wide properties (variables). For example, you can use it to maintain a Web page hit counter or to maintain the shared state for a multiuser game.

    Resource Managers

    A resource manager is a system service that manages durable data. Server applications use resource managers to maintain the durable state of the application, such as the record of inventory on hand, pending orders, and accounts receivable. Resource managers work in cooperation with the Microsoft Distributed Transaction Coordinator (MS DTC) to guarantee atomicity and isolation to an application. MTS supports resource managers, such as Microsoft SQL Server version 6.5, that implement the OLE Transactions protocol.

    The MS DTC is a system service that coordinates transactions. Work can be committed as an atomic transaction even if it spans multiple resource managers, potentially on separate computers. MS DTC was first released as part of SQL Server 6.5 and is included in MTS, providing a low-level infrastructure for transactions. MS DTC implements a two-phase commit protocol to ensure that the transaction outcome (either commit or abort) is consistent across all resource managers involved in a transaction. MS DTC ensures atomicity, regardless of failures.

    You might be asking if Visual FoxPro is a resource manager, because it has its own native database. Unfortunately, the answer is no. Visual FoxPro transactions are native to Visual FoxPro and do not go through the MS DTC. Therefore, automatic transaction support within MTS is not supported for Visual FoxPro data. You cannot use the Context object’s SetAbort method to abort a transaction if the data is stored in Visual FoxPro databases/tables. The database must either support OLE Transactions (SQL Server) or be XA-compliant (Oracle).

    Base Clients

    A base client is simply a client that runs outside of the MTS run-time environment, but instantiates MTS objects. In a three-tier architecture, a base client is typically the presentation layer, such as an application form or Web page. The base client neither knows nor needs to know that MTS is used in the middle tier. It merely creates an instance of an object that exists in an MTS package and awaits a response. The following table describes some of the differences between a base client and an MTS component, such as a Visual FoxPro DLL server.Expand table

    Base clientMTS component
    Can be EXEs, DLLs.Must be in-process DLL.
    MTS does not manage its process.Manages server processes that host MTS component.s
    MTS does not create or manage threads used by application.Creates and manages threads.
    Does not have implicit Context object.Each MTS object has own Context object.
    Cannot use Resource Dispensers.Can use Resource Dispensers.

    Just-In-Time Activation

    Just-in-Time (JIT) activation is the ability to activate an MTS object only as needed for executing requests from a client. Most Visual FoxPro developers are familiar with object instantiation, as in the following code:

    myObject = CreateObject("myclass")
    myObject.myMethod()
    myObject.myProperty = 123
    RELEASE myObject
    

    A “stateful” object created by this code retains state during the lifetime of the object (until it is released). This means that property values (such as myProperty) are retained between statement execution. When the object is finally released, all object references and state are released.

    There is overhead with creating objects from your Visual FoxPro components. Each time you instantiate an object, Visual FoxPro needs to allocate a certain amount of memory. In addition, the first time you create an object, Visual FoxPro takes a little extra time to load its run-time libraries. When the last instance is released, the entire Visual FoxPro run time is also released.

    JIT activation addresses many of these memory issues that affect performance. The first thing JIT does is cache the server’s run-time libraries in memory, even though no outstanding object references exist. The first time you instantiate a Visual FoxPro server that’s in an MTS package, the Visual FoxPro run time loads the address space of the MTS process. When you release the object, MTS still keeps the libraries in memory for a specified amount of time. You can change this setting in the package’s property sheet (default = 3 minutes). This saves having to reload the run time when the object count hits 0.

    The main thing that JIT activation offers is ability to transform your object from “stateful” to “stateless” mode. In the preceding example, you can interpret a “stateless” object as one having the initial default settings. So, in the example, the value of myProperty would be reset to its original setting. A stateless object is managed by MTS and is very lightweight, so it consumes much less memory. The only thing keeping the stateless object alive is the object reference held onto by the client. Internally, MTS recycles threads consumed by stateful objects when they go stateless. When a method is invoked on that object, it then becomes stateful again on a thread that could be different from the one originally created on.

    Putting your objects into a stateless mode is handled easily by the Context object. The following code illustrates putting an object in a stateless mode:

    #DEFINE MTX_CLASS   "MTXAS.APPSERVER.1"
    LOCAL oMTX,oContext
    oMtx = CREATEOBJECT(MTX_CLASS)
    oContext = oMtx.GetObjectContext()
    oContext.SetComplete()
    

    This code is actually called from within a method of your Visual FoxPro server. You can see if your object is stateless by viewing the status of your component in the MTS Explorer. A stateless object appears in the Objects column, but not in the Activated or In Call columns.

    Use the SetComplete method to put the object in a stateless mode. Use SetComplete for committing transactions (as we discuss in the next section, “Transactions”). You can also use SetAbort to make an object stateless.

    Again, when you change an object to stateless, all property settings revert to their original defaults. When you invoke a method (or property set/get) on this stateless object, the object is activated (goes stateful) and the object’s INIT event is fired. When you call SetComplete, the object DESTROY event is fired.

    Note   Any state that exists on the object is lost when the object is deactivated (SetComplete). If you need to save state, you should either persist information to a database or use the MTS Shared Property Manager.

    Because your object’s INIT is called whenever your object goes from Stateless to Stateful, you should try to minimize the amount of code in this event.

    Here is a simple scenario showing interaction between client and MTS server.

    Visual FoxPro server code:

    DEFINE CLASS mts2 AS Custom OLEPUBLIC
       MyColor = "Green"
       PROCEDURE InUsa (tcCustID)
          LOCAL llInUSA,oMTX,oContext
          oMtx = CreateObject("MTXAS.APPSERVER.1")
          oContext = oMtx.GetObjectContext()
          llInUSA = .F.
          USE CUSTOMER AGAIN SHARED
          LOCATE FOR UPPER(cust_id) == UPPER(tcCustID)
          IF FOUND()
             llInUSA = (ATC("USA",country)#0)
          ENDIF
          oContext.SetComplete()
          RETURN llInUSA
       ENDPROC
    ENDDEFINE
    

    Base client executes following code:

    LOCAL oCust,cCust,lUsa
    oCust = CreateObject("vfp_mts.mts2")
    ? oCust.MyColor
    Green
    oCust.MyColor = "Red"
    ? oCust.MyColor
    Red
    cCust = "JONES"
    lUsa = oCust.InUsa(cCust)   && object goes stateless (deactivated)
    ? oCust.MyColor      && object is activated (stateful)
    Green
    RELEASE oCust         && object is fully released
    

    Notice in the preceding example how the state of oCust is lost after the InUsa method is called. The MyColor property no longer returns Red, but is instead reset to its original value of Green.

    Transactions

    If you have used Visual FoxPro at all, you are probably aware that Visual FoxPro supports transactions. Changes to your data can be committed or rolled back. Though transactions are critical to MTS, don’t be misled by the name; there is a lot more to it than just transactions. However, the ability to have MTS automatically handle transactions between distributed objects is quite powerful. Transactions are often discussed in terms of the ACID acronym:

    • Atomicity—ensures that either the entire transaction commits or nothing commits.
    • Consistency—a transaction is a correct transformation of the system state.
    • Isolation—protects concurrent transactions from seeing each other’s partial and uncommitted results.
    • Durability—committed updates to managed resources can survive failures.

    As just mentioned, MTS transaction support is not compatible with Visual FoxPro data. It only works with databases supporting OLE transaction or XA protocols. Both SQL Server and Oracle data can be used with MTS in transactional fashion.

    You should understand what we mean by a transaction and to what extent things are either committed or rolled back. Consider the following scenario (all done within confines of two components in a single MTS package):

    1. Component A adds a new customer record to the Customer table in SQL Server.
    2. Component A writes out new record to a Visual FoxPro database (audit log).
    3. Component A sends e-mail notification of new customer to some manager.
    4. Component A calls Component B.
    5. Component B edits the Orders table with a new order in SQL Server.
    6. Component B writes out text log file of activity.
    7. Component B completes activity by committing the transaction (SetComplete).
    8. Component A discovers bad credit history with customer and aborts transaction (SetAbort).

    When Component B commits in step 7, not a whole lot happens because MTS manages the entire Context within the package in a distributed fashion. Component B actually inherits transaction state from Component A, so it cannot really fully commit the transaction. The real transaction terminates in step 8 when the last object with transaction state aborts. At this point, changes made to both Customer and Orders tables are rolled back because these tables are in SQL Server. Unfortunately, the Visual FoxPro table update, e-mail notification, and text log file activities are not rolled back. When a transaction is aborted/committed, only data managed through the MS DTC is affected. There is no event that is magically triggered. (Check out the MTS SDK for ideas on using Spy).

    Remember, good MTS apps are written with MTS in mind from the start. Managing transactions is very important, and while much of it is handled automatically, you will need to provide a fair amount of code to effectively manage all the resources being utilized in a transaction setting.

    Transaction support is set at the component level, but transactions can span multiple packages. You can set this option in the MTS Explorer from the component’s Property Sheet (see MTS Help for details on the various options). Again, the object’s Context manages and passes on transaction state for a given component. If the transaction setting of a component is marked as “Requires a transaction,” a transaction is always associated with the component. If another object that calls this component already has a transaction in effect, no new transaction is created. The component merely inherits the current one. A new transaction is only created if one does not already exist in the context.

    Figure 3. Setting Transaction support

    Let’s return a minute to the SetComplete and SetAbort methods. These methods actually serve two purposes. From their names, they imply functionality related to transactions. However, as already discussed, they also serve to deactivate objects (make them stateless). In fact, these methods can be used simply for JIT activation without any concern for transactional support. Again, SetComplete releases valuable resources/memory used by MTS to allow for improved scalability. The Context object also includes several other methods useful for transactions: EnableCommitDisableCommit, and IsInTransaction. The following example shows how to handle transactions in Visual FoxPro:

    LPARAMETER tcCustID
    LOCAL lFound,oMTX,oContext
    oMtx = CreateObject("MTXAS.APPSERVER.1")
    oContext = oMtx.GetObjectContext()
    USE CUSTOMER AGAIN SHARED
    LOCATE FOR UPPER(cust_id) == UPPER(tcCustID)
    lFound = FOUND()
    IF FOUND()
    oContext.SetComplete()
    ELSE
    oContext.SetAbort()
    ENDIF
    RETURN lFound
    

    In this scenario, we assume that another component already performed an update on another table (for example, Orders). If the customer ID in the preceding code was not found, the entire transaction would be rolled back.

    You’re probably wondering how transactions work in the code, which clearly appears to be against Visual FoxPro data. Actually, this example is using Remote Views against SQL Server data. Again, Visual FoxPro tables do not support OLE transactions, so you will not get MTS transaction support if you use DBF tables. However, data updates either to Remote Views or by SQL pass-through work just fine.

    **Tip   **Make sure that your connection to a remote data source is made without any login dialog box. If you are using a connection stored in a DBC, ensure that the Display ODBC logins prompt is set to Never. For access to remote data through SQL pass-through commands, you can use the SQLSetProp function:

     SQLSETPROP(0, 'DispLogin', 3)
    

    Programming Models

    MTS supports two programming models. The TransactionContext model is intended primarily for backward compatibility. It essentially lets the base client control the transaction. The assumption is that the COM component has no MTS awareness (that is, the component was written before MTS was available). The second model is called the ObjectContext model and assumes the COM component inside the MTS package has MTS smarts and is aware of its Context object.

    TransactionContext

    We do not recommend using this model for new three-tier applications, because it has limited access to the full capabilities of MTS. It merely offers a way to provide some transaction support to applications whose middle-tier components were developed without MTS in mind. The burden of transaction handling rests on the base client. With this model, the base client is likely to be a smart client that has scripting capabilities (for example, an application form). The base client is less likely to be a Web page, and it always runs outside of the MTS run-time environment.

    The following code snippet in a Visual FoxPro form (base client) shows this model in use. The middle-tier component is a Visual FoxPro server whose ProgID is “vfp_mts.mts1”. The assumption here is that this server knows nothing about MTS, thus requiring the base client to perform all transaction handling:

    #DEFINE TRANS_CLASS   "TxCtx.TransactionContext"
    THIS.oContext = CreateObject(TRANS_CLASS)
    LOCAL loCust
    loCust = THISFORM.oContext.CreateInstance("vfp_mts.mts1")
    RETURN loCust.lnUSA
    

    The code in the middle tier simply does a lookup in a SQL Server table for a customer’s home country. If the record was actually changed, the base client would have the capability to actually commit or roll back the transaction. The TransactionContext object only supports three methods: CreateInstanceCommit, and Abort.

    ObjectContext

    The ObjectContext model is the only model you should consider for new MTS application development. It relies on component awareness of MTS, but this should be your goal so that you can optimize performance and take advantage of MTS-specific features.

    Unlike the TransactionContext object, which uses the following PROGID:

    #DEFINE TRANS_CLASS   "TxCtx.TransactionContext"
    

    the ObjectContext object can be accessed using the following code:

    #DEFINE MTX_CLASS   "Mtxas.AppServer.1"
    

    The ObjectContext object, which can be referenced in your Visual FoxPro code, as shown here:

    LOCAL oMTX,oContext
    oMtx = CreateObject("MTXAS.APPSERVER.1")
    oContext = oMtx.GetObjectContext()
    

    contains the following properties, events, and methods (PEMs).Expand table

    PEMDescription
    CountReturns the number of Context object properties.
    CreateInstanceInstantiates another MTS object.
    DisableCommitDeclares that the object hasn’t finished its work and that its transactional updates are in an inconsistent state. The object retains its state across method calls, and any attempts to commit the transaction before the object calls EnableCommit or SetComplete will result in the transaction being aborted.
    EnableCommitDeclares that the object’s work isn’t necessarily finished, but its transactional updates are in a consistent state. This method allows the transaction to be committed, but the object retains its state across method calls until it calls SetComplete or SetAbort, or until the transaction is completed.
    IsCallerInRoleIndicates whether the object’s direct caller is in a specified role (either directly or as part of a group).
    IsInTransactionIndicates whether the object is executing within a transaction.
    IsSecurityEnabledIndicates whether security is enabled. MTS security is enabled unless the object is running in the client’s process.
    ItemReturns a Context object property.
    SecurityReturns a reference to an object’s SecurityProperty object.
    SetAbortDeclares that the object has completed its work and can be deactivated on returning from the currently executing method, but that its transactional updates are in an inconsistent state or that an unrecoverable error occurred. This means that the transaction in which the object was executing must be aborted. If any object executing within a transaction returns to its client after calling SetAbort, the entire transaction is doomed to abort.
    SetCompleteDeclares that the object has completed its work and can be deactivated on returning from the currently executing method. For objects that are executing within the scope of a transaction, it also indicates that the object’s transactional updates can be committed. When an object that is the root of a transaction calls SetComplete, MTS attempts to commit the transaction on return from the current method.

    Deployment

    Microsoft Transaction Server offers excellent tools for deploying both client- and server-side setups. Setups are made at the package level, so you should include all components for your application in a particular package. The deployment package contains all the distributed COM (DCOM) configuration settings you need, so you don’t have to fuss with the messy DCOM Configuration dialog box.

    To create a setup

    1. Click the package that you want to create setup.
    2. Select Export… from the Action menu. The Export dialog box is displayed.

    Figure 4. Exporting a package

    **Important   **The directions in the Export dialog box are not very clear. You should not simply type in a path as specified. If you do, the Export routine creates a file with a .pak extension in the folder location you specify. Instead, you should always type a full path and file name for the .pak file, as shown in Figure 4.

    You can also use the scriptable administration objects to automate deployment and distribution of your MTS packages. See the section “Remote Deployment and Administration” to follow for more details.

    The output of the Export operation consists of two setups:

    Server Setup

    This setup, which is placed in the folder specified in the Export dialog box, contains the .pak file and all COM DLL servers used by the package.

    Note   With Visual FoxPro servers, you will also have .tlb (type library) files included. You can install this package by selecting Install from the Package Wizard in MTS Explorer.

    Figure 5. Installing package from the Package Wizard

    Client Setup

    The Export process creates a separate subfolder named “clients” in the folder specified in the Export Package dialog box. The Clients folder contains a single .exe file that a user can double-click to run.

    The Client setup merely installs necessary files and registry keys needed by a client to access (remotely through DCOM) your MTS package and its COM servers.

    Remote Deployment and Administration

    The MTS Explorer allows you to manage remote components (those installed on a remote machine). The Remote Components folder contains the components that are registered locally on your local computer to run remotely on another computer. Using the Remote Components folder requires that you have MTS installed on the client machines that you want to configure. If you want to configure remote computers manually using the Explorer, add the components that will be accessed by remote computers to the Remote Components folder.

    Pushing and Pulling

    If both the server and client computer are running MTS, you can distribute a package by “pulling” and “pushing” components between one or more computers. You can “push” components by creating remote component entries on remote computers and “pull” components by adding component entries to your local computer. Once you create the remote component entries, you must add those component entries to your Remote Components folder on your local machine (pull the components).

    Before you deploy and administer packages, set your MTS server up by doing the following:

    • Configure roles and package identity on the system package.
    • Set up computers to administer.

    You must map the System Package Administrator role to the appropriate user in order to safely deploy and manage MTS packages. When MTS is installed, the system package does not have any users mapped to the administrator role. Therefore, security on the system package is disabled, and any user can use the MTS Explorer to modify package configuration on that computer. If you map users to system package roles, MTS will check roles when a user attempts to modify packages in the MTS Explorer.

    Roles

    By default, the system package has an Administrator role and a Reader role. Users mapped to the Administrator role of the system package can use any MTS Explorer function. Users that are mapped to the Reader role can view all objects in the MTS Explorer hierarchy but cannot install, create, change, or delete any objects, shut down server processes, or export packages. If you map your Windows NT domain user name to the System Package Administrator role, you will be able to add, modify, or delete any package in the MTS Explorer. If MTS is installed on a server whose role is a primary or backup domain controller, a user must be a domain administrator in order to manage packages in the MTS Explorer.

    You can also set up new roles for the system package. For example, you can configure a Developer role that allows users to install and run packages, but not delete or export them. The Windows NT user accounts or groups that you map to that role will be able to test installation of packages on that computer without having full administrative privileges over the computer.

    In order to work with a remote computer, you first need to add it to the Computers folder in the MTS Explorer:

    1. Click the Computers folder.
    2. Select New -> Computer from the Action menu.
    3. Enter name of the remote computer.

    Important   You must be mapped to the Administrator role on the remote computer in order to access it from your machine. In addition, you cannot remotely administer MTS on a Windows 95 computer from MTS on a Windows NT server.

    You should now see both My Computer and the new remote computer under the Computers folder. At this point, you can push and pull components between the two machines. Think of the Remote Components folder as its own special package. You are merely adding to it components that exist in one or more packages of remote machines.

    The following example pulls a component from a remote machine to My Computer.

    1. Click the Remote Components folder of My Computer.
    2. Select New-> Remote Component from the Action menu to display the dialog box shown here.

    Figure 6. Adding a component to Remote Components

    In this example, we select (and add) a component called test6.foobar2 from a package called aa on the remote machine calvinh5. This package also has another component (Visual FoxPro OLEPUBLIC class) named test6.foobar, which we do not select. When we click OK, a copy of the DLL and the type library are copied to the local machine (My Computer) and stored in a subfolder of your MTS root location (in this case, c:\ C:\Program Files\Mts\Remote\aa\). In addition, the server is now registered on your machine. Note that while the DLL is copied to your machine, the .dll registered in your registry points to the remote machine.

    If you encounter problems after you click OK, you may not have proper access rights to copy the server components. Ensure that the remote machine is configured with proper access privileges for you. At this point, you can go into Visual FoxPro running on the local machine and access the server:

    oServer = CreateObject("test6.foobar2")
    ? oServer.myeval("SYS(0)")
    

    You use MTS Explorer to view the activated object in the remote machine folder under the package it is registered in. You will not see the object activity in the Remote Components folder. See the “Working with Remote MTS Computers” topic in the MTS Help file for more details.

    Security

    Security in MTS is handled by roles. Roles are established at the package level. Components within that package can set up role memberships. The following MTS Explorer image shows a package called Devcon1, which contains three roles. Only the last two components contain Role Memberships.

    Figure 7. Package with roles

    If you navigate the Roles folder, you can see all Windows NT users or groups assigned to that particular role.

    To create a new role

    1. Click the Roles folder.
    2. Select New-> Role from the Action menu.
    3. Enter a new role name in the dialog box.

    You can add new users/groups to a particular role as follows:

    To add new users or groups

    1. Click the Users folder of the newly added role.
    2. Select New-> User from the Action menu.
    3. Select users/groups from the dialog box.

    MTS handles its security several different ways. The MTS security model consists of declarative security and programmatic security. Developers can build both declarative and programmatic security into their components prior to deploying them on a Windows NT security domain.

    You can administer package security using MTS Explorer. This form of declarative security, which does not require any component programming, is based on standard Windows NT security. This can be done by Package- or Component-level security.

    Declarative Security

    You can manage Declarative security at the package and at the component level through settings available in the Security tab of the Package Properties dialog box.

    Package-level security

    Each package has its own security access authorization, which can be set in the Package Properties dialog box.

    Figure 8. Package properties

    By default, the Security check box is not marked, so you need to check this box to enable security. If you do not enable security for the package, MTS will not check roles for the component. If security is enabled, you must also enable security at the component level in order to have roles checked.

    Component-level security

    Each installed component can also have its own security setting. You set security for a component through the same Enable authorization checking check box on the Property dialog box in MTS Explorer. If you are enabling security at both levels and you do have defined roles, you must include one of the roles in the component’s Role Membership folder. If you do not include a role in the folder, you will get an “Access is denied” error message when you try to access a property or method of the component. Of course, if you do not have any roles, you will get the same error.

    Note   You can still do a CreateObject on the component, but that is all.

    oContext = CreateObject("vfp_mts.mts1")
    oContext.Hello()   && will generate an Access is denied error
    

    To restrict access to a specific component within a package, you must understand how components in the package call one another. If a component is directly called by a base client, MTS checks roles for the component. If one component calls another component in the same package, MTS does not check roles because components within the same package are assumed to “trust” one another.

    When you change the security settings for a particular package or component, you need to shut down server processes before changes can take place. This option is available from the Action menu when Package is selected.

    Programmatic Security

    You can put code in your program to check for specific security access rights. The following three properties and methods from the Context object return information regarding security for that package or component.Expand table

    MethodsDescription
    IsCallerInRoleIndicates whether the object’s direct caller is in a specified role (either directly or as part of a group).
    IsSecurityEnabledIndicates whether security is enabled. MTS security is enabled unless the object is running in the client’s process.
    SecurityReturns a reference to an object’s SecurityProperty object.

    The following method checks whether the called object is in a particular role. The IsCallerInRole method is useful when the roles are defined, but if your code is generic and doesn’t know the particular roles associated with a component, you must handle this through your error routine.

    PROCEDURE GetRole (tcRole)   
       LOCAL oMTX,oContext,lSecurity,cRole,lHasRole
       IF EMPTY(tcRole)
          RETURN "No Role"
       ENDIF
       oMtx = CREATEOBJECT(MTX_CLASS)
       oContext = oMtx.GetObjectContext()
       IF oContext.IsSecurityEnabled
          THIS.SkipError=.T.
          lHasRole = oContext.IsCallerInRole(tcRole)
          THIS.SkipError=.F.
          DO CASE
          CASE THIS.HadError
             THIS.HadError = .F.
             cRole="Bad Role"
          CASE lHasRole 
             cRole="Yep"
          OTHERWISE
             cRole="Nope"
          ENDCASE
    ELSE
          cRole="No Security"
    ENDIF
       oContext.SetComplete()
       RETURN cRole
    ENDPROC
    

    Advanced users can access the SecurityProperty object to obtain more details on the user for handling security. The Security object offers the following additional methods.Expand table

    MethodDescription
    GetDirectCallerNameRetrieves the user name associated with the external process that called the currently executing method.
    GetDirectCreatorNameRetrieves the user name associated with the external process that directly created the current object.
    GetOriginalCallerNameRetrieves the user name associated with the base process that initiated the call sequence from which the current method was called.
    GetOriginalCreatorNameRetrieves the user name associated with the base process that initiated the activity in which the current object is executing.

    What type of security should you use? Programmatic security offers more power in terms of structuring specific functionality for particular roles. You can use Case statements, as in the previous example, which perform different tasks, depending on the role. Declarative security, on the other hand, can only control access at the component level (not method or lower).

    Changes to Programmatic security, however, require a new build of the component, which may not always be convenient or realistic. Controlling Component-level security for users and roles by using MTS Explorer to turn security on or off gives an administrator greater control. The optimal solution is one with utilizes both declarative and programmatic securities in the most efficient manner.

    Shared Property Manager

    The Shared Property Manager (SPM) MTS resource dispenser allows you to create and share properties across components. Because it is a resource dispenser, all other components in the same package can share information, but information cannot be shared across different packages. For example, if you want to keep a counter to use for generating unique IDs for objects in a package, you could create a Counter property to hold the latest unique ID value. This property would be preserved while the package was active (regardless of object state).

    The SPM also represents an excellent way for an object to preserve its state before being deactivated in a stateless mode (SetComplete). Just-In-Time activation does not affect or reset the state of SPM.

    The following example shows how to use the SPM with Visual FoxPro servers:

    #DEFINE MTX_CLASS        "MTXAS.APPSERVER.1"
    #DEFINE MTX_SHAREDPROPGRPMGR "MTxSpm.SharedPropertyGroupManager.1"
    PROCEDURE GetCount (lReset)
       LOCAL oCount 
       LOCAL oMTX,oContext
       LOCAL nIsolationMode,nReleaseMode,lExists
       oMtx = CREATEOBJECT(MTX_CLASS)
       oContext = oMtx.GetObjectContext()
       oSGM = oContext.CreateInstance(MTX_SHAREDPROPGRPMGR)
       nIsolationMode = 0
       nReleaseMode = 1
       
    * Get group reference in which property is contained
       oSG = oSGM.CreatePropertyGroup("CounterGroup", nIsolationMode,;
    nReleaseMode, @lExists)
       
    * Get object reference to shared property
       oCount = oSG.CreateProperty("nCount", @lExists)
    * check if property already exists otherwise reset
       IF lReset OR !lExists
          oCount.Value = 1
       ELSE
          oCount.Value = oCount.Value + 1
       ENDIF
       RETURN oCount.Value
    ENDPROC
    

    The following settings are available for Isolation and Release modes.

    Isolation mode

    LockSetGet 0 (default)—Locks a property during a Value call, assuring that every get or set operation on a shared property is atomic. This ensures that two clients can’t read or write to the same property at the same time, but doesn’t prevent other clients from concurrently accessing other properties in the same group.

    LockMethod 1—Locks all of the properties in the shared property group for exclusive use by the caller as long as the caller’s current method is executing. This is the appropriate mode to use when there are interdependencies among properties or in cases where a client may have to update a property immediately after reading it before it can be accessed again.

    Release mode

    Standard 0 (default)—When all clients have released their references on the property group, the property group is automatically destroyed.

    Process 1—The property group isn’t destroyed until the process in which it was created has terminated. You must still release all SharedPropertyGroup objects by setting them to Nothing.

    MTS Support for Internet Information Server

    MTS includes several special system packages for use with Microsoft Internet Information Server (IIS). The Windows NT Options Pack 4.0 integrates MTS and IIS more closely. In the future, you can expect even better integration to play a more central role in your Web applications.

    IIS Support

    • Transactional Active Server Pages—You can now run Scripts in Active Server Pages (ASP) within an MTS-managed transaction. This extends the benefits of MTS transaction protection to the entire Web application.
    • Crash Protection for IIS Applications—IIS Web applications can now run within their own MTS package, providing process isolation and crash protection for Web applications.
    • Transactional Events—You can embed commands in scripts on ASP pages, enabling you to customize Web application response based on transaction results.
    • Object Context for IIS Built-In Objects—The MTS object context mechanism, which masks the complexity of tracking user state information from the application developer, now tracks state information managed by IIS built-in objects. This extends the simplicity of the MTS programming model to Web developers.
    • Common Installation and Management—MTS and IIS now share common installation and a common management console, lowering the complexity of deploying and managing business applications on the Web.

    IIS System Packages

    If you use MTS with Internet Information Server version 4.0, the Packages Installed folder contains the following IIS-specific system packages.

    IIS in-process applications

    The IIS In-Process Applications folder contains the components for each Internet Information Server application running in the IIS process. An IIS application can run in the IIS process or in a separate application process. If an IIS application is running in the IIS process, the IIS application will appear as a component in the IIS In-Process Applications folder. If the IIS application is running in an individual application process, the IIS application will appear as a separate package in the MTS Explorer hierarchy.

    IIS utilities

    The IIS Utilities Folder contains the ObjectContext component required to enable transactions in ASP pages. For more information about transactional ASP pages, refer to the Internet Information Server documentation.

    Automating MTS Administration

    Microsoft Transaction Server contains Automation objects that you can use to program administrative and deployment procedures, including:

    • Installing a prebuilt package.
    • Creating a new package and installing components.
    • Enumerating through installed packages to update properties.
    • Enumerating through installed packages to delete a package.
    • Enumerating through installed components to delete a component.
    • Accessing related collection names.
    • Accessing property information.
    • Configuring a role.
    • Exporting a package.
    • Configuring a client to use Remote Components.

    You can use the following Admin objects in your Visual FoxPro code.Expand table

    ObjectDescription
    CatalogThe Catalog object enables you to connect to MTS Catalog and Access collections.
    CatalogObjectThe CatalogObject object allows you to get and set object properties.
    CatalogCollectionUse the CatalogCollection object to enumerate, add, delete, and modify Catalog objects and to access related collections.
    PackageUtilThe PackageUtil object enables installing and exporting a package. Instantiate this object by calling GetUtilInterface on a Packages collection.
    ComponentUtilCall the ComponentUtil object to install a component in a specific collection and import components registered as in-process servers. Create this object by calling GetUtilInterface on a ComponentsInPackage collection.
    RemoteComponentUtilUsing the RemoteComponentUtil object, you can program your application to pull remote components from a package on a remote server. Instantiate this object by calling GetUtilInterface on a RemoteComponents collection.
    RoleAssociationUtilCall methods on the RoleAssociationUtil object to associate roles with a component or interface. Create this object by calling the GetUtilInterface method on a RolesForPackageComponent or RolesForPackageComponentInterface collection.

    In addition, the following collections are also supported.Expand table

    Collection
    LocalComputer
    ComputerList
    Packages
    ComponentsInPackage
    RemoteComponents
    InterfacesForComponent
    InterfacesForRemoteComponent
    RolesForPackageComponent
    RolesForPackageComponentInterface
    MethodsForInterface
    RolesInPackage
    UsersInRole
    ErrorInfo
    PropertyInfo
    RelatedCollectionInfo

    If you want to get a reference to a particular collection, use the GetCollection method. The following example shows, first, getting the collection of packages and, second, getting a collection of all components in the first package:

    #DEFINE MTS_CATALOG      "MTSAdmin.Catalog.1"
    oCatalog = CreateObject(MTS_CATALOG)
    oPackages = oCatalog.GetCollection("Packages")
    oPackages.populate()
    ? oPackages.Count
    oComps = oPackages.GetCollection("ComponentsInPackage",;
    oPackages.Item(0).Key)
    oComps.Populate()
    

    Note   The GetCollection method merely returns an object reference to an empty collection. You need to explicitly call the Populate method to fill the collection.

    Collections are case sensitive, as in the following example code:

    oPackages = oCatalog.GetCollection("Localcomputer")   &&fails
    oPackages = oCatalog.GetCollection("LocalComputer")   &&works
    

    Note   Also keep in mind that all MTS collections are zero-based.

    oPackages = oCatalog.GetCollection("LocalComputer")
    oPackages.populate()
    ? oPackages.item[0].name
    

    See MTS Help for more specific language details.

    Visual FoxPro 6.0 is ideally suited for using MTS Automation because of the new Project Manager and Application Builder hooks support.

    Using Visual FoxPro 6.0 Project Hooks

    The MTS samples posted along with this document contain a special Project Hook class designed specially for MTS. This class automatically shuts down and refreshes MTS registered servers contained in that project. One of the issues that developers must consider when coding and testing servers under MTS is repeatedly opening the MTS Explorer to manually shut down processes so that servers can be rebuilt and overwritten. Using a Project Hook nicely automates this process. Here is sample code from the BeforeBuild event, which iterates through the Packages collection shutting-down processes.

    * BeforeBuild event
    LPARAMETERS cOutputName, nBuildAction, lRebuildAll, lShowErrors, lBuildNewGuids
    #DEFINE MTS_CATALOG      "MTSAdmin.Catalog.1"
    #DEFINE   MSG_MTSCHECK_LOC   "Shutting down MTS servers...."
    LOCAL oCatalog,oPackages,oUtil,i,j,oComps
    LOCAL oProject,lnServers,laProgIds,lcSaveExact
    THIS.lBuildNewGuids = lBuildNewGuids
    oProject = _VFP.ActiveProject
    lnServers = oProject.servers.count
    DIMENSION THIS.aServerInfo[1]
    STORE "" TO THIS.aServerInfo
    IF lnServers = 0 OR nBuildAction # 4
       RETURN
    ENDIF
    WAIT WINDOW MSG_MTSCHECK_LOC NOWAIT
    DIMENSION laProgIds[lnServers,3]
    FOR i = 1 TO lnServers
       laProgIds[m.i,1] = oProject.servers[m.i].progID
       laProgIds[m.i,2] = oProject.servers[m.i].CLSID
       laProgIds[m.i,3] = THIS.GetLocalServer(laProgIds[m.i,2])
    ENDFOR
    ACOPY(laProgIds,THIS.aServerInfo)
    * Shutdown servers
    oCatalog = CreateObject(MTS_CATALOG)
    oPackages = oCatalog.GetCollection("Packages")
    oUtil = oPackages.GetUtilInterface
    oPackages.Populate()
    lcSaveExact = SET("EXACT")
    SET EXACT ON
    FOR i = 0 TO oPackages.Count - 1
       oComps = oPackages.GetCollection("ComponentsInPackage",;
    oPackages.Item(m.i).Key)
       oComps.Populate()
       FOR j = 0 TO oComps.Count-1
    IF ASCAN(laProgIds,oComps.Item(m.j).Value("ProgID")) # 0
    oUtil.ShutdownPackage(oPackages.Item(m.i).Value("ID"))
    EXIT
    ENDIF
       ENDFOR
    ENDFOR
    WAIT CLEAR
    SET EXACT &lcSaveExact
    * User is building new GUIDs, so packages 
    * need to be reinstalled manually
    IF lBuildNewGuids
       RETURN
    ENDIF
    

    This is only one of the many possibilities provided by a Visual FoxPro Project Hook. The MTS Admin objects can save a great deal of time you normally would spend manually setting options in the MTS Explorer.

    Using Visual FoxPro 6.0 Application Builders

    As with the Project Hooks, you might also want to create an Application (Project) Builder that handles registration of Visual FoxPro Servers in MTS packages. The Visual FoxPro MTS samples include such a builder. (See the Readme file in the mtsvfpsample sample application for more details on setup and usage of these files.)

    This Builder simply enumerates through all the servers in your Visual FoxPro project and all the available MTS packages. You can then select (or create) a particular package and registered server to install in that package. Additionally, you can set the Transaction property for each component. The Visual FoxPro code called when the user clicks OK is as follows:

    #DEFINE   MTS_CATALOG      "MTSAdmin.Catalog.1"
    #DEFINE   ERR_NOACTION_LOC   "No action taken."
    LOCAL oCatalog,oPackages,oUtil,i,j,oComps,nPoslcPackage
    LOCAL lPackageExists,oCompRef
    LOCAL oProject,lnServers,laProgIds,lcSaveExact,oPackageRef,lctrans
    lcPackage = ALLTRIM(THIS.cboPackages.DisplayValue)
    lPackageExists = .f.
    SELECT mtssvrs
    LOCATE FOR include
    IF !FOUND() OR EMPTY(lcPackage)
       MESSAGEBOX(ERR_NOACTION_LOC)
       RETURN
    ENDIF
    THIS.Hide
    oCatalog = CreateObject(MTS_CATALOG)
    oPackages = oCatalog.GetCollection("Packages")
    oPackages.Populate()
    FOR i = 0 TO oPackages.Count-1
       IF UPPER(oPackages.Item(m.i).Name) == UPPER(lcPackage)
          oPackageRef = oPackages.Item(m.i)
          lPackageExists=.T.
          EXIT
       ENDIF
    ENDFOR
    IF !lPackageExists   &&creating new package
       oPackageRef = oPackages.Add
       oPackageRef.Value("Name") = lcPackage
       oPackages.SaveChanges
    ENDIF
    oComps = oPackages.GetCollection("ComponentsInPackage",;
    oPackageRef.Key)
    oUtil = oComps.GetUtilInterface
    SCAN FOR include
       oUtil.ImportComponentByName(ALLTRIM(progid))
    ENDSCAN
    oPackages.SaveChanges()
    oComps.Populate()
    SCAN FOR include
       DO CASE
       CASE trans = 1
          lctrans = "Supported"
       CASE trans = 2
          lctrans = "Required"
       CASE trans = 3
          lctrans = "Requires New"
       OTHERWISE
          lctrans = "Not Supported"         
       ENDCASE
       FOR j = 0 TO oComps.Count-1
          IF oComps.Item(m.j).Value("ProgID")=ALLTRIM(progid)
             oCompRef = oComps.Item(m.j)
             oCompRef.Value("Transaction") = lctrans
             oCompRef.Value("SecurityEnabled") = ;
    IIF(THIS.chkSecurity.Value,"Y","N")
          ENDIF
       ENDFOR
    ENDSCAN
    oComps.SaveChanges()
    oPackages.SaveChanges()
    

    Tips and Tricks

    Hopefully, this article offers enough insight into creating Visual FoxPro components that work well with your three-tier MTS applications. Here are a few final tips to consider:

    • Design your components with MTS in mind from the start.
    • Components must be in-process DLLs. Do not use Visual FoxPro EXE servers.
    • When adding Visual FoxPro components, make sure to select both .dll and .tlb files.
    • In the Project Info dialog box of Visual FoxPro DLL servers, set Instancing to MultiUse.
    • Don’t be afraid to mix with other components (for example, Visual Basic servers).
    • You must have DTC running for transaction support.
    • Call SetComplete regardless of whether you’re using transactions, because it places objects in stateless mode.
    • Your MTS object has an associated Context object. Do not place this code in the base client.
    • Connections must have DispLogin set to Never; for SQL pass-through, use SQLSetProp(0).
    • Minimize the number of PEMs on an object (protect your PEMs).
    • Because of page locking issues, limit the length of time you leave SQL Server 6.5 transactions uncommitted.
    • To use security, you must have a valid role associated with the component.
    • Avoid using CreateInstance on non-MTS components.
    • Do not pass object references of the Context object outside of the object itself.
    • Consider using disconnected ADO recordsets to move data between tiers.
    • You can pass Visual FoxPro data in strings, arrays, or ADO recordsets.
    • Passing Parameters:
      • Be careful when passing parameters.
      • Always use SafeArray when passing object references.
      • Passing by value:- Fastest and most efficient- Copies the parameters into a buffer- Sends all values at once
      • Passing by reference:- Sends a reference, but leaves the object back in the client.- Accessing the parameter scampers back to the client machine.
    • Always read the Late Breaking News! It contains important information such as Security configuration details.
    • Visit the Microsoft MTS Web site at www.microsoft.com/com/ for more information.
    • By default, MTS will create a maximum of 100 apartment threads for client work (per package). In Windows NT 4.0 Service Pack 4 (and later), you can tune the MTS activity thread pool. This will not affect the number of objects than can be created. It will simply configure the number that can be simultaneously in call. To tune the MTS activity thread pool:
      1. Open your Windows Registry using RegEdit and go to the package key:HKLM/Software/Microsoft/Transaction Server/Package/{your package GUID}
      2. Add a REG_DWORD named value:ThreadPoolMax
      3. Enter a value for ThreadPoolMax. Valid values are:0 to 0x7FFFFFFF

    The Microsoft Visual FoxPro 6.0 Component Gallery 

    • Article
    • 06/30/2006

    In this article

    1. Introduction
    2. The Visual FoxPro Component Gallery
    3. Understanding Item Types
    4. The BROWSER.DBF Structure

    Steven M. Black

    March 1999

    Summary: Discusses the new Microsoft Visual FoxPro Component Gallery. Covers the open architecture and programmable hooks that the Gallery and the companion Class Browser expose for customization. (17 printed pages)

    Contents

    Introduction The Visual FoxPro Component Gallery Understanding Item Types The BROWSER.DBF Structure

    Introduction

    This white paper discusses the new Microsoft® Visual FoxPro® Component Gallery. Together with the Visual FoxPro Class Browser, the Gallery provides useful ways to accomplish common development tasks. This document also discusses the open architecture and programmable hooks that these tools expose for customization. While this white paper presents the Gallery, an accompanying paper, The Visual FoxPro 6.0 Class Browser, presents the Class Browser, providing details specific to that development tool.

    Update

    The Visual FoxPro 6.0 Component Gallery and other related components have been updated. You can download this update from https://msdn.microsoft.com/vfoxpro/downloads/updates.asp. To ensure that you are using the latest version, you should download and install the update.

    The Component Gallery is the Class Browser’s companion. Both share the same display surface, and you can toggle between them with a handy toolbar button. The Component Gallery can be used to categorize and display almost anything (not just Visual FoxPro components), and its strength is in grouping the various artifacts of software development.

    The Component Gallery is a flexible and programmable shortcut manager and explorer. Since it shows nothing but shortcuts, nothing you do directly in the Component Gallery affects the underlying files. You can create new files through the Gallery, for example, but the element in the Gallery remains a shortcut to the new file. Delete the shortcut and the underlying file is not deleted. (You could extend the Gallery to delete the underlying file when you delete the shortcut, but writing, implementing, and living with this extension is up to you.)

    Visual FoxPro 6.0 uses a system memory variable (named GALLERY) to identify the Component Gallery application. In Visual FoxPro 6.0, the default is GALLERY.APP in your HOME( ) directory. By changing the value of GALLERY, you can wrap and substitute the Component Gallery application just as you do many other Visual FoxPro tools. Visual FoxPro thus continues to provide user-definable extensibility. GALLERY.APP is a wrapper for BROWSER.APP. Running GALLERY.APP is the same as running BROWSER.APP and passing the sixth parameter as true (.T.). You can run the Component Gallery programmatically by using the following code:

    DO (_GALLERY)
    

    The full syntax respected by the Component Gallery includes the following parameters:

    • First parameter (cFileName): File Name or file list (catalog(s) separated by commas).
    • Second parameter (cDefaultItem): Text of Catalog, Folder, or Item to be selected when the Component Gallery is started.
    • Third parameter (nWindowState): Window state of Component Gallery form when started (0=normal, 1=minimized, or 2=maximized).
    • Sixth parameter (lGallery): Must be true (.T.) to run in Component Gallery mode. False (.F.) is for Class Browser mode; refer to The Visual FoxPro 6.0 Class Browser.
    • Seventh parameter (lNoShow): Default false (.F.). If set to true (.T.), the Component Gallery is not activated or shown. You can then use the public memory variable, _oBrowser, to access the Component Gallery object model. (Refer to Visual FoxPro Help for documentation on the Class Browser methods, properties, and events.

    Because of its intimate partnership with the Class Browser, the Component Gallery supports all the add-in mechanisms found in the browser. The Component Gallery, however, adds metadata-driven display and behavior of items to its Class Browser functionality.

    Let’s define a few terms that will help us understand the Component Gallery. After that, we’ll look at how you can use the Component Gallery, then we’ll examine the metadata that makes it all work.

    Here are some terms that will serve us well in subsequent discussion.

    Catalog: The highest-level container in the Component Gallery and its unit of file storage. A catalog is a .DBF or .FPT table whose records define shortcuts to software resources. For example, you could have a catalog named Office Pool.DBF*,* which contained folders and shortcuts to tables, programs, documents, hyperlinks, and anything else needed to manage friendly office wagers. More than likely, you’ll also create project catalogs to organize all the artifacts of your software projects as they are created. Displayed in the Component Gallery, a catalog is a folder with no parent folder.

    Folder: Like a subdirectory, a logical package of items. Catalogs can contain zero or more folders. Folders are either static or dynamic. A static folder contains predefined shortcuts to items. A dynamic folder determines its contents each time the Component Gallery is refreshed. A dynamic folder can be defined as a directory such as “C:\Projects\*.*,” a Visual FoxPro project (.PJX) file, a class library (.VCX) file, a database (.DBC) file, or any URL or file that is valid in the Internet Explorer Web Browser control pane mode.

    Item: A shortcut to a particular artifact.

    Item Type: A category that defines the behavior of the items in the catalog. The default item types are stored in the home( )+”\Gallery\VfpGlry.VCX” class library, and are configurable for each catalog. (For each catalog, see the Properties dialog box, available on the Shortcut menu). The root catalog, always named “Catalogs,” contains the default item types that all catalogs inherit.

    By now you should be comfortable with explorer-type interfaces. If so then the basic features of the Component Gallery work pretty much as you expect.

    The Gallery is divided into two panes. The Catalog pane, on the left, lists the hierarchy of currently open catalogs. The Items pane, on the right, shows the items in the current catalog hierarchy. Both panes provide item-sensitive context menus for doing the usual useful things: cut, copy, paste, rename, and so on. You can also invoke item-sensitive property dialog boxes for selections in the left or right panes. Moreover, the entire Component Gallery is enabled for both regular and OLE drag-and-drop operations.

    In Web view mode, the Items pane is automatically hidden by an Internet Explorer Web browser control. When the selected folder is a dynamic folder that is a URL, the Component Gallery displays in Web view mode. In the Web view mode, the four display control buttons become Back, Forward, Stop, and Refresh buttons.

    As in the Class Browser, you can use the Item icon to drag the currently selected item to the desktop, design surface, or project. Right-clicking Item invokes a GetPict( ) dialog box to change the icon. A nice touch here is that when you select Cancel in the GetPict( ) dialog box, you get an option to reset the icon to the item default. Setting the icon using the Item icon is the same as setting the item picture in the Properties dialog box for that item.

    The View control box contains default and user-defined views of the Component Gallery. Views are queries of specific items in and across catalogs. For example, selecting Internet filters the catalogs to display Internet items only.

    To create your own custom views, see the Dynamic Views tab in the Component Gallery Options dialog box. If Advanced Editing mode is enabled, you can create custom item-type views.

    To create custom item-type views:

    1. Select an item and invoke its properties.
    2. Click the Views tab.
    3. In the EditBox, type a line item such as the following text.My Stuff=Test Files
    4. Press F5 to refresh the Component Gallery.
      The My Stuff view appears in the Views control box.
    5. Select this view, the Test Files folder appears.
    6. Select this folder and a shortcut for that item appears in the right pane.

    This process allows you to create custom item-type views, and any item can be in any view. Refer to the existing item type settings in the shortcut items included in the Visual FoxPro Catalog items.

    The Go to Browser button toggles the Component Gallery window to the standard Class Browser. Hint: right-clicking the button displays a long list of the previously opened folders.

    The Open button is for opening new catalogs. The Open dialog box is a little unconventional and merits explanation. In that discussion, we’ll take our first look at the Component Gallery internals.

    This isn’t your garden-variety Open dialog box. The Catalog box displays the catalogs currently registered on your system. The catalog names are kept in the BROWSER.DBF table, and the detail records for each catalog are stored in the GALLERY\VFPGLRY.DBF table. The Add catalog checkbox adds the contents of the catalog to the current view (the default is “replace”). In addition you can use the Browse button to select an existing catalog that is not listed in the catalog dropdown.

    When you click Options in the Component Gallery window, a three-tabbed dialog box appears wherein you can set certain Component Gallery properties.

    The Standard tab displays the general defaults for the Component Gallery itself; some of these are self-explanatory. Note, however, the Advanced editing enabled checkbox, which enables you to access advanced features of Component Gallery options and property dialogs.

    Use the Catalogs tab to maintain the catalogs that appear in the Catalog box in the Open dialog box. Click New to load a new catalog in the Catalogs pane. A Global catalog is visible in the Catalogs pane regardless of which catalog is selected for display. I’ve made my Favorites catalog a global catalog so I always have access to my favorites. A Default catalog opens whenever you invoke the Component Gallery. Note that when you invoke the Component Gallery from the Class Browser, it always comes up empty. The Component Gallery initially appears populated only when the original invocation is performed with the DO (_Gallery) command.

    The Dynamic Views tab can be used to create your own custom dynamic views of your catalogs. In the figures that follow, I’ve created a new dynamic view named “Excel Spreadsheets” that displays all items of type “file” that contain “.XLS” in their names.

    In the following example, I’ve created a dynamic view of “UseCase” documents by both creating and assigning such keywords as “Actor” and “Extends.” The keywords displayed in this list are stored in a table named Keywords.DBF.

    The Component Gallery Find button is a nice surprise—it works just like dynamic views! In effect, when you use Find you are creating a new persistent view like the one defined on the Dynamic Views tab. I’m not so sure I’m crazy about this. After all, cluttering my own dynamic views every time I search through a file might be a bit much. On the other hand, dynamic views are easy enough to purge in the Dynamic Views tab of the Component Gallery Options dialog box.

    Understanding Item Types

    The behavior of a Gallery item, as in what happens when you click it or drag it, is defined in its item type. The class library, Gallery\VfpGlry.VCX, stores the item types supplied by Microsoft, and you can modify, subclass, or simply copy these classes to create your own types. If you develop your own custom item types, it’s probably a good idea to store them in some other .VCX file, such as My_VfpGlry.VCX. This allows you to later update the Component Gallery class libraries without fear of clobbering your work.

    Here is the hierarchy of the Component Gallery item types supplied by Microsoft. _item and _folder are abstract root classes that are defined in _Gallery.VCX. All the others are in VfpGlry.VCX.

    When creating your own item types, the most flexible prototype is the _fileitem. In fact, _fileitem should serve most of your needs, since it invokes Windows file associations to run or modify the item. Moreover, the _fileitem type can redirect popular file extensions to other file types. We’ll talk more about redirection shortly.

    Item types can be tied to particular catalogs. The root catalog, which is always named “Catalog,” serves as the basis for all catalogs. If you select the Item Types tab on the Folder Properties of the root catalog, you’ll see something like this dialog box.

    Note the following points about the Item Types tab in this dialog box.

    The list of item types matches the item types you see in the New Item shortcut menu. To modify the New Item shortcut menu, simply edit this list.

    Each item type can be associated with display text, a class, and a class library. In this case the display text is “ActiveX,” the class is _ActivexItem, and the class library is VfpGlry.VCX.

    The lines in the properties edit box specify what’s displayed in the Class Item tab of the Item Properties dialog box. For example, the Properties box of the ActiveX item in the Component Gallery example above show the following:

    • File name: (and, within braces, “.ocx, .exe, and .dll”), cFileName—Specifies that the Class Item tab of this class of item will provide a label, textbox, and command button. This information is stored in the object cFileName property.
    • Remote path: (and, within braces, “.ocx, .exe, and .dll”), cRemoteField—Specifies that the Class Item tab of this class of item will provide a label, textbox, and command button. This information is stored in the object cRemoteField property.
    • ActiveX ProgID: cProgID—Specifies that the Class Item tab of this class of item will provide only a label and testbox for ActiveX ProgID. This information is stored in the object ProgID property.

    Note   The entries within braces create a command button with an ellipsis (…) that will, when clicked, display the Open dialog box that defaults to browse for the listed file extensions.

    The other lines of the ActiveX item type are out of view; they include entries for Class, Class library, Source project, and Associated file, and these all work the same as those already described.

    Note   Placing an asterisk (*) before the property name marks that property to be displayed as read-only text in the Properties dialog box. For example, the following entry in Class Item displays the textbox as read-only.

    *Base class:,cBaseClass
    

    If you create your own item types, you can make them available by clicking Add and specifying the new item type.

    Item Redirection

    The Properties page of the _FileItem item type is worth a look because, in addition to showing custom properties, it shows an example of item redirection. See the Redirect box in the following dialog box.

    This is the full list of redirections:Expand table

    APP=_sampleitemAVI=_videoitemBMP=_imageitem
    DBF=_dataitemFRX=_reportitemGIF=_imageitem
    H=_programitem.HTM=_urlitemHTML=_urlitem
    ICO=_imageitemJPG=_imageitemLBX=_reportitem
    LOG=_programitemMNX=_menuitemOCX=_activexitem
    PJX=_ProjectItemPRG=_programitemRMI=_sounditem
    SCX=_formitemTXT=_programitemWAV=_sounditem

    You can probably guess how redirections work: when an item with any of those file extensions is created, the designated item type is created instead. For example, if you try to add a .PRG file as an item, the Component Gallery uses the PRG redirection to create a _programitem instead of a _fileitem. This is why the fileitem item type is so flexible; it has the ability to properly redirect new items to the correct item type.

    The BROWSER.DBF Structure

    The Class Browser stores all its metadata in a table named BROWSER.DBF in your HOME( ) directory. The Component Gallery also uses BROWSER.DBF to store its catalog-related information. Here’s a field-by-field description of important elements in BROWSER.DBF that pertain to the Gallery.Expand table

    FieldDescription
    PLATFORM“WINDOWS” except for records of type “ADDIN” in which the field value is blank.
    TYPE“PREFW” records store browser and gallery preferences. “ADDIN” records store add-in information.
    ID“FORMINFO” records are used by the Class Browser to store form preferences and by the Component Gallery to store information about your catalogs. The only way to tell the difference is that Component Gallery records contain the string “.dbf” in the Name field.”BROWSER” records contain default settings for the Class Browser. See the Properties field for this record to see these default properties.“METHOD” records store Class Browser add-ins that are tied to a particular Class Browser event or method.“MENU” records store Class Browser add-ins that are not tied to a particular Class Browser event or method, and are therefore available on the add-in shortcut menu.
    DEFAULTLogical true (.T.) for the default Component Gallery catalog when the Component Gallery is started with an unspecified first parameter of GALLERY.APP.
    GLOBALApplies to Component Gallery catalog records. Logical true (.T.) if the catalog is global. By default, new catalogs are not global. To specify a catalog to global, select the Catalogs tab in the Component Gallery Options dialog box.
    BACKUPSpecifies, when true (.T.), that the Class Browser or Component Gallery check for duplicate files in the backup subfolder.When a catalog or a VCX is opened by browser/gallery, this field in the associated BROWSER.DBF record is queried. If the backup file doesn’t exist, one is automatically created (including a subfolder named Backup if needed). Then the Backup field is set to false (.F.) You can set this field programmatically to force the browser or gallery to automatically back up that file or table the next time that file is opened, and only the next time.You can set this field via add-in hooks or just at any time with a program that opens and updates browser.dbf.This feature is used internally in one special case. When browser.dbf is first created after VFP is installed, a new browser.dbf, containing the default catalogs (around 5 or so), is created. Because Visual FoxPro does not install the associated backup catalog tables, the Backup field is initially set to true (.T.) so that each catalog is backed up the very first time it is opened. Beyond that special function, its functionality is available to developers for their own purposes.
    NAMESpecifies the file name related to this record. For a Class Browser record, the file type could be, among other things, .VCX, .PJX, .SCX, .OCX, .DLL, .EXE, or APP.For Component Gallery records, the file type is .DBF.In the case of Class Browser and Component Gallery add-ins, the name field stores the name of the add-in. This is what will appear in the add-in shortcut menu if the add-in is not tied to an event or method.
    DESCProvides a description of the catalog referred to in the Name field. Used only by the Component Gallery.
    METHODStores the name of the method to which a Class Browser or Component Gallery add-in is tied. If the method field content equals “*” then the add-in will run for all methods.
    SCRIPTInternal Gallery use only
    PROGRAMUsed by the Class Browser and the Component Gallery to specify the name of the program to run by .PRG-based add-in.
    CLASSLIBUsed by the Class Browser and the Component Gallery to specify the name of the class library in the case of a .VCX-based add-in.
    CLASSNAMESpecifies the name of the class to run in the case of a .VCX-based add-in. Used by the Class Browser and the Component Gallery.
    FILEFILTERSpecifies file masks for which the add-in applies. The FileFilter is specified in the fourth parameter of the Add-in method.
    TOPSpecifies the top coordinate for the browser/gallery form.
    LEFTSpecifies the left coordinate for the browser/gallery form.
    HEIGHTSpecifies the height of the browser/gallery form.
    WIDTHSpecifies the width of the browser/gallery form.
    HEIGHT1Specifies the height of the class and member description panes in the Class Browser.
    HEIGHT2Specifies the height of the item description pane in the Component Gallery.
    WINDOWSTATSpecifies the display size of the Component Gallery or Class Browser.0 – Window is zoomed normal
    1 – Window is minimized
    2 – Window is maximized
    DESCBOXESSpecifies, if true (.T.), that the description panels are to be displayed. Used by the Class Browser and the Component Gallery.
    AUTOEXPANDSpecifies, if true (.T.), that the hierarchical items are automatically to be displayed expanded in the left-hand side pane. Used by the Class Browser and the Component Gallery.
    PUSHPINSpecifies, if true (.T.), that the display is always on top. Used by the Class Browser and the Component Gallery.
    VIEWMODEGallery listview mode (1 – 4).
    FONTINFOSpecifies the Class Browser and the Component Gallery display font preference.
    FORMCOUNTNumber of instances running for file.
    UPDATEDThe date and time this record was last updated.
    COMMENTUnused.
    User1….4Unused.

    The Catalog Table Structure

    This is a very brief overview of Component Gallery-specific metadata. The Component Gallery distributes its metadata to several locations.

    Like the Class Browser, the Component Gallery keeps some of its metadata on a table named BROWSER.DBF, which is found in your HOME( ) directory. The data therein stores the references to the available catalogs, as well as some of their properties such as whether the catalog is a global (auto-open) or default (in the default view). See the BROWSER.DBF metadata description.

    If you delete a Component Gallery catalog record from BROWSER.DBF, it won’t appear in the Component Gallery Open dialog box. The Component Gallery catalog records in BROWSER.DBF contain “.dbf” in the Name field. Since this field is of type memo, you can’t easily identify Component Gallery records in a simple browse of BROWSER.DBF.

    The rest of the Component Gallery metadata is stored in VFPGLRY.DBF, which installs in the Visual FoxPro Gallery subdirectory. This table stores catalog item type metadata. It is here that the behavior of the various item types is defined. When you look at the Component Gallery, you are looking at catalogs whose items are defined in the particular catalog tables, but whose behavior emanates from the items defined here.

    To illustrate some of the functionality of VFPGLRY.DBF, let’s examine fields in a representative record, the one with ID=”fileitem”.Expand table

    FieldValueComment
    Type“CLASS”Metadata class specification. Catalog items can “inherit” from one another. There are thus many different variants of “fileitem” elsewhere in the metadata, and they may override or augment the things defined in this record.The type field can be any value. The values that are reserved and used by the Component Gallery are:“FOLDER”—Folder item (catalog, if parent field is empty).“ITEM”— Item for the right pane, must have a valid parent field setting.“CLASS”—Specifies an item type setting for that specific catalog, beyond the default item types of vfpglry.vcx.“VIEW”—Specifies a custom view used when the catalog is open.“SCRIPT”—Used to specify a special record that contains code in the Script field, and can be called by having a property setting like cDblClick=<MyScript>.“OBJECT”—Used to specify a custom class to be instantiated when the catalog is refreshed. The ItemClass field is used to specify the class name, and the ClassLib field is used to specify the VCX of the class.
    ID“fileitem”The unique identifier for this type of item.
    Text“File”The item display text.
    Typedesc“Item”Specifies the type of element. This is not a folder, but an item.
    Desc The text that appears in the item description pane.
    PropertiesFile name:{},cFileName Parameters:{},cParamsSpecification for input fields that appear in the Properties dialog box for items of this type. Values inside the braces are used as the parameter in GetFile( ) dialogs.
    ClasslibVfpglry.vcxThe class library in which the item’s class is stored.
    Classname_fileitemThe default class that embodies this catalog item.
    ItemtpdescBMP=_imageitem ICO=_imageitem JPG=_imageitem GIF=_imageitem WAV=_sounditem RMI=_sounditem AVI=_videoitem DBF=_dataitem SCX=_formitem MNX=_menuitem FRX=_reportitem LBX=_reportitem PRG=_programitem APP=_sampleitem OCX=_activexitem HTM=_urlitem HTML=_urlitem PJX=_ProjectItem TXT=_programitem LOG=_programitem H=_programitemAlternate classes to embody file items of these particular types. Newly created items with these extensions are remapped to the designated item types.

    Other records may use different fields and different values, but this representative record is enough to get you started in working with the Component Gallery.

    Catalog tables contain records that reference actual catalog items. The main native catalog is named “Visual FoxPro Catalog,” and it is found in VFP_Catalog.DBF. All the Visual FoxPro 6.0 foundation classes, for example, are cataloged there.

    The structure of catalog tables is the same as that of VFPGLRY.DBF, so that much of what we’ve already seen also applies here. This is a good opportunity to look at a few other metadata fields and how they work. This example uses the record with ID=”clireg” in Activex_Catalog.Dbf. This item allows you to register a custom Visual FoxPro automation server remotely, using its generated .VBR file.Expand table

    FieldValueComment
    Type“ITEM” 
    ID“clireg”This item’s ID.
    Parent“actxtools”The ID of the parent catalog record, which refers to a folder named “Tools.”
    Desc“This tool allows you to register a custom VFP automation server remotely using the generated VBR file.”The description window text.
    PropertiescDblClick=<>You can override the events (keypress, click, dblclick, and rightclick) by setting the [cEventName] property. If it’s something like cDblClick=DO foo.prg, then it will run that line. If you set cDblClick=<testscript>, then it will run the code in the Script memo field of the record with ID= “testscript”. If you set cDblClick=<>, then it will run the code in the Script memo field of that record.Thus this DblClick runs the code found in the script field.You can use a record with Type=”SCRIPT” to provide, in the catalog table, a reusable Script memo field that can be called when you run the browser object and reference the .RunScript( ) method.
    Filename(HOME(6)+”CLIREG\CLIREG32.EXE”)The name, stored in oTHIS.cFileName, of the file to run. See the Script field below. Note that the whole behavior of this item is defined by the filename field and, in this case, the Script field. The ClassName and ClassLib fields are blank in this record.
    ScriptcVBRFile = GETFILE(“VBR”) cCliReg = oTHIS.cFIleName IF !FILE(m.cCliReg) RETURN .F. ENDIF IF EMPTY(m.cVBRFile) OR UPPER(JUSTEXT(m.cVBRFile))#”VBR” RETURN .F. ENDIF oTHIS.Runcode([RUN /N &cCliReg. “&cVBRFile.” -NOLOGO])The Script field provides code for the SCRIPT type item with the ID specified by [cEventName] in the properties field. This Visual FoxPro code will run in a code block upon DblClick.Note that in this version there is no script equivalent of DODEFAULT( ), so if you script an event, the default behavior for this event will not execute.If you need a behavior like DODEFAULT( ), just manually make the direct call in the custom script like oTHIS.DblClick

    Steven Black specializes in developing multilingual, multisite, and other challenging software situations, including project turnarounds and cleanups. He is the creator of Steven Black’s INTL Toolkit, a multilingual framework for FoxPro and Visual FoxPro. He’s a regular speaker at Visual FoxPro conferences, and his contributions occasionally darken the pages of FoxPro books and magazines.

    Microsoft Visual FoxPro 6.0 and Visual Studio Installer Tutorial 

    • Article
    • 06/30/2006

    In this article

    1. Tutorial
    2. Create an Application to Distribute
    3. Step 1: Open Visual Studio Installer
    4. Step 2a: Add Application Files to the Installer Project

    Show 9 more

    Microsoft Corporation

    December 1999

    Summary: This article lists the basic steps involved in creating, configuring, and building a Microsoft Windows Installer package (.msi) file with Microsoft Visual Studio Installer. (14 printed pages)Expand table

    Click to download the VFP_VSI.exe sample file.

    Microsoft® Visual Studio® Installer is a graphical tool that simplifies the creation of application setup programs for distribution to single user or enterprise-wide desktops. Setups created with the Visual Studio Installer provide advanced capabilities such as centralized distribution for maintenance and updates, application self-repair, and powerful installation rollback facilities.

    Visual Studio Installer setups are based on the new Microsoft Windows® installer technology. The Windows installer reduces the total cost of ownership (TCO) for customers by enabling them to efficiently install and configure applications. The Windows installer is part of the Windows 2000 and Zero Administration Windows (ZAW) efforts to reduce the overall cost of deploying, using, and managing desktop computers.

    For more information on the Visual Studio Installer, visit the Visual Studio Web site, https://msdn.microsoft.com/vstudio/downloads/tools/vsi11/default.aspx. In addition, you can read the Visual Studio Installer documentation.

    Tutorial

    This tutorial lists the basic steps involved in creating, configuring, and building a Microsoft Windows Installer package (.msi) file with Microsoft Visual Studio Installer. An .msi file is a storage file containing the instructions and data required to install an application.

    This tutorial will show how to author an .msi file to configure the installation of a Visual FoxPro® application. It will also show how to launch the .msi file and install the application.

    To author and launch an .msi file with Visual Studio Installer, complete these tasks:

    1. Open Visual Studio Installer and create an installer project as part of a Visual Studio solution.
    2. Add files to the installer project and configure file properties.
    3. If desired, configure the project properties.
    4. If desired, establish how to modify the target machine system registry when your product is installed and configure registry properties.
    5. If desired, establish how the target machine operating system will handle your installed document types, MIME types, COM objects, and type libraries, and configure properties for each of these objects.
    6. If desired, control and customize the installation dialogs presented when your users run the installer package file to install, repair, or uninstall your product.
    7. Add merge modules to the project.
    8. Build the installer package file.
    9. Test the installer package file.
    10. Distribute the application.

    Create an Application to Distribute

    For the purposes of this demo, the Visual FoxPro Application Wizard was used to create an application called VFPVSIDemo. The application was then built into an EXE, called VFPVSIDemo.exe.

    The data used by the application is in a folder named Data. This folder is a subfolder of the main application folder.

    Step 1: Open Visual Studio Installer

    1. Click Start, and select Programs.
    2. From the Programs menu, select Microsoft Visual Studio 6.0, and then select Microsoft Visual Studio 6.0 Enterprise Tools.
    3. From the Microsoft Visual Studio 6.0 Enterprise Tools menu, click Visual Studio Installer.
    4. The Microsoft Development Environment launches, and you can create a new installer project from the New tab in the New Project dialog box.
    5. Create an empty installer project by highlighting the Empty Installer icon.
    6. Enter VFPVSIDemo as the name of the project.Make a note of the directory in the Location textbox. This is where the application installer file you create will be located. You can change the location for your project if you like.
    7. Choose Open.

    Figure 1. Creating a new Visual Studio Installer project

    Visual Studio Installer creates your installer project. The Project Explorer displays your installer project hierarchy. You can expand the Target Machine node to start setting up the configuration of your installed product on the target machine.

    Figure 2. Empty Visual Studio Installer project

    For more detailed information about creating installer projects, see Creating and Opening Installer Projects.

    Step 2a: Add Application Files to the Installer Project

    The File System editor in Visual Studio Installer gives you a way to configure your application files on the target machine while you add them to the installer project.

    1. In the Project Explorer, expand the Target Machine node.
    2. Double-click File System in the Target Machine node.
    3. In the File System editor, right-click Application Folder.
    4. Select Add File(s) from the context menu.
    5. In the Browse for Files dialog box, navigate to the directory that contains the application. Select the files you want to add. In this case, choose the file VFPVSIDemo.exe.
    6. Click Open.The File System editor displays the file(s) you added in the folder you selected. The files are also listed in the installer project Files node in the Project Explorer.Figure 3. Files added to the installer project
    7. In the File System editor, select User’s Start Menu.
    8. In the Name column, right-click and select Create Shortcut.
    9. In the Shortcut Properties dialog, select VFPVSIDemo.exe and choose OK.
    10. Right-click the shortcut and choose Rename. Rename the shortcut VFPVSIDemo.

    This places a shortcut to the file VFPVSIDemo.exe on the user’s Start menu.

    See the following topics for more detailed information about working with files in an installer project:Expand table

    For information about:See:
    The Visual Studio Installer File System editorFile System Editor
    Adding files to an installer projectAdding Files to an Installer Project
    Adding, moving, or deleting different kinds of files in an installer project and managing the file structure of installer componentsManaging Components, Files, and Folders in an Installer Project
    Setting file propertiesFile Properties

    Step 2b: Add Data Files to the Installer Project

    In the previous step, you added the application files to the installer project. In this step, you will add the data files, which reside in a different directory.

    1. In the File System editor, right-click Application Folder.
    2. Select AddFolder from the context menu.
    3. Change the name of the new folder to Data.
    4. In the File System editor, right-click Data.
    5. Select Add File(s) from the context menu.
    6. In the Browse for Files dialog box, navigate to the directory that contains the application. Select the files you want to add. In this case, choose each of the data files.
    7. Click Open.Figure 4. Data files added to the installer project

    Step 3: (Optional) Configure Project Properties

    1. Select the VFPVSIDemo project in the Project Explorer window.
    2. At the end of the Project menu, select the VFPVSIDemoProperties option.

    The Project Properties dialog box appears. You can view or change the project properties in the Project Properties dialog box.

    For information about the different project properties and how to modify them, see Project Properties Dialog Box.

    Step 4: (Optional) Modify the Target Machine System Registry

    With the Visual Studio Installer Registry editor, you can specify registry values and keys in the target machine system.

    1. In the Project Explorer, expand the Target Machine node under your installer project.
    2. Double-click Registry in the Target Machine node.

    The Registry editor appears.

    See the following topics for more detailed information about manipulating the target machine registry:Expand table

    For information about:See:
    Adding and deleting registry keys and values, as well as setting registry valuesManipulating the Target Machine Registry
    The Visual Studio Installer Registry editorRegistry Editor
    Setting properties for registry entriesRegistry Properties

    Step 5: (Optional) Establish Document and MIME Type and COM Object Associations

    With the Visual Studio Installer Associations editor, you can specify how the target machine operating system will install and register your document types, MIME types, COM objects, and type libraries.

    1. In the Project Explorer, expand the Target Machine node under your installer project.
    2. Double-click Associations in the Target Machine node.

    The Associations editor appears.

    See the following topics for more detailed information about working in the Associations editor:Expand table

    For information about:See:
    Working with document types, extensions, verbs, MIME types, COM objects, and type librariesSetting File, MIME, COM Object, and Type Library Associations
    The Visual Studio Installer Associations editorAssociations Editor
    Configuring properties for document types, file extensions, verbs, COM objects, and type librariesVisual Studio Installer Object Properties

    Step 6: (Optional) Customize the Installation Run-Time Dialog Boxes

    With the Visual Studio Installer User Interface editor, you can customize the installation run-time display. Specifically, you can specify and customize dialogs that are displayed during the installation process.

    1. Open the solution containing your Visual Studio Installer project.
    2. In the Project Explorer, expand the Target Machine node under your installer project.
    3. Double-click User Interface in the Target Machine node.

    The User Interface editor appears.

    See the following topics for more detailed information about installation user interface dialogs:Expand table

    For information about:See:
    Available user interface dialogsInstallation User Interface Dialogs
    The Visual Studio Installer User Interface editorUser Interface Editor
    Adding dialogs to the installer projectAdding Installation Dialogs
    Deleting dialogs from the installer projectDeleting Installation Dialogs
    Customizing available dialogsCustomizing Installation Dialogs
    Working with dialog propertiesUser Interface Dialog Properties

    Step 7: Add Merge Modules

    A merge module (.msm file) is a single package that includes all files, resources, registry entries, and setup logic to install a shared component. Visual FoxPro applications should always include the following merge modules:

    • VFP6RUN.MSM
    • MSVCRT.MSM
    • OLEAUT32.MSM

    The files MSVCRT.MSM and OLEAUT32.MSM ship with Visual Studio Installer. You can find these and other merge modules in the directory c:\Program Files\Microsoft Visual Studio\Common\Tools\VSInst\BuildRes.

    Note   The files contained in MSVCRT.MSM and OLEAUT32.MSM are automatically installed by Windows 2000. Therefore you do not need to add these merge modules to the Installer project if you know the application will only be installed on Windows 2000.

    Save the file VFP6RUN.MSM (available from the sample download at the top of this article) to the directory with the other merge modules.

    1. Choose Add Merge Module(s) from the Project menu.
    2. In the Browse for Merge Module dialog highlight the file VFP6RUN.MSM and choose Open.

    The VFP6RUN.MSM merge module installs and properly registers the Visual FoxPro 6.0 run-time libraries. Refer to Using Microsoft Visual Studio Installer for Distributing Visual FoxPro 6.0 Applications for a reference guide to other available merge modules that ship with Visual Studio Installer.

    Step 8: Build an Installer Package (.msi) File

    After you configure all elements of an application’s installation in your installer project, you must build the project into an installer package (.msi) file. You can then distribute the .msi file to users who want to install your application.

    1. In the Project Explorer, select your installer project.
    2. Make sure the Build type project property (on the Build tab of the Project Properties dialog box) is set to either:
      • Installer
      —or—
    3. With the installer project selected in the Project Explorer, select Build from the Build menu.

    You should see the message Solution Update Succeeded in the Status Bar if the project built successfully. If errors occurred, you should see them in the Task List.

    For more information, see Building an Installer Package (.msi) File.

    Step 9: Test the Installer Package (.msi) File

    For development and debugging purposes, the best way to launch your installer package (.msi) file is from within the Microsoft development environment.

    1. In the Project Explorer window, right-click the VFPVSIDemo project.
    2. Select Launch Installer from the context menu.
    3. Select Next on the opening screen of the VFPVSIDemo Setup Wizard.Figure 5. Opening screen of VFPVSIDemo Setup Wizard
    4. In the Select Installation Folder step, you can choose to install the application in the default directory or change the directory.Figure 6. Select Installation Folder step in VFPVSIDemo Setup Wizard
    5. In the Confirm Installation step, select Next to begin the installation.
    6. When the installation is complete, select Close to exit the VFPVSIDemo Setup Wizard.
    7. Choose VFPVSIDemo from the Start menu to launch the application.

    For more information about these Windows installer requirements and launching an installer package file, see Launching an Installer Package File.

    Note   If you set the Build Type as Installer with Windows Installer Loader in the previous step, you should run SETUP.EXE file to test your setup.

    Run the application to confirm the installation succeeded. If you accepted the defaults, the application is installed in the directory C:\Program Files\VFPVSIDemo and the data is installed in C:\Program Files\VFPVSIDemo\Data.

    Step 10: Distribute the Application

    Your application is now ready for distribution. The file VFPVSIDEMO.MSI contains the application and the files in the VFP6RUN.MSM merge module.

    1. Locate the VFPVSIDemo.msi file. If you accepted the default Location when you created the project, it will be in a directory such as Visual Studio Projects\VFPVSIDemo\Output\DISK_1\.
    2. To launch the installer, double-click the file VFPVSIDemo.msi.
    3. Open the VFPVSIDemo Setup Wizard. Choose RepairVFPVSIDemo to reinstall the application. Choose RemoveVFPVSIDemo to uninstall the application. Then choose Finish.Figure 7. Repair or Remove in VFPVSIDemo Setup Wizard

    Using Microsoft Visual Studio Installer for Distributing Visual FoxPro 6.0 Applications 

    • Article
    • 06/30/2006

    In this article

    1. Introduction
    2. Visual FoxPro Distribution Scenarios
    3. Distributing Your Application
    4. Appendices

    Microsoft Corporation

    December 1999

    Summary: This article is a supplement to assist Microsoft Visual FoxPro 6.0 developers in using the Visual Studio Installer as an alternative to the Visual FoxPro 6.0 Setup Wizard. (13 printed pages)Expand table

    Click to download the VFP_VSI.exe sample file.

    Introduction

    The Microsoft® Visual Studio® Installer is a great new tool you can use to create customized setups for your Visual FoxPro® distributed applications. It is based on the new Microsoft Windows® installer, which reduces the total cost of ownership (TCO) for your customers by enabling them to efficiently install and configure your products and applications. The new Windows installer is part of the Windows 2000 and Zero Administration Windows (ZAW) efforts to reduce the overall cost of deploying, using, and managing desktop computers.

    This article is not meant as a replacement for the Visual Studio Installer (VSI) documentation, which you should read first. It is merely a supplement to assist Visual FoxPro developers in using VSI as an alternative to the Visual FoxPro 6.0 Setup Wizard. We highly recommend you reread the Visual Studio Installer Best Practices section on how to package your application components, available in the VSI documentation.

    Additionally, you should read the accompanying tutorial article, Microsoft Visual FoxPro 6.0 Visual Studio Installer Tutorial, which walks you through the process of creating an installer package with your Visual FoxPro application.

    This article is broken down into sections based on typical distributed application scenarios. At the end, you will find a reference guide to assist you in creating VSI setup scripts.

    Visual FoxPro Distribution Scenarios

    Simple Executable Application

    Many typical Visual FoxPro applications today are built entirely with Visual FoxPro and use native Fox data (that is, .dbc and .dbf files). The following steps are general guidelines to follow for creating a Visual Studio Installer setup for your Visual FoxPro distributed application.

    Note   The accompanying tutorial, Microsoft Visual FoxPro 6.0 Visual Studio Installer Tutorial provides more details if you are not familiar with the basics of using Visual Studio Installer.

    1. Open a new project. Launch the Visual Studio Installer and select a new project of type Empty Installer.
    2. Add application files. You can add files from the Project menu’s Add File(s) item or drag and drop them from the Windows Explorer to either the Project Explorer or File System window. (You cannot drag and drop an entire folder, only files from within.)
    3. Set application file locations. This step ensures that your application files are installed in the proper target location. Use the File System window to place files in the location where you want them installed.Note   If you manually drag and drop files from the Windows Explorer, the application folder structure is not preserved. You need to manually add subfolders to the Application Folder in the File System window to preserve the folder structure.
    4. Set file-specific settings. Open the Properties window to set individual file install settings for any file in your VSI project.
    5. Add a shortcut to application. You can select the User’s Desktop or User’s Start Menu folder in File System window as a place to create a shortcut to your main application. After selecting the desired location, right-click on the right pane and select Create Shortcut. Pick the name of your application from the dialog. If you want, you can add additional shortcuts to other files your application uses.
    6. Add required merge modules. Merge modules are packages of files and install information for common shared components. With Visual FoxPro applications, you should include the following merge modules:
      • VFP6RUN.MSM
      • MSVCRT.MSM
      • OLEAUT32.MSM
      Merge modules that ship with VSI are installed in the following location:C:\Program Files\Microsoft Visual Studio\Common\Tools\VSInst\BuildRes

    Copy

    This location includes MSVCRT.MSM and OLEAUT32.MSM. Merge modules can be added to your project in a way that is similar to how you add a file. The **Project** menu’s **Add Merge Module(s)** item allows you to do this.
    
    > **Note**`   `Windows 2000 installs files in these last two merge modules under System File Protection. If you are only distributing your application to customers running Windows 2000, you do not need to include these modules.
    
    
    1. Set Project Options. You do this through the Project menu’s myproject Properties item (see VSI documentation).Important   Choose the appropriate Build Type option based on your target customer. Picking the Installer with Windows Installer Loader option will add an extra 2.6 megabytes (MB) to the entire setup, but it is required for customers who do not have the Windows Installer loaded on their machines.
    2. Set additional VSI installer options (see VSI documentation).
    3. Build your .msi installer package file by selecting Build from the Build menu.

    The output of your project is a Microsoft Installer package file (.msi), which any user can double-click to run. See the section Distributing Your Application below for more details.

    Executable Application with ActiveX Controls

    A common element of many Visual FoxPro applications is ActiveX® Controls. You can include ActiveX Controls with your VSI setups by following these steps:

    1. Follow steps in the Simple Executable Application scenario above.
    2. Include the COMCAT.MSM merge module. Note that Windows 2000 also installs files in this merge module.
    3. Follow additional steps below based on specific ActiveX Controls being installed:Common ActiveX Controls—these are the common controls, which ship with Visual FoxPro 6.0 and Visual Studio 6.0. VSI ships with merge modules for most of these controls. Simply add the appropriate merge module for that control (see the Reference Guide below). For example, if your application uses the Treeview control, you should include the MSCOMCTL.MSM merge module.VBCCE Controls—Visual Basic® 6.0 allows developers to create custom ActiveX Controls. You will need to manually add this control to the project and set certain properties (for example, install location, registration). You can set the Register property for the ActiveX Control file to vsifrSelfReg (1) to register the file (see Important below for more details). The install location for this control can be the same as the application if the control is not likely to be shared with other applications. In addition to the actual control, you will also need to include the Visual Basic run-time merge module (MSVBVM60.MSM).MFC Controls—some of the older controls, such as the Calendar control, use the MFC libraries. You should include the MFC42.MSM merge module if this is the case. As with VBCEE controls, you will need to manually add the control to the project and set various settings.Third-Party Controls—refer to documentation provided by the vendor on how and where to install the control. Make sure you register the control. The documentation should also provide information on any dependency files needed (for example, MFC, Visual Basic run time). You may also have to add specific Registry keys (use VSI Registry window) for any necessary licensing requirements.

    Important   To ensure the Microsoft Windows installer knows about your installed files to roll back or advertise them, you must install the files in a manner compliant with Windows Installer requirements. Self-registering your files is not compliant with Windows installer requirements. The Associations Editor in Visual Studio Installer makes it possible for you to install Windows installer-compliant COM objects. For more information, see the Visual Studio Installer documentation.

    If you choose to register controls by setting the Register property to vsifrSelfReg, then you should also set the SharedLegacyFile property so that the application can be properly reference counted. This is essential if that control is shared by multiple applications.

    Note   The Common ActiveX Controls included in the VSI merge modules contain registration information that is Windows installer-compliant.

    Applications with HTML Help

    The VFP6RUN.MSM merge module includes both FOXHHELP.EXE and FOXHHELPPS.DLL files needed to support context HTML Help within your Visual FoxPro 6.0 applications. Besides your application specific .chm file, you will need to include the core HTML Help viewer files. The HTML Help viewer files are available as a redistributable called HHUPD.EXE, which can be downloaded from the MSDN Web site https://msdn.microsoft.com/library/tools/htmlhelp/wkshp/download.htm. Users will need to run this HHUPD.EXE installer after they run the .msi installer.

    Applications using MDAC Components

    If your applications use any of the following data components, you will want to include the Microsoft Data Access Components merge module (MDAC.MSM).

    • ODBC Drivers
    • OLE DB Providers
    • ADO
    • RDS

    Important   The MDAC merge module does not actually contain any MDAC files. It simply provides a check for the installer. If MDAC is not installed on the user’s system, then a message dialog is displayed indicating that the user needs to also install these components. You will still need to include the actual MDAC redistribution setup with your application. This setup (MDAC_TYP.EXE) is included at the following Visual FoxPro 6.0 SP3 location:

    <vfproot>\Distrib.src\System\

    You can also obtain MDAC_TYP.EXE from the Microsoft web site. Users will need to run the MDAC_TYP.EXE installer manually after they run the .msi installer.

    Shared Components

    Often, applications consist of components that are shared by multiple applications. Visual FoxPro frameworks, foundation classes, and other shared files and class libraries are examples of these types of components. As described in the Visual Studio Installer documentation, it is recommended that these types of files be combined into merge modules, which can be included later with any application installer package. This ensures that files are always installed in a consistent manner.

    The Visual Studio Installer also lets you combine files (as well as shortcuts, registry keys, and so on) into a common component. However, the Visual Studio Installer best practice recommendation is to make each file included in your installer project a component. One of the limitations of combining multiple files into a single component is that all files must be installed in the same directory on the target machine. A good example of when you might combine multiple files into a single component is Visual FoxPro binary files (for example, dbf/fpt, scx/sct, frx/frt, lbx/lbt).

    COM Servers

    A specific example of components that could be packaged into merge modules is a Visual FoxPro COM Server (both Local .exe and In-Proc .dll servers). You can then add your COM Server merge module to any VSI installer project.

    Correctly installing and registering COM objects is necessary to take advantage of Windows installer rollback and advertising features. As explained in the VSI documentation, two powerful features of the Windows installer are the abilities to:

    • Roll back an unsuccessful installation, returning the target machine to its preinstallation state.
    • Advertise installed products or even individual elements of a product, such as COM objects. Advertising makes a product or COM object available to the user or target machine (by placing a shortcut in the appropriate place, such as the Start menu or registry) without installing the product until the user or another machine function specifically calls the advertised element.

    To support rolling back component installation and registration if your product installation fails and component advertisement on the target machine, you must register installed COM objects by establishing the necessary associations. You can choose not to do so by self-registering your installed COM objects, but this sacrifices the enhanced Windows installer rollback and advertising functionality.

    With traditional scripted setup programs, self-registration was the accepted method for installing COM objects, and it is still a viable method. However, the Windows installer cannot perform rollback installations and registration of self-registered COM objects, and it cannot advertise those objects. This is because self-registered COM objects do not pass their installation and registration information to the Windows installer.

    To ensure that the Windows installer knows enough about your installed COM objects to perform a rollback on or advertise them, you must install those COM objects in a manner compliant with Windows installer requirements. With the Associations editor in Visual Studio Installer, you can install Windows installer-compliant COM objects.

    Additionally, type library information for the COM Server must also be captured because it is also registered in the Registry. With Visual FoxPro, a type library can be bound inside of the .exe or .dll server file, or exist separately as a .tlb file.

    When authoring a VSI setup to include a Visual FoxPro COM Server, you have two options for handling server registration:

    Option 1: You can set the Register property for the COM Server file to vsifrSelfReg (1). This option performs the older style self-registration. However, you lose many of the Windows installer capabilities just mentioned. It is the easiest option for authoring your VSI setup.

    Option 2: The recommended approach for registering COM servers requires a little more work. You will need to manually add Registry keys and COM Object associations to the VSI setup. Let’s walk through an example (note that all the sample files are included with the sample download at the top of this article):

    1. First, add your COM server file(s) to the setup. This is either the .exe or .dll file you created. If you built this file using Windows NT® under Visual FoxPro 6.0 Service Pack 3 (SP3), you do not need to include the .tlb type library file because it is bound into the server file. Otherwise, you need to include this file. After adding these files to the project, make sure to set the Register property to 0 so that they are not self-registered during installation.You can optionally add the server’s .vbr file, which is used by CLIREG32.EXE to register a COM server remotely.Note   The Visual Studio Installer does not support post-install actions as the Visual FoxPro Setup Wizard does, so you need to run CLIREG32.EXE separately after the setup.
    2. Open up the File System window from Target Machine node and select an install location for your server components. The Visual FoxPro 6.0 Setup Wizard typically installs COM servers in the Windows\OleSrv\ folder. You can choose to install to this location if you feel that your component may be shared by multiple applications. If you want to isolate your component specific for a single application, you can install it in the same location as the application.
    3. Author the Registry keys necessary to register the COM server. You can obtain the information to do this by opening up the .vbr file for that server. This file contains all the Registry keys written out when one self-registers a COM server (for example, REGSVR32 foxdemo1.dll). The following .vbr file contents are from a sample COM server called FOXDEMO1.DLL (note that this sample has just one OLEPUBLIC server and is specific for a multithreaded .dll server):VB5SERVERINFO VERSION=1.0.0

    HKEY_CLASSES_ROOT\foxdemo1.foxsvr1 = foxdemo1.foxsvr1 HKEY_CLASSES_ROOT\foxdemo1.foxsvr1\NotInsertable HKEY_CLASSES_ROOT\foxdemo1.foxsvr1\CLSID = {F802CDC0-D690-4603-9936-6860B86A3163} HKEY_CLASSES_ROOT\CLSID{F802CDC0-D690-4603-9936-6860B86A3163} = foxdemo1.foxsvr1 HKEY_CLASSES_ROOT\CLSID{F802CDC0-D690-4603-9936-6860B86A3163}\ProgId = foxdemo1.foxsvr1 HKEY_CLASSES_ROOT\CLSID{F802CDC0-D690-4603-9936-6860B86A3163}\VersionIndependentProgId = foxdemo1.foxsvr1 HKEY_CLASSES_ROOT\CLSID{F802CDC0-D690-4603-9936-6860B86A3163}\InProcServer32 = foxdemo1.dll HKEY_CLASSES_ROOT\CLSID{F802CDC0-D690-4603-9936-6860B86A3163}\InProcServer32\”ThreadingModel” = Apartment HKEY_CLASSES_ROOT\CLSID{F802CDC0-D690-4603-9936-6860B86A3163}\TypeLib = {1995B333-9FA9-4819-A320-DA074AB37324} HKEY_CLASSES_ROOT\CLSID{F802CDC0-D690-4603-9936-6860B86A3163}\Version = 1.0 HKEY_CLASSES_ROOT\INTERFACE{DB1D22E5-826B-47DF-95DD-516527BD6E8E} = foxsvr1 HKEY_CLASSES_ROOT\INTERFACE{DB1D22E5-826B-47DF-95DD-516527BD6E8E}\ProxyStubClsid = {00020424-0000-0000-C000-000000000046} HKEY_CLASSES_ROOT\INTERFACE{DB1D22E5-826B-47DF-95DD-516527BD6E8E}\ProxyStubClsid32 = {00020424-0000-0000-C000-000000000046} HKEY_CLASSES_ROOT\INTERFACE{DB1D22E5-826B-47DF-95DD-516527BD6E8E}\TypeLib = {1995B333-9FA9-4819-A320-DA074AB37324} HKEY_CLASSES_ROOT\INTERFACE{DB1D22E5-826B-47DF-95DD-516527BD6E8E}\TypeLib\”Version” = 1.0

    ; TypeLibrary registration HKEY_CLASSES_ROOT\TypeLib{1995B333-9FA9-4819-A320-DA074AB37324} HKEY_CLASSES_ROOT\TypeLib{1995B333-9FA9-4819-A320-DA074AB37324}\1.0 = foxdemo1 Type Library HKEY_CLASSES_ROOT\TypeLib{1995B333-9FA9-4819-A320-DA074AB37324}\1.0\0\win32 = foxdemo1.dll HKEY_CLASSES_ROOT\TypeLib{1995B333-9FA9-4819-A320-DA074AB37324}\1.0\FLAGS = 0

    If you take a close look at the .vbr file, you will see that there are four groups of Registry keys that we need to add. These are keys for PROGIDCLSIDINTERFACE, and TYPELIB. All of the keys fall under the HKEY_CLASSES_ROOT Registry hive. It is a good idea to open up the Registry using REGEDIT to see how the keys should appear. You can later run your .msi setup to see if the Registry keys are being written out properly.

    • PROGID—the PROGID keys are used by COM when you create an instance of the COM server. For example, in the above server, one would call the following:oServer = CreateObject(“foxdemo1.foxsvr1”) The PROGID keys are simply added to your VSI project through the Registry window. Right-click the appropriate node to add new Keys and String Values. You can copy and paste values from the .vbr file to save time.
    • CLSID—the CLSID keys (HKEY_CLASSES_ROOT\CLSID) require a little extra work because you will want to associate your COM server with these keys. You will first add most of the keys similar to the PROGID keys above using the Registry window.Note   A few Registry keys written out during a self-registration are not included in the .vbr file (Implemented Categories and Programmable). The sample includes these. You can also see them in the Registry using REGEDIT.Once you have entered all of the Registry keys except the one with the reference to the actual server file, you need to add a COM Object association for this file using the Associations window. The VSI documentation explains this. Make sure you enter the proper CLSID value.Note   The Windows installer actually adds an extra string value to this Registry key during install. This value may look a little weird, but it is needed by the Windows installer for features such as Advertising.
    • INTERFACE—the Interface keys are entered just like the PROGID keys using the Registry window.
    • TYPELIB—the last set of keys to add are the TYPELIB keys. Again, you will use the Registry window to do this (do not use the VSI Type Libraries option under the Associations window). The one tricky part is entering the name of the file under the WIN32 key because you don’t always know exactly where the file will be installed. The Windows Installer allows you to place custom properties or wildcards in the Value property. For example, you could set the value of the WIN32 key to the following:[TARGETDIR]foxdemo1.dll During the install process, the wildcard placeholder is replaced with the actual value of the folder specific to the target machine. In addition, you will need to use a Windows Installer property for the HELPDIR key. The Appendices below have some of the common Windows installer properties. Refer to the Windows 2000 Platform SDK for more details.

    You are now done and simply need to build your .msi installer package or .msm merge module. It is always a good idea to thoroughly test any setup such as this where you have manually entered Registry keys.

    **Tip   **If you are installing your COM Server onto a Windows 2000 or Windows 98 (Second Edition or later) machine, you should seriously consider installing the component directly to the application directory so that it is isolated from other applications. In order to do this, you must use Option 2 to register your component. The one difference to make in your setup is not to use the Associations window for handling the CLSID registry keys. Instead, you should simply add an entry in the Registry window with the name of your COM server but without a path. If no path is included, COM will first look in the application folder for that component. For more details on isolating components, go to http://search.microsoft.com/us/dev/default.asp and search on “DLL Hell.”

    Localized Applications

    The VFP6RUN.MSM file includes the standard language-neutral resource file (VFP6RENU.DLL), which is used for all English (US) shipping applications. If you want to include support for another localized resource file (VFP6Rxxx.DLL), simply drop that file into the project and install it in the Windows System folder. It does not need to be registered. You should set the File’s DoNotUninstall property to True. For example, include VFP6RDEU.DLL for the German run-time resource file.Expand table

    LanguageResource File
    GermanVFP6RDEU.DLL
    FrenchVFP6RFRA.DLL
    SpanishVFP6RESP.DLL
    Simplified ChineseVFP6RCHS.DLL
    Traditional ChineseVFP6RCHT.DLL

    Unsupported Scenarios

    The Visual FoxPro 6.0 Setup Wizard should still be used for the following scenarios:

    • Applications requiring post-executable actions.
    • Applications requiring Microsoft Graph run-time files.
    • COM Servers requiring DCOM and/or remote automation support (this can be done by manually adding Registry keys, but is not as flexible as Visual FoxPro Setup Wizard).

    Distributing Your Application

    When you distribute your application, you should still follow many of the same guidelines mentioned in the Visual FoxPro documentation. VSI setups (.msi files) use the new Windows Installer technology, which is available on certain platforms. The following steps are general installation instructions when distributing your application to customers. There are two basic scenarios to consider:

    • Installer package built with the Installer with Windows Installer Loader Build Type option. In the near future, this is likely to be the type of installation package you will want to create because many of your customers will still be running on older Windows operating systems. The user simply needs to run the SETUP.EXE file to install the entire application. This bootstrap loader file first checks for and, if necessary, installs the Windows Installer, then it installs your .msi package setup.—or—
    • Installer package not built with the Installer with Windows Installer Loader Build Type option. With these setups, the user already has Windows Installer installed on his or her machine. The user simply needs to run (double-click) the .msi package file to install it.

    Install any additional required setups (users will need to run these separately):

    • MDAC_TYP.EXE—if your application uses any MDAC components.
    • HHUPD.EXE—if your application uses HTML Help.

    Note   Building an installer with the Windows installer bootstrap loader creates these distinct files as part of your installer package. You must include all of these files on the media that you choose to distribute your application:

    • Your .msi file.
    • SETUP.EXE—the file that determines whether or not the Windows installer resides on the target machine and installs the Windows installer if necessary.
    • SETUP.INI—the file that tells SETUP.EXE the name of your .msi file to install.
    • INSTMSIW.EXE—the Windows installer for Windows NT machines. (Windows NT 3.51 is not supported.)
    • INSTMSIA.EXE—the Windows installer for Windows 95 and Windows 98 machines.

    Appendices

    VFP6RUN Merge Module

    The VFP6RUN.MSM merge module properly installs the necessary files to support your Visual FoxPro distributed applications, including COM servers, Active Documents, and normal Windows executables. As with the Visual FoxPro 6.0 SP3 Setup Wizard, run-time files are installed and registered in the Windows System directory. Because the VFP6RUN.MSM merge module is properly authored for Windows installer file installation and registration, it can take advantage of rollback and advertising features. The following files are included in the VFP6RUN merge module:Expand table

    File
    VFP6R.DLL
    VFP6T.DLL
    VFP6RENU.DLL
    VFP6RUN.EXE
    FOXHHELP.EXE
    FOXHHELPPS.DLL

    Reference Guide to VSI Merge Modules

    Expand table

    Core ComponentsMerge Module
    OLE Automation Support FilesOLEAUT32.MSM
    Microsoft Visual C Run-Time LibrariesMSVCRT.MSM
    Microsoft Component Category Manager LibraryCOMCAT.MSM
    Microsoft Foundation ClassesMFC42.MSM
    Visual Basic 6.0 Run-Time LibraryMSVBVM60.MSM
    Microsoft Data Access Components 2.1MDAC.MSM

    Expand table

    ActiveX ControlsMerge Module
    Microsoft Animation Control (v5.0)Microsoft UpDown Control (v5.0)COMCT232.MSM
    Microsoft Coolbar Control (v6.0)COMCT332.MSM
    Microsoft TabStrip Control (v5.0)Microsoft Toolbar Control (v5.0)Microsoft StatusBar Control (v5.0)Microsoft ProgressBar Control (v5.0)Microsoft TreeView Control (v5.0)Microsoft ListView Control (v50)Microsoft ImageList Control (v5.0)Microsoft Slider Control (v5.0)COMCTL32.MSM
    Microsoft Common Dialog Control (v6.0)COMDLG32.MSM
    Microsoft Data Bound Grid Control (v5.0)DBGRID32.MSM
    Microsoft DBList Control (v6.0)Microsoft DBCombo Control (v6.0)DBLIST32.MSM
    Microsoft Multimedia Control (v6.0)MCI32.MSM
    Microsoft Chart Control (v6.0) (OLE DB)MSCHRT20.MSM
    Microsoft Animation Control (v6.0)Microsoft UpDown Control (v6.0)Microsoft MonthView Control (v6.0)Microsoft Date and Time Picker Control (v6.0)Microsoft Flat ScrollBar Control (v6.0)MSCOMCT2.MSM
    Microsoft TabStrip Control (v6.0)Microsoft Toolbar Control (v6.0)Microsoft StatusBar Control (v6.0)Microsoft ProgressBar Control (v6.0)Microsoft TreeView Control (v6.0)Microsoft ListView Control (v6.0)Microsoft ImageList Control (v6.0)Microsoft Slider Control (v6.0)Microsoft ImageComboBox Control (v6.0)MSCOMCTL.MSM
    Microsoft Communications Control (v6.0)MSCOMM32.MSM
    Microsoft FlexGrid Control (v6.0)MSFLXGRD.MSM
    Microsoft Hierarchical FlexGrid Control (v6.0)MSHFLXGD.MSM
    Microsoft Internet Transfer Control (v6.0)MSINET.MSM
    Microsoft MAPI Session Control (v6.0)Microsoft MAPI Message Control (v6.0)MSMAPI32.MSM
    Microsoft Masked Edit Control (v6.0)MSMASK32.MSM
    Microsoft Winsock Control (v6.0)MSWINSCK.MSM
    Microsoft Picture Clip Control (v6.0)PICCLP32.MSM
    Microsoft SysInfo Control (v6.0)SYSINFO.MSM
    Microsoft Tabbed Dialog Control (v6.0)TABCTL32.MSM

    Common Windows Installer Properties

    Expand table

    Property nameBrief description of property
    SourceDirRoot directory containing the source files.
    TARGETDIRLocation into which the installation package is copied during an administrative installation.
    AppDataFolderFull path to the Application Data folder for the current user.
    CommonFilesFolderFull path to the Common Files folder for the current user.
    DesktopFolderFull path to the Desktop folder.
    FavoritesFolderFull path to the Favorites folder for the current user.
    FontsFolderFull path to the Fonts folder.
    NetHoodFolderFull path to the NetHood folder for the current user.
    PersonalFolderFull path to the Personal folder for the current user.
    PrintHoodFolderFull path to the PrintHood folder for the current user.
    ProgramFilesFolderFull path to the Program Files folder.
    ProgramMenuFolderFull path to the Program Menu folder.
    RecentFolderFull path to the Recent folder for the current user.
    SendToFolderFull path to the SendTo folder for the current user.
    StartMenuFolderFull path to the Start menu folder.
    StartupFolderFull path to the Startup folder.
    System16FolderFull path to folder for 16-bit system DLLs.
    SystemFolderFull path to the System folder.
    TempFolderFull path to the Temp folder.
    TemplateFolderFull path to the Template folder for the current user.
    WindowsFolderFull path to the Windows folder.
    WindowsVolumeThe volume of the Windows folder.

    Using MSMQ with Microsoft Visual FoxPro 6.0 

    • Article
    • 06/30/2006

    In this article

    1. Introduction
    2. All About MSMQ
    3. Features of MSMQ
    4. Terminology Overview

    Show 8 more

    Randy Brown
    Microsoft Corporation

    September 1999

    Summary: This article guides Visual FoxPro® developers through successfully writing Visual FoxPro code to access the Microsoft® Messaging Queue (MSMQ) COM objects directly. Many tips and tricks specific to Visual FoxPro are scattered throughout the code samples. (37 printed pages)Expand table

    Click to copy the MSMQwVFP6 sample file.

    Contents

    Introduction All About MSMQ Features of MSMQ Terminology Overview Programming MSMQ with VFP Basic Queue Operations Basic Message Operations Message Acknowledgments Response Messages Advanced VFP Programming for MSMQ Working with MSMQ Transactions Going Forward

    Introduction

    Microsoft® Messaging Queue (MSMQ) is an exciting technology that every Visual FoxPro® developer can employ in his or her application. This document will guide you through successfully writing Visual FoxPro code to access the MSMQ COM objects directly. Many tips and tricks specific to Visual FoxPro are scattered throughout the code samples. Many of the code samples contained in this document are included with the Visual FoxPro MSMQ web pack.

    The first part of this document describes general MSMQ concepts that you need to know. If you are already familiar with MSMQ, you can go directly to the programming sections.

    In preparation for reading this article, you may want to first install MSMQ and read through the documentation. The MSMQ SDK documentation is more detailed and recommended for developers. This article repeats sections from topics in the MSMQ documentation. If you have installed Microsoft Windows® 2000, the Component Services documentation contains expanded detail on messaging services:

    Note   There are differences between MSMQ 1.0 and 2.0 features not documented here, which appear in the Windows 2000 docs.

    MSMQ 1.0 is included as part of the Windows NT4 Options Pack, which is a free download from the Microsoft MSMQ Web site:

    www.microsoft.com/ntserver/appservice/exec/overview/MSMQ_Overview.asp

    MSMQ 1.0 is not installed by default, but rather as an option available in the Custom setup. MSMQ 2.0 will be incorporated directly with future versions of Windows. This document describes MSMQ in a version-independent manner, however, differences between versions, will be noted where applicable.

    Throughout this document, you will see references to e-mail. E-mail and Messaging are often compared and confused. In fact, many people often distinguish between the two with following analogy: E-mail is to People as Messaging is to Applications.

    All About MSMQ

    With the trend toward distributed computing in enterprise environments, it is important to have flexible and reliable communication among applications. Businesses often require independent applications running on different systems to communicate with each other and to exchange messages even though the applications may not be running at the same time.

    MSMQ is a “fast store-and-forward” service for Windows NT Server Enterprise Edition (Windows NT Server/E), that enables applications running at different times to communicate across heterogeneous networks and systems that may be temporarily offline. Applications send messages to MSMQ, and MSMQ uses queues of messages to ensure that the messages eventually reach their destination. MSMQ provides guaranteed message delivery, efficient routing, security, and priority-based messaging.

    Message queuing is like e-mail (asynchronous) versus the telephone (synchronous). See the example in Figure 1:

    Figure 1. Asynchronous versus synchronous communication

    Features of MSMQ

    MSMQ version 1.0 supports the following features:

    • Asynchronous communication
    • Message-Oriented Middleware (MOM) Connectionless messaging. With store-and-forward message queuing, applications aren’t affected by network fluctuations and do not have to establish sessions. Because MSMQ uses a sessionless model at the application level, the sender and receiver don’t need to support the same protocol. MSMQ supports Internet Protocol (IP) and Internet Packet eXchange (IPX).
    • Network traffic prioritization. Message prioritization allows urgent or important traffic to preempt less-important traffic so you can guarantee adequate response time for critical applications at the expense of less important applications.
    • Guaranteed delivery. Messages can be logged to a disk-based queue to provide guaranteed delivery.
    • Transactions. The MSMQ transaction flag can be used to implement transaction-based applications, ensure messages are delivered in order, ensure messages are delivered no more than once, and confirm messages reached or were retrieved from the destination queue.
    • Dynamic queues. Queue information resides in a dynamic/replicated database so administrators can change queue properties without affecting messaging applications. Using MSMQ Explorer, administrators can make these changes from any computer running MSMQ Explorer.
    • Routing. MSMQ supports smart routing, based on the physical topology of the network, session concentration, and transport connectivity. Session concentration allows efficient usage of slow links.
    • Security. MSMQ supports privacy and security through access control, auditing, encryption, and authentication. Access control is implemented using Windows NT security and digital signatures. Auditing is implemented through the Windows NT event logging service. Encryption and authentication (using digital signatures) are supported using public and private keys.
    • Disparate system integration. MSMQ-based applications can be implemented across a wide variety of hardware platforms using MSMQ connectivity products provided by Level 8 Systems.

    Dynamic queues, integrated security, manageable scalability, and smart routing differentiate MSMQ from other middleware implementations available today.

    MSMQ differs from Remote Procedure Calls (RPC), where applications are required to maintain sessions, and from Windows Sockets, and messaging API (MAPI). Although Windows Sockets provides low-level functions for writing applications, Windows Sockets does not allow applications to run at different times in the way that MSMQ does and MSMQ uses a more general-purpose message queuing model than MAPI.

    Terminology Overview

    MSMQ applications communicate between computers using a unit of information (text or binary data) called a messageTransactional messages, those which can be discarded if the transaction is aborted, can be used to pair the sending or receiving of any message with an action in another operation. Using transactional messages ensures that the unit of work is carried out as an atomic operation, that is, the operation succeeds or fails as a whole. Transactional messages can also be used to ensure that a message is delivered only once and that all messages sent from one computer to another are delivered in order. Positive and negative acknowledgements can be used to confirm messages reached or were retrieved from the destination queue. See Figure 2.

    Figure 2. Transactional messages

    MSMQ supports two delivery methods: express and recoverable. Choosing between express and recoverable delivery is a matter of trading performance and resource use for reliability and failure recovery. Express messages use fewer resources and are faster than recoverable messages, but cannot be recovered if the computer storing the memory-mapped message fails. Recoverable messages use more resources and are slower than express messages, but can be recovered no matter which computer fails.

    MSMQ uses public and private queues to store and forward messages. All MSMQ queues, regardless of their function, can be manipulated with the same MSMQ functions. This includes the special journal, dead letter, transactional dead letter, administration, system, and report queues. Each of the queues is simply a standard MSMQ queue used for a specific purpose. For more information on the MSMQ API, see the Microsoft Message Queuing Services Software Development Kit (MSMQ SDK).

    MSMQ routes and delivers messages based on a combination of queue priority and message priority. Messages are routed and delivered by queue priority first, and message priority second.

    MSMQ supports dependent clientsindependent clients, and servers. Independent clients and servers run the MSMQ Services and can communicate asynchronously, while MSMQ-dependent clients require synchronous access to an MSMQ Service.

    Some components of MSMQ Services hold copies of the MSMQ information store (MQIS) database. The MQIS is a distributed database that holds enterprise topology, enterprise settings, computer information, and queue information. MSMQ-based applications can query the MQIS to find queues and get queue properties.

    Note   With MSMQ 2.0, the MSMQ information store can also be Microsoft Active Directory™ services.

    All computers operate within one MSMQ enterprise, divided into sites, and connected through site links. Site link costs define the cost of sending messages between sites, making communication between any two computers fast and inexpensive. Computers running in MSMQ communicate over connected networks (CNs), a collection of computers where any two computers can communicate directly. MSMQ Services designated as in routing servers (InRSs), out routing servers (OutRSs), and site gates can be used to control the flow of messages and provide session concentration. MSMQ Services take all these factors into account when routing messages within your MSMQ enterprise.

    Note   Many of the MSMQ topology concepts have changed with MSMQ 2.0. PECs (Primary Enterprise Controllers) are now Domain Controllers, and the concept of connected networks no longer exists. Make sure to read through these documents carefully.

    Programming MSMQ with VFP

    This section of this article focuses on Visual FoxPro-specific programming practices for integrating MSMQ into your applications.

    Using the MSMQ ActiveX® objects, you can program all common messaging needs including:

    • Creating a message queue
    • Getting a List of Available Queues
    • Opening and deleting queues
    • Sending messages
    • Reading messages
    • Sending messages with acknowledgments
    • Responding to an event triggered when message arrives in queue

    There are various ActiveX objects (COM servers) available for accessing MSMQ, including those for handling queues, messages and events. This article is not a language reference, so not all the available objects, properties and methods are mentioned below. The focus is on specific scenarios with emphasis on real-world sample code. For information on all the MSMQ objects, refer to the Microsoft Message Queuing Services Administrator’s Guide:

    • MSMQQuery
    • MSMQQueueInfos
    • MSMQQueueInfo
    • MSMQQueue
    • MSMQMessage
    • MSMQEvent
    • MSMQApplication
    • MSMQCoordinatedTransactionDispenser
    • MSMQTransaction
    • MSMQTransactionDispenser

    You may not have a need for all of these objects (especially some of the transaction ones), but it’s a good idea to be somewhat familiar with them.

    In addition to the core set of objects, MSMQ also provides a rich set of automation components that support composing and parsing the body of MSMQ mail messages, which are used to communicate with e-mail based applications through the MSMQ mail services. These include objects such as MSMQMailEMailMSMQMailFormData, and MSMQMailRecipient. See the MSMQ SDK docs for more details.

    Before you begin using VFP and MSMQ, read some of the comments in source code. They contain valuable tips and idiosyncrasies with using the MSMQ objects.

    Important   It is highly recommended that you use Visual FoxPro 6.0 SP3 or higher when programming against MSMQ. There are API functions that require this version.

    Listed below are a few examples of why you should incorporate MSMQ into your applications.

    • Applications that are often disconnected – many Fox developers today are creating distributed multi-tier applications. With these types of applications, it’s sometimes the case where client machines are taken offline from the host server machine(s). This can apply to both Web or LAN based situations. One of the big advantages of MSMQ is that it handles both offline and online scenarios transparently, saving you from writing separate offline and online application logic.Think of this being similar to your e-mail client. You can write e-mail messages both offline and online without any behavioral distinction.
    • Asynchronous messaging – have you ever written a Visual FoxPro application where one of the application operations takes a long time to perform (e.g. printing a report, re-indexing a large database, etc.)? Visual FoxPro does not return control to the user until the operation is completed. This can be very annoying to the end user who is trying to be productive with your application. Many Visual FoxPro developers employ kludges to handle these situations such as Timers and DO WHILE loops which continuously poll some resource (e.g., file or table) for a change (semaphore) made by the application. These types of coding habits are not efficient and needlessly waste valuable system resources and processor time. With asynchronous messages, you can setup a VFP object that sits in limbo until a message arrives in a queue. Once this event happens, a method on your VFP object is called. You can call a VFP COM server, which runs in its own process, to handle the application request and allow the user to continue working. The MSMQ Message can contain all the information being passed from your application to your VFP COM “helper” server.
    • Workflow type applications – typical office settings today require efficient passing of information such as documents between various members of the organization. Along the way, this information is often manipulated and refined. With MSMQ, you can keep a nice audit trail and information can be passed in a secured fashion with guaranteed delivery. Because messages can be sent in a transaction, they will be protected from various risks to the system. See the Response Messages section below for more details.

    Basic Queue Operations

    Creating a Message Queue

    One of the first tasks you will want to do with MSMQ is to create a queue so that you can store messages. The simplest way to do this is by using the MSMQ explorer.

    1. In the MSMQ Explorer, right-click a computer node and select New -> Queue.
    2. In the dialog, enter a name for your queue. You will need to decide whether to make it transactional.

    Programmatically, you can create a queue with just a few lines of code. Here is the basic code you need to create a public message queue.

    lcQueueName = “MyQueue1”
    oQueueInfo = CreateObject(“msmq.msmqqueueinfo”)
    oQueueInfo.Pathname = “.\”+lcQueueName  &&must be unique
    oQueueInfo.Label = lcQueueName
    oQueueInfo.Create
    

    The important Pathname property controls the name and location of the queue. Because it is based on UNC naming conventions, you can include the computer name, or for local queues, use the “.\” qualifier. Alternately, you can use the FormatName property instead of Pathname. The FormatName property is the recommended strategy because it is better suited for offline work. You should be getting a reference to the QueueInfo object. There is a QueueInfos object that represents a collection of QueueInfo objects. Think of a QueueInfo as simply an object containing specific information about the Queue itself such as location. However, there is one important distinction, a QueueInfo does not contain any information about the contents of the queue. The information about the contents is stored in the Queue object. The Queue Query object, which is used to locate a specific queue, returns a QueueInfos object, distinguishing it from possible multiple queues with that same name existing within the enterprise.

    **Important   **To create a public message queue, you must be online (attached to a valid MSMQ Service (e.g., primary site controller). Independent clients cannot create public queues while offline.

    Before creating a public queue, check to see if it already exists by using the following syntax.

    lcQueueName = “myqueue1”
    
    * Try to locate queue first
    oQuery = create(“msmq.msmqquery”)
    
    * Lookup queue to see if it exists
    * Important - queue names are case-sensitive
    oQueueInfos = oQuery.LookupQueue(,,lcQueueName)
    
    * Move to first record in queue set
    oQueueInfo = oQueueInfos.Next()
    
    IF ISNULL(oQueueInfo)  &&queue not yet created so create it
       oQueueInfo = CreateObject(“msmq.msmqqueueinfo”)
       oQueueInfo.Pathname = “.\”+lcQueueName
       oQueueInfo.Label = lcQueueName
       oQueueInfo.Create
    ENDIF
    

    You may need to create a private queue for a variety of reasons, including performance and offline usage. A private queue is named similarly to that of a public queue except it has a “PRIVATE$\” qualifier immediately preceding the name of the queue.

    oQueueInfo.Pathname = “.\PRIVATE$\”+lcQueueName  &&must be unique
    

    Deleting a Message Queue

    While not necessarily a common operation, you may need to delete a particular queue. The following code snippet has this operation.

    IF MESSAGEBOX(“Delete queue?”,36+256)=6
       oQueueInfo = create(“msmq.msmqqueueinfo”)
       oQueueInfo.FormatName = cFormatName
       oQueueInfo.Delete
       RETURN
    ENDIF
    

    The QueueInfo’s PUBLIC format name is a unique identified key such as following:

    PUBLIC=179446c5-0001-11d3-8234-00c04f984590
    

    Getting a reference to a specific queue involves just two lines of code. This is an important concept to remember, that is, obtaining a reference to a specific queue whether it be for deleting, opening it up to send a message, opening it up to read a message, etc.

    oQueueInfo = create(“msmq.msmqqueueinfo”)
    oQueueInfo.FormatName = cFormatName
    

    Opening a Queue

    Queues are like tables with the messages being similar to records. Think of them also like cursors in that you can have many instances of the same queue open. The QueueInfo is 1:1 relation and points to the Queue object itself. A queue can be opened to either send messages, read (peek) messages, or retrieve (receive) messages. A queue can not be opened to both send and read a message with the same Open() call. However, you can open multiple instances of the same queue in different modes.

    To open a queue, you use the QueueInfo Open() method:

    oSendQueue = oQueueInfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)
    IF EMPTY(oSendQueue.IsOpen)
       RETURN
    ENDIF
    

    You are probably wondering about the checking here with IsOpen. You should always check to see if your Open operation succeeded. The queue may be unavailable or exclusively in use. The EMPTY() function is used because some versions of MSMQ return logical while others return 0/1.

    The source code includes an MSMQ.H file which is the #INCLUDE file for all the MSMQ constants. These constants are stored in the MSMQ type library. The samples include this file, but can alternately be recreated using the following code (you will need to have VB installed for the special COM server library that reads type libraries).

    * GETCONSTANTS.PRG
    LOCAL lctlbfile, oTLB, oTInfos, lcNewfile, i, j, lnTmpValue
    
    * MSMQ specific files
    lctlbfile = “c:\winnt\system32\mqoa.dll”
    lcNewFile = HOME()+”msmq.h”
    
    oTLB=create(“tli.tliapplication”)
    oTInfos=oTlb.TypeLibInfoFromFile(lctlbfile)
    
    SET TEXTMERGE ON NOSHOW TO (lcNewFile)
    \\* Constants for type library: <<lctlbfile>>
    \* <<oTInfos.HelpString>>
    \
    FOR i = 1 TO oTInfos.Constants.Count
       \* <<oTInfos.Constants[m.i].Name>> Enum
       \* <<oTInfos.Constants[m.i].HelpString>>
       FOR j = 1 TO oTInfos.Constants[m.i].Members.Count
          \#DEFINE 
          \\<<oTInfos.Constants[m.i].Members[m.j].Name>>    
          lnTmpValue = oTInfos.Constants[m.i].Members[m.j].Value    
          \\<<lnTmpValue>>
       ENDFOR
       \  
    ENDFOR
    
    SET TEXTMERGE TO
    SET TEXTMERGE OFF
    MODIFY FILE (lcNewFile) NOWAIT
    

    Getting a List of Available Public Queues

    You may have a need to get a list of all public queues available (independent clients need be online). The following code snippet populates an array aQueues with pathnames of public queues available.

    * Create/locate queue
    LOCAL oQuery,oQueueInfo,oQueueInfos,aQueues
    DIMENSION aQueues[1]
    
    oQuery = create(“msmq.msmqquery”)
    oQueueInfos = oQuery.LookupQueue()
    
    * Move to first record in queue set
    oQueueInfo = oQueueInfos.Reset
    oQueueInfo = oQueueInfos.Next
       
    DO WHILE !ISNULL(oQueueInfo)
       IF !EMPTY(aQueues[ALEN(aQueues)])
          DIMENSION aQueues[ALEN(aQueues)+1]
       ENDIF   
       aQueues[ALEN(aQueues)] = oQueueInfo.pathname
       oQueueInfo = oQueueInfos.Next
    ENDDO
    

    Getting List of Available Private Queues

    Obtaining a list of private queues is a little less intuitive, and the objects themselves do not support specific language to do this. The following work-around seems to handle this fine with MSMQ 1.0 and 2.0 (Microsoft does not support this strategy so use it at your risk).

    #DEFINE MSMQ_KEY         SOFTWARE\Microsoft\MSMQ\Setup”
    #DEFINE HKEY_LOCAL_MACHINE   2147483646
    
    LOCAL oQuery, QueueInfo, QueueInfos, aQueues, i, j, aKeys
    LOCAL aFiles,lcQueue,lcMSMQPath, oReg, oIni
    DIMENSION aQueues[1]
    DIMENSION akeys[1,1]
    DIMENSION aFiles[1]
    
    oReg = NewObject(“registry”,”ffc\registry.vcx”)
    oIni = NewObject(“oldinireg”,”ffc\registry.vcx”)
    IF oReg.EnumOptions(@akeys, MSMQ_KEY, HKEY_LOCAL_MACHINE, .F.) = 0
      FOR i = 1 TO ALEN(akeys,1)
        IF ATC(“Directory”,aKeys[m.i,1])#0
          lcMSMQPath = akeys[m.i,2]+”\Storage\LQS\”
          ADIR(aFiles, lcMSMQPath + “*.*”)
          FOR j = 1 TO ALEN(aFiles)
            lcQueue = ““
            oIni.GetIniEntry(@lcQueue,”Properties”,;
                “QueueName”,lcMSMQPath+aFiles[m.j])
            IF ATC(“private$”,lcQueue)#0
              IF !EMPTY(aQueues[ALEN(aQueues)])
                DIMENSION aQueues[ALEN(aQueues)+1]
              ENDIF
              aQueues[ALEN(aQueues)] = “.”+lcQueue
            ENDIF
          ENDFOR
          EXIT
        ENDIF
      ENDFOR
    ENDIF
    

    Basic Message Operations

    Once you have your queue created, you are going to want to create or read messages in it. By far, these are the most common things you do with messaging, just as you would do with e-mail.

    Creating/Sending a Message

    We now have our queue open specifically for sending a message. Remember, each object reference returned by the Open method can either be used for sending, peeking or receiving a message. However, you can have multiple concurrent object references, each performing a different function. Let’s go ahead and create a simple message.

    oMsg = create(“msmq.msmqmessage”)
    oMsg.Label = “My First Message”
    oMsg.Body = “This is body for my first message.”
    oMsg.Send(oSendQueue)
    

    In this example, we compose a message that is not dependent of any queue. The body of the message is text we want to post. Later, we will look at alternative content for the message body. When we are finished composing the message, we send it to a queue that we already have opened for sending messages. Sending messages is made simple using this core set of code, but there are lots of options/attributes that can be used.

    Sending Offline Messages

    If you are running an Independent Client machine that is temporarily offline, or the machine with the destination queue unavailable (e.g., offline), then you will need to handle opening a queue a little differently than the typical way using Pathname:

    oQueueInfo = create(“msmq.msmqqueueinfo”)
    oQueueInfo.Pathname = “randybr9\myQueue1”
    

    Earlier in this document, the FormatName was described as an alternative approach to using Pathname. If you are sending a message to a public queue while offline (even to your own machine), you must use the FormatName when getting a reference to the queue.

    Note   For private queues, it is fine to use Pathname.

    The reason for using FormatName is that MSMQ needs to access the MSMQ Services when getting information about a public queue to route the message (in MSMQ 1.0, this routing info is stored in a Microsoft SQL Server™ database called MQIS). In offline mode, this information is unavailable, so the queue cannot be opened.

    This concept is similar to working with e-mail offline. If you have your Microsoft Outlook® client opened offline and send a message, the message sits in limbo until you connect to your network where the e-mail server is available to resolve and provide proper routing information. The process of sending a message, when all information for proper routine is unavailable, is known in messaging lingo as Store and Forward.

    MSMQ provides this same service if your MSMQ Service is unavailable to route the message to a public queue. Instead of using the Pathname for queue specification, you use the FormatName. MSMQ supports several different types of Format Names for use. My preference is the Direct Format Name type (see MSMQ reference for details on other types).

    oQueueInfo = create(“msmq.msmqqueueinfo”)
    oQueueInfo.FormatName = “DIRECT=OS:randybr9\myQueue1”

    Here are some more examples of Direct Format Names:

    “DIRECT=TCP:157.18.3.1\MyQueue”
    “DIRECT=OS:elvisp.ms.com\myqueue”
    “DIRECT=OS:randybr2\PRIVATE$\myqueue”
    

    If using the Direct Format Name, MSMQ will not try to access queue information from the MQIS database. The message is in essence sent blindly to an address that may or may not exist. Until the machine is back online, that address cannot fully be resolved. This strategy can also improve performance. MSMQ will periodically check to see if you are online so that it can process the outgoing queues.

    Checking if you are Offline

    It’s a good idea if you are working with Independent Clients to have a check in your code to see if MSMQ is online/offline. Again, MSMQ does not support specific language for this, so you can try the following code:

    * This program checks to see if MSMQ is offline so
    * demos will use Private queues
    LOCAL x
    x = create(“checkoffline”)
    RETURN x.IsOffline()
    
    DEFINE CLASS checkoffline AS custom
    PROCEDURE IsOffline
       LOCAL lcQueueName,oQuery,oQueueInfos,oQueueInfo
       lcQueueName = ““
       oQuery = create(“msmq.msmqquery”)
       oQueueInfos = oQuery.LookupQueue
       oQueueInfo = oQueueInfos.Reset
       oQueueInfo = oQueueInfos.Next
       RETURN VARTYPE(oQueueInfo)#”O”
       
    PROCEDURE Error(p1,p2,p3)
    ENDDEFINE
    

    You should make sure you have a routine like this to determine if you can open a queue using Pathname or Formatname.

    Reading a Message

    Once your message queue starts to fill up with messages, you’ll probably want to read (handle) them. It is important that you understand the difference between reading (peeking) at messages vs. retrieving (receiving) them.

    MSMQ offers 2 options for viewing messages, the primary difference being the resulting action after processing of the message. If you Peek at a message, it is left in the queue. If you Receive a message, it is removed from the queue. The idea behind the later is that you are processing the message once and only once. These concepts are important because MSMQ guarantees delivery and is transactional. Acting on the same message twice can cause a redundant transaction. Again, you need to open a queue specifically for either of these types of message viewing.

    oRecQueue = oQueueInfo.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE)
    oPeekQueue = oQueueInfo.Open(MQ_PEEK_ACCESS, MQ_DENY_NONE)
    

    Let’s first look at message peeking. When you first open your queue for peeking, you need to see if any messages exist in the queue. The following code snippet shows this.

    oMsg = oPeekQueue.Peek(,,100)
    IF ISNULL(oMsg)
       ? “Queue is empty”
    ENDIF
    

    There are three Peek functions you can use (Peek, PeekCurrent, and PeekNext).

    Note   The documentation for these three functions for MSMQ 1.0 is incorrect in terms of the ordering of the parameters. The nReceiveTimeout parameter is actually the last parameter.

    PEEK([lWantsDesintationQueue],[lWantsBody],[nReceiveTimeout])
    

    The default for the nReceiveTimeout parameter is infinity, causing your machine to appear hung if it is trying to find a message in an empty queue. This documentation bug is also prevalent with the Receive and ReceiveCurrent functions. You can use the following code to iterate through all of the messages in your queue.

    oMsg = oPeekQueue.PeekCurrent(,,100)
    DO WHILE !ISNULL(oMsg)
       ? oMsg.Body,oMsg.Class
       oMsg = oPeekQueue.PeekNext(,,100)
    ENDDO
    oPeekQueue.Close
    

    Again, since we are only peeking at messages, none of the messages will be deleted from the queue. You can see them in the MSMQ Explorer. The next example shows actually Receiving messages for processing.

    nMessages = 0
    oMsg = oRecQueue.ReceiveCurrent(,,,100)
    DO WHILE !ISNULL(oMsg)
       nMessages = nMessages+1
       oMsg = oRecQueue.ReceiveCurrent(,,,100)
    ENDDO
    ? “Total messages:”,nMessages
    oRecQueue.Close
    

    If you run this code on your message queue, you will notice that the messages no longer appear in the Queue under MSMQ Explorer. Again, this is because Receiving messages causes their removal from the queue.

    Using a Journal

    You’re probably thinking that having messages removed from the queue is a bad thing since there is no way to trace their activity. And it’s likely that you want some sort of activity (audit) log for your application. MSMQ makes it simple to do this. When you create your public/private queue, you can automatically have an associated Journal queue created at the same time (or later on).

    oQueueInfo.Journal = 1 
    

    A Journal is simply an associated queue for processed messages. When a message is Received (via Receive or ReceiveCurrent), it is automatically processed and moved to the Journal queue. You can view the Queue’s Journal queue in the MSMQ Explorer by expanding the Queue’s tree node.

    In fact, you can also programmatically read through the messages in a particular Journal:

    * cFormatName is derived from original Queue (see above)
    oQueueInfo = create(“msmq.msmqqueueinfo”)
    oQueueInfo.FormatName = cFormatName+”;JOURNAL”
    oJournalQueue = oQueueInfo.Open(MQ_PEEK_ACCESS,MQ_DENY_NONE)
    oMsg = oJournalQueue.PeekCurrent(,,100)
    DO WHILE !ISNULL(oMsg)
       oMsg = oJournalQueue.PeekNext(,,100)
       ? oMsg.Body,oMsg.Class
    ENDDO
    oJournalQueue.Close
    

    Message Acknowledgments

    Sending a Message with Acknowledgment

    We’ve now added some simple messages to a queue and even found a way to read/process them. No doubt you’ve sent e-mail to a friend in the past and never received an acknowledgment. While this might be fine for simple e-mail, often with your application, you are going to want some sort of acknowledgment that the message was received.

    MSMQ offers two types of acknowledgments.

    • When message reached queue (MQMSG_ACKNOWLEDGMENT_FULL_REACH_QUEUE)
    • When message was actually read (MQMSG_ACKNOWLEDGMENT_FULL_RECEIVE)

    As with most operations involving MSMQ, acknowledgments are handled via sending a new message to a queue. The only difference with an Ack message is that there is no attached body. A special queue is setup for the acknowledgment message. This is referred to as an Admin Queue. An Admin Queue is actually just a normal queue (you can have a Journal associated with it), and Ack messages which you process (Receive) are removed (and optionally forwarded to associated Journal). An Admin Queue is created in the normal fashion like any other queue (see above).

    The primary difference with message acknowledgments is not in the Admin Queue, but rather in the composition of the message itself. Here is an example of a message being sent with instructions for acknowledgment.

    * Create new messages
    oSendQueue = oQueueInfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)
    IF EMPTY(oSendQueue.IsOpen)
       RETURN
    ENDIF
    oMsg = create(“msmq.msmqmessage”)
    oMsg.Label = “Test Message”
    oMsg.Body = “This is a sample message.”
    oMsg.Ack = MQMSG_ACKNOWLEDGMENT_FULL_RECEIVE
    *oMsg.Ack = MQMSG_ACKNOWLEDGMENT_FULL_REACH_QUEUE
    oMsg.AdminQueueInfo = oAdminQueueInfo
    oMsg.Send(oSendQueue)
    oSendQueue.Close
    

    The only difference with a normal message is setting of the Ack and AdminQueueInfo properties.

    Note   Setting of AdminQueueInfo property requires Visual FoxPro 6.0 SP3 or higher.

    Reading Message Acknowledgments

    You are going to want to check to see whether all of the messages reached their target queue, were received within a timeout period, etc. This is all handled by the Class property of the message.

    oRecQueue = oAdminQueueInfo.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE)
    oMsg = oRecQueue.PeekCurrent(,,100)
    IF !ISNULL(oMsg)
      DO CASE
      CASE oMsg.Class = MQMSG_CLASS_ACK_REACH_QUEUE
       MESSAGEBOX(“The message reached the queue.”)
      CASE oMsg.Class = MQMSG_CLASS_ACK_RECEIVE
       MESSAGEBOX(“The message was acknowledged as received.”)
      CASE oMsg.Class = MQMSG_CLASS_NACK_RECEIVE_TIMEOUT
       MESSAGEBOX(“Message was not removed from the queue in time.”)
      OTHERWISE
       MESSAGEBOX(“The message did not reach the queue.”)
      ENDCASE
      oMsg = oRecQueue.Receive(,,,100)  &&remove from queue
    ENDIF
    oRecQueue.Close
    

    Message Timeouts

    If you are receiving Ack messages based on when the target message queue actually processes (ReceiveReceiveCurrent) the message, you can also impose a timeout. This is handled by the message’s MaxTimeToReceieve property.

    If the time-to-be-received timer expires before the message is removed from the queue, MSMQ discards the message, sending it to the dead letter queue if the message’s Journal property is set to MQMSG_DEADLETTER.

    MSMQ can also send a negative acknowledgment message back to the sending application if the message is not retrieved before the timer expires.

    oMsg = create(“msmq.msmqmessage”)
    oMsg.Label = “Test Message”
    oMsg.Body = “This is a sample message.”
    oMsg.Ack = MQMSG_ACKNOWLEDGMENT_FULL_RECEIVE
    oMsg.MaxTimeToReceive = 20
    oMsg.AdminQueueInfo = oAdminQueueInfo
    oMsg.Send(oSendQueue)
    

    There is also a similar MaxTimeToReachQueue property.

    Note   If the queue is local, the message always reaches the queue.

    These two Acknowledgment operations are facilitated by MSMQ’s built-in Message Timers.

    More About Message Timers

    MSMQ provides two timers to help you maintain better control of your messages: a time-to-be-received and a time-to-reach-queue timer.

    The time-to-be-received timer determines how long a message remains in the system, starting from the time the message is sent, to the time it is removed from the target queue.

    The time-to-reach-queue timer determines how long a message has until it reaches the target Queue Manager of the target queue. Typically, this timer is set to a value less than the time-to-be-received setting.

    When both timers are used, and if the time-to-be-received timer is set to a shorter time interval than the time-to-reach-queue timer, it takes precedence over the time-to-reach-queue timer. MSMQ does not allow messages to remain in the system longer than the time allowed by their time-to-be-received timer.

    When either timer expires, MSMQ discards the message. However, MSMQ can also send a copy of the message to a dead letter queue or an acknowledgment message to an administration queue. If the message’s acknowledgment property specifies full or negative acknowledgments, MSMQ sends the appropriate negative acknowledgment message to the administration queue specified by the message. If the message’s journal property specifies a dead letter queue, a copy of the message is sent to one of two places. The copies of non-transactional messages are sent to the dead letter queue on the computer where the timer expired. Copies of transactional messages are copied to the transactional dead letter queue on the source machine.

    Response Messages

    Message acknowledgments are convenient for many application needs, especially those involving workflows. You might also want to consider a more detailed approach using an actual response message. Similar to the Admin Queue used for Ack messages, you will need to set up a special Response Queue for Response messages. A major difference with Ack messages is that the Response message contains a body. In reality, the Response Queue is nothing fancy and could easily be handled without the built-in functionality.

    Sending Message with Response

    Sending a message that asks for a response requires use of the ResponseQueueInfo property of your outgoing message.

    * Create new messages
    oSendQueue = oQueueInfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)
    oMsg = create(“msmq.msmqmessage”)
    oMsg.Label = “Test Message”
    oMsg.Body = “This is a sample message.”
    oMsg.Delivery = MQMSG_DELIVERY_RECOVERABLE
    oMsg.ResponseQueueInfo = oResponseQueueInfo
    oMsg.Send(oSendQueue)
    oSendQueue.Close
    

    Reading Message from Response Queue

    Messages can be read from the Response Queue. When a message arrives at its target queue, you can query the ResponseQueueInfo property to get an object reference to the Response Queue. Once you have this, you simply create a new message (with body) to send.

    * Read message from target queue
    oRecQueue = oQueueInfo.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE)
    oMsg = oRecQueue.Receive(,,,100)
    IF ISNULL(oMsg)
       RETURN
    ENDIF
    
    * See is a reponse queue is setup and send message if so
    IF !ISNULL(oMsg.ResponseQueueInfo)
       oRespQueue = oMsg.ResponseQueueInfo.Open(MQ_SEND_ACCESS,;
       MQ_DENY_NONE)
       oMsg2 = create(“msmq.msmqmessage”)
       oMsg2.Label = “Response Message”
       oMsg2.Body = “This is a response message”
       oID = oMsg.id
       cTmpStr=““ 
       FOR i = 1 TO ALEN(oID)
          cTmpStr = cTmpStr+CHR(oID[m.i])
       ENDFOR
       oMsg2.CorrelationId = CreateBinary(cTmpStr)
       oMsg2.Send(oRespQueue)
       MESSAGEBOX(“A response message was returned.”)
       oRespQueue.Close
    ENDIF
    

    Take a close note at the code for the CorrelationID property. This property is a 20-element array of bytes. You will need to first convert it to a string and then run it through Visual FoxPro’s CreateBinary function.

    Advanced VFP Programming for MSMQ

    In this section, we will explore a number of advanced topics that will be of value in your MSMQ application.

    Sending Private Messages

    MSMQ provides a secured channel for sending private, encrypted messages throughout your MSMQ enterprise. MSMQ ensures that the body of private messages are kept encrypted from the moment they leave the source Queue Manager to the moment they reach their target Queue Manager.

    With encryption and decryption provided by MSMQ Queue Managers, applications do not have to encrypt messages when they are sent, or decrypt received messages. When a private message is sent, the source Queue Manager encrypts the body of the message, then sends the message on to the target Queue Manager. When the target Queue Manager receives the message, it decodes the body of the message and passes the clear message on to the queue. The receiving application can then read the message from the queue without ever knowing it was encrypted.

    Note   The receiving application sees the message as clear text. However, it can look at the message’s privacy level to determine whether the message was sent encrypted, or look at the encryption algorithm used when the message was sent.

    Sending private messages is easy:

    1. Optional. Verify that the queue can receive private messages. The MSMQQueueInfo object’s PrivLevel must be set to MQ_PRIV_LEVEL_BODY or MQ_PRIV_LEVEL_OPTIONAL. If set to MQ_PRIV_LEVEL_BODY, the queue can only accept private messages. Non-private messages will be ignored.oQueueInfo.PrivLevel = MQ_PRIV_LEVEL_BODY
    2. Open the queue for sending messages.
    3. Set the MSMQMessage object’s PrivLevel property to MQMSG_PRIV_LEVEL_BODY.oMsg.PrivLevel = MQMSG_PRIV_LEVEL_BODY
    4. Optional. Set the encryption algorithm used to encrypt the message.oMsg.EncryptAlgorithm = MQMSG_CALG_RC4
    5. Send the message.

    Here is a sample VFP snippet putting it all together:

    * Create the queue with Privacy setting
    oQueueInfo = create(“msmq.msmqqueueinfo”)
    oQueueInfo.pathname = “.\”+lcQueueName  &&must be unique
    oQueueInfo.Label = lcQueueName
    oQueueInfo.PrivLevel = MQ_PRIV_LEVEL_OPTIONAL
    oQueueInfo.Journal = 1  
    oQueueInfo.Create
    
    * Create new message
    oSendQueue = oQueueInfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)
    oMsg  = create(“msmq.msmqmessage”)
    oMsg.Label = “My Private Message”
    oMsg.Body = “This is a private message.”
    oMsg.PrivLevel = MQMSG_PRIV_LEVEL_BODY
    oMsg.EncryptAlgorithm = MQMSG_CALG_RC4
    oMsg.Send(oSendQueue)
    oSendQueue.Close
    
    * Read the message
    oRecQueue = oQueueInfo.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE)
    oMsg = oRecQueue.ReceiveCurrent(,,,100)
    If oMsg.PrivLevel = MQMSG_PRIV_LEVEL_BODY
       ?”Private message: “ + oMsg.Label
    ELSE
       ?”Public message: “ + oMsg.Label
    ENDIF
    ?  + oMsg.Body
    ?  “Encryption alogithm is: “ + TRANS(oMsg.EncryptAlgorithm)
    oMsg = oRecQueue.ReceiveCurrent(,,,100)
    oRecQueue.Close
    

    Message Delivery Options

    An important concept you should understand when sending messages is the various Delivery options.

    • MQMSG_DELIVERY_RECOVERABLE – In every hop along its route, the message is forwarded to the next hop or stored locally in a backup file until delivered. This guarantees delivery even in the case of a machine crash.
    • MQMSG_DELIVERY_EXPRESS – The default. The message stays in memory until it can be delivered. (In-memory message store and forward.)

    When the message’s delivery mechanism is set to MQMSG_DELIVERY_EXPRESS, the message has faster throughput. When set to MQMSG_DELIVERY_RECOVERABLE, throughput may be slower. However, MSMQ guarantees that the message will be delivered, even if a computer crashes while the message is en-route to the queue.

    Handling this is in your code is simply a matter of setting a single message property.

    oMsg.Delivery = MQMSG_DELIVERY_EXPRESS 
    oMsg.Send(oSendQueue)
    

    Note   Messages must be sent in recoverable mode if the offline client computer is turned off. Messages sent in express mode are held in RAM and will be lost when the computer is turned off.

    Binding Excel Objects to Message Bodies

    One of the truly powerful features of MSMQ is the ability to attach COM objects to the bodies of messages. This works for quite a few common objects, including ADO recordsets and Excel spreadsheets. In this section, we will look at spreadsheets. Before you think about trying to attach a Visual FoxPro object, be aware of the following rule for message body content.

    The body of an MSMQ message can be a string, an array of bytes, or any persistent COM object that supports IDispatch and IPersist (IPersistStream or IPersistStorage).

    Note   Visual FoxPro 6.0 objects do not support the ability to persist themselves via IPersist.

    There are several ways to attach Excel data to your message. The following example demonstrates creating a message and attaching an existing Excel file to the message. You can use Visual FoxPro’s GETOBJECT() function to get an object reference to the file and set it directly to the Body property.

    * Attach existing Excel worksheet to message body
    #DEFINE cXLFile  “c:\offices.xls”
    oMsg = create(“msmq.msmqmessage”)
    oMsg.Label = “Excel OFFICES.XLS Message”
    oMsg.Body = Getobject(cXLFile)
    oMsg.Send(oSendQueue)
    oSendQueue.Close
    

    Alternatively, you can create an Excel spreadsheet object on the fly and persist its contents to the message body.

    * Attach Excel worksheet to message body
    oMsg = create(“msmq.msmqmessage”)
    oMsg.Label = “New Excel Object Message”
    oXL=Create(“excel.application”)
    oXL.workbooks.add
    oXL.rows(1).columns(1).value = “Dogs”
    oXL.rows(1).columns(2).value = “Cats”
    oXL.rows(2).columns(1).value = 333
    oXL.rows(2).columns(2).value = 555
    oMsg.Body = oXL.activesheet.parent
    oMsg.Send(oSendQueue)
    oSendQueue.Close
    oXL.DisplayAlerts = .F.
    oXL.quit
    

    Before reading the contents of your Excel spreadsheet object, first check the type of object you are dealing with. The following code uses the TYPE() function to check the object type, and shows accessing the Active Sheet object reference to obtain specific spreadsheet content. There is also code to iterate through the contents of the spreadsheet, however, you can use whatever automation calls you prefer.

    Note   The message body contains a reference to the application object.

    * Read in the Excel object
    oRecQueue = oQueueInfo.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE)
    oMsg = oRecQueue.PeekCurrent(,,100)
    oObj = oMsg.Body
    DO WHILE !ISNULL(oObj)
      IF TYPE(“oObj.Application.Name”)=“C” AND;
        ATC(“Excel”,oObj.Application.Name)#0
        oMsg = oRecQueue.ReceiveCurrent(,,,100)
        oObj = oMsg.Body
        oSheet = oObj.ActiveSheet
        ? “Excel contents:”
        FOR i = 1 TO 100
       IF EMPTY(oSheet.Rows(m.i).Columns(1).Text)
          EXIT
       ENDIF
          ?
       FOR j = 1 TO 100
          lcText = oSheet.Rows(m.i).Columns(m.j).Text
          IF EMPTY(lcText)
             EXIT
          ENDIF
             ?? lcText+”,”
       ENDFOR
        ENDFOR
        EXIT
      ENDIF
      oMsg = oRecQueue.PeekNext(,,100)
      oObj = oMsg.Body
    ENDDO
    oRecQueue.Close
    

    Binding ADO Recordset Objects to Message Bodies

    ADO recordsets represent a valuable medium for passing data via MSMQ messages. Rather than passing a long string representing a record from your FoxPro table, which you would later need to parse, you can pass a more efficient object. Additionally, the data is stored in an encrypted format.

    Using the new VFPCOM utility available from the Visual FoxPro Web site, (https://msdn.microsoft.com/vfoxpro/downloads/updates.asp), you now have an excellent mechanism for passing Visual FoxPro data. VFPCOM contains methods for converting VFP data to/from ADO recordsets. The following sample shows VFPCOM used to convert a VFP cursor to a recordset, and then attach that recordset to a message.

    oMsg = create(“msmq.msmqmessage”)
    oMsg.Label = “ADO Message”
    USE _samples+”\data\employee” AGAIN SHARED
    oComUtil = create(“vfpcom.comutil”)
    oRS = CreateObject(“ADODB.Recordset”)
    oComUtil.CursorToRS(oRS)
    oMsg.Body = oRS
    oMsg.Send(oSendQueue)
    oSendQueue.Close
    

    Reading and detaching the ADO recordset is easy as demonstrated in the following code, but don’t forget to first check for a valid ADO object. Use the TYPE() function with a common known member of the object.

    * Receive the messages
    oRecQueue = oQueueInfo.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE)
    * Get the ADO object
    oMsg = oRecQueue.PeekCurrent(,,100)
    oObj = oMsg.Body
    DO WHILE !ISNULL(oObj)
       IF TYPE(“oObj.eof”)=“L”
          oMsg = oRecQueue.ReceiveCurrent(,,,100)
          oObj = oMsg.Body
          oObj.MoveFirst
          DO WHILE !oObj.eof
             ? oObj.Fields[1].Value
             oObj.MoveNext
          ENDDO
          EXIT
       ENDIF
       oMsg = oRecQueue.PeekNext(,,100)
       oObj = oMsg.Body
    ENDDO
    oRecQueue.Close
    

    Using XML with Messages

    One of the more exciting uses for messages is passing of XML data. XML data can be used for a variety of purposes, including storage of relational data and other structured information. MSMQ messages are nicely suited for passing XML data, because the message body can persist this structured data.

    We’ve already discussed passing ADO recordsets and Microsoft Office objects such as Excel spreadsheets. You’re probably wishing that it was easy to attach VFP cursors and objects to messages as well. XML is a wonderful medium for doing just this.

    Rick Strahl’s Web site (www.west-wind.com/) contains an excellent set of XML classes called wwXML, which you can use with your applications. The following table contains some of the wwXML methods of interest.Expand table

    MethodDescription
    CursorToXMLConverts a cursor into an XML representation.
    XMLToCursorConverts an XML document created with CursorToXML back into a cursor.
    ObjectToXMLConverts a live reference of an object to XML. All variables are converted to text and stored. Optionally can walk nested objects.
    XMLToObjectCreates an object from an XML structure.

    Here is an example using wwXML to persist a VFP cursor.

    #DEFINE WWXML_PATH   “C:\VFP\WWXML\”
    LOCAL lcQueueName,oQueueInfo,oSendQueue, oXML,oMSG
    SET CLASSLIB TO (WWXML_PATH + “wwXML.vcx”) ADDITIVE
    SET PROCEDURE TO (WWXML_PATH + “wwUtils.prg”) ADDITIVE
    
    lcQueueName = “myXMLqueue”
    oQueueInfo = CreateObject(“msmq.msmqqueueinfo”)
    oQueueInfo.Formatname = “DIRECT=OS:.\”+lcQueueName
    oSendQueue = oQueueInfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)
    
    USE _samples+”\data\customer” AGAIN SHARED
    oXML = NewObject(“wwXML”)
    oXML.lCreateDataStructure = .T.
    
    oMsg = create(“msmq.msmqmessage”)
    oMsg.Label = “Persisted VFP Cursor - “ + TRANS(DATETIME())
    oMsg.Body = oXML.CursorToXML()
    oMsg.Send(oSendQueue)
    oSendQueue.Close
    

    One of the considerations when using XML with MSMQ 1.0, is that the XML will be stored as simple text, which typically is not encrypted. You may need to take some precautions and use security. There is also an EncryptAlgorithm message property that can be used to encrypt the message, however, this only applies for private messages.

    Working with MSMQ Events and Asynchronous Message Reading

    Applications such as Visual Basic® allow you to bind to events of COM objects. Visual FoxPro 6.0 supports this with ActiveX controls, but not with COM objects such as an ADO Recordset. This means you will not have the ability to bind a VFP object to a COM object and have user code executed when an event of the COM object is triggered.

    The new VFPCOM utility (see above) addresses this critical need. You can now have VFP code executed when a message arrives in a particular queue. MSMQ triggers an event that VFP can respond to. The advantage here is that your application can now handle reading messages in the queue asynchronously. Instead of having some object using up lots of processor time consumed in an endless DO WHILE loop, you can have your dormant objects awaken only when a message arrival event occurs.

    The process of setting up a queue for asynchronous reading of messages is as follows:

    1. Create your VFP MSMQ events class to handle reading of messages as they arrive in queues. This class needs to contain Arrived and ArrivedError methods to handle the message arrival events.
    2. Use VFPCOM to bind an instance of your VFP MSMQ events class to an instance of an MSMQEvent object. This is done with VFPCOM’s BindEvents method.
    3. Open the queue and call its EnableNotification method passing the MSMQEvent object you just setup with BindEvents.

    Note   You must leave the queue open and the BindEvents call intact, otherwise your event connection loses scope and will fail.

    The following class definition is a sample template that can be used for your event binding. Notice that you can use the AppSpecific property to special case handling for certain messages.

    DEFINE CLASS foxevent AS custom
       Procedure Arrived(oQueue,Cursor)
            oMsgRec = oQueue.PeekCurrent(,,0)
       ? “Message Arrived Event: “+TRANS(oMsgRec.AppSpecific)
       IF oMsgRec.AppSpecific = 33  &&get only this one
          oMsgRec = oQueue.ReceiveCurrent(,,,0)
          oMsgRec = oQueue.PeekCurrent(,,0)
          oQueue.EnableNotification(oMSMQEvent,MQMSG_CURRENT,1000)   
       ELSE
          oQueue.EnableNotification(oMSMQEvent,MQMSG_NEXT,1000)   
       ENDIF
       ENDPROC
    
       Procedure ArrivedError(Queue,ErrorCode,Cursor)
       ? “Message Arrived Error”
       ENDPROC
    ENDDEFINE
    

    Once you have your class defined, you can set things up for asynchronous reading of messages. The remainder of the code below shows how to set up the event handler. This is also a simple way to test the event handling by adding a bunch of messages.

    * Setup up event handler to receive the messages
    oMSMQEvent = create(“msmq.msmqevent”)
    oComUtil = create(“vfpcom.comutil”)
    oFoxEvents = create(“foxevent”)
    oComUtil.BindEvents(oMSMQEvent,oFoxEvents)
    oRecQueue = oQueueInfo.Open(MQ_RECEIVE_ACCESS,MQ_DENY_NONE)
    oRecQueue.EnableNotification(oMSMQEvent,MQMSG_CURRENT,1000)
    
    * Add a bunch of new message
    oSendQueue = oQueueInfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)
    oMsg = create(“msmq.msmqmessage”)
    oMsg.AppSpecific = 11
    oMsg.Send(oSendQueue)
    oMsg.AppSpecific = 22
    oMsg.Send(oSendQueue)
    oMsg.AppSpecific = 33
    oMsg.Send(oSendQueue)
    oMsg.AppSpecific = 44
    oMsg.Send(oSendQueue)
    oMsg.AppSpecific = 55
    oMsg.Label = “Message55”
    oMsg.Body = “This is body of message 55.”
    oMsg.Send(oSendQueue)
    oSendQueue.Close
    

    Working with MSMQ Transactions

    MSMQ transactions are used by the sending and receiving application. In this model, MSMQ uses two transactions, one to send messages to the queue and the other to retrieve messages from the queue. The sending transaction can commit to sending the messages to the queue and the receiving application can commit to retrieving the messages; MSMQ provides its own confirmation process to notify the sending application that either the messages were retrieved from the queue or why the receiving application failed to retrieve them. MSMQ provides both implicit and explicit mechanisms for incorporating transactions. There are two types of implicit transactions, MTS Transactions and XA-Compliant Transactions. Let’s quickly look at the two explicit ones (MSMQ Internal Transactions and MS DTC External Transactions) and then come back to the MTS Transactions.

    MSMQ Internal Transactions

    MSMQ Internal Transactions provide better performance for transactions that only send or receive MSMQ messages. Unlike MS DTC external transactions, MSMQ internal transactions cannot be passed to another resource manager. It is the cost of coordinating between several resource managers that make MSMQ internal transaction less expensive in terms of memory than MS DTC external transactions.

    Note   When sending a single message, MSMQ provides a single-message send operation that uses an MSMQ internal transaction. This mode of sending a message provides the best performance of all transaction types. When using this mode, MQBeginTransaction and Commit are implied.

    When setting up your queue for handling internal transactions, you must ensure that the queue is created to allow for transactions. This is handled in the Create() method shown below.

    oQueueInfo = create(“msmq.msmqqueueinfo”)
    oQueueInfo.pathname = “.\”+lcQueueName
    oQueueInfo.Label = lcQueueName
    oQueueInfo.Journal = 1
    * First parameter determines if queue is transactional
    oQueueInfo.Create(.T.)
    

    Sending Messages with Transactions

    Transactions can be included at the sending and receiving end of messages. The process for setting up messages for transactions is quite simple. You create an object instance of the MSMQ Transaction Dispenser object, to start a transaction. This object has a single method called BeginTransaction, which returns an MSMQ Transaction object. This object is then used to control Commit/Abort operations on sending/receiving messages. The following code demonstrates how this works for sending messages.

    * Setup Transaction and Transaction Dispenser objects
    oTransDisp  = create(“msmq.msmqtransactiondispenser”)
    oTrans = oTransDisp.BeginTransaction
    
    * Create new message
    oMsg  = create(“msmq.msmqmessage”)
    oMsg.Label = “My Trans Message”
    oMsg.Body = “This is a trans message.”
    oMsg.Send(oSendQueue, oTrans)
    oSendQueue.Close
    

    If your queue is not set up to handle transactions, you will get an error during the Send method call.

    At this point, we have a message that we sent to our queue. The message does not appear in the queue in the MSMQ Explorer because the Send transaction was not yet committed. If you commit the operation by calling the Transaction object’s commit method, then the message is posted to the queue. If you abort, then it is discarded.

    IF MESSAGEBOX(“Do you want to commit sending message(Yes) ;
      or abort(No)?”,36)=6
        oTrans.Commit
    ELSE
        oTrans.Abort  && causes message to be disgarded
        MESSAGEBOX(“Queue should be empty since message was disgarded.”)
        RETURN
    ENDIF
    

    Note   In the example I was actually able to commit/abort the transaction even after I closed the queue.

    Receiving Messages with Transactions

    A transaction can be associated with receiving message, just as it was with sending messages.

    oTransDisp  = create(“msmq.msmqtransactiondispenser”)
    oTrans = oTransDisp.BeginTransaction
    oMsg = oRecQueue.ReceiveCurrent(oTrans,,,100)
    ? oMsg.Label
    ? oMsg.Body
    oRecQueue.Close
    
    IF MESSAGEBOX(“Do you want to commit receiving message(Yes) ;
      or abort(No)?”,36)=6
        oTrans.Commit
        MESSAGEBOX(“Queue should be empty with message moved to Journal.”)
    ELSE
        oTrans.Abort 
        MESSAGEBOX(“Queue should contain unread message.”)
    ENDIF
    

    The Abort operation does not actually discard the message. It instead treats it as unread.

    Note   When message are not processed, this can be used as an alternate approach to using the Peek functions to read messages.

    MS DTC External Transactions

    MS DTC External Transactions are used when the transaction includes more actions than simply sending or retrieving MSMQ messages (more than one resource manager is used). In this case, the application must ask MS DTC (Microsoft® Distributed Transaction Coordinator) for a transaction object and explicitly reference that object each time it sends a message, retrieves a message, or executes an action of another resource manager.

    When an application is performing a MS DTC transaction, MSMQ is acting as part of a transaction processing system that includes a transaction manager and any number of resource managers.

    Programming to use explicit external transactions is not much different from the examples shown above with internal transactions. In fact, the only difference is the Transaction Dispenser being used.

    oTransDisp  = create(“msmq.msmqCoordinatedTransactionDispenser”)
    

    If you get an error message after your BeginTransaction call, you probably don’t have DTC running. You can turn it on via the SQL Server Service Manager (note: many people set their system to automatically turn on DTC during startup).

    oTransDisp  = create(“msmq.msmqCoordinatedTransactionDispenser”)
    oTrans = oTransDisp.BeginTransaction
    

    One interesting difference between the DTC External and Internal Transactions is that when you abort Receiving a message with a DTC External Transaction, the message is left intact in the queue. With Internal Transactions, the message is purged and moved to the Xact Dead Letter queue.

    MTS Transactions

    One of the nice features of MSMQ is its implicit coordination with Microsoft® Transaction Server to handle transactions. As you may know, MTS is a runtime environment used to handle robust distributed transactions. Visual FoxPro works very well with MTS, and with Visual FoxPro 6.0 SP3, you can achieve highly scalable applications using new multi-threaded DLL servers. When the application is running in the MTS environment, MSMQ can use the current MTS transaction if one is available.

    Programming for MTS Transactions requires using an MTS context object to obtain and make transactional calls. Again, you can control transactions in MSMQ for both sending and receiving messages. Unlike the explicit types shown above, the Send and Receive calls do not take a Transaction object as parameter, but rather a constant (MQ_MTS_TRANSACTION).

    oMsg.Send(oSendQueue, MQ_MTS_TRANSACTION)
    oMsg = oRecQueue.ReceiveCurrent(MQ_MTS_TRANSACTION,,,100)
    

    In your MTS server component, you can control Commit/Abort operations by using the SetAbort and SetComplete methods of the MTS context object. Below is pseudo-sample of how your MTS server might be structured to handle an MSMQ message in a transaction.

    * Your MTS server
    oMTX = Create(“MTXAS.APPSERVER.1”)
    oContext = oMTX.GetObjectContext()
    
    * Create new message and send it to queue
    oSendQueue = oQueueInfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)
    oMsg  = create(“msmq.msmqmessage”)
    oMsg.Label = “My MTS Message”
    oMsg.Body = “This is a MTS message.”
    oMsg.Send(oSendQueue, MQ_MTS_TRANSACTION)
    oSendQueue.Close
    
    * Do some other stuff here which may not cause abort action
    IF lHadSomeError
      oContext.SetAbort
    ELSE
      oContext.SetComplete
    ENDIF
    

    Transaction Programming Considerations

    • If some operations in a transaction fail, it is the application’s responsibility to decide whether to terminate the entire transaction (by calling the Transaction object’s abort member function) or commit the transaction anyway (if the failures are such that the transaction is still viable). If the application does commit to a transaction where some operations have failed, the failed operations will not be part of the transaction.
    • There is no limit to the number of messages sent, the number of messages retrieved, or the number of queues used in a single transaction. However, an application cannot send a message to a queue and then try to retrieve it during the same transaction.
    • Calling MQSendMessage does not actually send the message within the transaction. The actual sending is done at some time after MS DTC commits the transaction. When MS DTC returns a successful commit return value, the sending application is guaranteed that the message will be sent. If a transaction is aborted, all MSMQ transaction operations are rolled back: no messages are sent, and all retrieved messages are returned to their original place in the queue.
    • MSMQ guarantees exactly-once-delivery. This means that all messages sent to a queue will arrive once and only once. MSMQ takes special measures to prevent any message duplication or loss.
    • MSMQ guarantees that all messages sent to a specific transaction queue will arrive in the order they were sent by the transaction. This means that if transaction T1 sends messages M1 and M2 to queue Q1, M1 will arrive before M2. However, there is no guarantee if two transactions are sending messages to the same queue. If transaction T1 sends messages M1 and M2 to Q1, and a second transaction T2 sends messages M3 and M4 to Q1, MSMQ only guarantees that M1 will arrive before M2, and that M3 will arrive before M4. In order to guarantee that M1 and M2 will arrive before M3 and M4, the application must commit to T2 only after getting a successful return code from T1.MSMQ does not guarantee order of delivery to different queues, nor does it guarantee order of delivery from different computers.

    Message Authentication

    Message authentication allows the receiving application to verify the source of a message and that the message was not modified on its way to the queue. This is done by attaching a digital signature to the message when it is sent, then verifying the digital signature when the message reaches the queue. The receiving MSMQ Queue Manager uses the digital signature to verify the sender and that the message was not modified.

    To digitally sign a message, the sending application uses a public and private signing key pair to create the digital signature. MSMQ provides the key pair when an internal security certificate is used or when an external security certificate is used. External certificates are obtained from a certificate authority (CA).

    When an internal security certificate is used, the private signing key is registered the first time that the MSMQ Control Panel application is run. The public signing key is provided within the internal certificate.

    Internal certificates are used when the receiving application needs to validate the sender identifier attached to a message. When using an internal certificate, only the sender identifier is guaranteed correct.

    External certificates are used when you want to use the information in the certificate (not just the sender identifier sent with the message) to verify the source of a message. The information in the external certificate is guaranteed by the certificate authority that created the certificate.

    MSMQ does not validate an external certificate. The receiving application must validate the certificate before using an authenticated message. MSMQ generates the digital signature of a message when it is sent and verifies the digital signature when the message is received, but does not validate the certificate itself.

    Note   External certificates are required when communicating with operating environments other than Windows NT® where the sender identifier is meaningless.

    Going Forward

    As you no doubt have seen throughout the article, MSMQ offers endless opportunities for Visual FoxPro developers. MSMQ is a wonderful technology for use with Windows DNA applications where Visual FoxPro COM components can play an essential role in the middle tier.

    The samples included with this article contain valuable code you can use in your own applications. You might consider creating reusable classes for common operations such as opening queues, sending and receiving messages. Additionally, it is also useful to have a handy set of tools for working with MSMQ. The following tools included with the samples are invaluable in helping to develop and debug your MSMQ applications:

    MSGDISPATCH.SCX – lets you send a message to a queue. The form allows you to send normal text messages, but also lets you drag and drop Office documents (e.g., DOC, XLS and PPT files) onto the body area to have them attached to the message. Messages can be sent to both private and public queues. An admin queue can also be set up for message acknowledgments.

    MSGREADER.SCX – while the MSMQ Explorer does not allow you to send messages to a queue, you can view them. Unfortunately, the body contents displayed in the dialog is not very usable, especially with non-text bodies. This form lets you view all sorts of message bodies including plain text, Office documents, ADO recordsets and XML from Rick Strahl’s wwwXML classes.

    EVENTHANDLER.SCX – asynchronous events . The EventHandler uses the new VFPCOM utility to bind a Visual FoxPro object, which implements the same interface as the MSMQEvent class, to an MSMQ queue so that you can have Fox code executed when a message arrives in that queue.

    All of the tools and samples are “smart” in detecting whether you are online or offline. If you are offline, then the tools will display Private queues to select.

    Finally, more information on using MSMQ can be found at the following:

    • Microsoft MSMQ Web site: www.microsoft.com/ntserver/appservice/exec/overview/MSMQ_Overview.asp – contains the best reference set for using MSMQ including samples, technical papers, and other available references.
    • MSDN: https://msdn.microsoft.com/default.asp – lots of great articles on using MSMQ.
    • Microsoft Systems Journal: www.microsoft.com/msj/default.asp – a number of useful MSMQ articles have appeared in MSJ over the past few years. Many of the samples are written in Visual Basic, which can easily be converted to Visual FoxPro syntax.
    • Books – although slow in release, good books are starting to appear on the shelves of your local bookstore. You can search on some of the online book web sites for keywords including MSMQ, MTS, and Distributed Applications.

    The Visual FoxPro 6.0 Class Browser 

    • Article
    • 06/30/2006

    In this article

    1. Introduction
    2. What Is the Visual FoxPro Class Browser?
    3. What’s New in Visual FoxPro 6.0
    4. The Browser Interface

    Show 4 more

    Steven M. Black

    September 1998

    Summary: Describes the Microsoft® Visual FoxPro® version 6.0 Class Browser and how, combined with the Component Gallery, it can be an effective tool for a variety of development purposes. (9 printed pages)

    Contents

    Introduction What Is the Visual FoxPro Class Browser? What’s New in Visual FoxPro 6.0 The Browser Interface Class Management Write Your Own Add-Ins Appendix: Browser.dbf Structure About the Author

    Introduction

    This article discusses the Visual FoxPro Class Browser. Together with the new Component Gallery, the Class Browser provides many useful ways to accomplish common development tasks. This document also discusses the open architecture and programmable hooks that these tools expose for customization purposes.

    What Is the Visual FoxPro Class Browser?

    The Class Browser is useful for a variety of development purposes, such as:

    • Managing classes and class libraries, including adding, deleting, renaming, and redefining classes.
    • Browsing all the classes and class libraries used by a project or application.
    • Generating equivalent code for visual classes.
    • Browsing the interfaces of Microsoft ActiveX® controls and Component Object Model (COM) components.
    • Creating running instances at design time.

    What’s New in Visual FoxPro 6.0

    Most changes to the Visual FoxPro 6.0 Class Browser enhance its usability.

    • Mode button (cmdBrowser) has been added to the toolbar to toggle between the Class Browser and the new Component Gallery.
    • The Type drop-down combo box is now on the same line as the toolbar, resulting in more efficient use of display real estate.
    • You can size the individual panes in the Class Browser because the boundaries between panes now behave like splitter controls.
    • The Class Browser Shortcut menu provides new options. You can now toggle the visibility of the Parent Class toolbar, open a new instance of the Class Browser, open a new instance of the Gallery, and force the Class Browser display to refresh.
    • In the methods and properties pane you’ll notice the methods and properties now display icons to show the status (public, protected, and hidden) of these members. These icons are consistent with those used in Visual Modeler.
    • The Redefine dialog box has been enhanced to use a conventional class specification dialog box, rather than requiring you to type the class name, and optionally use GetFile( ) to specify its .vcx file.
    • If you open .tlb, .dll, .olb, or .ocx files in the Class Browser, you’ll notice the typelib information now includes much more detail, including properties, methods, and their parameters.Note    Because much useful information appears in the lower-right description pane, make sure you use the Class Browser Shortcut menu to toggle the description panes on.
    • If the .tlb, .dll, .olb, or .ocx file displayed in the Class Browser has an associated Help file, pressing the space bar will bring up help for the highlighted item.
    • In the Class Browser, you can export code to HTML. With a class highlighted in the left pane, right-click the View Code button. This invokes your Web browser and opens the browser window over the right pane of the Class Browser.
    • The View Code window is now modeless.
    • Right-click the Gallery/Browser Mode button to see a history of previously selected items and files.
    • With a class selected, Ctrl+ right-click the Class icon image to generate a new object instance created in the Command window.
    • Users of low-resolution displays will note that you can now resize the Class Browser to a smaller size than was possible before. The browser’s minimum dimensions in Visual FoxPro 5.0 are 123×252 pixels with two lines of display, and in Visual FoxPro 6.0 they are 131×155 pixels with five lines of display, so the browser in Visual FoxPro 6.0 can display a third less real estate in tight situations.

    Of course, the big change in the Class Browser is integration with the new Component Gallery.

    The Browser Interface

    Figure 1. The Class Browser interface

    Here are a few things you should know about the Class Browser to increase your productivity with this tool.Expand table

    Click this button to see the class code. If the output contains nested classes, the code won’t execute. Right-click this button and see the class code in HTML format. The window that appears is actually an instance of your browser, wherein you can use the Shortcut menu to view or print the HTML for displaying the source.
    Use this button to create a new class. This new class can be a subclass of the currently selected class, a subclass of any other class, or a subclass of a Visual FoxPro base class.
    You can redefine classes in the Class Browser with this icon. In Visual FoxPro 6.0, you can redefine a class to that of a different base class. You are warned that you will lose some intrinsic methods and properties in the process.
    When you open a Method Code window, this button (which floats in its own toolbar independent of the Class Browser) allows you to view the code hierarchy in parent class methods.

    View more than class libraries

    In the Class Browser Open dialog box, note the different types of files that are supported. Figure 2 shows the Open dialog box pointing to the Component Gallery directory, with the drop-down list expanded to show the types of files you can show in the Class Browser.

    Figure 2. The Class Browser Open dialog box

    You can open Visual FoxPro forms in the Class Browser, and many of the features, such as code generation, work as you might expect. This is very handy for sharing your code with other users via e-mail.

    If you open a Visual FoxPro project file, all the class libraries in that project will be visible in a single view. This is great if your project contains hundreds of classes and you have no idea in which library a particular class belongs.

    In the Class Browser you can open any .exe or COM files (for example, .ocx, .dll, or .tlb) and display their public interfaces. If Help is available, pressing the spacebar invokes it.

    To add controls to a form or class

    In the Class Browser, open the .vcx (class library) file containing the class of the object you want to add to the form, select the class, and then use the drag-and-drop operation to move the Class icon to the design surface.

    Invoke the class of a selected item on a form

    In the form or Class Designer, select a control. If you then invoke the Class Browser, the class and its class library will be displayed with the class for the selected control highlighted. This works with running forms too, except that it uses the control that has focus.

    Class Management

    Bewildered by many of the class management activities that you can do with the Class Browser? Then see the article, “Managing Classes with Visual FoxPro.”

    Write Your Own Add-Ins

    Class Browser add-ins are a built-in way you can extend the Class Browser. Add-ins are useful because of the endless variety of things you can do with them. For example, you can write an add-in to recursively call the Class Browser’s ExportCode( ) method to generate all the code for a particular class library. You can also create an add-in to modify how ExportCode( ) works, like run beautify.app as a post process to format the exported code just as you please.

    All Class Browser events and methods contain hooks to accept add-ins, and add-ins can also be run independently of Class Browser events and methods. See “Creating Add-Ins for the Visual FoxPro Class Browser” for more information.

    There you have it: a quick cafeteria-style tour of some of the neat things in the Visual FoxPro 6.0 Class Browser. Of course, you should also read the Visual FoxPro online Help for more details. These are great tools, and if you use Visual FoxPro every day it’s likely that you could make much better use of them.

    Appendix: Browser.dbf Structure

    The Class Browser stores all its metadata in a table named Browser.dbf found in your HOME() directory. The Component Gallery also uses Browser.dbf to store its catalog-related information. Table 1 provides a field-by-field description of important elements in Browser.dbf.

    Table 1. Browser.dbf MetadataExpand table

    FieldValuesDescriptionBG
    PLATFORMWINDOWS
    <EMPTY>
    Applies to records NOT of TYPE=”ADDIN.”
    Applies only to records of TYPE=”ADDIN.”
    TYPEPREFW

    ADDIN
    Specifies that the record stores browser and gallery preferences.
    Specifies that the record stores add-in information.
    IDFORMINFO


    BROWSER


    METHOD


    MENU
    Specifies that a Class Browser record stores form preferences; specifies that Gallery record stores catalog information.
    Specifies that record contains default settings for the Class Browser. See the PROPERTIES field.
    Specifies that the record contains a Class Browser add-in that is tied to a particular event or method.
    Specifies that the record stores a Class Browser add-in that is NOT tied to a particular event or method, and is thus available on the Add-in menu.
    • • • •• • •
    DEFAULT.T.
    .F.
    Specifies a Component Gallery catalog.
    Specifies a Class Browser record. The default is false (.F.).
     
    GLOBAL.T.
    .F.
    Specifies that a gallery catalog is global. The default is false (.F.) 
    BACKUP.F.
    .T.
    Specifies whether a backup is attempted the next time the file is opened. The default is false (.F.).When you open a catalog or a .vcx file in the Class Browser or Component Gallery, this field in the associated browser.dbf record is queried. If the value is logical .T. (true), a search is made for a file of the same name in the backup subfolder. If the backup file doesn’t exist, one is automatically created in a subfolder called Backup. Then the BACKUP field is set to .F.Through add-in hooks or with any program that opens and updates browser.dbf, you can set this field to force the Class Browser or Component Gallery to automatically back up a file or table the next time that file is opened, and only the next time.This feature is used internally in one special case; when browser.dbf is first created after Visual FoxPro is installed, a new browser.dbf is created with the default catalogs (around 5 or so). The BACKUP field is set to .T. so that each catalog gets backed up the first time it is opened because Visual FoxPro does not install the associated backup catalog tables. Beyond that special function, it can be used at will by developers for their own purpose.
    NAMEcFilenameA memo field that specifies the file name that relates to the current record. This value appears in the add-ins Shortcut menu if the add-in is NOT tied to an event or method.In Class Browser records the file extension can be .vcx, .pjx, .scx, .ovx, .dll, .exe, .app, or others. In Component Gallery records the file extension is .dbf.
    DESCcDescriptionA memo field that contains the description of the catalog referred to in the NAME field. 
    METHODcMethodNameA memo field that specifies the method to which a Class Browser or Component Gallery add-in is tied. If the method field is equal to “*” the add-in will execute for all methods.
    PROPERTIESmemoA memo field that specifies the default settings. 
    SCRIPT Internal Gallery use only. 
    PROGRAMcPRGFilenameA memo field that contains the name of the program to be run by a .prg-based add-in.
    CLASSLIBcClasslibNameA memo field that contains the name of the class library to be used by a .vcx-based add-in.
    CLASSNAMEcClassNameA memo field that contains the name of the class to be used by a .vcx-based add-in.
    DISPMODE<n>Specifies the display mode of the class library.
    1 = hierarchical
    2 = alphabetic
     
    TOP<nnn>A numeric field that specifies the stored top (y) coordinate for the Class Browser/Component Gallery form.
    LEFT<nnn>A numeric field that specifies the stored left (x) coordinate for the Class Browser/Component Gallery form.
    HEIGHT<nnn>A numeric field that specifies the stored height of the Class Browser/Component Gallery form.
    WIDTH<nnn>A numeric field that specifies the stored width of the Class Browser/Component Gallery form.
    HEIGHT1<nnn>A numeric field that specifies the stored height of the class and member description panes in the Class Browser. 
    HEIGHT2<nnn>A numeric field that specifies the stored height of the item description pane in the Component Gallery. 
    WINDOWSTAT<n>A numeric field that specifies the characteristics of the Class Browser or Component Gallery window.
    0 = Normal window
    1 = Minimized window
    2 = Maximized window
    PROTECTED.F.
    .T.
    A logical field that specifies whether protected members are displayed. The default is false (.F.). 
    EMPTY.F.
    .T.
    A logical field that specifies whether empty methods are to be displayed. 
    HIDDEN.F.
    .T.
    A logical field that specifies whether hidden members are to be displayed. 
    DESCBOXES.F.
    .T.
    A logical field that specifies whether description panes are to be displayed. 
    AUTOEXPAND.F.
    .T.
    A logical field that specifies whether hierarchical items in the treeview are to be automatically displayed expanded in the left-hand side pane. 
    PUSHPIN.F.
    .T.
    A logical field that specifies whether the display is always on top. 
    PCBROWSER.F.
    .T.
    A parent class toolbar flag. A logical field that specifies whether the toolbar is on for that file.  
    VIEWMODE<n>A numeric field that specifies the mode of the Gallery listview.
    1. Large (standard) Icons
    2. Small Icons
    3. List
    4. Report
     
    FONTINFOcFontPrefA memo field that contains the current display font preference.
    FORMCOUNT<n>A numeric field that specifies the number of Class Browser instances running for the .vcx file.
    UPDATED<DateTime>A datetime field that specifies when this record was last updated.
    COMMENT Unused
    User1….4 Unused

    About the Author

    Steven specializes in developing multilingual, multisite, and other challenging software situations, including project turnarounds and cleanups. He is the creator of Steven Black’s INTL Toolkit, a multilingual framework for FoxPro and Visual FoxPro. He’s a regular speaker at Visual FoxPro conferences, and his contributions occasionally darken the pages of FoxPro books and magazines.

    Supported Visual FoxPro SET Commands

    Unsupported Visual FoxPro Commands and Functions

    Symbols
    & Command

    && Command

    • Command

    NAME?

    ? | ?? Command

    ??? Command

    @ … BOX Command

    @ … CLASS Command

    @ … CLEAR Command

    @ … EDIT – Edit Boxes Command

    @ … FILL Command

    @ … GET – Check Boxes Command

    @ … GET – Combo Boxes Command

    @ … GET – Command Buttons Command

    @ … GET – List Boxes Command

    @ … GET – Option Buttons Command

    @ … GET – Spinners Command

    @ … GET – Text Boxes Command

    @ … GET – Transparent Buttons Command

    @ … MENU Command

    @ … PROMPT Command

    @ … SAY – Pictures & OLE Objects Command

    @ … SAY Command

    @ … SCROLL Command

    @ … TO Command

    \ | \ Command

    A
    ACCEPT Command

    ACTIVATE MENU Command

    ACTIVATE POPUP Command

    ACTIVATE SCREEN Command

    ACTIVATE WINDOW Command

    ADD CLASS Command

    ADD TABLE Command

    ALTER TABLE – SQL Command

    APPEND Command

    APPEND FROM ARRAY Command

    APPEND FROM Command

    APPEND GENERAL Command

    APPEND MEMO Command

    APPEND PROCEDURES Command

    ASSERT Command

    ASSIST Command

    AVERAGE Command

    B
    BEGIN TRANSACTION Command

    BLANK Command

    BROWSE Command

    BUILD APP Command

    BUILD DLL Command

    BUILD EXE Command

    BUILD MTDLL Command

    BUILD PROJECT Command

    C
    CALCULATE Command

    CALL Command

    CANCEL Command

    CD | CHDIR Command

    CHANGE Command

    CLEAR Commands

    CLOSE Commands

    CLOSE MEMO Command

    COMPILE Command

    COMPILE DATABASE Command

    COMPILE FORM Command

    CONTINUE Command

    COPY FILE Command

    COPY INDEXES Command

    COPY MEMO Command

    COPY PROCEDURES Command

    COPY STRUCTURE Command

    COPY STRUCTURE EXTENDED Command

    COPY TAG Command

    COPY TO ARRAY Command

    COPY TO Command

    COUNT Command

    CREATE CLASS Command

    CREATE CLASSLIB Command

    CREATE COLOR SET Command

    CREATE Command

    CREATE CONNECTION Command

    CREATE CURSOR – SQL Command

    CREATE DATABASE Command

    CREATE FORM Command

    CREATE FROM Command

    CREATE LABEL Command

    CREATE MENU Command

    CREATE PROJECT Command

    CREATE QUERY Command

    CREATE REPORT – Quick Report Command

    CREATE REPORT Command

    CREATE SCREEN – Quick Screen Command

    CREATE SCREEN Command

    CREATE SQL VIEW Command

    CREATE TABLE – SQL Command

    CREATE TRIGGER Command

    CREATE VIEW Command

    D
    DEACTIVATE MENU Command

    DEACTIVATE POPUP Command

    DEACTIVATE WINDOW Command

    DEBUG Command

    DEBUGOUT Command

    DECLARE – DLL Command

    DECLARE Command

    DEFINE BAR Command

    DEFINE BOX Command

    DEFINE CLASS Command

    DEFINE MENU Command

    DEFINE PAD Command

    DEFINE POPUP Command

    DEFINE WINDOW Command

    DELETE – SQL Command

    DELETE Command

    DELETE CONNECTION Command

    DELETE DATABASE Command

    DELETE FILE Command

    DELETE TAG Command

    DELETE TRIGGER Command

    DELETE VIEW Command

    DIMENSION Command

    DIR or DIRECTORY Command

    DISPLAY Command

    DISPLAY CONNECTIONS Command

    DISPLAY DATABASE Command

    DISPLAY DLLS Command

    DISPLAY FILES Command

    DISPLAY MEMORY Command

    DISPLAY OBJECTS Command

    DISPLAY PROCEDURES Command

    DISPLAY STATUS Command

    DISPLAY STRUCTURE Command

    DISPLAY TABLES Command

    DISPLAY VIEWS Command

    DO CASE … ENDCASE Command

    DO Command

    DO FORM Command

    DO WHILE … ENDDO Command

    DOEVENTS Command

    DROP TABLE Command

    DROP VIEW Command

    E
    EDIT Command

    EJECT Command

    EJECT PAGE Command

    END TRANSACTION Command

    ERASE Command

    ERROR Command

    EXIT Command

    EXPORT Command

    EXTERNAL Command

    F
    FIND Command

    FLUSH Command

    FOR EACH … ENDFOR Command

    FOR … ENDFOR Command

    FREE TABLE Command

    FUNCTION Command

    G
    GATHER Command

    GETEXPR Command

    GO | GOTO Command

    H
    HELP Command

    HIDE MENU Command

    HIDE POPUP Command

    HIDE WINDOW Command

    I
    IF … ENDIF Command

    IMPORT Command

    INDEX Command

    INPUT Command

    INSERT – SQL Command

    INSERT Command

    J
    JOIN Command

    K
    KEYBOARD Command

    L
    LABEL Command

    LIST Commands

    LIST CONNECTIONS Command

    LIST DATABASE Command

    LIST DLLS Command

    LIST OBJECTS Command

    LIST PROCEDURES Command

    LIST TABLES Command

    LIST VIEWS Command

    LOAD Command

    LOCAL Command

    LOCATE Command

    LOOP Command

    LPARAMETERS Command

    M
    MD | MKDIR Command

    MENU Command

    MENU TO Command

    MODIFY CLASS Command

    MODIFY COMMAND Command

    MODIFY CONNECTION Command

    MODIFY DATABASE Command

    MODIFY FILE Command

    MODIFY FORM Command

    MODIFY GENERAL Command

    MODIFY LABEL Command

    MODIFY MEMO Command

    MODIFY MENU Command

    MODIFY PROCEDURE Command

    MODIFY PROJECT Command

    MODIFY QUERY Command

    MODIFY REPORT Command

    MODIFY SCREEN Command

    MODIFY STRUCTURE Command

    MODIFY VIEW Command

    MODIFY WINDOW Command

    MOUSE Command

    MOVE POPUP Command

    MOVE WINDOW Command

    N
    NOTE Command

    O
    ON BAR Command

    ON ERROR Command

    ON ESCAPE Command

    ON EXIT BAR Command

    ON EXIT MENU Command

    ON EXIT PAD Command

    ON EXIT POPUP Command

    ON KEY = Command

    ON KEY Command

    ON KEY LABEL Command

    ON PAD Command

    ON PAGE Command

    ON READERROR Command

    ON SELECTION BAR Command

    ON SELECTION MENU Command

    ON SELECTION PAD Command

    ON SELECTION POPUP Command

    ON SHUTDOWN Command

    OPEN DATABASE Command

    P
    PACK Command

    PACK DATABASE Command

    PARAMETERS Command

    PLAY MACRO Command

    POP KEY Command

    POP MENU Command

    POP POPUP Command

    PRINTJOB … ENDPRINTJOB Command

    PRIVATE Command

    PROCEDURE Command

    PUBLIC Command

    PUSH KEY Command

    PUSH MENU Command

    PUSH POPUP Command

    Q
    QUIT Command

    R
    RD | RMDIR Command

    READ Command

    READ EVENTS Command

    READ MENU Command

    RECALL Command

    REGIONAL Command

    REINDEX Command

    RELEASE BAR Command

    RELEASE CLASSLIB Command

    RELEASE Command

    RELEASE LIBRARY Command

    RELEASE MENUS Command

    RELEASE PAD Command

    RELEASE POPUPS Command

    RELEASE PROCEDURE Command

    RELEASE WINDOWS Command

    REMOVE CLASS Command

    REMOVE TABLE Command

    RENAME CLASS Command

    RENAME Command

    RENAME CONNECTION Command

    RENAME TABLE Command

    RENAME VIEW Command

    REPLACE Command

    REPLACE FROM ARRAY Command

    REPORT Command

    RESTORE FROM Command

    RESTORE MACROS Command

    RESTORE SCREEN Command

    RESTORE WINDOW Command

    RESUME Command

    RETRY Command

    RETURN Command

    ROLLBACK Command

    RUN | Command

    S
    SAVE MACROS Command

    SAVE SCREEN Command

    SAVE TO Command

    SAVE WINDOWS Command

    SCAN … ENDSCAN Command

    SCATTER Command

    SCROLL Command

    SEEK Command

    SELECT – SQL Command

    SELECT Command

    SET ALTERNATE Command

    SET ANSI Command

    SET ASSERTS Command

    SET AUTOSAVE Command

    SET BELL Command

    SET BLOCKSIZE Command

    SET BORDER Command

    SET BROWSEIME Command

    SET BRSTATUS Command

    SET CARRY Command

    SET CENTURY Command

    SET CLASSLIB Command

    SET CLEAR Command

    SET CLOCK Command

    SET COLLATE Command

    SET COLOR OF Command

    SET COLOR OF SCHEME Command

    SET COLOR SET Command

    SET COLOR TO Command

    SET Command

    SET COMPATIBLE Command

    SET CONFIRM Command

    SET CONSOLE Command

    SET COVERAGE Command

    SET CPCOMPILE Command

    SET CPDIALOG Command

    SET CURRENCY Command

    SET CURSOR Command

    SET DATABASE Command

    SET DATASESSION Command

    SET DATE Command

    SET DEBUG Command

    SET DEBUGOUT Command

    SET DECIMALS Command

    SET DEFAULT Command

    SET DELETED Command

    SET DELIMITERS Command

    SET DEVELOPMENT Command

    SET DEVICE Command

    SET DISPLAY Command

    SET DOHISTORY Command

    SET ECHO Command

    SET ESCAPE Command

    SET EVENTLIST Command

    SET EVENTTRACKING Command

    SET EXACT Command

    SET EXCLUSIVE Command

    SET FDOW Command

    SET FIELDS Command

    SET FILTER Command

    SET FIXED Command

    SET FORMAT Command

    SET FULLPATH Command

    SET FUNCTION Command

    SET FWEEK Command

    SET HEADINGS Command

    SET HELP Command

    SET HELPFILTER Command

    SET HOURS Command

    SET INDEX Command

    SET INTENSITY Command

    SET KEY Command

    SET KEYCOMP Command

    SET LIBRARY Command

    SET LOCK Command

    SET LOGERRORS Command

    SET MACKEY Command

    SET MARGIN Command

    SET MARK OF Command

    SET MARK TO Command

    SET MEMOWIDTH Command

    SET MESSAGE Command

    SET MULTILOCKS Command

    SET NEAR Command

    SET NOCPTRANS Command

    SET NOTIFY Command

    SET NULL Command

    SET NULLDISPLAY Command

    SET ODOMETER Command

    SET OLEOBJECT Command

    SET OPTIMIZE Command

    SET ORDER Command

    SET PALETTE Command

    SET PATH Command

    SET PDSETUP Command

    SET POINT Command

    SET PRINTER Command

    SET PROCEDURE Command

    SET READBORDER Command

    SET REFRESH Command

    SET RELATION Command

    SET RELATION OFF Command

    SET REPROCESS Command

    SET RESOURCE Command

    SET SAFETY Command

    SET SECONDS Command

    SET SEPARATOR Command

    SET SKIP Command

    SET SKIP OF Command

    SET SPACE Command

    SET STATUS BAR Command

    SET STATUS Command

    SET STEP Command

    SET STRICTDATE Command

    SET SYSFORMATS Command

    SET SYSMENU Command

    SET TALK Command

    SET TEXTMERGE Command

    SET TEXTMERGE DELIMITERS Command

    SET TOPIC Command

    SET TOPIC ID Command

    SET TRBETWEEN Command

    SET TYPEAHEAD Command

    SET UDFPARMS Command

    SET UNIQUE Command

    SET VIEW Command

    SET VOLUME Command

    SET WINDOW OF MEMO Command

    SHOW GET Command

    SHOW GETS Command

    SHOW MENU Command

    SHOW OBJECT Command

    SHOW POPUP Command

    SHOW WINDOW Command

    SIZE POPUP Command

    SIZE WINDOW Command

    SKIP Command

    SORT Command

    STORE Command

    SUM Command

    SUSPEND Command

    SYS(2001) – SET … Command Status

    T
    TEXT … ENDTEXT Command

    TOTAL Command

    TYPE Command

    U
    UNLOCK Command

    UPDATE – SQL Command

    UPDATE Command

    USE Command

    V
    VALIDATE DATABASE Command

    W
    WAIT Command

    WITH … ENDWITH Command

    X
    Y
    Z
    ZAP Command

    ZOOM WINDOW Command

    Visual FoxPro IDE Enhancements

    This version of Visual FoxPro includes many enhancements to the Interactive Development Environment (IDE), including changes to the window behavior, Options dialog box, and system menus.

    Docking Windows
    Visual FoxPro provides docking functionality to its core IDE windows. When you drag a dockable window to a Visual FoxPro window boundary, it reconfigures against the boundary you choose. There are three types of docking behavior supported. For details, see Docking Windows.

    Normal Docking Windows dock to a boundary of the main Visual FoxPro window.
    Linked Docking Windows dock to each other and simultaneously share a dockable window container.
    Tabbed Docking Windows dock to each other and share the full window through tabs.
    The following windows are dockable:

    Command window
    Document View window
    Data Session window
    Properties window
    Debugger window
    Watch window
    Trace window
    Output window
    Locals window
    Call Stack window
    Document View Window
    The new Document View window makes it possible for you to view and navigate to any procedure, function, #DEFINE definition or preprocessor directive in your program or class. The Document View window is a more flexible modeless window that replaces the Procedures/Functions model dialog box that was available in previous versions of Visual FoxPro. For details, see Document View Window.

    Properties Windows
    The following enhancements have been added to the Properties window. For details, see Properties Window.

    The Properties window can now be activated without the form/class designer opened. Properties of the desktop (_SCREEN) are displayed even if the form/class designer is not active.
    ActiveX control properties, events, and methods are now displayed in a different color to distinguish them from native ones.
    Methods and events that have code in parent classes now show inherited class information.
    The Properties window is now available from the Windows menu and the Standard toolbar.
    Command Window
    The contents of the Command window are saved to a file, _command.prg. You can clear the window by selecting Clear from the Shortcut menu. The file is read only at startup, so it can be used by multiple instances of Visual FoxPro. For details, see Command Window.

    Standard Toolbar
    The Standard toolbar now provides easy access to common Visual FoxPro tools, including the Properties window, Document View window, Class Browser, and Object Browser.

    Report Designer
    The Report Designer is much more accessible through the keyboard and now includes the following functionality. For details, see Report Designer.

    Bands menu option
    Makes it possible for you to access the dialog boxes for the properties of individual bands.
    Insert Control menu option
    Makes it possible for you to select controls to place in your report.
    Control of Foreground and Background Colors
    Makes it possible for you to manage foreground and background colors through additions to the Format menu, when the Report Designer is open.
    The Report Designer also includes new keyboard navigation:

    CTRL+TAB to toggle in and out of Tab mode.
    TAB and SHIFT+TAB to move between report objects.
    CTRL+E to toggle into and ESC to toggle out of Label editing.
    Options Dialog Box
    A number of enhancements have been added to the Options dialog box to offer improved use of the IDE. For details, see Options Dialog Box.

    View Tab
    You can now control the number of Most Recently Used files that are displayed in the File menu and in IntelliSense.
    File Locations Tab
    The File Locations tab makes it possible for you to specify the paths of the following additional Visual FoxPro items: File Type Description
    FoxCode Table Specifies the location of FoxCode.dbf for IntelliSense records. For more information, see _FoxCode System Variable and Customizing IntelliSense Using FoxCode.
    FoxTask Table Specifies the location of the table that retains current TaskList shortcut records. For details, see _FoxTask System Variable.
    IntelliSense Manager Specifies the location of the program assigned to the _Codesense System Variable.
    Task List Specifies the location of the program assigned to the _TASKLIST System Variable.
    Object Browser Specifies the location of the program assigned to the _ObjectBrowser System Variable.

    IDE Tab
    The IDE tab makes it possible for you to specify formatting, Save, appearance, and behavior settings for Visual FoxPro file types. The Edit, Format, Tools, and Window menus incorporate changes to add editor and other functionality to the IDE.
    Miscellaneous IDE Enhancements
    In addition to the above-mentioned improvements, Visual FoxPro now contains a wealth of other improvements, including:

    Your Foxuser.dbf resource file is now opened as shared so that you can run multiple instances or allow multiple users to access it simultaneously.
    The Windows menu has a new Cascading menu item to allow you to have your windows reorganized on your desktop in a cascading fashion.
    The form/class designer allows you to more easily drilldown into container classes such as pageframes. By holding down the CTRL or CTRL+SHIFT keys, you can now click directly on a control within a container to select it.
    In the form/class designer, you can hold down the CTRL or CTRL+SHIFT keys, and use the arrow keys to move or resize a control by the amount of your grid scale associated with the Snap-to-Grid setting.
    Additional information and value tips have been added to a number of design surfaces. Extended information is displayed for fields in the database and view designers and the data environment. The Method editor displays value tips for events and methods in the procedures drop-down list. The Watch and Locals debug windows have value tips for expressions that exceed the width of the column displaying the value.
    WAIT WINDOW and Visual FoxPro System dialog boxes (for example, error) now inherit their font settings from your Windows Appearance setting in the Display control panel. Additionally, you can use CTRL+C to copy the contents of a System dialog box to the Clipboard.
    See Also
    Visual FoxPro Interactive Development Environment | Task List Manager | IntelliSense Overview | Visual FoxPro Editor Enhancements | Editor Tab, Tools Options Dialog Box | File Locations Tab, Tools Options Dialog Box | IDE Tab, Tools Options Dialog Box | Report Designer | Docking Windows | Command Window | Document View Window | Data Session Window | Properties Window | Debugger Window | Watch Window | Trace Window | Debug Output Window | Locals Window | Call Stack Window

    Visual FoxPro Editor Enhancements

    The Visual FoxPro Editor includes many enhancements to make it easier to edit and examine code including additional functionality and redistribution of settings and controls.

    The following IDE changes support some of the added functionality of the Visual FoxPro Editor.

    Bookmarks and Shortcuts

    The Visual FoxPro Editor now displays a selection margin on the left side of the window so you can highlight a line and specify breakpoints, bookmarks or shortcuts. For details, see Creating Bookmarks and Shortcuts.

    Bookmarks reference a specific line of source code you might want to return to for further editing or viewing. You can add a shortcut from the selection margin or Editor menu. Bookmarks are not saved between sessions of Visual FoxPro.

    Similar to Bookmarks, Shortcuts are persistent code markers that are stored in the Foxtask table and can be accessed using the Task List Manager.

    Find Dialog Box

    The Find dialog box has new support for performing searches using wildcard pattern matching. Additionally, you can perform searches using several new keyboard shortcuts without opening up the Find dialog box.

    Embedded Hyperlinks

    Visual FoxPro Editor supports embedding and enabling hyperlinks. When you include any valid hyperlink protocol trigger, Visual FoxPro applies hyperlink attributes to the entered text. For details, see “Embedding Hyperlinks” in Dynamic Information Sharing.

    Options Dialog Box

    The Options dialog box has the following enhancements: Editor Tab The Editor tab of the Options dialog box provides the functionality of the Syntax coloring tab, as well as additional options related to the Visual FoxPro Editor. IDE Tab The IDE tab makes it possible for you to specify settings for various types of editors used by Visual FoxPro, including programs, methods, stored procedures, text files and memos. These settings are the defaults used for a new document of a specific type. Once a document is created, its specific settings are stored in the Foxuser resource file, so they can be restored when that document is opened again.

    An Override check box provides the ability to globally override a specific document’s settings stored in the Foxuser resource file.

    If you use Visual FoxPro editors in your distributed applications, you can control their functionality by limiting access to the IntelliSense functions and disabling the availability of hyperlinks.

    Miscellaneous Editor Enhancements

    In addition to the previously mentioned improvements, this version of Visual FoxPro contains a wealth of other improvements including:

    • In this version of Visual FoxPro, the editor opens files as DENY WRITE rather than DENY READ, so a file can be read or copied even while it is open in the Visual FoxPro Editor.
    • You can swiftly selections of text to upper or lower case from the Format or Editor shortcut menus.
    • The Format menu has new options to toggle word wrap and viewing white space (tab, space and paragraph marks).
    • A dirty file indicator mark (asterisk) is now displayed next to the file name in the title bar of the editor window if the document contains any unsaved changes.
    • You can now control whether indentation inserts tabs or spaces. The amount of the indentation can also be set.
    • The characters used for comment strings when you select Comment from the Format or Editor shortcut menus can be set in the Options dialog box.
    • While editing source code, the editor now highlights the parameter contents of a function, when you type a close parenthesis character. The duration of the highlighting can be set in the Options dialog box.
    • A number of new keyboard shortcuts have been added to the editor to improve developer productivity. See Keyboard Shortcuts topic for more details.

    IntelliSense in Visual FoxPro

    IntelliSense displays information in windows and lists that assists you with statement and function completion syntax and displays the available variables, objects, properties, methods, and events of objects.

    In Visual FoxPro, although IntelliSense always is available for native commands and functions, strong typing allows full IntelliSense support in editor windows for all user-defined code elements.

    The following are some features of IntelliSense in Visual FoxPro:

    • When you type a table-related keyword in the Visual FoxPro Editor or in the Command window, the Auto Table/Field drop-down list displays the valid members in the current context.
    • When you type one of the listed commands in the Command window, Visual FoxPro displays a list of the appropriate MRU files.
    • You can access IntelliSense functionality automatically for containers and controls in Visual FoxPro visual designers, such as the Form designer.
    • IntelliSense functionality is activated as you type in the Visual FoxPro Editor, in code editor windows for methods, and in the Command window.
    • Use the Visual FoxPro IntelliSense Manager Window to modify the appearance and behavior of the IntelliSense functionality.
    • You can modify or add to the functionality of IntelliSense in Visual FoxPro by modifying the contents of FoxCode.dbf.
    • You can enable or disable IntelliSense functionality programmatically by setting the _VFP.EditorOptions property value. For more information, see EditorOptions Property.

    Task List Manager

    The Visual FoxPro Task List Manager makes it possible for you to keep track of Shortcuts to locations in your code that you might want to return to for further editing. Additionally, the Task List Manager makes it possible for you organize your personal and business to-do lists in a manner similar to Microsoft Outlook.

    By Amjad Izhar
    Contact: amjad.izhar@gmail.com
    https://amjadizhar.blog

  • Al Riyadh Newspaper: February 17, 2025

    Al Riyadh Newspaper: February 17, 2025

    Several news articles, press releases, and opinion pieces cover diverse topics relevant to Saudi Arabia. The collection discusses economic matters like inflation rates, private sector growth, and tourism trends in the Kingdom. It also highlights various social initiatives such as community development programs, awards for social investment, and efforts to combat childhood cancer. Furthermore, there are articles on sports, including the Saudi Forum for Media and Formula E racing, and international relations, notably concerning the war in Ukraine and Saudi Arabia’s role in global energy markets. The articles demonstrate a wide array of the region’s current events and concerns, from local cultural topics to coverage of global events with regional influence.

    Source Material Review & Study Guide

    I. Quiz: Short Answer Questions

    Answer the following questions in 2-3 sentences each.

    1. According to the provided text, how does the Kingdom maintain a lower inflation rate compared to other G20 countries?
    2. What economic sectors are expected to contribute to Saudi Arabia’s non-oil sector growth in the coming years?
    3. What is the purpose of the King Salman Humanitarian Aid and Relief Center? Give at least one example of the center’s work in 2025, according to the text.
    4. What health issue was the focus of a campaign on February 15, 2025, as highlighted in the text? What are the most common types of this health issue in children?
    5. What was the focus of the 8th International Conference on Data Science and Machine Learning (CDMA2025) at Prince Sultan University?
    6. What is the King Abdullah bin Abdulaziz International Centre for Interreligious and Intercultural Dialogue (KAICIID) doing to promote the Saudi national identity?
    7. According to the text, how is Saudi Arabia working to create an attractive investment environment?
    8. What is the “Saudi Media Forum 2025” and what is its purpose?
    9. According to the text, what are some challenges of the “Generative AI” adoption among Saudi organizations?
    10. According to the text, what was the United States’ involvement in Ukrainian matters?

    II. Quiz Answer Key

    1. The Kingdom maintains a lower inflation rate by controlling prices of housing, water, electricity, fuel, and gas, and providing direct subsidies, according to the text. This is despite increases in some consumer prices, such as food and transportation.
    2. The non-oil sector is expected to grow due to efficiency, flexibility, and innovation, supported by public and private investments in strategic sectors.
    3. The center aims to alleviate the suffering of people in need and those affected by crises and disasters. In 2025, they distributed over 3,000 tons of dates in Yemen and food baskets and health kits in Syria.
    4. The campaign focused on childhood cancer, raising awareness about early detection, diagnosis, and treatment. The most common types of cancer in children are leukemia, brain cancer, lymphoma, neuroblastoma, and soft tissue sarcomas.
    5. The conference focused on the transformative impact of artificial intelligence, advanced systems, robotics, and software revolution in various sectors.
    6. KAICIID fosters dialogue and builds bridges to promote a cohesive society and strengthen civic engagement.
    7. Saudi Arabia is providing attractive investment opportunities for the private sector, both domestic and international, including offering investment opportunities worth $1.8 trillion to global companies and incentives for the local private sector.
    8. The Saudi Media Forum 2025 is an event aimed at developing the media sector. It includes sessions focused on developing talent, modernizing the sector, and defining new roles for media in various fields, showcasing the Kingdom’s achievements and developmental progress.
    9. Challenges include skills gaps and difficulties in scaling generative AI workloads from development to production. Data security and privacy are also concerns.
    10. The text mentions that Russian and American officials discussed settling the conflict in Ukraine and ensuring security guarantees for the country’s strength and prosperity.

    III. Essay Questions

    Address each of the following essay prompts in a well-structured essay of approximately 500-750 words.

    1. Analyze Saudi Arabia’s economic diversification efforts as depicted in the provided text. What are the key strategies and sectors targeted, and what challenges and opportunities are presented by these efforts?
    2. Examine the role of humanitarian aid and international cooperation in Saudi Arabia’s foreign policy. How does the King Salman Humanitarian Aid and Relief Center contribute to the Kingdom’s global image and influence, and what are the potential limitations of this approach?
    3. Discuss the significance of cultural initiatives and events, such as the Saudi Media Forum and art exhibitions, in promoting Saudi Arabia’s national identity and soft power. How effective are these initiatives in shaping international perceptions of the Kingdom, and what are the potential areas for improvement?
    4. Evaluate the impact of technological advancements, particularly in artificial intelligence and digital transformation, on Saudi Arabia’s economy and society. What opportunities and challenges do these technologies present, and what measures are being taken to ensure their responsible and beneficial implementation?
    5. Analyze the relationship between Saudi Arabia and the United States as it is represented in the provided texts. What are the key areas of cooperation and contention between the two countries, and how might these dynamics evolve in the coming years?

    IV. Glossary of Key Terms

    • Inflation: A general increase in prices and fall in the purchasing value of money.
    • G20: The Group of Twenty, an intergovernmental forum comprising 19 countries plus the European Union. It works to address major issues related to the global economy.
    • Non-Oil Sector: Sectors of the economy that do not involve the production or sale of petroleum products.
    • Economic Diversification: The process of shifting an economy away from a single income source toward multiple revenue streams from a wider array of sectors.
    • Strategic Sectors: Key industries identified as crucial for long-term economic growth and national development.
    • Public Investment Fund (PIF): A sovereign wealth fund owned by Saudi Arabia, playing a key role in economic diversification and investment projects.
    • Humanitarian Aid: Assistance provided to people in distress or need, often in response to natural disasters or conflicts.
    • Soft Power: The ability to influence others through attraction rather than coercion or payment.
    • Artificial Intelligence (AI): The theory and development of computer systems able to perform tasks that normally require human intelligence.
    • Digital Transformation: The integration of digital technology into all areas of a business, fundamentally changing how it operates and delivers value.
    • Generative AI: A type of artificial intelligence that can generate new content, such as text, images, or audio.
    • Sustainable Tourism: Tourism that takes full account of its current and future economic, social, and environmental impacts, addressing the needs of visitors, the industry, the environment, and host communities.
    • Saudi Vision 2030: A strategic framework to reduce Saudi Arabia’s dependence on oil, diversify its economy, and develop public service sectors such as health, education, infrastructure, recreation, and tourism.
    • National Identity: A sense of belonging to a nation and a feeling of cohesion among its people, often based on shared culture, values, and history.

    Saudi Arabia in 2025: Growth, Innovation, and Global Role

    Okay, here’s a briefing document summarizing the key themes and ideas from the provided text excerpts.

    Briefing Document: Analysis of “20692.pdf” Excerpts

    Overview: The excerpts from “20692.pdf” present a snapshot of Saudi Arabia in early 2025, covering diverse topics ranging from economic indicators and investment strategies to cultural events, healthcare initiatives, and international relations. The overall tone is optimistic, highlighting progress, innovation, and the Kingdom’s growing role on the global stage.

    Key Themes & Ideas:

    • Economic Growth and Diversification: A major theme is the Kingdom’s efforts to diversify its economy away from oil dependence and attract foreign investment.
    • Quote: ” (The Minister of Economy and Planning praised the efficiency and flexibility of the Saudi private sector, expecting the non-oil sector to grow by 4.8% in 2025 and 6.2% in 2026, supported by innovation). This quote demonstrates the expected growth in the non-oil sector.
    • Quote: “.” (…that the Kingdom needs investments worth a trillion dollars in infrastructure over the next seven to ten years…). This highlights the scale of investment needed.
    • Low Inflation: Saudi Arabia recorded the lowest inflation rate among the G20 countries, with a rate of 2.0% in January 2025 compared to January of the previous year.
    • Investment in Strategic Sectors: The Kingdom is actively investing in strategic sectors and infrastructure projects.
    • Quote: (The importance of cooperation between the governmental and private sectors, which the Kingdom is witnessing, and the role of the Public Investment Fund in this context). This emphasizes the importance of public-private partnerships.
    • The Public Investment Fund (PIF) is a central player, offering investment opportunities to the private sector worth 40 billion riyals.
    • Technological Advancement and Digital Transformation: There’s a strong emphasis on embracing digital technologies and fostering innovation.
    • Quote: “جامعة سلطان و»الحكومة الرقمية« تعززان التحول الرقمي” (Sultan University and the “Digital Government” enhance digital transformation). This illustrates efforts to promote digital transformation.
    • Launch of AI initiatives: King Saud University launched five initiatives to support digital transformation in the field of artificial intelligence, including establishing an AI office, creating AI labs, and launching AI-related student clubs.
    • The “Saudi Forum for Artificial Intelligence” highlights the transformative impact of AI and robotics across various sectors.
    • Humanitarian Efforts and Global Role: The Kingdom is actively engaged in humanitarian aid and plays a significant role in international affairs. (King Salman Center… for Relief and Humanitarian Works implements its humanitarian projects to alleviate the suffering of humanity in a number of countries in need and affected by crises and disasters). This quote shows the Kingdom’s focus on humanitarian aid.
    • The King Salman Center for Relief and Humanitarian Aid is a key player, implementing projects in Yemen, Syria, and Sudan.
    • The “Ita’am 4” initiative aims to distribute 390,109 food baskets in 27 countries during Ramadan.
    • Cultural Events and Promotion of National Identity: The excerpts highlight cultural events and initiatives aimed at promoting Saudi heritage and identity.
    • The “Saudi Forum for Media 2025” aims to develop the media sector and showcase the Kingdom’s achievements.
    • Exhibition on Al-Sharqiya doors: King Abdulaziz Center for World Culture (“Ithra”) showcased traditional doors from the Eastern region as a cultural heritage.
    • Focus on Social Issues: There’s attention given to important social issues such as child cancer awareness.
    • February 15th marks the International Childhood Cancer Day, with the Kingdom participating in awareness campaigns.
    • Prince Sita Award: Honoring winners of the Prince Sita Award, highlighting the importance of building relationships and promoting values of cooperation and compassion.
    • Tourism: There is a growing demand for rental housing in Mecca due to the increasing seasons and development movement.
    • The Grand Mosque and the Prophet’s Mosque in Mecca and Medina were captured in photographs, providing an opportunity for the public to discover the beauty of the holy sites and the relationship of pilgrims and worshippers to the Islamic sites.

    Points of Interest:

    • Low Inflation Amidst Global Concerns: The Kingdom’s ability to maintain low inflation, as stated, is noteworthy given global inflationary pressures.
    • AI and its Adoption: AI will be a challenge for organizations due to skills gaps and experience.
    • Regional and International Involvement: Reports of Saudi Arabia’s involvement in international affairs, for example the meeting with other countries to discuss the war on Ukraine.

    Potential Implications:

    • The economic diversification efforts, if successful, could significantly strengthen the Kingdom’s long-term stability and reduce its vulnerability to oil price fluctuations.
    • Investment in technology and digital transformation could lead to greater innovation and competitiveness.
    • Continued humanitarian efforts could enhance Saudi Arabia’s reputation and influence in the international community.

    Overall, the excerpts portray a dynamic and ambitious Saudi Arabia actively pursuing economic development, technological advancement, and a prominent role in global affairs.

    Saudi Arabia: Recent Developments and Initiatives FAQ

    FAQ about Recent Developments and Initiatives in Saudi Arabia

    Here are some frequently asked questions based on the provided news excerpts, covering various aspects of Saudi Arabian society, economy, and international relations:

    1. What is the status of inflation in Saudi Arabia compared to other G20 countries?

    Saudi Arabia has maintained one of the lowest inflation rates among G20 countries. In January 2025, the inflation rate was recorded at 2.0%, driven by increased prices in housing, water, electricity, gas, and fuel, but offset by decreases in transportation costs. The Saudi Central Bank’s policies and the government’s measures, including direct support and capping fuel prices, have been effective in curbing inflation.

    2. How is Saudi Arabia promoting private sector involvement in its economic transformation?

    The Saudi government acknowledges that it cannot solely finance its ambitious infrastructure projects. Minister of Economy and Planning emphasized the efficiency, flexibility, and innovation of the Saudi private sector, which is projected to drive non-oil sector growth. The Public Investment Fund (PIF) is playing a key role in this effort, with initiatives to offer investment opportunities worth billions of riyals to the private sector, aiming to boost local content and stimulate the economy.

    3. What steps is Saudi Arabia taking to advance digital transformation and artificial intelligence (AI)?

    Saudi Arabia is heavily investing in digital transformation, with initiatives like the “KSU Smartest” event at King Saud University showcasing AI applications. King Saud University is launching a new AI office and establishing AI and learning labs across all colleges. There are also programs to develop skills in AI and robotics, aimed at aligning with the Kingdom’s Vision 2030 goals.

    4. How is Saudi Arabia addressing humanitarian needs both domestically and internationally?

    The King Salman Humanitarian Aid and Relief Centre (KSRelief) is actively involved in providing aid to various countries, including Yemen, Syria, and Sudan. They distribute food baskets, medical supplies, and other forms of assistance to those affected by crises and disasters. Domestically, initiatives like the “Itaam 4” campaign aim to distribute food packages during Ramadan to needy families across Saudi Arabia.

    5. What efforts are being made to enhance tourism and cultural experiences in Saudi Arabia?

    Developments include a focus on the Red Sea as a tourist destination, as well as promoting cultural events. There’s also an effort to improve the experiences for visitors to holy sites like Mecca and Medina, and to promote Saudi Arabia’s cultural heritage through events such as the “Expo Juffer” photography exhibition.

    6. How is Saudi Arabia emphasizing sustainability in tourism and travel?

    A growing number of travelers (over 80%) consider the environmental impact when planning their trips, surpassing the regional average. While 71% confirmed sustainable practices in their accommodations during their last vacation, only 40% actively sought these options before booking, highlighting an area for improvement.

    7. What role is the Saudi Arabian government playing in the development of the real estate sector?

    The Saudi Arabian real estate sector is experiencing significant growth, driven by rising demand for housing in major cities. The government is issuing numerous building permits and working to transfer knowledge and expertise to the private sector to support this growth and align with Vision 2030.

    8. What are some of the challenges and opportunities facing the Saudi media landscape?

    The Saudi media landscape is undergoing a rapid transformation, driven by digital technologies and AI. The Saudi Media Forum serves as a platform to discuss these changes and identify ways to enhance Saudi Arabia’s position as a leading media force. There is a focus on correcting stereotypes, promoting Saudi culture, and leveraging media for diplomatic and cultural exchange. Some challenges include navigating issues of media integrity and adapting to new technologies.

    Saudi Arabia: Transformation and Global Role

    Saudi Arabia is a country undergoing significant transformation and playing an increasingly important role on the global stage, as evidenced by a variety of initiatives and events.

    Here’s a breakdown of key aspects:

    • Economic Development and Investment: Saudi Arabia is projected to become one of the most attractive investment destinations globally, drawing investors from around the world. The Kingdom is undertaking massive infrastructure projects valued at over a trillion dollars to boost the national economy and attract foreign investment. These projects are not merely temporary boosts but are designed to create a long-term economic foundation. The country aims to develop its infrastructure to meet current needs and ensure its position in the future global market.
    • Global Dialogue Facilitation: Saudi Arabia is emerging as a preferred location for international dialogue among world leaders. The Kingdom has expressed its willingness to host summits and promote dialogue between various nations, such as Russia and Ukraine, to achieve lasting peace. This reflects the country’s commitment to finding political solutions to global crises and collaborating with international partners to address pressing global issues.
    • Low Inflation Rate: Saudi Arabia has maintained one of the lowest inflation rates among the G20 countries. In January 2025, the inflation rate was recorded at 2.0% compared to the previous year.
    • Support for Regional Stability: The Kingdom is a proponent of regional stability, offering its support to Lebanon in response to attempts to undermine the safety of Lebanese citizens.
    • Technological Advancement: Saudi Arabia is actively promoting digital transformation through initiatives such as the CDMA2025 conference and collaborations between universities and digital government entities. These efforts aim to enhance research, knowledge transfer, and skill development in digital governance and internet governance.
    • Cultural and Heritage Preservation: The Kingdom is investing in the preservation and promotion of its cultural heritage through various initiatives, such as supporting environmental tourism, highlighting natural resources, and organizing festivals.
    • Philanthropic Activities: Saudi Arabia is recognizing and celebrating contributions to humanitarian and national achievements through awards like the Princess Sita Award for Development.
    • Arts and Culture Promotion: Saudi Arabia is actively involved in promoting arts and culture through initiatives like the King Abdulaziz Center for World Culture’s (Ithra) award for Cultural Communication, exhibitions, and collaborations with organizations like the Red Sea Film Foundation.
    • Space Program: The Kingdom is investing in its space program and plans to launch the Saudi Space Agency’s first center to study the future of space, reflecting the country’s ambition to be at the forefront of space exploration and technology.

    Saudi Arabia Inflation Rate, January 2025

    Here’s what the sources say about inflation rates:

    • Low Inflation Rate Saudi Arabia has maintained one of the lowest inflation rates among the G20 countries.
    • In January 2025, the inflation rate was recorded at 2.0% compared to January of the previous year.
    • The increase in inflation was driven by a rise in the prices of the housing, water, electricity, and gas section by 8.0%. Additionally, the cost of food and beverages increased by 0.8%, the prices of personal goods and services went up by 3.3%.
    • There was a decline in the prices of the transport section by 1.9%.
    • Experts confirm that Saudi Arabia continues to control inflation rates at the lowest levels due to its appropriate financial policies and measures. These policies enable it to maintain those low levels compared to other economies, in addition to continuously stimulating activities to increase investment, which supports the labor market, improves domestic demand, and stimulates consumption.
    • January 2025 statistics indicated that the rent prices for housing increased by 9.7% in January 2025, due to the increase in villa rents by 7.7%. The housing section is influential in the continuation of the annual inflation rate for December 2024, given its weight of 25.5%.
    • Food and beverage prices showed an increase of 0.8%, driven by a rise in vegetable prices of 5.6%. The prices of miscellaneous goods and services also increased by 3.3%, affected by the increase in the prices of jewelry, watches, and precious artifacts. Restaurant and hotel prices recorded an increase of 0.8%, driven by an increase in hotel service prices of 3.1%, while furnished apartments recorded an increase of 0.6%, affected by an increase in tuition fees for pre-primary and primary education by 0.6%.
    • The bulletin indicated a decrease in the prices of the furnishing and household equipment section by 2.4%, due to a decrease in the prices of furniture, carpets, and floor coverings by 4.0%. The clothing and footwear section decreased by 1.5%, affected by a decrease in the prices of ready-made clothes by 3.3%.
    • Car purchases prices decreased by 1.9%.
    • On a monthly basis, the consumer price index recorded a slight increase of 0.3% in January 2025 compared to December 2024. The housing section increased by 0.3%, driven by an increase in actual housing rent prices. The food and beverage section also witnessed an increase of 0.3%, and the prices of fish and seafood increased by 1.7%.
    • The prices of personal goods and services increased by 0.5%.
    • There was no change in the prices of restaurants and hotels.
    • The advisor Dr. Abdulrahman Biba, mentioned that the continuation of the inflation rate at this low level compared to the inflation rates recorded by the economies of the world confirms the success and effectiveness of the financial policies and measures followed by the Saudi Central Bank, as well as the governmental efforts, including direct support and setting a maximum price ceiling for fuel.
    • The consumer price index (CPI) reflects changes in the prices paid by consumers for a fixed basket of goods and services consisting of 490 items. This basket is based on the results of the household expenditure and income survey conducted in 2018, and the relevant prices are collected through field visits to points of sale.

    Social Investment Initiatives in Saudi Arabia

    Here’s what the sources say about social investment in Saudi Arabia:

    • Princess Sita Award for Development This award recognizes and celebrates contributions to humanitarian and national achievements.
    • Investment in Organizational Culture Investing in developing a strong organizational culture is a sustainable approach to achieving the desired goals of the company, its profitability, environment, and reputation. A positive work culture ensures employee commitment, which in turn translates into innovation and productivity.
    • Initiatives for Social Responsibility The Saudi government supports social responsibility through various initiatives and programs. For example, the Al Watania Company for Industries was awarded for its efforts in social work, and NEOM was recognized for its social responsibility initiatives and programs within NEOM.
    • Support for Charitable Organizations Charitable organizations and associations play an important role in serving the community. They provide programs for orphans and aim to deliver the best services to them.
    • Community Partnerships Partnerships between governmental entities and the private sector contribute to achieving sustainable development. For example, a collaboration in the Al-Qassim region aims to increase green spaces, improve the environment, and develop operational efficiency.
    • Initiatives to Improve the Urban Landscape The Riyadh region is undertaking initiatives to improve the urban landscape and foster a sense of belonging among residents. For example, there are initiatives to name gardens, enhance local identity, and promote community engagement in decision-making related to public facilities.
    • Support for Families of Patients Some organizations focus on providing support and care for patients and their families. For instance, the “Friends of Patients” association exemplifies efforts to meet patient needs.

    Global Oil Market: Production, Demand, and Geopolitics

    Here’s what the sources say about oil:

    • Oil Prices and Production: There is discussion regarding Saudi Arabia potentially increasing oil production to utilize its full capacity, depending on the long-term strategy and requirements for economic growth.
    • Global Oil Market Dynamics: Some countries should consider building new oil pipelines after tariffs revealed weaknesses in infrastructure. The US President threatened trade wars.
    • Russian Oil in Asia: An Indian oil minister stated that refineries in South Asia would only purchase Russian oil if supplied by non-sanctioned foreign companies.
    • China’s Fuel Demand: The International Energy Agency (IEA) cautioned that China’s demand for transportation fuel may have peaked, with overall fuel consumption potentially reaching 8.1 million barrels per day by the end of 2024.
    • US-Canada Relations: Canada sees some parts of the trade relationship with the United States as unsustainable.
    • Houthi Attacks on Oil Facilities: There’s mention of Houthi attacks on oil facilities, particularly affecting areas like Bab al-Mandab, with concerns about their impact on maritime navigation and global trade.
    • Hedge Funds and Oil Prices: There is mention of hedge funds reducing their bullish bets on oil prices, which could influence market dynamics.
    • Saudi Aramco’s Production and Projects: Saudi Aramco is moving forward with projects related to unconventional gas and liquids, which could impact future oil and gas production capacities.

    Saudi Arabia’s Inflation Rate and Economic Strategies in January 2025

    Saudi Arabia maintained a low inflation rate in January 2025 through several key strategies and policies. The inflation rate was recorded at 2.0% in January 2025, compared to January of the previous year.

    Key factors that contributed to keeping inflation under control include:

    • Financial Policies and Measures: Implementing appropriate financial policies and measures enabled the Kingdom to maintain low inflation levels compared to other economies.
    • Continuous Investment Stimulation: Continuously stimulating activities to increase investment supported the labor market, improved domestic demand, and stimulated consumption.
    • Government Support: The government provided direct support and set a maximum price ceiling for fuel.
    • Housing Market Influence: The housing section significantly influenced the annual inflation rate, with rent prices for housing increasing by 9.7% in January 2025 due to a 7.7% increase in villa rents.
    • Consumer Price Index (CPI): The CPI, which reflects changes in prices paid by consumers for a fixed basket of 490 items, is monitored to understand and manage inflation.

    Two Holy Mosques: Spiritual Depth Through Photography

    The objective of the “اك�سبوجر” 2025 photography exhibition is to showcase the depth of the spiritual aspect of the Two Holy Mosques by transforming ordinary scenes into artistic paintings that reflect the Islamic arts and architecture in these two mosques.

    Key goals of the exhibition are:

    • To offer an exploration of the human experience using photography as a tool for visual storytelling.
    • To capture moments of worship and reverence of pilgrims and worshippers.
    • To provide an opportunity to appreciate the creative talent of Saudi photographers in portraying the holiest Islamic sites.
    • To highlight the harmony and spiritual depth within the scenes of Muslim worshippers circling the Kaaba.

    Saudi Forum for Media 2025: Strategic Dimensions

    The Saudi Forum for Media 2025 has several strategic dimensions aimed at enhancing the Kingdom’s role and influence in the global media landscape. These dimensions include:

    • Adapting to Global Changes: The forum aims to help Saudi media keep pace with global transformations and to enhance the Kingdom’s position as an effective soft power.
    • Exploring Opportunities and Challenges: It will address challenges and opportunities related to digital developments that can be leveraged to boost Saudi media’s influence internationally.
    • Geopolitical Role and Vision 2030: The forum seeks to leverage Saudi Arabia’s developing geopolitical role and Vision 2030 to aid in its media-related goals.
    • Journalism Innovation: It focuses on the latest developments in the media sector, including humanistic and smart journalism.
    • Economic Transformation in Media: The forum explores the economic shifts in the media landscape, such as digital platforms like Netflix and Sony Pictures, and seeks to develop sustainable economic models for Saudi media.
    • Addressing Key Issues: Discussions will cover how Saudi media can elevate the Kingdom’s global media presence and correct stereotypical images of the Arab and Islamic world.
    • Cultural Diplomacy: It will also address how media content can enhance the Kingdom’s cultural diplomacy strategies.
    • High-Level Participation: The forum will act as a strategic platform by gathering political figures, major companies, and media personalities to discuss vital issues like artificial intelligence and sustainability.
    • Shaping the Future of Media: The forum aims to shape the future of media in Saudi Arabia and the Arab world, with a focus on turning discussions into tangible outcomes.

    By Amjad Izhar
    Contact: amjad.izhar@gmail.com
    https://amjadizhar.blog

  • The Transformative Power of February’s Full Moon

    The Transformative Power of February’s Full Moon

    The February full moon, historically known as the Snow Moon, blazes with extraordinary intensity this year as it illuminates the zodiac sign of Leo. Unlike its tranquil namesake, this lunation crackles with fiery energy, amplified by dynamic planetary alignments. While all zodiac signs may sense its electrifying undercurrents, three in particular—Taurus, Leo, and Aquarius—are poised to experience profound shifts. These individuals will navigate challenges that demand introspection, resilience, and a bold embrace of authenticity, ultimately unlocking pathways to personal evolution.

    Taurus: Embracing the Unfamiliar
    Under this lunation, Taurus finds itself at a cosmic crossroads as celestial tensions disrupt its innate preference for stability. The alignment of the Sun, Moon, and Mercury with Uranus in Taurus creates a push-pull dynamic, urging those born under this earth sign to venture beyond their emotional and psychological safe zones. Sudden revelations or external changes may force Taureans to reevaluate long-held habits, particularly in how they project their identity. This period demands adaptability, challenging their natural inclination to cling to routine, and instead inviting them to explore uncharted facets of their persona.

    The full moon’s energy also illuminates the necessity of inner transformation as a foundation for future aspirations. Taureans are encouraged to confront fears tied to impermanence, recognizing that growth requires releasing outdated versions of themselves. While the pressure to evolve may feel daunting, this lunation rewards courage. By channeling their legendary determination into self-reinvention rather than resistance, Taurus individuals can dismantle emotional barriers, paving the way for a future aligned with their truest ambitions.

    Leo: The Spotlight on Authenticity
    As the full moon radiates in their own sign, Leos are thrust into a moment of self-reflection, where their goals and desires come under intense scrutiny. This lunation amplifies their natural magnetism but also highlights obstacles—external criticisms, career upheavals, or lingering self-doubt—that threaten to derail their progress. The key lies in distinguishing between genuine ambition and the weight of others’ expectations. Leos must confront whether their pursuits stem from authentic passion or a desire to meet societal or relational standards, a process that demands brutal honesty.

    Yet, this lunar phase also empowers Leos to reclaim their narrative. By leaning into their innate confidence and creativity, they can transmute challenges into opportunities for clarity. The fiery energy of the moon fuels their courage to shed superficial distractions and focus on what truly matters. For Leos, success under this lumination isn’t about brute force but about refining their vision, trusting that staying true to their core values will guide them through turbulence. The path forward may be rugged, but their unwavering self-belief becomes the compass.

    Aquarius: Navigating Emotional Depths
    For Aquarius, typically the zodiac’s detached analyst, this full moon illuminates the intricate dance of relationships. Positioned in their sector of partnerships, the lunation urges a shift from intellectual detachment to emotional engagement. Aquarians may find themselves unexpectedly confronting buried sentiments within close bonds, whether romantic, familial, or platonic. Memories or unresolved tensions could surface, challenging their tendency to rationalize feelings rather than experience them. This phase invites a delicate balance: maintaining their signature objectivity while allowing space for vulnerability.

    The lunation’s call to soften resonates deeply here. Aquarians are reminded that connection requires courage—not just to love others, but to trust that opening their heart won’t dilute their individuality. Embracing vulnerability becomes an act of strength, proving that authenticity isn’t diminished by emotional exposure. By acknowledging their sensitivities, Aquarius individuals can forge deeper, more meaningful connections without sacrificing their unique perspective. This lunar moment is less about losing oneself in others and more about discovering how intimacy enriches their visionary spirit.

    Conclusion: A Catalyst for Renewal
    February’s full moon serves as a celestial mirror, reflecting areas of life where growth is both urgent and inevitable. For Taurus, Leo, and Aquarius, the lunation’s blaze illuminates distinct challenges—whether reinventing identity, honing ambition, or embracing vulnerability. Yet, each sign is equipped with innate strengths to navigate these trials. By leaning into courage, authenticity, and emotional honesty, this fiery lunation becomes less a source of drama and more a catalyst for profound, lasting transformation.

    By Amjad Izhar
    Contact: amjad.izhar@gmail.com
    https://amjadizhar.blog

  • Descriptive and Inferential Statistics: A Comprehensive Guide

    Descriptive and Inferential Statistics: A Comprehensive Guide

    The text is from a lesson on descriptive and inferential statistics, including hands-on Python code examples. It begins with foundational concepts like machine learning and domain knowledge, then progresses to core statistical measures such as mean, median, mode, range, variance, and standard deviation. Data representation via histograms and distribution types (Gaussian, skewed, uniform, bimodal, multimodal) is discussed along with practical applications using Python libraries, namely NumPy, Matplotlib, Seaborn, SciPy and Pandas. The lesson transitions to inferential statistics, covering point and interval estimation, confidence intervals, hypothesis testing, t-tests, and z-tests, again reinforced with Python implementations. The speaker poses practice questions that are meant for the student, so the student can gauge their understanding. Real-world examples are used, such as food delivery services like Swiggy, to illustrate the utility of statistical methods in everyday business scenarios.

    Data Analysis & Statistical Inference: A Study Guide

    Quiz

    Instructions: Answer the following questions in 2-3 sentences each.

    1. What is the key difference between descriptive and inferential statistics?
    2. Explain why sampling is essential in inferential statistics.
    3. Define “measure of central tendency” and list its three common types.
    4. Explain why it is important to know the center (average) of a dataset?
    5. Differentiate between population mean and sample mean.
    6. Explain why is the median sometimes a better measure of central tendency than the mean.
    7. Define “measure of dispersion” and its relation to data.
    8. What does a small range indicate about data points in a dataset? How does this differ from a larger range?
    9. Explain the difference between variance and standard deviation.
    10. Describe a real-world scenario where understanding data distribution (normal, skewed, etc.) is crucial for decision-making.

    Quiz Answer Key

    1. Descriptive statistics summarize and describe the characteristics of a dataset, while inferential statistics use sample data to make predictions or inferences about a larger population. Descriptive statistics focus on what is, while inferential statistics try to determine what might be beyond the data at hand.
    2. Sampling allows us to gather data from a smaller, manageable group and then use that information to make broader generalizations about the entire population. It is often impractical or impossible to collect data from every member of a population, making sampling a necessary and efficient approach.
    3. A measure of central tendency is a single value that attempts to describe a set of data by identifying the central position within that set. The three common types are the mean (average), median (middle value), and mode (most frequent value).
    4. The center or average of a dataset gives you an understanding of what a “typical” value looks like. Knowing the center helps in understanding trends, patterns, and behaviors of your data, so you can make predictions.
    5. Population mean is the average of all values in the entire population, while sample mean is the average of values taken from a subset (sample) of the population. Population mean is a fixed but typically unknown value, while the sample mean varies depending on the sample taken.
    6. Median is often a better measure when outliers are present in the data. Outliers drastically affect the mean by pulling it away from the central tendency, while the median is more resistant to extreme values as it focuses on the middle position.
    7. A measure of dispersion quantifies the spread or variability of data points in a dataset. It indicates how much the individual values deviate from the central tendency, showcasing the consistency or inconsistency within the data.
    8. A small range indicates that the data points are clustered closely together, suggesting low variability. A larger range indicates that the data points are more spread out, reflecting higher variability.
    9. Variance measures the average squared deviation of data points from the mean, providing a sense of the overall spread. Standard deviation is the square root of the variance and represents the typical distance of data points from the mean, expressed in the original units of measurement.
    10. An example is medical research, where understanding the distribution of a patient’s symptoms is important. Different groups of patients with similar symptoms may follow normal and/or skewed distributions, which helps doctors determine risk factors and personalize treatment.

    Essay Questions

    1. Discuss the importance of both descriptive and inferential statistics in the process of data analysis. Provide examples of how each type of statistic contributes to a comprehensive understanding of data and how they are used together to solve real-world problems.
    2. Explain the concept of “measure of central tendency,” describing the characteristics, advantages, and disadvantages of using the mean, median, and mode. Provide examples of datasets where one measure would be more appropriate than the others, justifying your choices.
    3. Discuss the significance of understanding data distribution (e.g., normal, skewed, uniform, bimodal, multimodal). Explain how different distributions can affect the choice of statistical methods and how visual representations of data distribution can aid in data analysis.
    4. Explain the concepts of hypothesis testing, null hypothesis, alternate hypothesis, p-value, and significance level (alpha). Describe the steps involved in conducting a hypothesis test and how to interpret the results, including the implications of rejecting or failing to reject the null hypothesis.
    5. Discuss the importance of sampling techniques in inferential statistics. Compare and contrast different sampling methods (e.g., random sampling, stratified sampling, cluster sampling) and explain how the choice of sampling method can impact the validity and generalizability of research findings.

    Glossary of Key Terms

    • Descriptive Statistics: Methods for summarizing and describing the characteristics of a dataset (e.g., mean, median, mode, standard deviation).
    • Inferential Statistics: Methods for using sample data to make inferences or generalizations about a larger population.
    • Population: The entire group of individuals, objects, or events of interest in a study.
    • Sample: A subset of the population that is selected for analysis.
    • Sampling: Collection of samples from the population.
    • Measure of Central Tendency: A single value that attempts to describe a set of data by identifying the central position within that set (e.g., mean, median, mode).
    • Mean: The average of all values in a dataset, calculated by summing the values and dividing by the number of values.
    • Median: The middle value in a dataset when the values are arranged in order.
    • Mode: The most frequent value in a dataset.
    • Measure of Dispersion: A statistical measure that quantifies the spread or variability of data points in a dataset (e.g., range, variance, standard deviation).
    • Range: The difference between the maximum and minimum values in a dataset.
    • Variance: A measure of how spread out the data points are from the mean; it is the average of the squared differences from the mean.
    • Standard Deviation: A measure of the typical distance of data points from the mean; it is the square root of the variance.
    • Data Distribution: The way data points are spread out across a range of values, often visualized using histograms or other graphical representations (e.g., normal distribution, skewed distribution).
    • Normal Distribution: Also known as Gaussian distribution, a symmetrical bell-shaped distribution characterized by the mean, median, and mode being equal.
    • Skewed Distribution: An asymmetrical distribution where the data is concentrated on one side of the mean, resulting in a long tail on the other side (either left-skewed or right-skewed).
    • Hypothesis Testing: A statistical method used to determine whether there is enough evidence to reject a null hypothesis in favor of an alternative hypothesis.
    • Null Hypothesis (H0): A statement that there is no significant difference or relationship between variables.
    • Alternative Hypothesis (H1): A statement that contradicts the null hypothesis, suggesting there is a significant difference or relationship between variables.
    • P-value: The probability of obtaining results as extreme as or more extreme than the observed results, assuming the null hypothesis is true.
    • Significance Level (Alpha): A pre-determined threshold used to decide whether to reject the null hypothesis; typically set at 0.05.
    • Confidence Interval: A range of values that is likely to contain the true population parameter with a certain level of confidence.
    • T-test: Statistical test used to determine if there is a significant difference between the means of two groups.
    • Z-test: Statistical test used to determine if there is a significant difference between a sample mean and population mean.

    Statistical Concepts: An Overview

    Okay, I have analyzed the provided text excerpts. Here’s a briefing document summarizing the key themes and ideas presented, along with relevant quotes:

    Briefing Document: Summary of Statistics Concepts

    I. Descriptive Statistics

    • Theme: Summarizing and describing the main features of a dataset.
    • Main Ideas:Descriptive statistics involve extracting meaningful insights from data by analyzing and describing its features.
    • Examples include finding the maximum, minimum, and average values within a dataset. “Taking it out descriptive statistics where we what do whatever our important people do These are the features, let’s analyze it Let us do it and describe it here now”.
    • Creating visualizations (e.g., pie charts) to represent these summarized features is also part of descriptive statistics. “If I make a graph by creating surgeries If I describe it then this also Part of descriptive statistics”.
    • Descriptive statistics simplifies data for people to understand the main parameters of the data.

    II. Inferential Statistics

    • Theme: Making predictions about a population based on a sample of data.
    • Main Ideas:Inferential statistics uses sample data to draw conclusions and make predictions about a larger population. “Sample data is being collected And based on the sample data, the whole What is being done for Bangalore Prediction is being performed this for the whole of Bangalore”.
    • This involves collecting a representative sample and using statistical techniques to generalize findings to the entire population.
    • The source uses the analogy of testing water samples from different streams of a river to predict the overall pollution level of the entire river.
    • Hypothesis testing, confidence intervals, and regression analysis are important techniques in inferential statistics.
    • A key application is in situations where it’s impractical to survey an entire population (e.g., a startup in Bangalore gauging customer satisfaction). “The startup is in Bangalore so I am in Bangalore to ask each of your customers I will not go Nana, how do you feel about it brother How is my service looking then I What did you do from a survey from different places took the sample and analyzed it and Predict for all of Bangalore”.
    • “This is a part of statistics It is a branch that deals with data analysis Generalizing and testing hypotheses it helps”.

    III. Measure of Central Tendency

    • Theme: Understanding the “center” or typical value of a dataset.
    • Main Ideas:Measure of central tendency helps to understand the clustering point of data.
    • The purpose is to find a value around which the data points are clustered. “Their use is to understand the center of the data set By doing this we can know the values ​​of the data Around which place are these three clustered?”
    • The source focuses on three key measures:
    • Mean: The average of all values. The mean can be calculated for the entire population or only for the sample. “Mean is a statistical measure which This represents the central tendency It is the average of all the values ​​in a data set So we know what mean is We also know mean as average”.
    • Median: The middle value when the data is sorted. “The median is never an effect Never assume that what you are thinking is wrong with outliers does not give value so we call it median I needed it”. It is immune to outliers, making it useful when extreme values are present.
    • Mode: The most frequently occurring value. “In statistics the mud is a measure of The central tendency that represents the The value that appears most frequently”. Datasets can have multiple modes (multimodal).
    • The text provides code snippets in Python using libraries such as NumPy, Statistics, and Pandas to calculate these measures. The libraries helps to compute the same values in a simple line of code instead of applying the formula manually.
    • The choice of measure depends on the distribution of the data and the presence of outliers.
    • Real-life applications include determining average customer spending in a shop to inform purchasing decisions.

    IV. Measure of Dispersion

    • Theme: Quantifying the spread or variability of data.
    • Main Ideas:Dispersion measures how spread out the data points are in a dataset. “The extent of the spread or data out major to major it tells that How”.
    • Key measures include:
    • Range: The difference between the maximum and minimum values. “It indicates how far the data Points are spread out by showing the Difference between the minimum and the maximum Values ​​in a data set”. Highly sensitive to outliers.
    • Variance: The average squared deviation from the mean. Quantifies how much individual values differ from the average. It is measured differently depending on the population and the sample. “Variance a statistic which is the variation in the variation between the values ​​of the data set or quantifies the dispersion, i.e.”.
    • Standard Deviation: The square root of the variance. Provides a more interpretable measure of spread in the original units of the data. By computing square root of the variance, we can use the standard deviation as the measurement unit.
    • Python code examples illustrate how to calculate these measures using NumPy, Pandas and Scipy libraries.
    • Dispersion measures are essential for understanding the distribution of data and identifying potential outliers.
    • The sample variance is divided by n-1 instead of n to provide a less biased estimate of the population variance because population is always bigger and more spread then the sample.
    • “Always remember this, I have asked you many times goes to you in your interview question You are asked when you will take the Judd test”.

    V. Data Distribution

    • Theme: Understanding the shape and characteristics of data distributions.
    • Main Ideas: The text covers several common distributions:
    • Normal (Gaussian) Distribution: A bell-shaped, symmetrical distribution where the mean, median, and mode are equal. “The Goschen distribution is the one whose Mean, mode, and median all three come to one point at this point its mean will also be this At the point, its median will also be there and on the same”. Data is concentrated near the center. Within one standard deviation of the mean, approximately 68.2% of the data falls. 95.4% within two and 99.7% within three standard deviations.
    • Skewed Distribution: An asymmetrical distribution with a “tail” extending to one side. Can be either positively skewed (right-skewed, tail on the right) or negatively skewed (left-skewed, tail on the left). “Skew Skew Distribution Skewness which happens to be a Statistics We had studied the bell shape curve completely from simatic even if i back up Let me show you the symmetry curve”.
    • Uniform Distribution: All values have equal probability. Forms a straight, horizontal line when plotted. “The probability equals a straight It is a horizontal line that indicates that the concurrency of any value is equal to There will be a chance to come”.
    • Bimodal Distribution: Has two distinct peaks or modes, indicating two separate groups or clusters within the data. “Look at the distribution by model Distribution One Statistics by just as the name suggests is it coming model bye means bicycle”. The data is divided into two different clusters.
    • Multimodal Distribution: Has more than two distinct peaks or modes. Suggests multiple sub-groups within the data. “Multimodal distributions are a statistician is a distribution in which two to three parts of the data are have more distinct peaks or modes there are more than two always remember this”.
    • The source provides Python code for generating and plotting these distributions using libraries like NumPy, Matplotlib, and Seaborn. The curve can be ploted by kd2 option on snss.

    VI. Hypothesis Testing

    • Theme: A framework for making decisions about populations based on sample data.
    • Main Ideas:Involves formulating a null hypothesis (a statement to be tested) and an alternative hypothesis.
    • The goal is to determine if there is enough evidence to reject the null hypothesis.
    • Key concepts:
    • P-value: The probability of obtaining results as extreme as the observed results, assuming the null hypothesis is true.
    • Significance Level (Alpha): A pre-determined threshold for rejecting the null hypothesis (typically 0.05). If the p-value is less than alpha, the null hypothesis is rejected.
    • Confidence Interval: A range within which the population parameter is likely to fall.
    • Examples include testing the fairness of a coin or the effectiveness of a new drug.
    • A p-value is considered acceptable when 95 percent of the interval test is inside, meaning if P Value is smaller than alpha you may reject the null hypothesis.
    • In this case, the p value indicates if the null hypothesis is false.
    • If P is greater than Alpha you can accept the null hypothesis.
    • Hypothesis Testing Irrentia No such values Take for example a company okay there’s a pharmaceutical company that Suppose a drug manufacturer makes medicines Now it makes the drug different I will try different samples in different people and then based on that I will tell you that yes, this drug is for the entire population“.

    VII. T-Test

    • Theme: Comparing the means of two groups.
    • Main Ideas:Used to determine if there is a significant difference between the means of two independent groups. “The t Test is a Hypothesis Use tests to determine if a significant Difference between the means of two groups such as that many times we have two groups here”.
    • Applicable when sample sizes are small.
    • Example: Comparing the performance of students taught using traditional methods versus online methods. The idea is to understand what group has the biggest performance.

    VIII. Z-Test

    • Theme: Testing the mean of a sample against a known population mean.
    • Main Ideas:Used when the sample size is large (n >= 30) and the population standard deviation is known. “Method of fancy statistics is which is used when you want to test that the mean of the sample is equal to the population mean or is it not right”.
    • In order for the T test to be a Z Test the value of N has to be bigger or equal to 30.
    • Example: Testing if the average weight of a product from a company matches its claimed average weight.
    • The Z test requires also to know the standard deviation.

    This briefing document should provide a good overview of the statistical concepts discussed in the provided text. I have tried to include all the most pertinent points while also highlighting key terminology and examples to facilitate understanding.

    Statistics and Data Analysis: Key Concepts Explained

    FAQs on Statistics and Data Analysis

    1. What is the difference between descriptive and inferential statistics?

    Descriptive statistics focuses on summarizing and describing the main features of a dataset. This involves calculating measures like mean, median, mode, maximum, minimum, and creating visualizations like pie charts and histograms. For instance, calculating the average, minimum, and maximum profit from a company’s profit data is descriptive statistics.

    Inferential statistics, on the other hand, uses sample data to make predictions or inferences about a larger population. For example, collecting customer satisfaction ratings from a sample of Bangalore residents and using that data to predict the satisfaction of all customers in Bangalore is inferential statistics. Techniques like hypothesis testing and confidence intervals are key tools.

    2. What is “Measure of Central Tendency,” and what are its common types?

    Measure of central tendency is used to understand the center or typical value of a dataset. It helps to identify around which value the data points are clustered. The three common types are:

    • Mean: The average of all values in a dataset. Calculated by summing all values and dividing by the number of values. Both population mean and sample mean are important perspectives. Population mean is for the entire population data while sample mean is calculated from a subset.
    • Median: The middle value in a sorted dataset. It is less sensitive to outliers compared to the mean. To find the median, sort the data in ascending or descending order. If there are an even number of values, the median is the average of the two middle values.
    • Mode: The value that appears most frequently in a dataset. A dataset can have multiple modes (multimodal) or no mode at all if no value is repeated.

    3. How do population mean and sample mean differ in descriptive statistics, and why is this distinction important in prediction models?

    The population mean refers to the average of all values in an entire population, while the sample mean is the average calculated from a subset (sample) of that population. The formula for population mean (μ) is the summation of all x values divided by N (total population count) whereas the sample mean (x̄) is the summation of all x values divided by n (sample size).

    This distinction is crucial in prediction models because we often use sample data to make predictions about the entire population. The sample mean acts as an estimate for the population mean.

    4. How can you determine the central tendency for data sets with missing values?

    Missing values are commonly dealt with using the mode. Replace a missing value with the most frequent value.

    5. How are variance and standard deviation used to measure data dispersion?

    Variance and standard deviation are measures of dispersion that quantify how spread out the data points are in a dataset.

    • Variance: Calculates the average squared difference of each data point from the mean. There are separate formulas for population variance (σ²) and sample variance (s²).
    • Standard Deviation: The square root of the variance. It provides a more interpretable measure of spread in the same units as the original data.

    A smaller range indicates that the data points are close together, while a larger range suggests they are spread far apart. However, the range is sensitive to outliers.

    6. What is the significance of choosing n-1 rather than n when calculating the sample variance, especially when making predictions?

    When calculating sample variance, n-1 (Bessel’s correction) is used in the denominator instead of n to provide an unbiased estimate of the population variance. Dividing by n tends to underestimate the population variance, especially with smaller sample sizes. This correction is important because in inferential statistics, we use the sample variance to estimate the variance of the entire population.

    7. How do different distribution types like Gaussian (normal), skewed, uniform, and bimodal influence data analysis and interpretation?

    Understanding the distribution of data is critical for accurate analysis and interpretation:

    • Gaussian (Normal) Distribution: Characterized by a bell-shaped curve, where most data points cluster around the mean. The mean, median, and mode are equal.
    • Skewed Distribution: Asymmetrical distribution where data is concentrated on one side. In positive (right) skewness, the tail is longer on the right, and the mean is greater than the median and mode. In negative (left) skewness, the tail is longer on the left, and the mean is less than the median and mode.
    • Uniform Distribution: All values have equal probability, resulting in a flat, horizontal line.
    • Bimodal Distribution: Two distinct peaks or modes, indicating the presence of two separate groups or clusters within the data.

    8. What are the purposes of confidence intervals and hypothesis testing in inferential statistics, and how are these performed with tools like Z-tests, T-tests, and P-values?

    • Confidence Intervals: Provide a range within which a population parameter (e.g., mean) is likely to fall, with a certain level of confidence.
    • Hypothesis Testing: A process used to determine whether there is enough evidence to reject a null hypothesis (a statement about a population parameter).
    • Z-test: Used to test hypotheses when the sample size is large (n >= 30) and the population standard deviation is known.
    • T-test: Used when the sample size is small or the population standard deviation is unknown. It’s often used to check if there is a significant difference in means of two independent groups.
    • P-value: The probability of obtaining test results at least as extreme as the results actually observed, assuming that the null hypothesis is correct.
    • If the p-value is less than a significance level (alpha, commonly 0.05), we reject the null hypothesis. If the p-value is greater than alpha, we fail to reject the null hypothesis.

    Python for Statistical Analysis: A Data Science Perspective

    Python’s use in statistical analysis, especially within data science, is mentioned throughout the sources. Here’s a breakdown:

    • Python as a programming language Python, when combined with statistics, enables users to perform mathematical calculations and solve data-related problems, making statistical equations easier to handle. It is a tool for data analysis.
    • Libraries Python offers libraries such as NumPy, SciPy, Pandas, Seaborn and Matplotlib to facilitate statistical computations, data manipulation, and visualization.
    • Use Cases Python’s role involves extracting insights from data and working with algorithms, making it relevant for roles like Data Scientist, Machine Learning Engineer, AI Engineer, Data Analyst, and Business Analyst.
    • Machine Learning Python is the foundation for machine learning algorithms. When combined with statistics, it is heavily utilized by Machine Learning Engineers.
    • Coding Examples The excerpts include practical coding examples using Python libraries to calculate statistical measures such as mean, median, variance, standard deviation, and to generate data visualizations like histograms and distribution plots.
    • Considerations
    • The sources emphasize the importance of understanding the theoretical concepts behind statistical methods before implementing them in Python code.
    • Some of the sources suggest to independently verify information obtained through external resources like Google and ChaGPT.

    Machine Learning: Statistics, Python, and Data Science

    The sources discuss machine learning in the context of statistics and Python. Here’s a summary:

    • Role of Statistics Statistics serves as a foundation for machine learning algorithms.
    • Relationship with Python Python is used to implement machine learning models. Machine learning algorithms are built on Python, and the combination of statistics and Python is heavily utilized by Machine Learning Engineers.
    • Skills for Data Scientists A data scientist combines statistics, Python, machine learning, and domain knowledge to solve problems.
    • Importance of a Statistical Foundation When approaching a problem with data, a solid statistical foundation is essential for extracting insights, and machine learning algorithms are used to analyze the data.
    • Premium Courses Premium courses in Data Science and Data Analytics are available, which cover machine learning algorithms in conjunction with statistics.

    The Importance of Domain Knowledge in Data Science

    Domain knowledge is a key component, alongside statistics, Python, and machine learning, for a data scientist. Having domain knowledge means understanding the specific field or industry to which data science is being applied.

    • Importance Domain knowledge is essential for solving problems effectively. It allows a data scientist to identify the most relevant problems to solve and to interpret the results of their analysis in a meaningful way.
    • Real-World Application The source uses the example of Swiggy, a food aggregator platform, to illustrate how statistics is applied in a real-life business context. Understanding the business model and operations of Swiggy constitutes domain knowledge in this instance.
    • Integration with Other Skills Domain knowledge complements skills in statistics, Python, and machine learning, enabling data scientists to extract insights and make informed decisions.

    Descriptive Statistics: Summarizing and Understanding Data

    Descriptive statistics is a fundamental aspect of statistical analysis that focuses on summarizing and describing the main features of a dataset. Here’s a detailed overview from the sources:

    • Definition Descriptive statistics involves identifying, visualizing, analyzing, and describing the main features of a dataset. Its primary goal is to understand hidden patterns within the data and present them in a simple, understandable manner. It is a branch of statistics that allows us to do something with the data and helps to draw better conclusions.
    • Real-Life Examples
    • Swiggy When you open the Swiggy app, statistics begin to work to deliver food, using delivery time estimations, travel time, weather conditions, and distance calculations. Descriptive statistics gives an idea of the maximum time it will take for delivery to reach a home and how much time it will take for the delivery person to travel.
    • Healthcare A healthcare company can use descriptive statistics to analyze customer blood pressure data. By calculating the mean, mode, median, and standard deviation, the company can understand how many customers have high or low blood pressure. This information helps in making decisions about medicine stock.
    • Website Traffic Descriptive statistics can be applied to website traffic data to analyze hourly visits, page views, and bounce rates. By applying measures such as median and standard deviation, website owners can understand user behavior through graphs.
    • Sales Data. Descriptive statistics summarizes important features of sales data, such as average monthly sales, maximum gross sales, and minimum gross sales.
    • Methods Descriptive statistics uses several techniques:
    • Measures of Central Tendency These include the mean, median, and mode, which help to understand the center of the data set and the values around which the data is clustered.
    • Measures of Variability These include range, variance, and standard deviation, which describe the spread or dispersion of the data.
    • Data Representation Charts, graphs, tables, frequency distribution, and jitter plots are used to visualize and summarize data.
    • Techniques
    • Mean (Average) It is a statistical measure representing the central tendency and is calculated by summing all values in a dataset and dividing by the number of values. It can be looked at from the perspectives of both population mean and sample mean.
    • Median The median is the middle value in a dataset when arranged in ascending or descending order. It is less affected by outliers and skewed data.
    • Mode The mode is the value that appears most frequently in a dataset. Datasets can have multiple modes (multimodal).
    • Purpose The main purpose of descriptive statistics is to understand the hidden patterns inside the data and tell them in simple terms. By summarizing and visualizing data, descriptive statistics helps in making informed decisions and gaining insights.
    • Relation to Python Python, combined with libraries, is often used for descriptive statistical analysis. Python is a useful programming language that helps with coding to represent data via descriptive statistics.

    Inferential Statistics: Techniques, Hypothesis Testing, and Applications

    Inferential statistics involves making predictions and generalizations about a population based on a smaller sample of data. It contrasts with descriptive statistics, which focuses on summarizing the characteristics of a dataset without making inferences beyond that dataset.

    Here’s a breakdown of key concepts and techniques within inferential statistics from the sources:

    • Definition Inferential statistics is used to complete a study with a small sample of data and perform predictions about populations. It is a branch of statistics that deals with data analysis, generalizing, and testing hypotheses.
    • Techniques Several techniques are used in inferential statistics to draw conclusions and make predictions about a population based on sample data:
    • Estimation This involves approximating population parameters based on sample data. There are two types of estimation:
    • Point Estimation Provides a single, fixed number as the estimate.
    • Interval Estimation Provides a range within which the parameter is expected to fall.
    • Confidence Intervals A confidence interval is a range that estimates the value of a population parameter with a certain level of confidence. It indicates that if multiple samples are taken and confidence intervals are calculated, a certain percentage of them will cover the true parameter value.
    • Hypothesis Testing This is a systematic process for evaluating evidence and making decisions about claims or hypotheses. It involves the following steps:
    • Null Hypothesis The initial assumption or claim that is being tested.
    • Alternative Hypothesis The opposite of the null hypothesis, which is considered if the null hypothesis is rejected.
    • Experiment/Test A statistical test is performed to gather evidence. Common tests include the t-test, z-test, ANOVA, and Chi-Square test.
    • Decision Based on the test results, a decision is made whether to accept or reject the null hypothesis.
    • Examples
    • Exit Polls Exit polls are a common example of inferential statistics, where samples are taken from different places to predict which party will win in a particular area.
    • Drug Effectiveness Studies A drug company uses inferential statistics to determine if a new drug is effective for the entire population by testing it on different samples.
    • Customer Satisfaction Surveys A startup in Bangalore uses surveys to collect feedback from customers in different areas and predict overall customer satisfaction across the city.
    • Water Quality Analysis Samples are collected from different streams of a river to make predictions about the overall pollution levels of the entire river.
    • P-Value Test
    • The p-value test is used in hypothesis testing to determine the probability of obtaining results as extreme as, or more extreme than, the observed results, assuming the null hypothesis is true.
    • A smaller p-value (typically less than a significance level α, commonly 0.05) indicates stronger evidence against the null hypothesis, leading to its rejection. Conversely, a larger p-value suggests that there is not enough evidence to reject the null hypothesis.
    • T-Test
    • The t-test is used to determine if there is a significant difference between the means of two groups.
    • It is often used when dealing with small sample sizes to analyze the population.
    • Z-Test
    • The z-test is used to test if the mean of a sample is equal to the population mean.
    • It is appropriate when the sample size is large (n ≥ 30) and the population standard deviation (σ) is known.
    • Relationship to Sample Data
    • In inferential statistics, predictions for an entire population are based on sample data. The samples are a subset of the population.
    • Hypothesis testing in practice
    • A pharmaceutical company manufactures drugs and tests different samples on different people. Based on this, it predicts whether the drug is good for the entire population or not.
    Statistics for Data Science Full Course | 3+ Hours Beginner to Advanced

    By Amjad Izhar
    Contact: amjad.izhar@gmail.com
    https://amjadizhar.blog

  • AI, Machine Learning, and Deep Learning Essentials

    AI, Machine Learning, and Deep Learning Essentials

    The provided document serves as a comprehensive educational resource on artificial intelligence, machine learning, and deep learning. It starts with basic definitions and progresses to cover advanced topics like neural networks, language processing, and computer vision. The material discusses algorithms, techniques, and tools used in AI development, highlighting real-world applications across various industries such as healthcare, finance, and retail. It emphasizes the importance of ethical considerations, responsible AI practices, and the skills needed to pursue a career in this evolving field. Practical examples and code snippets are included, with a strong focus on using Python and popular libraries like TensorFlow. The document also compares different learning methods, such as supervised, unsupervised, and reinforcement learning.

    Artificial Intelligence and Deep Learning Study Guide

    Quiz

    Instructions: Answer the following questions in 2-3 sentences each.

    1. What is NumPy, and why is it essential in machine learning?
    2. Explain the difference between stemming and lemmatization in natural language processing.
    3. What is an activation function in the context of artificial neural networks, and what role does it play?
    4. Describe the purpose and function of a “dense layer” in a neural network.
    5. What are stop words, and why are they removed in NLP tasks?
    6. Explain the purpose of a document term matrix (DTM) in natural language processing.
    7. Describe the basic structure and function of a single artificial neuron (perceptron).
    8. What are exploding and vanishing gradients, and how can they affect the training of recurrent neural networks (RNNs)?
    9. What are LSTMs and how do they address the limitations of traditional RNNs?
    10. Explain the roles of the generator and discriminator in generative adversarial networks (GANs).

    Quiz Answer Key

    1. NumPy is a Python library primarily used for numerical computations, providing support for multi-dimensional arrays and mathematical functions. It is crucial in machine learning for efficient data manipulation and mathematical operations necessary for training models.
    2. Stemming and lemmatization are techniques in NLP to reduce words to their root form. Stemming uses heuristics to chop off prefixes or suffixes, while lemmatization considers the word’s meaning and morphological analysis to return a valid word (lemma).
    3. An activation function in neural networks introduces non-linearity, allowing the network to learn complex patterns. It determines whether a neuron should “fire” based on a threshold, transforming the weighted sum of inputs into an output signal.
    4. A dense layer is a standard layer type in neural networks where each neuron is connected to every neuron in the preceding layer. These layers learn complex relationships between features by adjusting the weights of these connections.
    5. Stop words are common words in a language (e.g., “the,” “is,” “a”) that are often removed from text during NLP tasks. Removing them helps to focus on more meaningful words and reduce noise in the data.
    6. A document term matrix (DTM) in NLP is a matrix that represents the frequency of words in a collection of documents. It is used to quantify and compare documents based on their word content, enabling various text analysis tasks.
    7. A perceptron consists of inputs, weights, a summation function, and an activation function. It calculates a weighted sum of inputs, applies the activation function to determine the output, and is the basic building block of neural networks.
    8. Exploding gradients cause instability due to extremely large weight updates, while vanishing gradients hinder learning due to minuscule weight updates. Techniques like gradient clipping, truncated BPTT, and ReLU activation functions are used to mitigate these problems.
    9. LSTMs (Long Short-Term Memory networks) are a type of RNN architecture designed to handle long-term dependencies by incorporating a cell state and gates (forget, input, output) to regulate information flow, thus addressing vanishing gradient problems.
    10. In GANs (Generative Adversarial Networks), the generator creates synthetic data (e.g., images), while the discriminator evaluates whether the data is real or fake. They compete in a zero-sum game, improving each other until the generator produces highly realistic data.

    Essay Questions

    1. Discuss the role of transfer learning in deep learning. How does it improve efficiency and performance, and what are some of its limitations?
    2. Explain the process of training a deep neural network, including the concepts of forward propagation, backpropagation, loss functions, and optimization algorithms.
    3. Compare and contrast different types of neural network architectures, such as convolutional neural networks (CNNs), recurrent neural networks (RNNs), and transformers.
    4. Discuss the ethical considerations surrounding the development and deployment of AI technologies, including bias, privacy, and job displacement.
    5. Describe the application of AI in a specific industry (e.g., healthcare, finance, transportation) and discuss the potential benefits and challenges associated with its adoption.

    Glossary of Key Terms

    • Activation Function: A function in a neural network that introduces non-linearity, determining whether a neuron should “fire” or not.
    • Adam Optimizer: An optimization algorithm used to update the weights of a neural network during training, combining the benefits of AdaGrad and RMSProp.
    • Artificial Neural Network (ANN): A computational model inspired by the structure and function of biological neural networks, used for machine learning and deep learning.
    • Backpropagation: An algorithm used to train neural networks by calculating the gradient of the loss function with respect to the network’s weights and biases.
    • Convolutional Neural Network (CNN): A type of neural network designed for processing grid-like data, such as images, using convolutional layers.
    • Dense Layer: A fully connected layer in a neural network where each neuron is connected to every neuron in the preceding layer.
    • Document Term Matrix (DTM): A matrix representing the frequency of words in a collection of documents, used for text analysis.
    • Epoch: One complete pass through the entire training dataset during the training of a neural network.
    • Generative Adversarial Network (GAN): A type of neural network architecture consisting of two networks (generator and discriminator) that compete against each other.
    • Lemmatization: The process of reducing words to their base or dictionary form (lemma) using morphological analysis.
    • Long Short-Term Memory (LSTM): A type of recurrent neural network architecture designed to handle long-term dependencies in sequential data.
    • Natural Language Processing (NLP): A field of artificial intelligence focused on enabling computers to understand, interpret, and generate human language.
    • NumPy: A Python library used for numerical computations, providing support for multi-dimensional arrays and mathematical functions.
    • Optimizer: An algorithm used to adjust the parameters of a machine learning model to minimize the loss function.
    • Perceptron: A single-layer neural network that performs binary classification by learning a linear decision boundary.
    • ReLU (Rectified Linear Unit): A commonly used activation function in neural networks, defined as f(x) = max(0, x).
    • Recurrent Neural Network (RNN): A type of neural network designed for processing sequential data, such as text or time series.
    • Stemming: The process of reducing words to their root form by chopping off prefixes or suffixes.
    • Stop Words: Common words in a language (e.g., “the,” “is,” “a”) that are often removed from text during NLP tasks.
    • TensorFlow: An open-source software library for machine learning and deep learning, developed by Google.
    • Tokenization: A process in natural language processing that involves breaking down a text into smaller units called tokens (words, phrases, symbols).
    • Truncated Backpropagation Through Time (TBPTT): A variant of backpropagation through time used to train recurrent neural networks by limiting the number of time steps considered during backpropagation.

    AI, ML, and NLP: Concepts and Applications

    Okay, here’s a briefing document summarizing the main themes and important ideas from the provided document excerpts:

    Briefing Document: Analysis of AI and Machine Learning Concepts

    Overview: The document excerpts cover a wide range of topics within the fields of Artificial Intelligence (AI), Machine Learning (ML), and Natural Language Processing (NLP). It provides introductions to fundamental concepts, tools, techniques, and use cases within these domains. The material seems designed for instructional purposes, offering practical examples and code snippets to illustrate the concepts.

    Key Themes and Ideas:

    1. Introduction to Python and Essential Libraries:
    • The document begins with the basics of Python setup and introduces key libraries for data science and ML:
    • NumPy: “It makes complex mathematical implementations very simple right it’s mainly known for computing mathematical data so numai is a package that you should be using for any sort of statistical analysis or data analysis that involves a lot of math.” NumPy is essential for numerical computation and array manipulation.
    • Pandas: Used for data processing and working with data in CSV format. Example provided of loading a CSV file for weather prediction.
    • TensorFlow: “Tensorflow is nothing but a python library for implementing deep learning models.” A core library for building and training deep learning models.
    • Matplotlib: “mat plot lab is used for visualization.” Used for creating plots and visualizations of data.
    1. Machine Learning Fundamentals:
    • Classification: Described with an example of predicting rain: “learning model has to classify the output into two classes that is either yes or no yes will stand for it will rain tomorrow and no will basically denot that it will not rain tomorrow right this is a classification problem.”
    • Neural Networks:Dense Layers: “a dense layer is standard layer type that works for most cases right in a dense layer all the neurons in the layer will receive input from all the neurons in the previous layer.”
    • Activation Functions: “activation function it is nothing but in order to provide a threshold so if your output is above the threshold then only this neuron will fire otherwise it won’t fire.” Examples mentioned: step function, sigmoid function, ReLU (Rectified Linear Unit) function (“we want to remove all the negative values from our output that we got through the convolution layer”).
    • Model Training: Includes steps for defining a model, compiling it with an optimizer (Adam is mentioned: “The optimizer equal to Adam uses the Adam Optimizer an efficient and widely used algorithm for optimizing neural networks”), a loss function (e.g., “pass underscore categorical underscore cross entrophy cross entropy”), and metrics (e.g., “metrix equal to accuracy”). The fit function is used for training.
    • Evaluation: The evaluate function is used to evaluate the model’s performance on test data.
    • Convolutional Neural Networks (CNNs):Image Processing: Explains how computers interpret images using pixel values and color channels (RGB). Image size is represented as “B cross a cross 3” where B is rows, A is columns, and 3 is the color channels.
    • Feature Extraction: Discusses using filters to extract features from images: “we are going to put this particular feature on our image of X all right and we are going to multiply the corresponding pixel values.”
    • Max Pooling: A method for reducing the size of the image and retaining the most important information. “we are reducing the size of our image…we have taken a window size of 2 cross2 so when we keep this window at this particular position we see that one is the highest value so we going to keep one here.”
    • Object Detection: Mentions YOLO (You Only Look Once) and SSD (Single Shot Detector) as algorithms used for object detection in applications like self-driving cars and security systems.
    • Artificial Neurons (Perceptrons): Explanation of how a single artificial neuron, or perceptron, works, including inputs (X1, X2,…Xn), corresponding weights (W1, W2,…Wn), a weighted sum, and an activation function to determine if the neuron “fires.” The importance of assigning weights to different factors or inputs in a neuron and how a computer decides whether to increase or decrease a weight.
    • Back Propagation: Involves calculating the change in error with respect to variables like weight to adjust the weights and reduce the error. “we are trying to reduce the error so for that we need to figure out what will be the change in error if my variables are changed.” A graph of square error versus weight is used to determine the correct weight value.
    1. Natural Language Processing (NLP):
    • Applications: NLP is used by Netflix to “understand the type of movies that a person likes by the way a person has rated the movie or by the way the person has reviewed a movie so by understanding what type of review a person is giving to a movie Netflix will recommend more movies that you like.”
    • Tokenization: Breaking down sentences into individual words or tokens.
    • Stemming and Lemmatization: Techniques for reducing words to their root form.
    • Stemming: “stemming algorithm basically does that it works by cutting off the end or the beginning of the word and taking into account a list of common prefixes and suffixes that can be found in an inflicted word.” Limitations of stemming are mentioned, as it can sometimes result in inaccurate root words.
    • Lemmatization: “lemmatization on the other hand takes into consideration the morphological analysis of the words it does not randomly cut the word in the beginning and the ending it understands what the word means and only then it cuts the word.”
    • Stop Words: Commonly used words that are often removed from text for analysis.
    • Document Term Matrix (DTM): A matrix showing the frequency of words in a particular document.
    • Natural Language Generation: Includes having a brief plan about the text, sentence planning, and text realization.
    1. Recurrent Neural Networks (RNNs) and LSTMs:
    • Recurrent Neural Networks (RNNs): Explains the concept of recurrent neural networks, where the output at a given time step (t) depends on the input at that time and the information from the previous time step (t-1).
    • Long Short-Term Memory (LSTM) Networks: LSTMs address the limitations of traditional RNNs, such as vanishing and exploding gradients. The key to LSTM is the cell state, which is a horizontal line running through the top of the diagram. Discusses the forget gate layer, sigmoid layer, and tan layer. The four steps of LSTM are:
    • Deciding what information to throw away from the cell state.
    • Deciding what new information to store in the cell state.
    • Combining the information to update the cell state.
    • Getting the new output.
    • Use Case: LSTM is used to predict the next word in a sentence.
    1. Generative AI and Tools:
    • Generative Adversarial Networks (GANs): Discusses the generator and discriminator components of GANs. “from random noise the generator generates an image which is evaluated by the discriminator that whether it’s a real or a fake image after evaluating the discriminator will send a feedback to the generator.”
    • Google AI and Gemini: Describes how to set up a Conda environment and configure the Google AI API key using Python code, specifically working with the Gemini model. Code snippets are provided.
    • Text Prediction: Describes how language models predict text by calculating probabilities for each possible word based on their likelihood in context, stating that language models trained on massive amounts of text gain a wider vocabulary and more nuanced understanding of language patterns.
    • Image Generation with Parameters: Explores parameters in image generation:
    • Aspect Ratio: Modifying the height and width ratio of an image (e.g., “16 by9”).
    • Negative Prompting: Removing specific objects from an image (e.g., “clouds”).
    • Stylize: Controls the imagination of the image.
    • Chaos: A higher value of this parameter leads to unexpected and unique outcomes.
    1. AI-Assisted Coding and Development:
    • GitHub Copilot: Describes GitHub Copilot and its capabilities, including code completion, error fixing (“fix this option”), and answering questions about code.
    • ChatGPT: One of the best things about Chip is that it gives free access to AI content development.
    • Grammarly: A great tool for improving product description.
    1. Other AI Concepts:
    • Expert Systems: A computer system that mimics the decision-making ability of a human being.
    • Fuzzy Logic Systems: Unlike traditional systems that give binary outputs, fuzzy logic systems can provide outputs with degrees of truth or certainty.
    • Markov Decision Process: Discusses the components of a Markov decision process, including states, actions, rewards, policy, and value, and explains how an agent takes actions to transition between states while receiving rewards.
    • Relationship to Human Brain: Neural Networks are similar to the human brain as just like how our brain contains billions of neurons similarly artificial neural networks contain multiple perceptrons. Dendrites, which receive input signals in the brain, are analogous to the input layer in artificial neural networks.

    Quotes Demonstrating Practical Application:

    • Example of setting up a Conda environment: “cond create hyphen P virtual environment which is V EnV Python and equal equal to we are using 3.10 which is the python version and give hyphen y”
    • Example of installing TensorFlow: “pip install tensorflow”
    • Example of code to load the MNIST dataset using TensorFlow: “train underscore images comma train uncore labels and give comma and again inside the bracket let us type testore images comma testore labels and equal to TF dot caras dot data sets dot mist. loore data”
    • Example of defining a neural network model: “my model equal to TF dokas do models do sequential function”

    Overall Impression:

    The excerpts provide a valuable introduction to core AI, ML, and NLP concepts, offering a blend of theoretical explanations and practical examples, making it suitable for individuals learning or exploring these fields. The inclusion of code snippets and tool demonstrations enhances the material’s utility for hands-on learning.

    AI, ML, and NLP: Concepts Explained

    FAQ on Artificial Intelligence and Machine Learning Concepts

    Here’s an 8-question FAQ based on the provided source material, covering key concepts in AI, machine learning, and natural language processing.

    Question 1: What is NumPy and why is it important in machine learning?

    NumPy is a Python library primarily used for numerical computations. Its most important feature is its support for multi-dimensional arrays. It simplifies complex mathematical implementations and is commonly used for statistical and data analysis, especially when handling large datasets. In machine learning, it is critical for handling data inputs and performing operations on tensors.

    Question 2: How do classification models work, and what is a “target variable”?

    Classification models categorize output into distinct classes (e.g., yes/no, cat/dog). The model learns from input variables (features) to predict the “target variable,” which is the variable we are trying to predict. An example is predicting whether it will rain tomorrow (target variable: “rain tomorrow”) based on various weather conditions (features: temperature, humidity, wind speed, etc.).

    Question 3: Explain the process of building a neural network model, including layers and activation functions.

    Building a neural network model involves creating layers, each with weights corresponding to the following layer. Dense layers are standard layer types for most cases, where all neurons are connected to each other. Activation functions (e.g., step function, sigmoid function, ReLU) introduce thresholds; a neuron “fires” only if its output exceeds this threshold. Training involves comparing the model’s output with the desired output and adjusting weights through a process like backpropagation to minimize the error.

    Question 4: What is Natural Language Processing (NLP), and what are techniques like stemming and lemmatization used for?

    NLP is a field focused on enabling computers to understand and process human language. Stemming simplifies word analysis by removing prefixes and suffixes to find the root form (e.g., “detecting,” “detected” become “detect”). Lemmatization, on the other hand, takes the morphological analysis of words into account, grouping together inflected forms of a word (e.g., “gone,” “going,” “went” become “go”). Lemmatization produces a proper word, while stemming may not. Stop words are common words removed to focus on more significant terms.

    Question 5: What is a Document Term Matrix (DTM) and how is it used in NLP?

    A Document Term Matrix (DTM) is a matrix that shows the frequency of words in a particular document. It helps understand if specific words are present in documents by assigning a numerical value that corresponds to the frequency of each word in each document.

    Question 6: What are Convolutional Neural Networks (CNNs) and what are some of their applications?

    CNNs are a type of neural network commonly used for image recognition and processing. They use filters to detect specific features in an image and ReLU functions to remove negative values from the output. Pooling reduces the size of the image while preserving important information. CNNs have applications in self-driving cars (detecting pedestrians), security systems (facial recognition), medical imaging (detecting anomalies), and satellite imagery (monitoring deforestation).

    Question 7: Explain the concept of backpropagation and how it’s used to train neural networks.

    Backpropagation is a process used to train neural networks by calculating the gradient of the loss function with respect to the network’s weights and biases. It involves computing the error between the predicted output and the actual output, then adjusting the weights to minimize this error. The process iteratively adjusts the weights until the network’s performance improves and the error is minimized.

    Question 8: What are Recurrent Neural Networks (RNNs) and Long Short-Term Memory networks (LSTMs), and how do they address limitations of standard neural networks in processing sequential data?

    RNNs are designed for processing sequential data (e.g., text, time series). They have feedback loops that allow information to persist across time steps. LSTMs are a special type of RNN that addresses the vanishing gradient problem, which can occur in standard RNNs when dealing with long sequences. LSTMs have memory cells that can store information over extended periods, making them suitable for tasks like natural language processing where long-term dependencies are important.

    Artificial Intelligence: Foundations, Applications, and Ethics

    AI, or artificial intelligence, uses advanced computer programs to mimic human thinking, enabling learning from data, complex problem-solving, and decision-making. Ongoing research aims to improve AI abilities and ensure its responsible use.

    Key aspects of AI:

    • Definition: AI is a branch of computer science focused on creating systems that perform tasks normally requiring human intelligence.
    • Capabilities: These tasks include understanding natural language, recognizing patterns, making decisions, and learning from experience.
    • Methods: AI employs methods like machine learning, deep learning, and natural language processing.
    • Impact: It is revolutionizing fields like healthcare, finance, transportation, and entertainment.
    • Challenges: AI development brings challenges such as data biases, ethical issues, and transparency concerns.
    • Real-world applications:Cybersecurity: AI plays a vital role in cyber security by detecting threats.
    • Content recommendation: AI enhances personalized entertainment experiences on platforms like Netflix and Spotify.
    • Healthcare: AI is used for analyzing medical images and predicting health risks.
    • Marketing: AI improves marketing strategies and customer experiences.
    • Retail: AI personalizes shopping experiences and optimizes inventory management.
    • Automotive Industry: AI is integral to design, development, and operation of vehicles.

    AI is a broad field with different domains and branches, including machine learning, deep learning, natural language processing, robotics, expert systems, and fuzzy logic.

    • Machine learning is a subset of AI that enables computers to make data-driven decisions and improve over time when exposed to new data.
    • Deep learning and neural networks are also domains of AI.

    Stages and Types of AI AI is structured along three evolutionary stages:

    • Artificial Narrow Intelligence (ANI): Also known as weak AI, it focuses on specific tasks. Examples include Alexa and self-driving cars.
    • Artificial General Intelligence (AGI): Also known as strong AI, it involves machines possessing the ability to think and make decisions like human beings.
    • Artificial Super Intelligence (ASI): This is a hypothetical stage where computers’ capabilities surpass human intelligence.

    AI can also be categorized into four types based on functionality:

    • Reactive Machines AI: Operates based on present data without forming inferences.
    • Limited Memory AI: Can make decisions based on past data.
    • Theory of Mind AI: Focuses on emotional intelligence and understanding human thoughts, but is not yet fully developed.
    • Self-Aware AI: Machines possess their own consciousness, which is a currently far-fetched concept.

    History of AI The concept of AI dates back to classical ages with machines and mechanical men in Greek mythology.

    • 1950: Alan Turing proposed the Turing Test to determine if a computer can think intelligently like a human.
    • 1951: The era of game AI began with computer scientists developing programs for checkers and chess.
    • 1956: John McCarthy coined the term “artificial intelligence”.
    • 1959: The first AI laboratory was established at MIT.

    Generative AI Generative AI is a type of AI that can produce new content, such as text, images, and audio.

    • Applications: Generative AI has various applications across industries including text generation, language translation, business insights, music composition.
    • Prompt Engineering: Prompt engineering involves creating effective prompts or instructions to guide AI systems to produce the expected outcome.
    • It improves model performance, customization, and reliability.
    • Clear and tailored prompts help AI models produce accurate and relevant content.
    • Effective prompts should be clear, provide context, show examples, and be concise.
    • Large Language Models (LLMs): Models like Google’s Sparm and Meta’s Llama drive applications such as chatbots and language translation by learning from data to predict and generate text sequences.

    AI Ethics AI ethics refers to the principles and practices that ensure AI systems are developed and used ethically, without bias, and with transparency and accountability.

    • Core Principles: Fairness, reliability and safety, privacy and security, accountability, and transparency.
    • Implementation:
    • Define goals and expectations for the AI.
    • Collect necessary data and information.
    • Select appropriate tools to enhance AI capabilities.
    • Create fair and ethical models.
    • Train the system to make ethical decisions.
    • Evaluate the AI system to ensure fairness.
    • Deploy the AI solution ethically.

    AI in Business AI is transforming businesses by automating tasks, analyzing data, and predicting customer needs and market trends.

    • Benefits: Efficiency, cost savings, personalization, and better decision-making.
    • Use Cases:
    • Marketing and Sales: AI personalizes marketing campaigns, recommends products, and generates content.
    • Human Resources and Finance: AI streamlines recruitment, improves employee onboarding, detects fraud, and manages risk.

    AI in Web Development AI is also transforming web development by simplifying workflows and boosting efficiency.

    • AI Tools: Conversational AI (ChatGPT), AI-powered code suggestions (GitHub Copilot), AI website builders (Wix ADI), UI design tools (Galileo AI).
    • Advantages: Automated testing, improved SEO, better user experience, and faster development.

    AI in Manufacturing AI is transforming production processes in the manufacturing sector.

    • Key Segments: Predictive maintenance, quality control and inspection, and supply chain management.
    • Benefits: Energy efficiency, customization, and cost reduction.

    Machine Learning: Definitions, Process, Types, Problems, and Tools

    Machine learning (ML) is a subset of AI that enables computers to act and make data-driven decisions to carry out certain tasks. These programs or algorithms are designed to learn and improve over time when exposed to new data. The term “machine learning” was coined by Arthur Samuel in 1959.

    Key aspects of machine learning:

    • Definition: Machine learning provides machines with the ability to learn automatically and improve from experience without being explicitly programmed.
    • Data-driven Decisions: ML enables computers to act and make decisions based on data.
    • Algorithms: ML employs algorithms that learn and improve with exposure to new data.
    • Relationship to AI: Machine learning is a subset of AI, focusing on algorithms that allow machines to learn from data.
    • Solving Problems: The basic aim of machine learning is to solve problems or find solutions by using data.

    The Machine Learning Process The machine learning process involves building a predictive model to find a solution for a particular problem. A well-defined machine learning process has around seven steps:

    1. Defining the Objective: Understand what needs to be predicted.
    2. Data Gathering/Collection: Collect data relevant to the problem.
    3. Data Preparation: Prepare and preprocess the data.
    4. Data Exploration/Exploratory Data Analysis (EDA): Understand patterns and correlations in the data.
    5. Building a Machine Learning Model: Use insights from data exploration to build the model. Split the data set into training and testing data.
    6. Model Evaluation and Optimization: Test the model’s efficiency using the testing data set.
    7. Predictions: Use the model to make predictions.

    Types of Machine Learning There are three main approaches to machine learning:

    • Supervised Learning: Machines are trained using labeled data. Algorithms include linear regression, logistic regression, and support vector machines.
    • Unsupervised Learning: Machines are trained on unlabeled data without guidance. K-means clustering is a common algorithm.
    • Reinforcement Learning: An agent interacts with an environment to learn through trial and error, producing actions and receiving rewards. Q-learning is a key algorithm.

    Types of Problems Solved by Machine Learning:

    • Regression: The output is a continuous quantity (e.g., predicting the speed of a car).
    • Classification: The output is a categorical variable (e.g., predicting rain occurrence).
    • Clustering: Used in unsupervised learning to solve clustering problems.

    Limitations of Machine Learning

    • High Dimensional Data: ML algorithms struggle with high-dimensional data.
    • Feature Extraction: ML requires manual feature extraction, which can be tedious.

    Machine Learning Tools in Python

    • TensorFlow: An open-source library developed by Google, used in machine learning applications. It helps visualize each part of a graph.
    • Scikit-learn: A Python library associated with NumPy and SciPy, is useful for complex data analysis and feature extraction. It is used for implementing standard machine learning and data mining tasks like reducing dimensionality, classification, regression, clustering, and model selection.
    • NumPy: Popular for machine learning tasks in Python.
    • Keras: Runs smoothly on both CPU and GPU and supports neural network models, is completely Python-based.
    • Natural Language Toolkit (NLTK): An open-source Python library mainly used for natural language processing, text analysis, and text mining.

    Deep Learning: Definition, Functionality, Applications, and Tools

    Deep learning is a particular kind of machine learning that is inspired by the functionality of brain cells called neurons, which led to the concept of artificial neural networks. It is based on the concept of neural networks. Deep learning models are capable of learning to focus on the right features by themselves requiring minimal human intervention, meaning that feature extraction will be performed by the deep learning model itself.

    Key aspects of deep learning:

    • Definition: Deep learning is a collection of statistical machine learning techniques used to learn feature hierarchies based on the concept of artificial neural networks.
    • Neural Networks: Deep learning is based on neural networks with multiple layers.
    • Feature extraction: Deep learning models are capable of learning to focus on the right features by themselves requiring minimal human intervention.
    • Relationship to AI and ML: AI is a broader umbrella under which machine learning and deep learning come. Deep learning is a subset of machine learning and the next evolution of machine learning.
    • Functionality: Deep learning mimics the basic component of the human brain called the brain cell, also known as a neuron. Inspired by a neuron, an artificial neuron was developed.

    How Deep Learning Works Deep learning is implemented with the help of neural networks, and the motivation behind neural networks are neurons, which are brain cells. A deep neural network will have three layers:

    • Input layer: Receives all the inputs.
    • Hidden layers: Layers between the input and output layers.
    • Output Layer: Provides the desired output.

    The number of hidden layers in a deep learning network will depend on the type of problem and the available data.

    Advantages of deep learning:

    • Feature extraction: Deep learning models are capable of learning to focus on the right features by themselves requiring minimal human intervention. The model itself will learn which features are most significant in predicting the output.
    • High dimensional data: Deep learning is mainly used to deal with high dimensional data and is often used in object detection and image processing.

    Applications of Deep Learning

    • Fraud detection: Deep learning is used to identify any possible fraudulent activities.
    • Face verification: Facebook makes use of deep learning technology for face verification.
    • Self-driving cars: Deep learning is used in self-driving cars.
    • Object detection: Deep learning is used for object detection systems, enabling safe navigation and supports decision making models.
    • Image Creation: Deep learning advances image creation, text generation, and audio synthesis within the field of generative AI.
    • Medical field: Deep learning has applications for disease diagnosis by analyzing medical images and patient data.

    Deep Learning Tools

    • TensorFlow: A popular open source framework developed by Google for building and training machine learning models.
    • Keras: The simplest package to implement neural networks. Keras runs smoothly on both CPU and GPU, supports neural network models, and is Python-based, making it easy to debug.
    • PyTorch: Is more research-focused, favored for its dynamic computational graphs and ease of experimentations.
    • Theano: Designed to handle computations required for large neural network algorithms.

    Limitations of Machine Learning That Deep Learning Addresses

    • High dimensionality of data: Deep learning models can generate the features on which the outcome will depend on.
    • Manual feature extraction: Deep learning models are capable of learning to focus on the right features by themselves requiring little guidance from the programmer.

    Python for AI, ML, and Data Science

    Python is a popular programming language often used in the fields of AI, machine learning, and data science. It is considered the most popular and most used language for data science, AI, machine learning, and deep learning.

    Key aspects of Python:

    • Readability and Simplicity: Python’s syntax is similar to the English language, making it easy to learn and understand. Its simple syntax can be used to solve both simple and complex problems.
    • Less Coding: Python requires less coding compared to other languages. Python uses something known as “check as you code” methodology, which eases the process of testing.
    • Pre-built Libraries: Python has pre-defined libraries for machine learning and deep learning algorithms, making it convenient for AI developers because the algorithms are already prebuilt in libraries. Instead of coding each algorithm, you can call the function and load the library.
    • Platform Independence: Python allows projects to run on different operating systems, with packages like Pi installer addressing dependency issues when transferring code between platforms.
    • Massive Community Support: Python has many online communities, forums, and Facebook groups that can help with errors or problems in the code.

    Python Packages for AI, ML, and NLP:

    • TensorFlow: An open-source library developed by Google, commonly used for machine learning projects. It allows easy visualization of each part of the graph.
    • Scikit-learn: A Python library associated with NumPy and SciPy, useful for complex data analysis and feature extraction. It is used for implementing standard machine learning and data mining tasks like reducing dimensionality, classification, regression, clustering, and model selection.
    • NumPy: A popular library for machine learning in Python, used internally by TensorFlow and other libraries for performing multiple operations on tensors. Its array interface supports multi-dimensional arrays. NumPy makes complex mathematical implementations simple and is known for computing mathematical data.
    • Theano: A computational framework used for computing multi-dimensional arrays that works similarly to TensorFlow. It was designed to handle the types of computations required for large neural network algorithms and is considered an industry standard for deep learning research and development.
    • Keras: A popular Python package with functionalities for compiling models, processing data sets, and visualizing graphs. It is simple to implement neural networks with Keras, which runs smoothly on both CPU and GPU.
    • Natural Language Toolkit (NLTK): An open-source Python library mainly used for natural language processing, text analysis, and text mining.

    To set up Python for AI development:

    1. Install Python: Download the latest version of Python from the official website and follow the installation instructions. Make sure to add Python to the system path during installation.
    2. Install PyCharm: Download and install PyCharm, an IDE (Integrated Development Environment), from JetBrains. Choose the Community Edition, which is open source.
    3. Configure PyCharm: During the PyCharm setup, create a desktop shortcut, update the content menu, and update the path version.
    4. Connect Python with PyCharm: Open PyCharm and create a new project. Set the environment to a virtual environment and select the Python version.
    5. Write your first Python program: Right-click on the new project, select “New,” and choose “Python File”. Give the file a name (e.g., “demo.py”) and press Enter. Then, type print(“Hello, World!”) and run the code.

    TensorFlow: An Overview of Google’s Machine Learning Framework

    TensorFlow is a powerful open-source machine learning framework developed by Google and is a toolkit for creating artificial intelligence systems. TensorFlow is a versatile platform that empowers developers to seamlessly transform AI and ML ideas into scalable solutions.

    Key aspects of TensorFlow:

    • Versatility and Flexibility: TensorFlow enables developers to build a wide range of models with customizable implementations. It offers APIs ranging from high-level Keras for simplicity to low-level APIs for advanced customization, catering to diverse developer needs.
    • Scalability: TensorFlow’s scalability allows it to handle massive datasets and complex models efficiently, making it ideal for large-scale AI systems in applications like image recognition and natural language processing.
    • Ecosystem: TensorFlow has a large and established ecosystem with an active community, extensive documentation, and a proven track record. Its rich ecosystem includes pre-trained models and numerous resources that simplify its adaptation and usage.
    • Cross-platform support: TensorFlow enables seamless deployment across different operating systems and hardware platforms.
    • Optimized Performance: TensorFlow runs efficiently on CPUs, GPUs, and TPUs, ensuring faster training and inferences times.
    • Tensors and Computational Graphs: TensorFlow utilizes tensors (multi-dimensional arrays) and computational graphs to perform operations, making it adaptable and scalable for various machine learning tasks.
    • Visualization and Debugging Tools: TensorFlow features visualizations and debugging tools that enhance model understanding and troubleshooting.

    Key Capabilities of TensorFlow:

    • Open Source and Community-Driven: TensorFlow is an open-source community-driven framework that evolves through contributions.
    • Tensors: TensorFlow utilizes tensors, multi-dimensional arrays, for efficient data representation and manipulation.
    • Flexible Architecture: Its flexible architecture allows developers to choose between static graphs for optimized performance and eager execution for an interactive development experience.
    • Versatility: TensorFlow supports a wide range of applications including natural language processing, generative AI, computer vision, and more.
    • Cross-Platform Compatibility: It offers cross-platform compatibility, running efficiently on CPUs, GPUs, and TPUs, enabling developers to leverage the best hardware for their needs.

    Real-World Applications of TensorFlow:

    • Computer Vision: TensorFlow is used for identifying objects in images with algorithms like YOLO and SSD, enabling tasks such as detecting pedestrians and obstacles in self-driving cars or identifying suspicious objects in security systems. It aids in analyzing X-rays or MRIs to detect anomalies and assist in monitoring deforestations, identifying land use patterns, and predicting natural disasters. Additionally, TensorFlow powers security systems and user authentication, enabling facial recognition for tasks like facial deduction and identifications.
    • Natural Language Processing: TensorFlow is instrumental in tasks like spam detection and sentiment analysis, where it helps identify spam emails and determine the emotional tone of text, such as customer reviews or social media posts. It provides services like Google Translate, enabling accurate translations between numerous languages and facilitating global communications.
    • Generative AI: TensorFlow powers GANs and similar models, enabling the creation of realistic images, art, and even the manipulation of existing visuals. It facilitates the creation of deep fake audio and speech generation, producing synthetic media where a person’s likeness or voice can be convincingly replicated.
    • Healthcare: TensorFlow is used for predicting analytics to forecast disease outbreaks, identify high-risk patients, and optimize treatment plans, as well as for medical image analysis to detect anomalies in X-rays, MRIs, and CT scans.
    • Autonomous Vehicles: TensorFlow powers object detection systems, enabling safe navigation and supports decision-making models.
    • Finance: TensorFlow is utilized for algorithmic trading, analyzing market trends, and detecting fraudulent transactions.
    • Retail: Retail applications include inventory management to predict demand and reduce stockouts along with personalized recommendations to enhance customer experience and boost sales.
    • Entertainment: TensorFlow facilitates content creation, such as generating music or art, and it is used in video and audio processing tasks like noise reduction and voice stabilization.

    Comparison with Other Frameworks: TensorFlow is known for its flexibility and versatility, enabling developers to build a wide range of models with customizable implementations, while PyTorch is recognized as intuitive and Pythonic, offering a user-friendly approach. TensorFlow excels with robust tools for deploying models in real-world environments, whereas PyTorch is more research-focused, favored for its dynamic computational graphs and ease of experimentation.

    Installing TensorFlow: To get started with TensorFlow, you first need to install the necessary prerequisites, including Python 3.5 or a higher version. You can use a package manager like pip. To install TensorFlow, you can run pip install tensorflow. To ensure that TensorFlow has been installed successfully, you can verify the installation by running the following command: python -c “import tensorflow as tf; print(tf.__version__)”. This will display the installed version of TensorFlow, confirming that the installation was successful.

    TensorFlow Ecosystem: The TensorFlow ecosystem provides a comprehensive set of tools for building, training, and deploying machine learning models. At its core is TensorFlow, the foundation of the ecosystem. TensorFlow Lite enables running models on mobile and embedded devices, while TensorFlow Extended supports building production-grade ML pipelines, including data validation and model serving. The TensorFlow Model Garden offers pre-trained models and examples for tasks like image classification and NLP. TensorFlow.js allows running ML models in web browsers, and TensorFlow Hub provides a library of pre-trained models for easy integration into projects.

    Building a Churn Prediction Model Using TensorFlow: There are three main steps in building a churn prediction model using TensorFlow:

    • Model Creation: Create a model by defining its architecture, including layers and parameters tailored to the specific problem of prediction customer churn.
    • Model Training: Train the model using historical data, where it learns patterns and relationships that help predict customer behavior.
    • Prediction: Use the trained model to make predictions, identifying customers likely to churn based on input data.
    Artificial Intelligence Full Course – 10 Hours | Artificial Intelligence Tutorial 2025 | Edureka

    By Amjad Izhar
    Contact: amjad.izhar@gmail.com
    https://amjadizhar.blog

  • Hard Times By Charles Dickens

    Hard Times By Charles Dickens

    Mr. Gradgrind’s rigidly fact-based educational methods fail his children, Louisa and Thomas, who secretly attend a theatrical performance. This leads to a family crisis and exploration of their stifled emotions. Mr. Bounderby, Gradgrind’s self-made friend, embodies the town’s materialistic values. A bank robbery further complicates matters, with suspicion falling on Tom, who flees with the help of James Harthouse, a charming but morally bankrupt gentleman who also becomes involved with Louisa. The novel explores themes of social class, emotional repression, and the destructive nature of unchecked ambition.

    Hard Times Study Guide

    Quiz

    1. Describe the initial encounter between Sissy Jupe (girl number 20) and Mr. Gradgrind’s educational methods. Sissy Jupe struggles to define a horse based on Mr. Gradgrind’s facts and is scolded for using her imagination when she says she would like a carpet with pictures of flowers on it because she loves flowers. Mr. Gradgrind wants children to accept facts only and not “fancy.”
    2. How does the narrator characterize Mr. M’Choakumchild and his teaching style? Mr. M’Choakumchild is depicted as a product of a rigid, fact-based system, a “factory” for turning out teachers. He is extremely knowledgeable in many academic areas, but lacks practical wisdom and understanding of how to teach effectively. He teaches by rote memorization.
    3. Explain Mr. Gradgrind’s educational philosophy and how it is implemented in his own household. Mr. Gradgrind believes in education based solely on facts, dismissing imagination and emotions. His children are raised like models, trained from a young age with lectures and devoid of traditional childhood experiences, like stories and moon-gazing.
    4. What does the “horse-riding establishment” represent in opposition to Mr. Gradgrind’s world? The horse-riding establishment represents entertainment, imagination, and freedom of expression which are all things that Mr. Gradgrind and his education oppose. The show emphasizes spectacle and artistry as opposed to facts and logic.
    5. What is the significance of the “keynote” of Coketown? Coketown is described as a place dominated by industry and devoid of beauty or nature, reflecting the destructive influence of an entirely fact-based society. It is a town of red brick, smoke, machinery, and dirty canals which represents the results of Mr. Gradgrind’s values on society.
    6. Describe Mr. Bounderby’s character and his relationship with the Gradgrind family. Mr. Bounderby is a boastful, self-made man who values practicality and dismisses sentimentality. He is highly interested in the Gradgrind family, particularly Louisa, but often displays arrogance and insensitivity in his interactions with them.
    7. What causes Mr. Gradgrind concern about his children’s education, and what is Mr. Bounderby’s perspective? Mr. Gradgrind is worried that some “idle imagination” has “crept” into his children’s minds, showing a weakness of his educational system. Mr. Bounderby dismisses the concern, calling any curiosity about outsiders “vulgar” and wanting “idle” children to be punished.
    8. What happens to Sissy Jupe and why? Sissy is eventually taken in by the Gradgrinds because Mr. Bounderby is upset that she was admitted to the school and Mr. Gradgrind sees it as a way to remove her “fancy” from the school and expose it to the “facts.” Also, Sissy’s father has run off and she has no one else to take care of her.
    9. Explain the symbolism of the “statistical clock” in Mr. Gradgrind’s study. The “statistical clock” symbolizes the cold, calculating nature of Mr. Gradgrind’s approach to life and education. The beat “like a rap upon a coffin lid” shows how deathly this approach is for imagination and emotion.
    10. Why does Louisa agree to marry Mr. Bounderby, and how does she feel about it? Louisa agrees to marry Mr. Bounderby as a dutiful act, as her father had “proposed” and it was “not important to her.” She accepts it with little emotion, but this is because she sees it as a strategic act to help her brother Tom and herself get out of their father’s control.

    Essay Questions

    1. Analyze the role of imagination versus fact in the novel, using specific examples from the text. How does the author portray the consequences of prioritizing one over the other?
    2. Compare and contrast the characters of Mr. Gradgrind and Mr. Bounderby. How do their individual philosophies contribute to the overall themes of the novel?
    3. Discuss the significance of Coketown as a setting in Hard Times. How does the author use the town to symbolize the industrial and social issues of the time?
    4. Explore the development of Louisa Gradgrind’s character throughout the novel. How does she evolve in her understanding of emotions and human connection?
    5. Examine the author’s use of satire in Hard Times. What aspects of Victorian society are being critiqued, and how is this critique delivered?

    Glossary of Key Terms

    Quadruped: An animal that has four feet.

    Graminivorous: An animal that eats primarily grasses.

    Incisive: Sharp teeth used for cutting.

    Bolus: A soft mass of chewed food that is swallowed; or something that is forced upon someone.

    Fistic Phraseology: Language related to boxing, which Mr. Gradgrind’s third gentleman is described in.

    Millennium: A period of 1000 years; in this case, used satirically to represent a supposed perfect future in Mr. Gradgrind’s model society.

    Conchological: Relating to the study of shells, showing how Mr. Gradgrind’s kids have cabinets with samples in them.

    Metallurgical: Relating to the study of metals, showing how Mr. Gradgrind’s kids have cabinets with samples in them.

    Mineralogical: Relating to the study of minerals, showing how Mr. Gradgrind’s kids have cabinets with samples in them.

    Ruminating: An animal that digests food in two steps, first by chewing, then by regurgitating.

    Riffraff: Disreputable or worthless people.

    Tag, Rag, and Bobtail: A group of low or common people.

    Nuptial: Relating to marriage or a wedding.

    Aphorism: A concise statement of a scientific principle.

    Simoom: A hot, dry, suffocating wind.

    Propose: To present for consideration or acceptance; often used in marriage proposals.

    Humbug: Deceptive or false talk or behavior.

    Hard Times: An Analysis

    Okay, here is a detailed briefing document analyzing the provided excerpts from “01.pdf”:

    Briefing Document: Analysis of “01.pdf” Excerpts

    Overall Theme: The provided excerpts present a critical examination of a rigid, fact-based educational philosophy and its detrimental impact on individuals, particularly children, in the industrial town of Coketown. The document contrasts this system, embodied by Thomas Gradgrind and his associates, with the natural human need for imagination, emotion, and compassion, symbolized by characters like Sissy Jupe and other “strollers.” It also explores the consequences of this philosophy on interpersonal relationships, social structures, and the overall human condition.

    Key Themes and Ideas:

    1. The Tyranny of “Fact”: The dominant idea is the oppressive nature of a purely factual, utilitarian approach to education and life. Mr. Gradgrind and his followers believe in quantifiable knowledge and demonstrable truth, dismissing imagination, fancy, and emotion as frivolous and dangerous. This is evident in:
    • The examination of children where they are pressured to deny their natural inclination to use imagination, such as wanting to paper a room with horses or use flowered carpets: “of course no said the gentleman with an indignant look at the wrong half why then you are not to see anywhere what you don’t see in fact you are not to have anywhere what you don’t have in fact what is called taste is only another name for fact”
    • The emphasis on mathematical figures and primary colors for all art and decoration, devoid of any personal expression: “you must use said the gentleman for all these purposes combinations and modifications in primary colors of mathematical figures which are susceptible of proof and demonstration”
    • The training of schoolmasters as if they are manufactured products: “he and some 140 other school Masters had been lately turned at the same time in the same Factory on the same principles like so many piano for legs.”
    1. Suppression of Imagination and Emotion: The education system actively suppresses creativity, imagination, and emotional expression, particularly through Mr. Gradgrind’s treatment of his own children and Cecilia Jupe.
    • Gradgrind’s children are forced to focus on facts, “no little grad grind had ever seen a face in the Moon it was up in the moon before it could speak distinctly no little grad grind had ever learned the silly jingle Twinkle twinkle little star how I wonder what you are”
    • Sissy Jupe, who represents a more natural, imaginative worldview, is constantly criticized and corrected for her emotional responses and “fancy.” “but you mustn’t fancy cried the gentleman quite elated by coming so happily to his point that’s it you are never to fancy”
    • This suppression is extended to other forms of artistic expression like drawing, the students are not to “paint foreign birds and butterflies upon your crockery.”
    1. The Dehumanizing Effects of Industrialization: Coketown is presented as a bleak, oppressive place, a direct consequence of the industrial mindset. The focus is on production, efficiency, and material wealth, at the expense of human well-being and beauty.
    • Coketown is described as a “Triumph of fact,” a place of “unnatural red and black,” filled with “interminable serpents of smoke” and a “river that ran purple with ill-smelling dye.”
    • The Millers in the town are shown as fragile, and only interested in their own wealth, constantly using the threat of “pitching their property into the Atlantic” to get their way.
    • The descriptions of the factories and the conditions of the workers are negative. “the steam engines Shone with it the dresses of the hands were soiled with it the Mills throughout their many stories oozed and trickled it the atmosphere of those fairy palaces was like the breath of the simum and their inhabitants wasting with heat toiled languidly in the desert but no”
    1. Class Divisions and Social Injustice: The excerpts highlight the stark class divisions and the exploitation of the working class.
    • Mr. Bounderby, a self-made man, is presented as a cruel and hypocritical capitalist who exploits the working class while claiming to be one of them. He often refers to his past as “a ragged Street boy who never washed his face unless it was at a pump.” He has “no reason in looking with interest at a parcel of vagabonds returned bounderby when when I was a vagabond myself nobody looked with any interest at me.”
    • The working class is depicted as suffering from poor living conditions, dangerous working environments, and a lack of opportunities.
    • The idea that anyone can pull themselves up by their bootstraps is also present and criticized “what one person can do another can do this again was among the fictions of kok town any capitalist there who had made £60,000 out of6 P always professed to wonder why the 60,000 nearest hands didn’t each make £60,000 out of six p.”
    • Characters like Bitzer, who completely embraces Gradgrind’s philosophy, actively betray and exploit others for personal gain.
    1. The Flawed Nature of the Fact-Based System: The text begins to demonstrate how this system is beginning to show its weakness. Mr. Gradgrind shows doubts “I confess however that the misgiving has crossed me on my way home in idle imagination” and Louisa and Thomas begin to show signs of imagination and curiosity: “as if something had crept into Thomas’s and Louisa’s Minds which is or rather which is not I don’t know that I can express myself better than by saying which has never been intended to be developed and in which their reason has no part there certainly is no reason in looking with interest at a parcel of vagabonds”
    2. The Potential for Redemption: Despite the bleakness, there are hints of hope and the possibility of change.
    • Cecilia Jupe, despite being seen as wrong by the new system, is still kind and her love and acceptance is presented as a positive.
    • Characters like Louisa, even within the strictures of her upbringing, begin to show signs of individuality and discontent, suggesting they may break free from their intellectual prison
    • There is even the promise of change in some of the main characters with a possible turn away from “fact” and the beginning of a possible acceptance of human feelings.

    Character Analysis:

    • Thomas Gradgrind: The embodiment of the fact-based philosophy. He is a rigid, unemotional man who sees human beings as data points. While he sees himself as eminently practical “he had a particular pride in the phrase eminently practical which was considered to have a special application to him”, he is ultimately shown to be flawed.
    • Josiah Bounderby: A self-made industrialist who embodies the excesses of the industrial system. He is boastful, cruel, and hypocritical.
    • Sissy Jupe: A symbol of natural human feelings, compassion, and imagination. She is the antithesis of Gradgrind’s principles.
    • Louisa Gradgrind: A daughter of Mr. Gradgrind, who is taught to value reason, logic and fact over emotion and imagination but she begins to show signs of imagination and unhappiness. She is cold and reserved but struggles with the emotional suppression inherent in her upbringing.
    • Thomas Gradgrind Jr. (The Welp): A son of Mr. Gradgrind, also raised on facts, but is rebellious, unmotivated, and ultimately dishonest.
    • Bitzer: A product of the fact-based system who embodies cold, calculating self-interest.
    • James Hartouse: A man from the upper classes who is bored and takes advantage of women, he is the opposite of Mr. Bounderby in mannerisms and class, but just as terrible a person.
    • Mrs. Sparsit: An older woman and associate of Mr. Bounderby, she is class conscious, judgemental and manipulative.

    Quotes Illustrating Key Ideas:

    • On Fact vs. Fancy: “you are never to fancy you are not Cecilia jup Thomas grad grind solemnly repeated to do anything of that kind fact fact fact said the gentleman and fact fact fact repeated Thomas grad grind.”
    • On the Dehumanizing Nature of Education: “no little grad grind had ever learned the silly jingle Twinkle twinkle little star how I wonder what you are no little grad grind had ever known Wonder on the subject”
    • On the Industrial Setting: “it was a town of red brick or of brick that would have been red if the Smoke and Ashes had allowed it but as matters stood it was a town of unnatural red and black like the painted face of a Savage”
    • On Bitzer and Utilitarianism: “I have gone over the calculations in my mind and I find that to compound a felony even on very high terms indeed would not be as safe and good for me as my improved prospects in the bank”
    • On the Nature of the Working Class: “they are the finest people in the world these fellows are they have got the gift of the gab they have they only want to have their rights explained to them they do”

    Significance of the Excerpts:

    These excerpts provide a glimpse into a society where rationality and fact are prioritized over humanity and emotion. They raise questions about the nature of education, the impact of industrialization, and the consequences of suppressing imagination and individual expression. The conflict between these opposing worldviews is a central element of the story and sets the stage for the personal and social crises that will unfold throughout the narrative. It is a cautionary tale of the dangers of extremism in thought and society.

    Hard Times: Fact vs. Fancy

    FAQ: Key Themes and Ideas from the Provided Text

    • What is the core philosophy of Mr. Gradgrind’s educational approach, and how is it implemented in his school?
    • Mr. Gradgrind’s core philosophy is rooted in “fact” and reason, devoid of “fancy” or imagination. This approach is implemented through a rigid curriculum focused on demonstrable knowledge, mathematical figures, and the observable world. Students are discouraged from engaging with imaginative literature or art, even to the point of disallowing the representation of flowers on carpets or horses on wallpaper. The goal is to produce individuals who are strictly logical and practical, without any room for emotional or creative thought. Mr. M’Choakumchild and his fellow teachers were essentially factory-produced with the same rigid principle to ensure they will follow the system.
    • How does the text contrast the world of “fact” with the world of “fancy,” and what are the implications of this contrast?
    • The text sharply contrasts the world of “fact,” represented by Mr. Gradgrind and his school, with the world of “fancy,” embodied by the circus performers like Sissy Jupe and her family. Fact is associated with practicality, reason, and the denial of imagination and emotion. Fancy is linked with creativity, imagination, and the emotional richness of life. The text suggests that a world solely governed by fact is a bleak and sterile place, devoid of human warmth and joy. The implications are that neglecting imagination and emotion in favor of pure reason leads to a limited, unhappy existence. Even Mr. Gradgrind, who is so convinced of fact, is surprised that his own children have a tendency towards fancy.
    • What role does Mr. Bounderby play in the story, and what does his character represent?
    • Mr. Bounderby is a self-made, boastful industrialist who is a staunch proponent of the “fact” philosophy. He presents himself as a rough and honest man who has risen from poverty through hard work. However, his character is ultimately a caricature of the overly pragmatic and unfeeling nature of industrial society. He represents the dehumanizing aspects of unchecked capitalism and the tendency to reduce human worth to mere economic productivity. His treatment of those around him and his insensitivity demonstrate a profound lack of compassion.
    • How are children depicted in the text, and what does this say about the educational system in the story?
    • Children are depicted as either overly-repressed automatons, like the young Gradgrinds, who have been trained to analyze every aspect of their surroundings and dismiss anything remotely fantastical, or as having a natural capacity for wonder and imagination, like Sissy Jupe. The educational system, as presented, is shown to be detrimental to the children, stifling their creativity and emotional development, ultimately shaping them into individuals who are devoid of independent thought and empathy, making them more like machines than living beings. The children who are trained with facts are unhappy, and when their curiosity gets the better of them, their parents are shocked.
    • What is the significance of Koketown as a setting, and what does it represent about industrial society?
    • Koketown is depicted as a bleak and oppressive industrial town dominated by factories, smoke, and pollution. It symbolizes the dehumanizing effects of industrialization, where individuals are reduced to mere cogs in a machine. The town’s focus on production and economic gain at the expense of human well-being represents the negative aspects of a society driven solely by industrial progress and material accumulation, while ignoring the human cost. Koketown is a triumph of fact.
    • How does the story explore the themes of social class and power dynamics?
    • The story explores social class and power dynamics through the contrasting lives of the wealthy industrialists like Bounderby and the working-class “hands” of Koketown. The industrialists hold all the power, exploiting the labor of the working class while simultaneously judging them for their poverty and so-called “improvidence”. The system is portrayed as one where the wealthy stay wealthy, and anyone who doesn’t adhere to the way things are is “lazy” or “improvident”. The power dynamic is further solidified by those like Bitzer who willingly exploit those of his own class in order to rise through the social system, thereby making the system and power structure that much more robust and stable.
    • What role do women play in the narrative, and how are their experiences shaped by the societal values and gender roles?
    • Women in the narrative occupy different roles that are shaped by societal values and gender roles of the time. Louisa Gradgrind is initially presented as a product of her father’s system of fact, resulting in her emotional detachment and submission to an unhappy marriage. Mrs. Gradgrind’s character is an example of a woman who is completely passive and sickly with her only purpose in life to agree with her husband. Mrs. Sparsit, while more active, still remains subservient to Mr. Bounderby, even as she criticizes his and Louisa’s actions. They are all affected and limited by the rigid gender roles in society.
    • How does the story ultimately suggest the need for a balance between “fact” and “fancy,” reason and emotion?
    • Through the struggles and unhappiness of characters like Louisa Gradgrind and the stifled environment of Koketown, the story suggests the necessity for a balance between reason and emotion, fact and imagination. The characters who have embraced only one extreme become unhappy and maladjusted. The narrative suggests that a truly fulfilling life requires a blending of both worlds—the ability to engage with reason, logic, and tangible reality, as well as the ability to feel, imagine, and express emotion. The narrative shows the detrimental effects of too much fact and makes a case for the importance of a healthy balance.

    Family Disgrace in Hard Times

    Family disgrace is a significant theme in the sources, manifesting in various forms and impacting different characters. Here’s a breakdown of instances of family disgrace:

    • Josiah Bounderby’s fabricated past: Bounderby repeatedly claims to have been “born in a ditch” and abandoned by his mother, whom he calls “probably the very worst woman that ever lived in the world”. He uses this narrative to emphasize his self-made status and to look down upon others, contrasting it with the supposed luxury of people like Mrs. Sparsit. However, later in the text, his mother, Mrs. Pegler, appears and reveals that his story is a complete fabrication. She explains that he came from humble but loving parents who pinched to provide him with an education. This revelation exposes Bounderby as a liar and a humbug, disgrac
    • ing him in the eyes of those who had believed his story and demonstrating the shallowness of his character.
    • Stephen Blackpool’s wrongful accusation: Stephen Blackpool is ostracized by his fellow workers and labeled a “hand…sent to Coventry” after refusing to join a union. He is then accused of robbery based on circumstantial evidence. This wrongful accusation brings disgrace upon him and his community. This is further complicated by his attempts to remain faithful to his word not to join the union while still being faithful to his fellow workers. Although he eventually receives help from Louisa, he feels compelled to leave town to seek a new life.
    • Tom Gradgrind’s crimes: Tom Gradgrind, the son of Mr. Gradgrind, is revealed to be the actual thief in the bank robbery. He admits to forcing the safe, taking money over time, and dropping the key to make it look like an outside job. This act of dishonesty brings shame upon his family, especially his father, who prided himself on his rational and moral way of life. The disgrace is compounded by the fact that Tom has long taken advantage of his family, especially his sister, as they helped him financially. His behavior culminates in the performance where he is seen dressed in a clown suit, which symbolizes the absurdity of his actions and further shames his family.
    • Mrs. Sparsit’s fall from grace: While not directly a disgrace on her family, Mrs. Sparsit, who is a “PO,” or person of ancient stock, faces a fall from her high social position due to the nature of her employment with Bounderby. She is a “highly connected lady” but is reduced to a position of subservience. Her “social widowhood” due to her late husband, combined with her position as a servant creates a form of disgrace for her and her family. Additionally, her constant observation and judgment of Louisa’s actions, which she envisions as a steady descent down a “mighty staircase” towards ruin, are eventually exposed as biased. She ultimately is ejected from Bounderby’s home, which highlights her powerlessness.
    • Louisa Gradgrind’s unhappy marriage: While not a disgrace in the traditional sense, Louisa’s marriage to Bounderby is depicted as a source of unhappiness and emotional turmoil. She marries him not out of love but out of a sense of duty and, perhaps, partially due to her brother’s desire for money. Her inability to connect with Bounderby, combined with her emotional repression, suggest a kind of internal family disgrace – a failure of human connection and happiness within the family unit. This is also coupled with the failure of her education to prepare her for actual human experiences.

    These instances of family disgrace highlight the complexities of relationships, the devastating effects of lies and social status, and the failures of rigid systems of morality and education. The characters face different types of disgrace, but each highlights the vulnerability of individuals within their social and familial contexts.

    Idle Imagination in Hard Times

    Idle imagination is portrayed as a dangerous and detrimental force in the sources, particularly by Mr. Gradgrind and Mr. Bounderby, who see it as a direct threat to their rigid systems of fact and reason. Here’s a breakdown of how idle imagination is presented:

    • A threat to reason: Mr. Gradgrind believes that “the reason is…the only faculty to which education should be addressed”. He sees imagination as something that “has never been intended to be developed” and has “no part” in reason. He views any interest in things outside of practical facts as a sign that “something has crept into Thomas’s and Louisa’s minds”. This suggests that imagination is viewed as an unwanted intruder that can corrupt the purity of a mind trained on logic and fact.
    • The source of “vulgar curiosity”: When Mr. Gradgrind discovers that his children, Louisa and Thomas, have shown an interest in Sissy Jupe, a “stroller’s child,” he attributes this to “idle imagination”. He and Bounderby consider this curiosity “vulgar” and incomprehensible because it lacks any basis in reason or practicality. This establishes that imagination, in their view, leads to inappropriate and unproductive interests.
    • A “very bad thing” for Louisa: Mr. Bounderby considers idle imagination to be “a cursed bad thing for a girl like Louisa”. This reveals a gendered aspect of their views; imagination is seen as particularly dangerous for women, perhaps because it is seen as leading them away from practical concerns and domestic duties.
    • Link to “Idol story books”: Mr. Gradgrind wonders if “any Idol story book can have got into the house,” suggesting that imaginative stories are a source of corruption. He believes that “minds that have been practically formed by rule and line from the cradle upwards” are susceptible to the influence of such “story books.” This suggests that those who are indoctrinated with facts and reason from childhood can be negatively impacted if exposed to imagination and fantasy.
    • Readers in Koketown: Despite Mr. Gradgrind’s efforts to control what people read, the residents of Koketown continue to “persist in wondering”. They seek out and are comforted by “mere fables about men and women more or less like themselves and about children more or less like their own,” finding solace in stories rather than in “tabular statements”. This demonstrates the futility of trying to suppress the human need for imagination and stories, suggesting it is an innate human need.
    • Louisa’s wondering: Louisa herself is portrayed as someone who struggles with “unmanageable thoughts” that make her “wonder”. She often sits by the fire, looking at the flames, and contemplates her life and her brother. This shows that even those raised in an environment that discourages imagination are not immune to its influence. Her mother scolds her for wondering.
    • The stifling of imagination: The sources suggest that the suppression of imagination leads to unhappiness and a lack of fulfillment. For example, Tom Gradgrind expresses his hatred of his life and wishes to “blow up” all the facts and figures he’s been forced to learn. Louisa also feels her life is unfortunate, in part because she lacks the means to “lighten” Tom’s mind or bring him relief from his boredom. These examples highlight the negative consequences of a life devoid of imagination.
    • Sissy Jupe as a contrast: In contrast, Sissy Jupe, who comes from a background of storytelling and performance, is portrayed as someone with a natural capacity for compassion and imagination. Though considered academically slow by Mr. Gradgrind’s standards, she possesses an emotional intelligence that is lacking in those who have been trained only in facts and figures. Her presence highlights the value of imagination and emotion in human life.

    Overall, the sources present idle imagination as a concept that is feared and actively suppressed by those who value reason and fact above all else. However, the text also suggests that imagination is a vital aspect of human experience, and that its suppression leads to a diminished and unhappy life. The presence of the “unlucky infants” who are told “never to wonder” further emphasizes how important imagination is, as its absence creates “melancholy” conditions. The narrative shows the limits of a fact-based system and hints that imagination can be a positive force when balanced with reason and education.

    Coketown’s Social Divisions

    Social divisions are a prominent theme in the sources, highlighting the stark inequalities and rigid class structures that exist in the fictional industrial town of Coketown. These divisions are explored through various characters and their interactions, revealing the complex power dynamics and the dehumanizing effects of industrial capitalism. Here’s a detailed look at the social divisions depicted:

    • The Industrialists vs. the Working Class: The most significant division is between the wealthy industrialists, like Bounderby and Gradgrind, and the working class, often referred to as “hands”. This division is characterized by a vast disparity in wealth and power, with the industrialists controlling the means of production and the lives of the workers. The industrialists view the working class as mere “hands” or “figures in a sum”, devoid of individual needs or feelings, while the workers live in poverty, subjected to harsh working conditions, and often denied basic rights and freedoms.
    • Bounderby’s fabricated origins as a tool to further social division: Bounderby’s constant boasting about his supposed impoverished upbringing is used to emphasize his self-made status and to create a stark contrast between himself and those he considers to be privileged. This manufactured narrative allows him to further distance himself from his workers, creating an “us versus them” dynamic that perpetuates the social divide. His claims are designed to shame those who come from privilege, while simultaneously reinforcing his supposed merit and superiority. The fact that this story is a lie exposes the hypocrisy of his position as a self-made man, and the hollowness of the social divisions he attempts to create.
    • The treatment of the working class: The working class is depicted as living in monotonous, unhealthy conditions in Coketown, where “every day was the same as yesterday and tomorrow”. They work long hours in factories with “rattling and a trembling all day long”. The town itself is described as “severely workful,” lacking any beauty or joy, which further demonstrates the dehumanization of the working class.
    • The impact of industrialization on the working class: The industrial setting, with its “steam engine worked monotonously up and down like the head of an elephant in a state of melancholy madness,” represents the mechanical and relentless nature of work. The factories are described as “fairy palaces” where the workers “wasting with heat toiled languidly in the desert”, highlighting the stark contrast between the supposed progress of industry and the human cost. The emphasis on facts and figures, along with the suppression of imagination, further dehumanizes the working class, reducing them to mere components of the industrial machine.
    • The limited social mobility: The sources show that it is nearly impossible for individuals to move beyond the class they were born into. Steven Blackpool, for example, is trapped in his circumstances as a working-class man and cannot escape his unhappy marriage or find justice within the system. He is even denied the right to seek legal help because he lacks the necessary financial resources. This shows the entrenched nature of social divisions and the limited opportunities for upward mobility for the working class.
    • The role of education in perpetuating divisions: Mr. Gradgrind’s system of education, which emphasizes facts and figures while suppressing imagination and emotion, is presented as a tool for reinforcing social divisions. By training children to accept their place in society, this system perpetuates the power imbalance between the industrialists and the working class. The educational system is a “mere question of figures” and a method of teaching children to understand themselves as “mere questions of figures”.
    • The “us versus them” mentality: Bounderby frequently uses “us versus them” rhetoric, portraying the working class as lazy, ungrateful, and prone to vices, while positioning himself and other industrialists as responsible and hardworking. He is incapable of seeing his workers as fully human, which further deepens the social divide. Bounderby’s opinions are shared by others, such as Bitzer, who believes the working class’s desire for “recreations” is “stuff and nonsense,” and that their need to combine together is a path to criminality.
    • The “highly connected” vs the “scum of the earth”: Bounderby also highlights a distinction between the “highly connected,” like Mrs. Sparsit, and those he considers to be “scum of the Earth,” which he claims to be. This further demonstrates the social strata that are present, even among those who are not working class. His use of these terms is indicative of his perception of society as rigidly hierarchical, with some people naturally superior to others due to their lineage.
    • The limitations of “benevolence”: Bounderby’s view of the working class is that no matter what is done for them, “they were never thankful for it”. The industrialists in the book do not see a need to understand or empathize with the working class, but only see them as a population that needs to be controlled. Despite the appearance of concern, the industrialists, such as Bounderby and Gradgrind, ultimately prioritize their own interests and maintain their power and status within the existing social structure.
    • The emergence of Unions: In response to their harsh treatment, the working class attempts to unite and form unions. However, this attempt at collective action is seen as a threat to the established order. Bounderby and other industrialists view the unions as a sign of disloyalty and rebellion, and seek to suppress them through intimidation and legal action. The novel portrays these unions and the characters that lead them as flawed, highlighting the difficulty of organized resistance in such a system.
    • The role of compassion: Sissy Jupe is presented as a contrast to the harsh realities of Coketown and its rigid social structures. Her capacity for empathy, love and imagination are meant to illustrate the possibility of bridging social divides and offering a more humane way of living. Her work with the children in Coketown, and her care for Louisa highlights this.

    In summary, the sources depict a society deeply fractured by social divisions based on wealth, class, and power. These divisions are not only reflected in the material conditions of life but also in the attitudes, beliefs, and behaviors of the characters. The novel criticizes the rigid, dehumanizing aspects of industrial capitalism and the social hierarchies it perpetuates, while also suggesting that compassion, empathy, and imagination can offer a way forward towards a more just and humane society. The starkness of the divisions contributes to the overall atmosphere of repression and unhappiness that pervades the text.

    Coketown Bank Robbery: A Social Commentary

    The bank robbery in the sources is a significant event that exposes the social divisions and moral failings within the fictional town of Coketown. It serves as a catalyst for several plot developments and reveals the complex relationships between characters. Here’s a detailed analysis of the robbery:

    • The crime: The robbery occurs at Mr. Bounderby’s bank, where a sum of approximately £150 is stolen from a safe in young Tom Gradgrind’s closet. The method involves forcing the lock on the safe and using a false key to open the main door, which was then double-locked again.
    • Initial suspicion of Stephen Blackpool: Immediately after the robbery is discovered, suspicion falls on Stephen Blackpool, a working-class man who is already marginalized and ostracized by both his fellow workers and his employer. This is based on several factors:
    • Stephen had been seen “lurking about” the bank at night.
    • Mrs. Sparsit reported that he was “lurking for no good” and had called Bitzer’s attention to him.
    • Stephen had previously visited Bounderby’s house to ask about dissolving his marriage and had been warned against “mischievous strangers”, which Mr. Bounderby now uses to suggest Stephen’s criminal nature.
    • Bounderby’s prejudice against the working class leads him to believe that any “dissatisfied hand” is “fit for anything bad”.
    • The role of a “mysterious old woman”: An “old woman” is also implicated in the robbery. She is described as someone who appears to have been “flying into town on a broomstick every now and then”. She is seen watching the bank and then meeting with Stephen. This character is later revealed to be Mrs. Pegler, Bounderby’s mother.
    • Bounderby’s reaction and public accusations: Bounderby, in his typical manner, makes a public spectacle of the robbery, using it as an opportunity to reinforce his prejudices against the working class. He issues a public placard offering a £20 reward for Stephen Blackpool’s apprehension, describing him in detail and branding him as a thief. He uses the robbery to further portray himself as a victim and to emphasize the dishonesty of the working class.
    • The impact on Stephen: As a result of the accusations, Stephen is further isolated and becomes the subject of public scorn. The local delegate, Slackbridge, uses the robbery to denounce Stephen and to solidify his own position as a champion of the working class. Slackbridge uses this incident to encourage a sense of victimhood amongst the workers and further separate them from those who are different.
    • Rachel’s intervention: Rachel, a close friend of Stephen, defends his character and insists on his innocence. She reveals that Stephen had made a promise to her to avoid trouble and that he would not break his word. Rachel tells Mr. Bounderby that Stephen is not a thief and vows that he will return to clear his name.
    • The real culprit: It is eventually revealed that Tom Gradgrind Jr., Louisa’s brother, is the real thief. This fact is uncovered gradually:
    • Louisa’s realization that Tom must have been involved in the robbery during his visit to Stephen’s lodgings.
    • Tom’s own confession as he is being helped to escape, overheard by Bitzer.
    • Louisa’s later confirmation to her father about her suspicion of Tom’s involvement and planning.
    • Tom’s motives: Tom was in “a horrible mess” and desperately needed money. He resented his family, particularly Mr. Bounderby, and sought to escape his circumstances. He used his connections to the bank, and his knowledge of its security, to commit the crime and to then blame it on Stephen. He is described as an “unhappy” and “wretched” boy who felt that “nobody cared for” him.
    • Bitzer’s actions: Bitzer, motivated by self-interest and a desire for promotion, becomes instrumental in preventing Tom’s escape. He sees the situation as a business transaction and is willing to betray the Gradgrinds in order to advance his own career.
    • The attempted escape: With Louisa’s help, Tom attempts to flee Coketown, but he is ultimately betrayed by Bitzer, who intends to return Tom to Mr. Bounderby. However, Mr. Sleary, a character from Sissy Jupe’s background, enables Tom’s eventual escape.

    In summary, the bank robbery is not just a simple crime, but a complex event that reveals:

    • The social injustices and prejudices prevalent in Coketown: The immediate suspicion of Stephen, a working-class man, highlights the deep-seated prejudices against the lower classes.
    • The hypocrisy of Bounderby and the failures of Gradgrind’s educational system: Bounderby’s self-serving nature and Gradgrind’s failure to understand his own children.
    • The corrupting influence of self-interest: Bitzer’s actions reveal the ruthless nature of the pursuit of personal gain at any cost.
    • The importance of empathy and compassion: The actions of Rachel and Sissy demonstrate the value of love, loyalty, and compassion.

    The robbery serves as a turning point in the narrative, forcing characters to confront their own biases and moral failings, and ultimately paving the way for personal growth and change. The plot point demonstrates the systemic issues in Coketown and highlights the way in which a rigid focus on facts and figures leads to a misunderstanding of human nature.

    Louisa’s Descent: A Metaphorical Journey

    Louisa’s “descent” is a metaphorical journey that represents her emotional and moral deterioration, influenced by her repressive upbringing and unhappy marriage. This decline is a central theme in the sources, and is marked by key events and relationships:

    • Repressive Upbringing: Louisa’s father, Mr. Gradgrind, raises her with a strict emphasis on facts and reason, neglecting her emotional development. This system, devoid of “sentiment and affection,” leaves her with a “starved imagination”. As a child she is told “never wonder,” which stifles her curiosity and emotional expression. This upbringing leaves her ill-equipped to navigate complex relationships or to understand her own feelings.
    • The “Staircase” Metaphor: Mrs. Sparsit, a character in the story, imagines Louisa’s life as a “mighty staircase with a dark pit of shame and ruin at the bottom”. Mrs. Sparsit observes Louisa’s “descent” with a mix of fascination and vindictive glee, seeing her fall as a confirmation of her own twisted worldview. She watches Louisa “coming down sometimes slowly sometimes quickly sometimes several steps at one bout sometimes stopping never turning back”.
    • An Unhappy Marriage: Louisa enters into a loveless marriage with Mr. Bounderby, a man much older than herself, due to her father’s encouragement. She views the marriage as a “tangible fact” and a “question of fact”, devoid of love or affection. This union further suppresses her emotions and leaves her feeling isolated and trapped. The marriage is presented as a purely practical arrangement.
    • Relationship with James Harthouse: Louisa develops a complex relationship with James Harthouse, a charismatic and cynical politician. He is attracted to her suppressed passions, recognizing them as a result of her upbringing. This relationship introduces a new level of danger to Louisa’s life as it represents a challenge to the status quo and to her marriage. He manipulates her, preying on her emotional vulnerabilities and further complicating her life.
    • Emotional Numbness and Detachment: Louisa displays a notable detachment from her own life and relationships, further indicating her decline. She observes her own life as if she is watching a play. This detachment and numbness stems from her emotionally stifled upbringing.
    • Turning Point: Louisa’s emotional crisis reaches its peak when she flees her home and returns to her father. This marks a turning point, where she begins to acknowledge the emotional damage she has suffered. This crisis, where she confronts her father with her unhappiness, compels her father to also question his own system of education and the values he has instilled in his children.
    • Self-Reflection and Transformation: Following her emotional breakdown, Louisa begins a path of self-reflection. She acknowledges the failure of her education and recognizes her emotional deprivation. She admits to her sister, Sissy Jupe, that she has “always been so proud and so hardened so confused and troubled so resentful and unjust to everyone and to myself that everything is stormy dark and wicked to me”. She recognizes that she is “devoid” of the good things in life, which include “peace contentment honor”. She seeks out Sissy’s help, recognizing the value of Sissy’s emotional intelligence and her ability to love unconditionally.
    • Seeking Redemption: In the end, Louisa expresses a desire for change and seeks to understand the value of empathy and compassion. She reflects on Sissy Jupe’s emotional intelligence as what she lacked in her life. She shows an understanding that life should have a balance of “machinery and reality” as well as “imaginative Graces and delights”.

    Louisa’s “descent” is not merely a downward spiral, but a journey through emotional awakening and self-awareness. By experiencing the limitations of her rigidly factual education, the unhappiness of a loveless marriage, and the complexities of human relationships, she is able to recognize the value of emotions, imagination, and compassion, leading her towards redemption. While this growth is not without pain and struggle, it paves the way for a more fulfilling life where she can be a positive influence on others.

    Hard Times 💖 By Charles Dickens FULL Audiobook

    By Amjad Izhar
    Contact: amjad.izhar@gmail.com
    https://amjadizhar.blog

  • Sajjan Beparwah Pakistani Punjabi Super Hit Movie Noor Jahan Hit Songs Habib Naghma

    Sajjan Beparwah Pakistani Punjabi Super Hit Movie Noor Jahan Hit Songs Habib Naghma

    The text comprises a dramatic monologue or play script, exploring complex themes of love, family honor, poverty, and justice within a rural South Asian community. The narrative unfolds through interwoven conversations and monologues revealing multiple perspectives on moral dilemmas, particularly concerning the selling of daughters and the consequences of vendettas. The dialogue is rich in emotional intensity, reflecting the characters’ struggles with societal pressures and personal choices. Multiple storylines intertwine, focusing on various characters grappling with difficult situations and the implications of their actions. The piece concludes with a sense of unresolved tension, leaving the audience to consider the lasting impact of the characters’ choices and the overall societal complexities presented.

    Text Analysis Study Guide

    Quiz

    Instructions: Answer each question in 2-3 sentences.

    1. What are some of the recurring themes in the text regarding family relationships?
    2. How does the text portray the power dynamics between the wealthy and the poor?
    3. What role does alcohol play in the lives of some of the characters?
    4. What is the significance of land ownership in the text?
    5. How does the text depict the legal system and its impact on individuals?
    6. Describe the ways in which honor is a major concern for different characters.
    7. How are women’s roles and expectations portrayed in the text?
    8. How do some of the characters use language to manipulate or deceive others?
    9. What is the role of violence in the text, and what motivations drive it?
    10. What are the main conflicts in the text, and how do they relate to each other?

    Quiz Answer Key

    1. Family relationships are shown as complex, often strained by conflict, loyalty, and betrayal. There is both deep affection and significant tension, particularly between parents and children and siblings.
    2. The wealthy hold considerable power, often using their resources to manipulate the poor and the legal system. The poor are often at the mercy of the wealthy and face exploitation.
    3. Alcohol is depicted as a destructive force in the text, leading to violence, poor judgment, and manipulation of others. It’s often shown as a way for characters to cope with their circumstances.
    4. Land ownership is a source of power and conflict, with characters willing to go to great lengths to acquire or maintain it. The loss of land is portrayed as a significant blow to social status.
    5. The legal system is often shown as corrupt and easily manipulated by the wealthy, failing to protect the poor. Lawsuits are used as a tool for personal gain and vengeance.
    6. Honor is a central concern, with characters taking extreme actions to protect their reputation and family name. This can be the basis for violence, betrayal, and complex relationships.
    7. Women are often portrayed as having limited agency within a patriarchal society, being objects of negotiation and control. They must uphold family honor while also facing personal struggles and limited choices.
    8. Characters use language to manipulate, deceive, or negotiate their way through conflicts. This includes both subtle persuasion and outright lying to gain advantage.
    9. Violence is used as a way to settle scores, enforce power, and seek revenge. This can be both physical and emotional violence with characters driven by jealousy, greed, and the need to protect their honor.
    10. The main conflicts include class struggles, family disputes, legal battles, and conflicts over land and honor. These different conflicts are interwoven and influence characters’ motivations and actions throughout the story.

    Essay Questions

    Instructions: Answer each question in a well-structured essay format.

    1. Analyze the text’s depiction of social class and its impact on characters’ lives and relationships. Consider the roles and constraints placed on the wealthy, laborers, and other social groups present in the text.
    2. Explore the significance of honor as a theme in the text, including its role in shaping characters’ decisions and actions. How do cultural notions of honor and shame influence the story’s events and outcomes?
    3. Discuss the portrayal of women in the text. What are their roles within families and communities, and to what extent are they able to assert their agency? How do gender dynamics contribute to the central conflicts?
    4. Examine the role of language and communication in the text. How do characters use language to manipulate, deceive, or pursue their goals? How does miscommunication contribute to the story’s conflicts?
    5. Evaluate the ending of the text. What are the central conflicts that remain unresolved? Does the conclusion offer any sense of hope or resolution, or does it further expose the tensions within the text?

    Glossary of Key Terms

    • Chaudhary: A term used to denote a person of power and status, often a landlord or head of a village.
    • Jatt: A term referencing a particular social group or caste in South Asia, often associated with land ownership and agriculture.
    • Tilak: A mark or symbol worn on the forehead, often with religious or cultural significance.
    • Halal: In the context of the text, refers to actions that are considered proper and permissible according to religious or moral standards.
    • Doli: A type of palanquin, traditionally used for carrying a bride during wedding processions.
    • Thandar: A police officer, often used in a local context.
    • Inshallah: An Arabic phrase meaning “God willing,” used to express hope or intention for a future event.
    • Bena: An ambiguous term in the text that seems to refer to a kind of longing or desire.
    • Holi: A Hindu spring festival, celebrated with colors.
    • Dangal: A traditional Indian wrestling tournament.

    Honor, Love, and Revenge in a Class-Bound Society

    Okay, here is a detailed briefing document based on the provided text, exploring its main themes, key ideas, and notable quotes:

    Briefing Document: Analysis of “Pasted Text”

    I. Overview:

    The provided text appears to be a transcript of a dramatic narrative, likely from a play or film script. It’s characterized by intense dialogue, shifting perspectives, and a strong sense of conflict rooted in social hierarchies, family honor, love, and revenge. The setting seems to be a rural community, possibly in South Asia, where traditional values and patriarchal structures are prominent. The language is evocative, employing colloquialisms, curses, and poetic pronouncements.

    II. Main Themes and Key Ideas:

    1. Social Hierarchy and Class Conflict: The narrative is deeply embedded in the power dynamics of a class-based society. The “Choudhary” (a title suggesting a landowner or village leader) and their family occupy a position of privilege, while laborers and other poorer villagers are often subjected to their whims and exploitation.
    • Quote: “Being the daughter of a chowdhary’s worker, She started coming and going.” This highlights the class difference and the limited agency of those from lower social strata.
    • Quote: “I think of him as a worker who works for them. You are the people and we are the ones who do your housework.” This starkly contrasts the different positions in the social structure.
    • Idea: The text constantly showcases how the rich use their power (legal, financial, social) to manipulate and dominate the poor.
    1. Honor, Shame, and Family Reputation: A recurring theme is the immense importance of family honor and reputation, particularly related to women. Marriages are often transactional, and the actions of family members, especially women, can bring shame or pride to the whole family.
    • Quote: “I fear your honor, you are a good house.” This illustrates the value placed on a family’s reputation.
    • Idea: There’s a strong sense of patriarchal control where women are often viewed as a means to maintain or enhance family standing. The treatment of daughters as “another’s wealth” underscores this patriarchal aspect.
    • Quote: “Honor has been auctioned off for this.” This line represents the deep shame experienced when family honor is compromised.
    1. Love and Sacrifice: The narrative explores the complexities of love, which is often juxtaposed against social constraints and familial obligations. Characters make immense sacrifices for love, often leading to tragedy and further conflict.
    • Quote: “He did it, and I did it in my love.” This shows the characters’ extreme actions performed for love.
    • Idea: The characters grapple with different kinds of love: familial love, romantic love, and love for one’s community. These are often in conflict.
    • Idea: The idea of love being a driving force behind the decisions of characters often leads to tragedy.
    1. Justice and Revenge: The story is driven by a cycle of violence, where acts of injustice often lead to desires for revenge. The legal system is often depicted as corrupt and easily manipulated by the wealthy.
    • Quote: “The entire land was sold for a lawsuit.” This illustrates how legal battles are tools for power, often leaving the poor impoverished.
    • Quote: “Revenge for giving him a hug from you. I will take it.” This reveals the intense desire for retribution.
    • Idea: The quest for justice is often pursued through personal vendettas, demonstrating the breakdown of institutional fairness.
    1. Materialism and Greed: The desire for wealth, land, and material possessions is another potent theme, often leading to corruption, exploitation, and the erosion of human values.
    • Quote: “What should we do with these newly acquired lands?” The question emphasizes the materialistic focus of the wealthy.
    • Idea: The desire for material gain drives many of the conflicts and negative actions seen in the text, showing the dark side of ambition.
    • Quote: “The price of the food was paid and our gentleman was in need.” This line highlights the stark transactional nature of their society.
    1. Moral Ambiguity and the Nature of Good and Evil: The text rarely presents clear-cut heroes and villains. Characters often exhibit a mix of good and bad qualities, making it difficult to judge them definitively.
    • Idea: Characters often act out of desperation or under duress, blurring the lines between right and wrong. The text shows how difficult it is to be good within a corrupt system.
    • Idea: The cycle of violence and revenge raises questions about moral responsibility and the difficulty of breaking these cycles.
    1. The Importance of Relationships (Both good and bad): Characters are deeply interwoven and defined by their connections to each other (father/daughter, friends, lovers, rivals) which drives the narrative forward
    • Idea: Relationships are often transactional but it does show that even in a ruthless environment like the one described, that connection is still crucial to the human condition.

    III. Significant Characters and Relationships:

    • Choudhary: Represents the wealthy and powerful landowning class. Their actions are often morally ambiguous, driven by their own self-interest and desire to protect their social standing. Multiple Choudharys appear, highlighting the system of power rather than one bad individual.
    • Laborers/Workers: Represent the poor and marginalized, often victimized by the Choudharys and their system. They are also capable of love, loyalty, and vengeance. They are the opposite of the Choudharys in the class system.
    • The Women: Characters like Farida, Pino, and other women, are pivotal. They are often caught between family honor and their own desires, leading to difficult choices and often tragic outcomes.
    • Friends: Friendship proves important to the lives of the characters, both the loyal bonds and betrayals drive the narrative.

    IV. Stylistic Elements:

    • Intense Dialogue: The use of direct, often heated dialogue, creates a sense of immediacy and drama. The characters often argue and express raw emotions.
    • Colloquial Language: The use of idioms, curses, and colloquialisms gives the text a sense of authenticity and grounds it in a specific cultural context.
    • Poetic Pronouncements: Characters use poetic and often metaphorical language to express their feelings, often at moments of heightened emotion.

    V. Conclusion:

    The text provides a compelling look at a complex society grappling with issues of class, honor, love, justice, and revenge. It is not a simple story of good versus evil but a portrayal of deeply flawed characters navigating a corrupt and often brutal world. The narrative’s power lies in its intense emotionality, its exploration of moral ambiguities, and its depiction of the human condition under oppressive circumstances. This document presents the core concepts of the text while leaving room for deeper interpretations.

    Honor, Land, and Justice in a Rural Society

    FAQ

    • What are the primary social conflicts depicted in this text? The text revolves around conflicts stemming from class disparities, honor, and family relationships. There are tensions between landowners (Chaudharis) and laborers, often resulting in exploitation and violence. Honor, particularly regarding women and family reputation, is a central motivator, driving actions like arranged marriages, revenge killings, and land disputes. Family loyalties are also frequently tested, as individuals choose between loyalty to family, love, or their own principles.
    • How is the concept of ‘honor’ presented and what are its consequences? Honor is portrayed as a rigid social construct, especially concerning women. It dictates that women’s actions reflect on the entire family. Violations of honor, often perceived as disrespect or inappropriate romantic relationships, can lead to severe consequences such as murder, forced marriages, or complete social ostracization. The pursuit of honor frequently leads to violence, injustice, and cycles of revenge, suggesting its destructive nature within this society.
    • What role does land ownership play in the narrative? Land ownership is directly tied to power and social status. The Chaudharis, as landowners, hold considerable sway over the laborers who often depend on them. Disputes over land are common and can be the source of long-standing feuds and legal battles that consume entire families financially and emotionally. Land is also used as a tool for manipulation and control, with ownership sometimes offered or taken away as part of marriage agreements or as collateral.
    • How are women portrayed within the given context? Women are often depicted as vulnerable and their lives are significantly controlled by male relatives. They are frequently treated as commodities, whose value is primarily determined by their family’s honor and their potential to be traded in marriage deals. The text also demonstrates some women challenging these restrictions, exhibiting agency through their actions and defying social expectations. Despite their lack of freedom and limited power, they still actively participate in influencing the decisions of their male counterparts within the family and community.
    • What is the significance of the ‘worker’ or ‘laborer’ character, and how are they treated? The worker or laborer class faces significant injustice and exploitation. They are often depicted as being at the mercy of the Chaudharis, with little legal or social power. Their labor is often underpaid, and they’re often considered subservient, making them easy to be manipulated and oppressed. Despite this, there is also resilience and solidarity among them. Their lives are constantly at risk due to land disputes or other conflict, and their plight acts as a clear contrast to the landowners.
    • What is the significance of the concept of ‘debt’ and how is it used? Debt acts as a major constraint and a tool of exploitation. It can be a financial burden passed down through generations or the burden of obligation when favors are done for an individual or a family. The text depicts how financial debt often forces people into difficult situations, making them vulnerable to coercion or unfair arrangements, like selling family land or even marrying off daughters for compensation. The idea of “social debt” also exists where favors performed create a never-ending obligation to the benefactor.
    • How is the legal system portrayed in this narrative? The legal system is depicted as largely flawed and unjust. It is often influenced by the wealth and power of the landowners, leading to biased outcomes. The legal system is seen as a tool to oppress the poor, leaving them unable to find justice and recourse for any wrongdoing committed against them. Cases can drag on for years, bankrupting families and creating ongoing conflicts. The legal system’s inefficiency and corruption further contributes to the cycles of violence and revenge within the society.
    • What are the prevailing themes regarding morality and justice? Morality and justice are frequently compromised in this text. The characters often grapple with ethical dilemmas, choosing between doing what is morally right and succumbing to societal pressures or the desire for revenge. The traditional systems of justice and morality are challenged by actions driven by greed, pride, and the pursuit of honor. The text also explores concepts of individual responsibility and agency within a world where systems are broken, and morality is often a matter of perception.

    Love, Honor, and Social Status

    The sources explore love and relationships through various lenses, often intertwined with themes of family, honor, and social status. Here’s a breakdown of the different aspects of love and relationships as depicted in the sources:

    Romantic Love and Relationships:

    • The sources depict romantic relationships, often between individuals of different social classes, that are passionate but face significant obstacles.
    • Love is often portrayed as a powerful force, driving characters to make extreme choices. For instance, one character admits to having committed a violent act “in my love”.
    • There are hints of love triangles or complicated romantic situations. Some characters express their love directly, while others seem to be involved in more complex romantic entanglements.
    • Some relationships are described as being based on true affection and a desire to be together. For example, a character says “I found a gem in your eyes. I have built a palace of thoughts for you”.
    • Love is often shown as a source of both joy and pain. Characters express deep affection, but they also struggle with heartbreak and disappointment.

    Family Relationships:

    • The sources highlight the strong bonds within families, particularly between parents and children.
    • Parents make significant sacrifices for their children, often driven by love and a desire to protect them. For example, one character states “Sons are the lights of the home”.
    • However, family relationships are also fraught with conflict. Disputes arise over issues such as marriage, honor, and financial matters.
    • There are contrasting views on the value of sons and daughters. Some believe that sons are the ‘lights of the home’ while others highlight the importance and value of daughters.
    • The sources also discuss the importance of respecting elders and family members, with a specific emphasis on respecting the role of parents.

    Relationships and Social Status:

    • Social status and wealth greatly influence relationships. The “Chaudhary,” a figure of high social standing, is often at the center of relationship conflicts.
    • Marriages are often seen as transactions or means of gaining social or financial advantage, sometimes overriding the desires and wishes of those involved.
    • The sources also touch upon the idea of love and relationships across class lines, where those from lower classes struggle to gain acceptance.
    • Honor and reputation are closely tied to relationships. Characters are willing to go to extreme lengths to protect their family’s honor and avoid being shamed.
    • There is a sense of injustice in how those of lower classes are treated. For example, a character states, “Even if the daughter of the bride becomes a customer, for them There is nothing wrong with you, you are someone’s son, a laborer.”

    Other Notable Aspects:

    • There is an emphasis on commitment, loyalty, and the importance of keeping one’s word within relationships.
    • The sources discuss complex relationships between friends and betrayals.
    • The concept of “halal,” or what is permissible, also plays a role in relationships, particularly within the context of marriage and duty.

    In conclusion, the sources provide a complex look into various types of love and relationships and emphasize that they are often shaped by social status, family dynamics, and the importance of honor. These elements interweave and create tension and conflicts among individuals.

    Murder, Lawsuits, and Social Justice

    The sources contain frequent references to murder and lawsuits, often intertwined with themes of honor, family, and social status. Here’s a breakdown of how these elements are portrayed:

    Murder:

    • Murder is a recurring theme, with several characters either committing or being accused of murder. These acts are often driven by intense emotions such as love, revenge, and anger.
    • One character admits to having killed someone “in my love”.
    • The murders are often violent, with descriptions of stabbing and other forms of physical assault.
    • There’s a sense of retribution, with characters seeking revenge for the murder of loved ones. For example, a character vows to seek revenge for the murder of his son.
    • In one instance, a character is killed for marrying someone else’s young daughter.
    • The consequences of murder are severe, often leading to imprisonment and legal battles.
    • There is also a sense of injustice, as some murders are committed by those in power or those who can manipulate the system.
    • The sources suggest that murders are sometimes committed for financial gain or to resolve disputes over land or property.
    • There are mentions of the use of bribes to influence outcomes in cases of murder.

    Lawsuits:

    • Lawsuits are a prominent aspect of the narrative, often arising from disputes over land, property, and murder.
    • The sources suggest that the legal system is often biased, with those in power having an advantage.
    • The financial burden of lawsuits is significant, with families selling land and property to pay legal fees.
    • Lawsuits are often protracted and complex, with multiple cases being filed and the legal process dragging on for years.
    • There is a sense of desperation and helplessness among those caught in the legal system.
    • The outcomes of lawsuits are often unpredictable, adding to the characters’ anxieties and frustrations.
    • Characters try to manipulate or influence the outcome of lawsuits through bribery or connections. For example, a character asks, “If you had him kill you by giving him a bribe, and now Never even to meet him.”
    • A character says, “The entire land was sold for a lawsuit.”
    • The sources indicate a distrust in the legal system, with characters often feeling that justice is not served.

    Interplay between Murder and Lawsuits:

    • Murder often leads to lawsuits, which are further complicated by the social and economic status of those involved.
    • The pursuit of justice is a major driver of the narrative, with characters seeking retribution for murder through legal channels.
    • The legal system is often portrayed as corrupt and unreliable, with the powerful manipulating the process to their advantage.
    • The sources also show the emotional toll of murder and lawsuits on individuals and families, with characters experiencing grief, anger, and despair.

    Other Notable Aspects:

    • The sources highlight the significance of honor and reputation within the context of murder and lawsuits. Characters are willing to go to extreme lengths to protect their families from shame.
    • There is a sense of injustice in how the legal system treats those from lower classes, with the rich and powerful often escaping punishment.
    • The sources also explore the psychological impact of violence and legal battles on the characters, with many of them becoming disillusioned and embittered.

    In conclusion, murder and lawsuits are central themes in the sources, revealing a society riddled with violence, injustice, and corruption. These elements are closely tied to the themes of love, honor, family, and social status, creating a complex and often tragic narrative.

    Family Honor and Social Dynamics

    Family honor is a central theme in the sources, deeply influencing the actions and decisions of the characters. Here’s an analysis of how family honor is depicted:

    Importance of Family Reputation:

    • The sources emphasize that maintaining family honor is paramount. Characters are highly concerned with their family’s reputation within the community. They are willing to make significant sacrifices to protect it.
    • Characters will go to great lengths to avoid shame or disgrace. The actions of individual family members reflect on the entire family, and their misdeeds can bring dishonor to everyone.
    • One character states, “Dishonesty is our good blood”, suggesting that family reputation is tied to honesty.

    Actions to Preserve Honor:

    • Marriages are often arranged to preserve family honor or to improve a family’s social standing. In some instances, a daughter’s hand is offered to settle disputes or financial obligations.
    • The sources depict that family honor can be a motivating factor for both violence and reconciliation. Characters seek revenge to avenge perceived slights to their family, but also to defend their family’s honor.
    • Conflicts often arise when honor is threatened. Characters engage in disputes and lawsuits to defend their family’s reputation. For example, one character says, “I have sentenced my daughter to death for this,” highlighting the extreme measures taken to preserve honor.
    • Characters take great care to avoid situations that might bring shame upon their families. For instance, a character says, “I won’t let you die of love pain,” indicating a desire to avoid the dishonor that would come from a relationship that goes against social norms.

    Conflicts Arising from Honor:

    • The pursuit of honor can lead to internal conflicts within families, as characters grapple with competing values and desires.
    • Characters often feel pressured to conform to expectations. For instance, a character says, “I am a crazy person, even a child of one year old”, which shows how individuals may feel pressured to adhere to a rigid code of conduct.
    • There are instances where a family’s reputation is damaged because of a son’s misdeeds, such as murder. In these cases, family members are prepared to pay a price to restore honor.
    • The sources highlight the conflict between individual desires and the demands of family honor. Characters are often forced to choose between their personal happiness and the expectations of their family and community.

    Gender and Honor:

    • The sources suggest that women’s actions are particularly tied to family honor. A woman’s behavior and choices can either bring honor or disgrace to her family.
    • The honor of daughters is treated as a valuable commodity and often used as leverage or collateral in negotiations and disputes.
    • The sources reveal that when honor is compromised, it is often women who bear the brunt of the consequences, such as being sold into marriage.
    • Sons also play a role in upholding family honor, often expected to be protectors and defenders of their families.
    • There is an imbalance, as sons are often given more leeway than daughters. One character states, “If a son goes to jail, he will be acquitted, but if a daughter goes Education should be given from home, not from the next household.”

    Social Status and Honor:

    • Social status significantly influences how honor is perceived and maintained. Characters from higher social classes, like the “Chaudhary,” have more to lose in terms of reputation and are more likely to enforce codes of honor.
    • The sources suggest that the wealthy can sometimes manipulate or circumvent codes of honor, further emphasizing the social inequalities.
    • Those from lower social classes struggle to uphold their honor in a system that often disadvantages them. One character remarks, “Even if the daughter of the bride becomes a customer, for them There is nothing wrong with you, you are someone’s son, a laborer.”

    Other Notable Aspects:

    • The sources show how the concept of “izzat” (respect/honor) is a powerful motivator for characters. They go to great lengths to maintain their standing in the community.
    • The sources also display a sense of disillusionment with the emphasis on family honor as it becomes a source of conflict and oppression. Characters question the value of maintaining a strict code of honor at the expense of personal happiness.
    • The concept of “halal” is also linked to honor, with characters wanting to do what is permissible within the context of their social and moral codes.

    In conclusion, family honor is a dominant theme in the sources, shaping characters’ actions and relationships, and acting as a powerful force that can lead to both conflict and sacrifice. The sources reveal how the rigid adherence to family honor can lead to both tragic outcomes and expressions of enduring loyalty and love, with the concept deeply entwined with social status, gender, and individual choices.

    Wealth, Poverty, and Power

    Poverty and wealth are major themes in the sources, often presented in stark contrast and highlighting the social and economic disparities that exist within the community. The sources explore how wealth and poverty shape individuals’ lives, their relationships, and their interactions with the legal and social systems.

    Wealth and its Implications

    • Power and Influence: The sources frequently associate wealth with power and influence. Those who are wealthy, like the “Chaudhary,” often have the ability to manipulate the legal system, exploit the poor, and control social dynamics.
    • Social Status: Wealth is a key determinant of social status, separating the rich from the poor and creating a hierarchy within the community. Those with wealth enjoy privileges and advantages that are not available to the less fortunate.
    • Control and Exploitation: Wealthy individuals often control resources like land and property. They can exploit laborers and workers who depend on them for their livelihoods.
    • Materialism: Some wealthy characters prioritize material possessions and financial gain over ethical or moral considerations. They engage in business and trade, sometimes exploiting others for profit.
    • Entitlement and Arrogance: The sources depict wealthy characters as sometimes arrogant and entitled, looking down upon those who are poor and treating them unfairly.
    • Corruption: Wealthy individuals are often involved in corrupt practices such as bribery and manipulation of the legal system. They are able to use their wealth to influence outcomes in their favor.
    • Responsibility: Despite their negative behavior, the sources also highlight expectations of wealthy people that they will take care of the poor, reflecting a sense of social responsibility that is often unfulfilled.

    Poverty and its Challenges

    • Lack of Resources: The sources depict the struggles of poor individuals who lack basic resources such as money, land, and property. They are often forced to work as laborers, earning meager wages and living in difficult conditions.
    • Dependence: The poor are often dependent on wealthy individuals for their survival, making them vulnerable to exploitation and abuse. They lack power and agency, often having to accept unfair treatment to survive.
    • Limited Opportunities: Poverty limits opportunities for education and social mobility, perpetuating the cycle of poverty. The children of laborers are often forced to work instead of attending school.
    • Social Stigma: The poor are often stigmatized and looked down upon by those who are wealthy, contributing to a sense of marginalization and despair.
    • Powerlessness: The poor are frequently powerless in the face of the legal and social systems, unable to seek justice or challenge the authority of the wealthy. They are often subject to unfair treatment and abuse without recourse.
    • Desperation: The sources highlight the desperation of those living in poverty, who sometimes resort to extreme measures to survive, including selling their land, and taking out loans to pay for legal battles.
    • Hardship: The lives of the poor are depicted as filled with hardship, including strenuous labor, poor living conditions, and lack of access to essential services.
    • Vulnerability: The sources suggest that the poor are vulnerable to the whims of the wealthy and are sometimes used as pawns in their games.

    Interactions between Rich and Poor

    • Exploitation: The sources highlight the exploitative relationship between the wealthy and the poor. The wealthy often use their resources to benefit at the expense of those who are less fortunate.
    • Dependence: The poor are often dependent on the wealthy for their livelihoods and are often forced to accept unfavorable terms.
    • Social Tensions: The stark contrast between poverty and wealth creates social tensions and conflicts within the community. The resentment of the poor towards the rich is palpable in many instances.
    • Manipulation: Wealthy individuals sometimes use their power to manipulate and control the poor, often for their own benefit.
    • Conditional Charity: There are instances where the wealthy provide charity, but often with conditions or self-serving motives.

    Other Notable Aspects

    • Inheritance: The sources touch on inheritance, with some characters concerned about their land and property being passed on to future generations.
    • Debt: Debt is another significant theme, with many characters struggling to repay loans, often to wealthy moneylenders.
    • Economic Injustice: The sources portray a society with significant economic injustice, where the wealthy benefit at the expense of the poor.
    • Social Mobility: The sources indicate that there is little opportunity for social mobility, with the poor often trapped in their circumstances.

    In conclusion, the sources present a stark depiction of the disparities between the wealthy and the poor. The wealthy wield power and influence, while the poor struggle with hardship and exploitation. These economic differences are a major source of social tension, injustice, and conflict in the world portrayed in the sources.

    Substance Abuse and Societal Impact

    Alcohol and drugs play a significant role in the sources, influencing characters’ actions, relationships, and overall well-being. Here’s an analysis of how these substances are depicted:

    Alcohol Consumption:

    • Common Occurrence: Alcohol consumption appears to be a common practice, especially among certain characters, with many scenes depicting characters drinking or being intoxicated.
    • Social Activity: Drinking is often presented as a social activity, with characters gathering to drink and socialize. It can be part of celebrations, or a way to pass the time.
    • Escape from Reality: For some characters, alcohol seems to be a way to escape from the harsh realities of their lives. They use it to forget their troubles and cope with difficult situations.
    • Addiction and Dependence: The sources depict characters struggling with alcohol addiction and dependence. They are unable to function without drinking, and their addiction leads to negative consequences.
    • Negative Consequences: Alcohol abuse is associated with a range of negative consequences, including violence, poor decision-making, and health problems. Characters are shown behaving irrationally and engaging in destructive behaviors when drunk. For example, one character says, “Drinking alcohol at night and throwing bricks at people Walking I find out as the day progresses”.
    • Financial Implications: Characters who are addicted to alcohol often squander their money on drinks, leading to financial difficulties for themselves and their families. One character mentions, “It’s a loss, son, save the money, I’ll drink”.
    • Moral Condemnation: Some characters condemn drinking, seeing it as a vice that leads to immoral behavior. Others accept drinking as a normal part of their culture.
    • Manipulation: Some characters offer alcohol to others as a means of manipulation or control.
    • Social Commentary: Alcohol is also associated with the rich and their excesses. One character states, “Oh, what a drug of the rich, you have given me…”. The sources are using alcohol as a lens through which the morality and power dynamics of the society are examined.

    Drug Use:

    • Use of Substances: The sources also mention the use of drugs, which are sometimes used in combination with alcohol. The specific types of drugs are not always clear, but they are associated with negative behaviors.
    • Manipulation and Control: Drugs are also used as a tool for manipulation and control. Characters are sometimes drugged against their will or given substances to make them more compliant. For example, one character says, “I’ll give you drugs and come and check on you”
    • Criminal Activity: The sources imply that drugs are connected with criminal activity. Characters are shown to be involved in illegal activities related to drug use.

    Impact of Substance Use:

    • Violence and Conflict: Both alcohol and drug use contribute to violence and conflict in the sources. Characters who are under the influence of these substances are more likely to engage in fights and other aggressive behaviors.
    • Family Discord: Substance abuse creates tension and discord within families. The sources depict family members struggling to cope with the destructive behaviors of loved ones who are addicted to alcohol or drugs.
    • Health Problems: The sources hint at the health problems associated with substance abuse. Characters are described as being sick or having damaged lungs due to their drinking habits.
    • Economic Strain: The misuse of alcohol and drugs leads to economic problems, as individuals squander their money on these substances, or are exploited or manipulated due to their dependence.
    • Moral Decline: Substance abuse is associated with a decline in moral behavior. Characters who are addicted to alcohol or drugs are more likely to engage in dishonest or unethical actions.
    • Loss of Control: Characters under the influence of alcohol and drugs often display a loss of control over their actions, which leads to mistakes, regret, and negative consequences.
    • Social Commentary: The portrayal of alcohol and drug use highlights the social and economic issues that exist within the community. These substances are often used by those who are struggling with poverty or oppression, offering a temporary escape from their difficult circumstances.
    • Cycle of Addiction: The sources suggest a cycle of addiction, with characters getting trapped in destructive patterns of substance abuse that are difficult to break.

    In conclusion, alcohol and drugs are significant elements in the sources, influencing characters’ behaviors, social interactions, and overall well-being. These substances are often associated with negative consequences such as violence, financial problems, and a decline in moral values, while at other times, they are used as part of social gatherings. They highlight the vulnerabilities and problems faced by individuals and the communities in the sources, as well as the power dynamics and social inequalities that exist.

    Sajan Beparwah film Pakistani Punjabi Noor Jahan Song

    By Amjad Izhar
    Contact: amjad.izhar@gmail.com
    https://amjadizhar.blog

  • The Money System: How Money is Created and Who Benefits

    The Money System: How Money is Created and Who Benefits

    The text explores the complexities of the global monetary system, arguing that the current system, where private banks create the majority of money as debt, is inherently unstable and unfair. It highlights how this system leads to boom-and-bust cycles, exacerbates inequality, and concentrates wealth in the hands of a few. The text examines the historical evolution of money, from commodity-based systems to the current fiat money system, and proposes alternative models for a more equitable and stable monetary system. It criticizes the lack of democratic control over money creation and the undue influence of financial institutions on government policies. Finally, it uses anecdotes and data to illustrate the negative consequences of the current system for ordinary citizens.

    01
    Amazon Prime FREE Membership

    Understanding the Modern Monetary System: A Study Guide

    Quiz

    Instructions: Answer the following questions in 2-3 sentences each.

    1. How does the current system of money creation differ from the historical model involving notes and coins?
    2. What is the primary mechanism by which commercial banks create new money?
    3. Explain the concept of “Commercial Bank money.”
    4. How does the Bank of England create physical currency? What happens to the profit?
    5. Why is the idea that banks simply lend out depositors’ money a misconception?
    6. What are two major issues with private banks controlling the money supply?
    7. Describe the role of Central Bank Reserves in interbank transactions.
    8. How does quantitative easing impact the creation of money?
    9. Why did the Bretton Woods system of a gold-backed dollar collapse?
    10. Explain how a “currency war” occurs and what its effects are.

    Quiz Answer Key

    1. Historically, physical notes and coins were a significant portion of the money supply. Today, the vast majority of money is digital and created by commercial banks as debt through loans, not by central banks.
    2. Commercial banks create new money by issuing loans to the public. This process involves creating new digital deposits, which appear as credit in the borrowers’ accounts, effectively increasing the money supply.
    3. “Commercial Bank money” refers to the digital money created by commercial banks when they issue loans. This is different from the physical cash printed by central banks and is the vast majority of money in circulation.
    4. The Bank of England creates physical currency by printing notes at a cost and then selling them at face value to high street banks. The profit goes directly to the treasury, which is used to reduce taxes.
    5. Banks do not simply lend out depositors’ money; instead, they create new money when they issue loans. Depositors’ funds are an accounting entry, and the loans create new credit for borrowers.
    6. First, it necessitates a growing national debt and secondly, banks are incentivized to create more debt and therefore the money supply tends to grow constantly. This growth leads to inflationary pressures and bubbles.
    7. Central Bank Reserves are an electronic form of money that banks use to settle payments with each other, held in accounts at the central bank. They are essential for ensuring that interbank transactions can occur.
    8. Quantitative easing is a process where the central bank provides the settlement banks with Central Bank Reserves for free, often in exchange for buying government bonds. This process increases the available Central Reserve Currency.
    9. The Bretton Woods system collapsed because the U.S. was printing more money than it had gold to back, causing a lack of faith in the system by other countries who sought to redeem their dollars for gold.
    10. A currency war occurs when countries attempt to lower the value of their currency to boost exports. This leads to a competitive cycle of devaluations, which can destabilize the global economy.

    Essay Questions

    Instructions: Answer the following essay questions with a well-structured, multi-paragraph response.

    1. Analyze the historical evolution of the money system, from commodity-based money to the current debt-based system. What are the key differences and consequences of these shifts?
    2. Discuss the argument that the current money system inherently favors the banking sector, creating an uneven distribution of wealth and economic instability.
    3. Evaluate the role of central banks in the modern monetary system. Are they effective regulators, or are they merely enablers of financial excess?
    4. Explain the interconnectedness of debt, money creation, and economic cycles. How does the system lead to boom and bust cycles?
    5. Consider alternative models of money creation and financial regulation. What changes would be necessary to create a more stable and equitable system?

    Glossary of Key Terms

    • Commercial Bank Money: Digital money created by commercial banks when they issue loans, representing the majority of the money supply.
    • Central Bank Reserves: An electronic form of money that banks use to settle payments with each other, held in accounts at the central bank.
    • Demand Deposits: Funds held in bank accounts, accessible on demand, which are used to make payments.
    • Fiat Money: Currency that is not backed by a physical commodity like gold, but rather by a government’s promise, like government debt.
    • Fractional Reserve Banking: A system where banks are required to hold only a fraction of their deposits in reserves, allowing them to create new money through lending. This system no longer applies.
    • Quantitative Easing: A monetary policy where a central bank introduces new money into the money supply by purchasing assets (often government bonds) from commercial banks.
    • Inflation: A general increase in prices and fall in the purchasing value of money over time.
    • Debt-Based Money System: A system in which money is primarily created by banks through debt, rather than by the government, meaning that every pound of money in the system also has a pound of debt.
    • Securitization: The process of transforming illiquid assets into marketable securities.
    • Currency War: A situation where countries competitively devalue their currencies to gain a trade advantage.
    • Leveraged Buyout: The acquisition of a company using a significant amount of borrowed money (debt), often with the purchased company becoming responsible for that debt.
    • Balance of Trade: The difference in value between a country’s imports and exports over a certain time.
    • Structural Adjustment Program: A policy prescribed to countries by the IMF or the World Bank, usually involving deregulation, privatization, and reduced public spending.
    • Efficient Market Hypothesis: An investment theory that claims that assets are always fairly priced, so it is impossible to “beat the market.”

    The Political Economy of Money

    Okay, here is a detailed briefing document synthesizing the key themes and ideas from the provided text.

    Briefing Document: Analysis of Monetary System & Economic Crisis

    Introduction:

    This document analyzes the provided text, focusing on its core arguments concerning the nature of money creation, the role of banks, the causes of economic crises, and the implications for society. The text presents a critical perspective on the modern financial system, arguing that it is inherently unstable, unjustly structured, and ultimately harmful to the majority of the population.

    Key Themes and Ideas:

    1. Money Creation:
    • Commercial Banks Create Most Money: The text emphatically states that the vast majority of money in circulation (97-98%) is not created by central banks or governments but by commercial banks when they issue loans. This is called “Commercial Bank money.”
    • Digital Money: Most money is now digital, consisting of electronic entries in bank databases. This has become dominant since the 1840s legislation limited the creation of paper money.
    • Money Creation as Debt: New money is primarily created when banks make loans, meaning that the majority of the money supply exists as debt. As the text states: “money in the current system is debt…it’s created when Banks make loans.”
    • Central Banks and Physical Money Central banks like the Bank of England only create a small proportion of money, mostly physical cash.
    • Profit from Money Creation: When the central bank creates physical money, the profit (the difference between the cost of printing the note and its face value) goes to the treasury. However, banks profit from creating digital money by charging interest on loans.
    1. The Role of Banks:
    • Profit-Driven: Banks are portrayed as profit-seeking entities that prioritize their own interests and expansion over the needs of society.
    • Unregulated Money Creation: The text argues that banks are largely unrestricted in how much money they create and where they allocate it, subject primarily to their own “willingness to lend.”
    • Influence on the Economy: Banks’ lending decisions heavily influence the shape of the economy and can lead to asset bubbles. “Where that gets spent determines you know the shape of our economy effectively”.
    • The Creation of Asset Bubbles: The text argues that because banks make loans to purchase assets like houses it leads to asset bubbles. “If you have somebody creating money that can only be spent on one thing which is housing then the price of that thing is going to go up.”
    • Systemic Risk: The current system is set up to guarantee profit for the banks, and because we need to borrow from the banks to have an economy it is guaranteed that banks can leverage that fact.
    1. The Inherent Instability of the System:
    • Boom and Bust Cycles: The text connects the way banks create money to the recurring boom and bust cycles, highlighting that debt expansion fuels booms, but over-indebtedness leads to crises. “We have a system where we have to borrow in order to have an economy we have to be in out to the banks and that that guarantees you know a massive profit for the banks this is the boom bust cycle.”
    • Debt Dependence: The system requires ever-increasing debt for the economy to function; therefore the government is forced to find new and innovative ways to borrow.
    • Private Debt into Public Debt: In times of crisis private debt is turned into public debt when governments bail out the banks. The cost of these bailouts is then passed onto the public through austerity measures, public asset sales, etc. “The spending cuts agenda is an attempt by the government to shift debt from its account to that of the public”.
    • Misconceptions About Banking: The public is often mistaken about how banks operate, assuming they either keep deposits safely or lend them out to borrowers. This misunderstanding is exacerbated by politicians and many economists.
    1. Inflation and Asset Bubbles:
    • Inflation as a Consequence: The text contends that inflation results from the money supply expanding faster than the real economy, especially when new money goes into non-productive areas like housing. As the text says, “inflation is what happens when too much money is chasing too few goods and services.”
    • Housing as a vehicle for Bubble Creation “Unlike tulips which are a disposable luxury houses are both a necessity and a luxury and as such they are ideal as a vehicle for money and bubble creation.”
    • House Price Inflation: Inflation in house prices redistributes wealth from the poor to the rich, and inflates a false sense of wealth. “Rising house prices do not create additional uh net GDP value to the economy it they they actually what they do is they redistribute wealth”.
    • Speculative Investment: Banks are incentivized to lend into speculative markets like housing, rather than businesses, reducing productive investment.
    1. Central Bank Reserves and Quantitative Easing:
    • Central Bank Reserves: Commercial banks use Central Bank Reserves, an electronic form of cash kept in accounts with the central bank, for payments among themselves.
    • Quantitative Easing: Quantitative Easing involves the central bank creating reserves out of nothing to buy bonds from banks, effectively giving banks this money for free and removing meaningful fractional reserve banking. “Quantitative easing in effect gives settlement Banks the central Reserve currency for free…as a consequence there is no longer a meaningful fractional reserve.”
    1. The Historical Context of Monetary Systems:
    • Gold Standard and its Demise: The text reviews the history of the gold standard, emphasizing that it provided a fixed anchor for currencies. It then explains how that was replaced by a system linked to the dollar, and ultimately to a system backed by nothing since 1971.
    • Bretton Woods System: The Bretton Woods Agreement sought to manage the world monetary system but ultimately failed, which lead to modern era of financial system without such controls.
    • Modern Era of Financial System: “This is the point in which we enter the modern era of the financial system.”
    1. Consequences of the Current System:
    • Transfer of wealth from the Poor to the Rich The monetary system, the text argues, is designed to give wealth to the rich from the poor because the poor pay interest on debt. “The way a debt-based money system works it guarantees that for every pound of money there’s going to be a pound of debt now that debt is typically going to end up with you know the poor.”
    • Decreasing Living Standards: Bank-created fiat currency allows private banks to extract wealth from the economy, resulting in a gradual decrease in the standard of living.
    • Debt Slavery: As people become poorer, they become more dependent on debt, creating a cycle of debt slavery.
    • Inequality: The system exacerbates inequality by redistributing wealth from the poor to the rich, thus rendering redistribution tax systems ineffective.
    • Democratic Deficit: The text highlights a democratic deficit because of the powerful role that banks and private entities have in the creation of money, “so if we’re going to allow anybody to create new money out of nothing then we should at least have some democratic control over how that money is used.”
    • Banking Crises and Social Costs: Banking crises impoverish people and have serious health consequences.
    1. The Global Financial System:
    • Currency Wars: Countries engage in “currency wars,” devaluing their currencies to boost exports, leading to instability.
    • Foreign Exchange Market: The Foreign Exchange Market is the largest in the world with trillions traded each day. It can cause financial instability for vulnerable countries. “Volatility creates a need…what does it do to countries if there are suddenly huge and instantly fluctuating Financial flows.”
    • Financial Warfare: Financial crises are often instigated by the withdrawal of a country’s currency, which can be seen as a kind of financial warfare.
    • IMF and Structural Adjustment: The International Monetary Fund (IMF) is criticized for imposing “structural adjustment” policies on indebted countries that ultimately harm those countries.
    1. Proposed Solutions and Reforms:
    • Need for Monetary System Reform: The text calls for a fundamental reform of the monetary system, including separating money creation from private banking.
    • Democratic Control: There’s a demand for democratic control over how new money is allocated.
    • Money Backed by Real Assets The narrator proposes new forms of currencies based on either a basket of currencies, renewable energy, or commodities rather than debt.
    • Regulation of Housing: The text suggests regulating the housing market and controlling the amount of money banks put into housing.
    • Targeted Investment: The document advocates directing credit towards productive investment, such as small business development and infrastructure.
    • Fair and Stable System: A call is made for creating a fair and stable monetary system for all.
    • International Cooperation: The text suggests the need for international agreements to manage the global economy.

    Conclusion:

    The provided text presents a scathing critique of the current monetary system, arguing that it is structurally flawed, socially unjust, and economically unsustainable. It proposes that the prevailing system, dominated by private banks and driven by debt creation, is a root cause of financial instability, inequality, and reduced living standards. The text calls for radical reforms to democratize and re-engineer money creation.

    Understanding Money Creation and the Financial System

    FAQ: Understanding Money Creation and the Current Financial System

    1. How is the majority of money created, and who controls this process?
    2. Contrary to popular belief, the majority of money in circulation today (around 97%) is not created by central banks or governments, but by commercial banks when they issue loans. When a bank approves a loan, it essentially creates new digital money (known as commercial bank money) as an accounting entry in the borrower’s account. This process is not based on existing deposits, but rather an expansion of credit. This means private banks largely control the money supply and its allocation.
    3. What is the difference between physical cash (notes and coins) and the digital money created by banks?
    4. Physical cash, which accounts for a very small percentage of the total money supply (around 2-3%), is created by the central bank (like the Bank of England). The profit from creating physical money goes to the treasury. Digital money, or commercial bank money, is created by commercial banks when they make loans. Unlike physical cash, there is no production cost with digital money creation. The banks keep the interest generated by this debt as profit, creating a much larger source of revenue than the treasury.
    5. Why is the current system inherently unstable, and what is the “boom and bust” cycle?
    6. The system is unstable because it’s based on continuous debt creation. Banks are incentivized to issue as many loans as possible, because that’s how they create new money and profit. This leads to excessive lending, driving up asset prices (like housing) and creating economic bubbles. When these bubbles burst, people default on loans and the system contracts, causing recessions. Also, because almost all money is created as debt, for the economy to grow, debt must continuously increase leading to a boom/bust cycle as eventually the debt becomes too much.
    7. What are some of the problems associated with allowing private banks to create money?
    8. Allowing private banks to create the majority of money presents several issues: 1. It forces the economy to operate using debt money, requiring ever-increasing levels of debt to grow. 2. Banks are incentivized to lend and create new money according to their own priorities and profit motives, which do not necessarily align with the public good. This can lead to investment in speculative areas like housing, rather than productive areas like businesses and infrastructure. 3. It creates an imbalance of power, with banks controlling a resource that affects the entire economy. 4. It can lead to a cycle of booms and busts.
    9. How does inflation relate to the money supply, and what is the impact of rising house prices?

    Inflation occurs when there is more money in the economy than the available goods and services. When private banks create new money through loans, if that new money is not matched by an increase in production it creates inflation. This can lead to a rise in general prices, but also creates artificial price rises in areas with high demand like the housing sector. Rising house prices driven by increased credit can make some people feel wealthier, but do not increase overall GDP and may negatively affect younger people trying to enter the market. It effectively redistributes wealth towards those who already own houses, creating inequality.

    1. What is “Central Bank Reserve” currency, and how is it different from the money most people use?
    2. Central Bank Reserves are a type of electronic money that only commercial banks can access. They hold these reserves in accounts at the central bank. When banks make payments to each other, they move this central reserve currency rather than the money in ordinary citizens’ accounts. Central banks create this reserve money through various means, including quantitative easing (QE) where they create these reserves to purchase bonds, essentially making it available for free to commercial banks. This is different from what most people use in everyday transactions. This central reserve currency functions more like the ‘real’ money that banks settle interbank transactions with.
    3. What has happened since the collapse of the Bretton Woods system and the end of the gold standard?
    4. Since the collapse of the dollar-gold standard in 1971 and deregulation of the financial system, money creation has grown exponentially. With no gold backing, the value of currency is based on belief (or credit), and not backed by any specific commodity. This period saw massive expansion of global markets, exponential growth of bank assets and the development of sophisticated financial instruments like derivatives, credit default swaps, and other forms of securitization. This also led to a highly volatile currency market where trillions of dollars are traded daily, contributing to financial instability and inequality.
    5. What are the potential implications of this system for individuals and the broader economy?
    6. The current system is designed to redistribute wealth towards the banking sector and the very wealthy. It has resulted in stagnant or declining real incomes for many and increased debt dependence as people become poorer and have to use credit to bridge the gap. Additionally the system has resulted in an increase in privatizations which move risk and debt to individuals. It is a system that favors those who are already wealthy and puts an enormous burden of debt on the poor and creates inequality. The system is also unstable, prone to crises, and gives too much power to private banks.

    The Creation and Consequences of Money

    Money creation is a complex process that has evolved over time, and it is not always well-understood by the public or even by economists [1-3]. Here’s a breakdown of how money is created, according to the sources:

    Historical Context:

    • Prior to 1844, private banks could create their own banknotes [4]. They would issue paper notes as a representation of the money held in a bank account [5]. These paper notes became widely accepted as money, and banks realized they could profit by creating more notes and lending them out, charging interest [5]. This practice led to inflation, which caused the government to take control of paper money creation [5].
    • In 1844, the power to create paper money was transferred to the Bank of England [4, 5]. However, this legislation did not include demand deposits, which are electronic forms of money held in bank accounts [5].

    Modern Money Creation:

    • Today, most money is not physical cash but digital [5].
    • Commercial banks create the vast majority of new money in circulation as “commercial bank money” when they issue loans [2, 4, 5]. When a customer repays a loan, that commercial bank money is destroyed [2].
    • When banks buy securities, such as bonds, they add the bond to their assets and increase the company’s bank deposits by the corresponding amount [6].
    • This process is not well-understood by the public, with many believing that banks lend out depositors’ money [2]. In reality, banks create new money when they make loans [2].
    • The Bank of England also creates money, but it is a small portion of the total money supply [4]. When the Bank of England creates a £10 note, it costs only a few pence to print and is sold to High Street banks at face value. The profit from creating physical money goes to the treasury [4].

    Central Bank Reserves:

    • Banks use an electronic version of cash called Central Bank Reserves to make payments between each other [7].
    • These reserves are held in accounts at the Bank of England but are not accessible to the public [7].
    • The Bank of England creates Central Bank Reserves out of nothing by increasing the available credit in the settlement bank’s account [8]. They often use this to buy bonds from High Street Banks [8].

    Quantitative Easing

    • In March 2009, the Bank of England introduced quantitative easing which gives settlement banks central reserve currency for free [9].

    Key Concepts:

    • Fractional Reserve Banking: The system in which banks hold a fraction of their deposits in reserve and lend out the rest [9]. However, with quantitative easing, there is no longer a meaningful fractional reserve [9].
    • Commercial Bank Money: Accounting entries that banks use when they create credit [5]. Most of the money in circulation is this electronic form [5].
    • Demand Deposits: Money held in bank accounts [5].
    • Fiat Money: Money that is not backed by a physical commodity like gold or silver [4, 9].
    • Debt-based money: The current system of money creation is debt-based, meaning that the money supply increases when banks issue loans, which creates debt [10, 11].

    Consequences of the Current System:

    • The current system is inherently unstable [1].
    • It guarantees that the economy must borrow money from banks to have money in circulation [10, 11].
    • It leads to a boom-bust cycle [12].
    • It allows private banks to control the money supply and allocate it according to their priorities [2, 6].
    • It creates an incentive for banks to lend as much as possible, leading to excessive debt [10].
    • It results in a transfer of wealth from the poor to the rich [13, 14].
    • It causes inflation because it increases the money supply without a corresponding increase in economic output [15, 16].
    • The creation of money by private banks for nonproductive usage causes real inflation and is a tax on the purchasing power of the medium of exchange [17].
    • It lowers the standard of living of the majority and distributes the wealth among the privileged [18].

    Alternative Systems

    • Some suggest a new currency backed by a scarce resource like energy [19].
    • Another option would be a basket of currencies or commodities [19].

    In conclusion, the current system of money creation is largely controlled by private banks and is based on debt. This system has significant consequences for the economy, including inflation, inequality, and instability [1, 10, 13, 15, 17, 18].

    The Global Monetary System: Creation, Consequences, and Alternatives

    The monetary system is a complex and often misunderstood framework that governs the creation, distribution, and value of money [1]. The sources emphasize that the current monetary system is largely controlled by private banks and is based on debt, which leads to a number of economic and social consequences [2-4].

    Here’s a breakdown of the key aspects of the monetary system, as described in the sources:

    Creation of Money:

    • The majority of money is created by commercial banks when they issue loans [2, 5, 6]. This is done through accounting entries, often referred to as “commercial bank money” [2, 6]. When a loan is repaid, this money is effectively destroyed [2].
    • Central banks, like the Bank of England, also create money, but it is a much smaller portion of the total money supply [5]. The Bank of England profits from creating physical money, which goes to the treasury [5].
    • The current system is largely digital, with most money existing as numbers in computer systems [6].
    • This system is a form of fiat money, meaning it is not backed by any physical commodity like gold [7, 8].

    Evolution of the Monetary System:

    • Historically, various forms of money coexisted, including private bank notes [5, 6].
    • Prior to 1844, private banks created their own banknotes, but this led to instability and inflation [5, 6].
    • In 1844, the power to create paper money was given to the Bank of England, but this did not include electronic forms of money [6].
    • The gold standard was a system where currencies were pegged to gold, but this system broke down after World War I and was replaced by the Bretton Woods system, where currencies were pegged to the dollar, which was in turn pegged to gold [7, 9]. This system ended in 1971, leading to the current system of floating exchange rates [7, 10].

    Key Components of the Modern Monetary System:

    • Commercial Bank Money: The digital money created by commercial banks when they make loans. This is the largest component of the money supply [2, 5, 6].
    • Central Bank Reserves: An electronic form of cash that banks use to make payments between each other. These are held at the central bank and are not accessible to the public [11, 12].
    • Fractional Reserve Banking: The practice where banks lend out most of the money they receive as deposits, while keeping a small amount in reserve. However, the sources indicate that quantitative easing has rendered this system largely meaningless [9].
    • Debt: The current system is debt-based. New money is created when banks make loans, which creates debt [3, 4].

    Consequences of the Current System:

    • Instability: The system is inherently unstable and prone to boom and bust cycles [1, 3].
    • Debt Dependence: The economy is forced to borrow from banks to have money in circulation [3, 4].
    • Inflation: The creation of money by private banks for nonproductive use causes inflation, which is a tax on the purchasing power of the medium of exchange [8, 13].
    • Wealth Inequality: The system transfers wealth from the poor to the rich [14, 15].
    • Financial Crises: The system is prone to financial crises and requires government intervention to bail out banks [11, 15, 16].
    • Lack of Democratic Control: Private banks control the majority of the money supply and can allocate it according to their own priorities rather than the needs of society [2, 11].
    • Speculation: The system encourages speculation, particularly in assets like housing, which can lead to bubbles [17-19].

    Alternatives to the Current System:

    • Some propose a new currency backed by a scarce resource like energy [20].
    • Others suggest using a basket of currencies or commodities to back up international currencies [20].
    • Direct credit regulation where central banks determine the amount of credit creation needed to achieve desired economic growth and allocate it to specific sectors, limiting purely speculative transactions [13, 21].

    Global Implications:

    • The current system allows dominant countries to exert power and control over others [1, 22-24].
    • The system can lead to currency wars, where countries devalue their currencies to gain a competitive advantage [10, 25].
    • Developing countries are often forced to adopt policies that benefit richer countries, leading to dependence and a loss of sovereignty [23, 24, 26].
    • The system can lead to financial warfare and crises caused by rapid withdrawal of currencies or speculative attacks that force countries to deregulate their markets and conform their financial systems to that of the dominant party [22, 23, 27].
    • International organizations like the IMF can impose conditions on countries facing debt problems, often leading to cuts in public spending and the privatization of industries [24, 26].

    In conclusion, the sources describe a monetary system that is complex, unstable, and prone to abuse. The system is largely controlled by private banks and is based on debt, leading to significant economic and social consequences, and some are advocating for reforms to create a fairer and more stable system [1, 20, 28].

    Economic Crises: Causes, Characteristics, and Solutions

    An economic crisis is a recurring feature of the current monetary system, according to the sources, which describe a system that is inherently unstable and prone to boom and bust cycles [1, 2]. Here’s a breakdown of how the sources explain the causes, characteristics, and consequences of economic crises:

    Causes of Economic Crises:

    • Debt-Based Money System: The current system is fundamentally debt-based, meaning that new money is created when banks issue loans [3, 4]. This creates an incentive for banks to lend as much as possible, leading to excessive debt accumulation [2].
    • Private Bank Control of Money Creation: Private banks create the vast majority of new money in circulation, and they allocate this money according to their own priorities, not necessarily those of society [3, 5]. This can lead to speculative bubbles and misallocation of resources [2].
    • Speculation and Asset Bubbles: The system encourages speculation, particularly in assets like housing [6, 7]. When too much money chases too few goods or services, it causes inflation, and when this inflation occurs in specific sectors, it can lead to asset bubbles [8]. These bubbles eventually burst, triggering economic downturns [2, 7].
    • Lack of Regulation: The lack of effective regulation allows banks to engage in risky practices, further contributing to instability [9, 10].
    • Boom and Bust Cycle: The system inherently creates a boom and bust cycle. During booms, it becomes easier to borrow, leading to even more debt, until some borrowers default and a wave of defaults ripples across the economy [11].
    • International Imbalances: Countries can accumulate trade imbalances, where they spend more than they earn and have to borrow from abroad [12, 13]. These imbalances can lead to financial instability when the ability to repay debts is called into question [13].
    • Currency Wars: Countries may engage in competitive devaluations, where they try to lower the exchange rate of their currency, which creates instability in the global economy [13, 14].
    • Financial Warfare: Rapid withdrawals of a nation’s currency or speculative attacks can cause financial crises, particularly in developing countries that are then forced to deregulate their markets [15, 16].

    Characteristics of an Economic Crisis:

    • Bank Insolvency: As defaults rise, banks become insolvent and stop lending, which exacerbates the recession [11].
    • Credit Crunches: The banking system seizes up when banks do not have enough central bank reserves to make payments [17, 18].
    • Recession: The economy shrinks, leading to job losses and increased dependence on debt [11, 19].
    • Increased Poverty: Economic crises drive people into poverty [20].
    • Mortality increases: The mortality statistics of people who go into poverty rise [20].
    • Transfer of Risk to Taxpayers: Governments often bail out banks to prevent a complete collapse of the system. This transfers the risk from the banks to the taxpayers, often through austerity measures [21, 22].
    • Increased Public Debt: Government bailouts and other measures increase public debt, leading to policies like spending cuts and privatization of public services [22].
    • Increased Private Debt: The government shifts debt from the public sector to the private sector which is essentially a way of transferring risk from the government to individuals [22].

    Consequences of Economic Crises:

    • Increased Debt: The system ensures that debt will continue to rise, even when economies recover. This means the debt will eventually become too much, and the cycle will repeat [23].
    • Wealth Inequality: Economic crises exacerbate wealth inequality, with the poor and middle classes bearing the brunt of the negative effects [24, 25]. The system effectively redistributes wealth from the poor to the rich, and from small businesses to the financial sector [21, 25].
    • Lower Standard of Living: The system leads to a gradual decrease in the standard of living as real incomes decline and people become more dependent on debt [24, 25].
    • Loss of Democratic Control: The dependence of governments on the financial markets and international organizations like the IMF can undermine democratic control and lead to policies that benefit the financial sector over the public [26].
    • Erosion of Public Services: Governments often implement austerity measures, including cuts to public services and privatization of assets, in response to economic crises [22].

    Responses to Economic Crises:

    • Government Bailouts: Governments often bail out banks to prevent a complete collapse of the system [5, 21]. However, this perpetuates the existing system [5].
    • Austerity Measures: Governments implement spending cuts and tax increases to reduce public debt and deficits [22].
    • Quantitative Easing: Central banks increase the money supply to try and stimulate the economy [18].

    Potential Solutions/Reforms:

    • Monetary Reform: The sources suggest the need for a fundamental reform of the monetary system to prevent banks from creating money as debt [23].
    • Direct Credit Regulation: Central banks could determine the necessary amount of credit creation to achieve desired economic growth and allocate it to specific sectors, limiting purely speculative transactions [24, 27].
    • Currency Backed by Scarce Resources: One proposal is to create a new currency backed by something scarce and valuable like energy or renewable energy [28].
    • Basket of Currencies or Commodities: Another suggestion is to back international currencies with a basket of different currencies or commodities [28].
    • Regulation of Financial Markets: The sources call for increased regulation of financial markets to prevent risky practices and excessive speculation [6, 11, 27].
    • Democratic Control over Money Creation: If new money is to be created by any entity, then there should be some democratic control over how that money is used [5].

    In conclusion, the sources portray economic crises as an inherent feature of the current monetary system, driven by debt-based money creation, private bank control, and speculative practices. These crises lead to a range of negative consequences, including increased debt, inequality, and reduced living standards. The sources emphasize the need for fundamental reforms to create a more stable and equitable system [28, 29].

    Bank Regulation and Monetary Reform

    Bank regulation is a critical issue discussed in the sources, particularly in the context of the current monetary system’s instability and its tendency to create economic crises [1-39]. The sources argue that insufficient regulation of banks is a major factor contributing to economic instability, inequality, and the recurring boom and bust cycles [1, 7, 9, 16, 36].

    Here’s a breakdown of the key points regarding bank regulation, according to the sources:

    • Deregulation as a Problem: The sources suggest that the deregulation of the financial system, particularly since the 1970s, has exacerbated the problems associated with the current monetary system [15, 35, 36]. This deregulation has allowed banks to engage in increasingly risky behavior without sufficient oversight.
    • Lack of Control Over Money Creation: Currently, private banks create the vast majority of new money in circulation as debt [2-4]. This gives them significant power over the economy and its direction [10]. The sources argue that this process should be subject to greater democratic control to ensure money is used for the benefit of society, not just the banks’ profits [10].
    • Inadequate Reserve Requirements: Traditionally, banks were required to hold a certain percentage of their deposits in reserve. However, the sources indicate that in recent times, these reserve requirements have been weakened or eliminated [13]. The introduction of quantitative easing has made the fractional reserve system largely meaningless [13].
    • Speculative Lending: Banks tend to prioritize lending for speculative purposes, such as mortgages, over productive investments like small businesses [17]. This is partly due to the perceived lower risk associated with secured loans, but it also leads to asset bubbles and distorts the economy [16, 17]. There is an argument that banks should be incentivized to make loans for productive purposes [19].
    • Failure of Self-Regulation: The idea that financial markets are self-regulating and stable has been proven false by the 2008 financial crisis [36]. The belief that markets would resolve all problems of exchange is not supported by evidence, rather, the markets require regulation [30, 36].
    • The Need for Direct Credit Regulation: Some sources suggest that central banks should directly regulate credit by determining the desired level of economic growth, calculating the amount of credit creation necessary to achieve it, and allocating this credit across different banks and sectors, suppressing unproductive credit for purely speculative transactions [19, 20].
    • Government Reluctance to Regulate: Governments often show reluctance to regulate the housing market and the amount of money banks put into houses [17]. This reluctance is seen as a reflection of a lack of will to challenge powerful financial markets [19].
    • Regulation as a Smokescreen: Some sources suggest that calls for increased regulation are a smokescreen, focusing on the symptoms rather than addressing the core issue of how money is created [9]. They argue that the focus needs to be on the monetary system itself, not just the banking sector [9].
    • Consequences of Insufficient Regulation:
    • Economic Instability: The lack of effective regulation leads to boom and bust cycles, financial crises, and recessions [1, 7, 9].
    • Wealth Inequality: The system allows banks to extract wealth from the economy, exacerbating income inequality [20-22].
    • Moral Hazard: The knowledge that governments will likely bail out banks in a crisis creates a moral hazard, encouraging risky behavior [22, 23].
    • Erosion of Public Services: In the wake of bank bailouts, governments often resort to austerity measures, including cuts to public services [23, 37].
    • International Implications: The lack of regulation in one country can have significant international consequences, as seen in the global financial crisis [1, 26-35]. This is particularly true when dominant countries fail to regulate their financial systems, creating instability and a loss of sovereignty for developing nations [29, 32-35].

    Potential Regulatory Reforms

    • Monetary Reform: The sources emphasize the need for a fundamental reform of the monetary system, including how money is created, to prevent banks from creating money as debt [24, 38].
    • Democratic Control over Money Creation: There is a strong argument that the creation of new money should be subject to democratic oversight to ensure that it is used for the public good, and not just for the benefit of private banks [10].
    • Direct Credit Regulation: Central banks should determine the necessary amount of credit creation to achieve desired economic growth and allocate it to specific sectors, limiting purely speculative transactions [19, 20].
    • Restrictions on Speculative Lending: Regulations to restrict the amount of lending for speculative purposes, such as housing, and to encourage lending for productive activities are needed [17, 19].
    • Increased Transparency and Oversight: Greater transparency in banking practices and stronger oversight are needed to prevent risky behavior and to hold banks accountable.
    • International Cooperation: International cooperation is needed to create a more stable and equitable global financial system and to prevent regulatory arbitrage, where banks move to jurisdictions with weaker regulations [38].

    In conclusion, the sources highlight a strong need for increased bank regulation, as the current lack of it is a major contributor to economic instability and inequality [1, 7, 9, 16, 36]. The regulation needed extends beyond simply overseeing the banking sector itself, but includes the need for a fundamental reform of the monetary system and democratic control over the creation and allocation of money [10, 24, 38].

    Global Monetary Systems and Economic Inequality

    The sources discuss the global economy primarily in the context of the current monetary system, its inherent instabilities, and the power dynamics it creates between nations. Here’s a summary of the key points:

    Global Monetary System:

    • The current global financial system is characterized by a lack of a fixed exchange rate system and is described as “chaotically organized” [1]. Historically, monetary systems were designed to give the dominant international power an advantage [2].
    • The Bretton Woods system, established after World War II, pegged currencies to the dollar, which was in turn backed by gold. This system was intended to manage imbalances and promote stability [3, 4]. However, this system broke down in 1971 when the US ended the dollar’s convertibility to gold [4, 5].
    • Since then, the global financial system has been characterized by deregulation and the rise of private banks as the primary creators of money [5, 6]. This has led to increased speculation and instability [5, 7, 8].
    • The sources suggest that the current system has evolved to the point that making money from money is more profitable than producing anything at all [9, 10].

    International Trade and Imbalances:

    • Trade imbalances are a major issue [4]. Countries with trade deficits spend more than they earn and must borrow from abroad [11]. This can lead to financial instability if these debts cannot be repaid [4, 11].
    • Foreign exchange reserves are accumulated by countries with trade surpluses [12]. However, these reserves cannot be directly used for domestic spending; they can only be used abroad or for imports [12].
    • The sources describe a situation where some countries have accumulated large surpluses while others have accumulated large debts [11]. This is an unsustainable situation and can lead to economic crises [11].
    • The UK has had a long-term deficit on its visible balance of trade (goods) since the 1980s [12].
    • Currency wars occur when countries competitively devalue their currencies to boost exports [11]. This can lead to instability as other nations retaliate by doing the same [1, 11].
    • There are no mechanisms to reconcile trade imbalances in the international economy [12].

    Financial Speculation and Instability:

    • Financial speculation has become a dominant feature of the global economy [10]. Currency trading has become the largest and most liquid market in the world, with trillions of dollars being exchanged daily [1, 13].
    • Volatility in financial markets can cause instability, especially for developing countries [13].
    • Financial contagion is the rapid spread of financial instability from one country to another [14].
    • Speculative attacks can cause a country’s currency to collapse [10].

    Power Dynamics and Inequality:

    • The current monetary system gives enormous power to the dominant international power [2]. This has led to a form of “economic warfare”, where rich countries use their financial power to control poorer countries [10, 14].
    • The International Monetary Fund (IMF) is described as an institution that enforces the current global financial system by imposing conditions on countries with debt problems. These conditions often include deregulation and cuts to public spending, which can harm developing countries [6, 7].
    • The sources suggest that the current system is designed to make certain people very rich at the expense of a nation’s citizens and taxpayers [15]. It has led to increased wealth inequality, with the rich becoming richer while the poor and middle classes become more dependent on debt [16, 17].
    • The global financial crisis caused by the banking sector drove more than 100 million people back into poverty [18].
    • Some sources suggest that globalization and deregulation have led to a “neoliberal” world order that benefits large corporations and the financial sector at the expense of public well-being [6].
    • There’s an argument that the current system allows private banks to extract wealth from the economy, resulting in a lower standard of living for the majority [15, 19].
    • Developing countries that face debt crises are often forced to restructure their economies, cut public spending, and focus on exports, which does not help them develop their economies [6, 10].

    Possible Solutions and Reforms:

    • The sources propose that the global financial system needs to be reformed to be more stable and equitable [2].
    • A new international agreement, similar to Bretton Woods but with more flexibility, is suggested to regulate the global economy [2].
    • International cooperation is seen as a way to stabilize the international economy by having countries come together to write an agreement that allows currencies to be pegged against baskets of goods or currencies [2].
    • Some propose that backing currencies with scarce resources like energy or renewable energy would be a way to promote investment in those areas [2].
    • Others propose that backing international currencies with a basket of currencies or commodities might help stabilize them [2].
    • The idea of having democratic control over the creation of new money is also discussed, even on the international level [20].

    In summary, the sources paint a picture of a global economy characterized by instability, power imbalances, and increasing inequality. The current monetary system is seen as a major contributor to these problems, with deregulation, speculation, and a lack of effective international cooperation playing key roles. The sources call for fundamental reforms to create a more stable, equitable, and sustainable global economy that benefits all countries and people.

    The System of Money | Inside the Financial Machine | Understanding the Matrix

    By Amjad Izhar
    Contact: amjad.izhar@gmail.com
    https://amjadizhar.blog

  • A Critique of Historical Narratives in South Asia by Hassan Nisar

    A Critique of Historical Narratives in South Asia by Hassan Nisar

    The provided text is a rambling, critical monologue that challenges the historical narratives of various rulers and their impact on India and Pakistan. The speaker disputes claims about the extent and nature of Muslim rule, questioning the fairness and accuracy of historical accounts. They criticize the adoption of Western systems and institutions, arguing they are not genuinely embraced. The speaker also attacks the current political and social systems, suggesting they are based on falsehoods and serve the interests of elites. Finally, the monologue expresses resentment towards the perceived injustices inflicted upon their community throughout history.

    Study Guide: Analysis of “Pasted Text”

    Quiz

    Instructions: Answer each question in 2-3 sentences.

    1. According to the speaker, what is a primary method used by rulers to control populations?
    2. What historical period does the speaker reference when discussing the lack of difference between Hindus and Muslims?
    3. What is the speaker’s perspective on Mahmud Ghaznavi?
    4. How does the speaker describe the relationship between Pakistan and its neighbors?
    5. What is the speaker’s opinion on the portrayal of Muslim rule in the region?
    6. What does the speaker imply about the current state of governance and the judicial system?
    7. According to the speaker, what is the relationship between the rulers and the education of their people?
    8. What does the speaker say about the accomplishments of rulers?
    9. What does the speaker suggest is not native to their own culture?
    10. What does the speaker state about the renaming of places and its significance?

    Quiz Answer Key

    1. The speaker claims that rulers exploit illiterate, ignorant, and emotional people, similar to how they believe Muslims are taught. They suggest this is a common tactic used to control and manipulate populations for their own benefit.
    2. The speaker mentions the time of Barr Sagir (likely referring to the Indian subcontinent) where they believe there was no difference between Hindus and Muslims and that a Mughal prince incited rebellion; the Rajputs also fought amongst themselves.
    3. The speaker defends Mahmud Ghaznavi to a degree and considers him a robber.
    4. The speaker suggests that Pakistan is treated poorly by its neighbors, while it is innocent, and is the voice of innocence. The text alludes that the surrounding behavior has affected Pakistan.
    5. The speaker argues that the Muslim rule is misrepresented; a few years is not a long time. They believe the duration and nature of their governance has been incorrectly portrayed.
    6. The speaker implies that the current systems, such as the civil service, judicial and political systems, are not native and have been adopted without any true reform of values. They believe these systems are flawed, are often taken advantage of, and are not working as intended.
    7. The speaker implies that a ruler should be a teacher but the text mentions poor education, insinuating a failure to educate the population.
    8. The speaker states that rulers do nothing and the results are zero. They believe rulers focus on creating superficial results and do not build real lasting positive change.
    9. The speaker suggests that a multitude of modern advancements, including the civil service, judicial system, and even basic infrastructure (like flush toilets), are not native to their culture.
    10. The speaker suggests that the renaming of places reflects a deeper shift in ideology and erasure of history, citing personal experiences with the names of the city where he lives.

    Essay Questions

    Instructions: Compose a well-organized essay for each prompt, incorporating evidence from the source material.

    1. Analyze the speaker’s perspective on the historical narratives surrounding the region. How does the speaker’s account challenge or contradict common understandings of history?
    2. Examine the speaker’s criticism of existing political and social systems. What specific aspects do they target and what alternative do they seem to advocate for?
    3. Discuss the speaker’s use of “us” versus “them” language. What are the implications of this linguistic framework in understanding the speaker’s worldview?
    4. Explore the speaker’s stance on colonialism and its lasting impact. How do they connect the colonial past with present social and political issues?
    5. Consider the speaker’s overall message. What are the key themes and what broader arguments does the speaker want the audience to consider?

    Glossary of Key Terms

    • Barr Sagir: A term that refers to the Indian subcontinent. Often used in the context of historical and cultural discussions relating to this region.
    • Mughal Prince: In this context, referring to a member of the Mughal dynasty, which ruled much of the Indian subcontinent for centuries.
    • Rajputs: A clan that had an important role in the history of the Indian subcontinent, often known for their warrior traditions and rivalries.
    • Mahmud Ghaznavi: An Islamic conqueror from the 11th century, known for his military campaigns and looting raids, but also for patronage of culture.
    • Shari: Likely refers to Sharia, the religious law of Islam.
    • Chakla: A colloquial term referring to a red light district or place of prostitution, which the speaker uses to imply corruption and misrule.
    • Jat/Gujjar/Ra/Fala: Refers to various castes and communities, the speaker mentions these in the context of corruption within government and that it was not an issue with white people.
    • Sultanate of Delhi: Refers to various Muslim rulers who governed Delhi from the late 12th century to the early 16th century.
    • Caliphate: Refers to a political-religious system of government led by a Caliph, considered a successor of the Prophet Muhammad.
    • Kaiser-Kasra: A reference to ancient Persian emperors, symbolizing power, and in this case, the downfall of such empires.
    • Ayesha Jalal: A South Asian historian and scholar. The speaker is referring to her historical analysis and views on the political and historical narrative of Pakistan.
    • Khawaja Asaf: A Pakistani politician. The speaker is referring to their political views on how history has been used to inform ideology.
    • Lyallpur/Faisalabad: The name of a city that was originally called Lyallpur, and then renamed Faisalabad. The speaker seems to resent the renaming.
    • Sir James Lyall: A British colonial administrator after whom Lyallpur was named. The speaker uses his story to critique the history surrounding it.

    A Critical Analysis of Indian History and Governance

    Okay, here’s a briefing document summarizing the key themes and ideas from the provided text excerpt.

    Briefing Document: Analysis of “Pasted Text”

    Document Overview: This document analyzes a transcribed text excerpt which appears to be from a spoken monologue or interview. The speaker expresses a series of often disjointed and emotionally charged thoughts about history, power, identity, and governance, particularly focusing on the Indian subcontinent and its historical interactions with Muslim rule, British colonialism, and contemporary political dynamics. The tone is often critical, accusatory, and at times, appears conspiratorial.

    Key Themes and Ideas:

    1. Critique of Rulers and Exploitation:
    • Theme: The speaker strongly condemns rulers (including, but not limited to, Narendra Modi) for exploiting the “illiterate, ignorant, and emotional” populace. This exploitation is framed as a historical pattern, not a modern phenomenon, with the speaker comparing it to manipulation by past rulers.
    • Quote: “Rulers like Narendra Modi do this to exploit illiterate, ignorant and emotional people. Just like Muslims, this is what is taught to us also.”
    • Analysis: This establishes a recurring theme of power being abused by those in charge, regardless of religious or national affiliation. There’s a sense of victimhood portrayed on the part of “the people” who are seen as easily manipulated by these leaders.
    1. History as a Source of Conflict and Identity:
    • Theme: The speaker sees history, particularly the history of Muslim rule in the Indian subcontinent and the subsequent British colonial era, as a major source of division and conflict. They argue that this history is selectively used to perpetuate divisions and misunderstandings.
    • Quote: “This is the population, there was no difference between Hindus and Muslims, the Mughal prince rebelled and let them go with him, the Rajputs fought and quarreled and even today this is the biggest identity of our country…”
    • Analysis: This statement challenges the traditional narrative of a deeply ingrained Hindu-Muslim divide, suggesting it’s a more recent construction driven by political motivations. The speaker also hints that internal conflicts are also a cause of disunity.
    1. Reinterpretation of Historical Narratives:
    • Theme: The speaker actively seeks to debunk established historical narratives. They challenge the conventional view of Muslim rule as solely exploitative, pointing out some of the achievements during that period. They even try to justify Mahmud of Ghazni’s actions by saying he was not the only one guilty of robbery.
    • Quote: “Aswar has said only one decent thing in the last one and a half years that Mahmud Ghaznavi was a robber and I defended him, I defended him, the rest is all a lie…”
    • Analysis: This demonstrates a desire to challenge dominant narratives and present a more nuanced perspective on historical figures and events, although this perspective is itself subject to debate.
    1. Critique of Post-Colonial Systems and Institutions:
    • Theme: The speaker is extremely critical of the present-day political, judicial, and administrative systems, seeing them as mere imitations of colonial systems that lack authenticity and are inherently flawed.
    • Quote: “Your entire civil service system, your judicial system, your political system, nothing is yours…”
    • Analysis: This paints a picture of a post-colonial society that has not been able to escape the shadow of its past, and that lacks independent agency, innovation and direction.
    1. Emphasis on Material Dependency and Lack of Originality:
    • Theme: The speaker emphasizes a pervasive dependence on foreign technology and systems. They use this as an argument against the claim of independence or success.
    • Quote: “like the MACHINE is not yours, the injection is not yours, the car is not yours, the camera is not yours, the electricity is not yours The car is not yours, it is not yours there is nothing in this world that can be compared with your life…”
    • Analysis: This paints a picture of a society dependent on outside forces for their development, lacking in the innovation that it needs to be truly independent.
    1. Critique of Identity Politics and Name Changes:
    • Theme: The speaker is critical of renaming cities and locations based on changing political and religious narratives, suggesting it’s a superficial attempt to rewrite history rather than acknowledging it.
    • Quote: “I am a resident of Lyallpur, I have never said Faisalabad till date, you sycophants, if you want to flatter me by some beautiful name Name King Faisal’s city after him…”
    • Analysis: This highlights how changing names can be seen as manipulative and disconnected from the history of these locations. It calls for preserving the continuity of place names, in contrast to political changes.
    1. The Use of Rhetorical Devices and Emotion:
    • Theme: The language is highly emotive, often using strong accusatory words, and sweeping generalizations. There’s a lack of formal argumentation and the speaker relies heavily on rhetorical questions, personal anecdotes, and a stream-of-consciousness style, making it challenging to pinpoint factual claims within the emotional delivery.
    • Analysis: The tone and manner of speech suggest this is not an academic essay, but an outpouring of feeling. This has implications for interpreting the accuracy and validity of the claims made in the text.

    Overall Interpretation:

    The speaker in this excerpt appears to be a deeply critical individual, disillusioned with the current state of affairs in the Indian subcontinent. They view history as a tool of manipulation, and see modern systems as flawed and derived from colonial influences, lacking any true independence. The speaker expresses a sense of frustration and anger towards perceived injustices and manipulation by rulers across the ages. There is a strong undertone of a desire for authenticity and a genuine national identity, free from the shackles of historical and foreign influences, and from what is perceived as manufactured divides between different groups of people.

    Further Research:

    To better understand the context of this text, further research into the following would be beneficial:

    • The speaker’s background and political affiliations.
    • Specific historical events and figures mentioned (e.g., Mahmud Ghaznavi, the Mughal rulers, Sir James Lyall).
    • The context of the quote from Ayesha Jalal and Khawaja Asif.
    • The intended audience of the discourse.

    This document should provide a solid foundation for understanding the complexities and nuances within the provided text.

    Historical Critiques of South Asia

    FAQ: Historical Perspectives and Societal Critiques

    1. The speaker claims that people have been enslaved for centuries. Who are these people and what is the speaker’s view on the role of rulers in this process?

    The speaker asserts that people have been enslaved for centuries, specifically citing those in the Indian subcontinent. They attribute this enslavement to rulers like Narendra Modi, accusing them of exploiting illiterate, ignorant, and emotional populations. The speaker argues that such rulers, similar to those in the past, indoctrinate their people to maintain power. This critique suggests a pattern of manipulation and oppression throughout history.

    2. The speaker discusses the historical relationship between Hindus and Muslims in the region. What is the speaker’s take on the past interactions?

    The speaker claims that historically there was not a major difference between Hindus and Muslims, instead focusing on the actions of specific people in power. The speaker references a Mughal prince rebelling and the subsequent divisions and quarrels. They see this conflict as an ongoing legacy that shapes modern identities in the country. The speaker is implying that the historical tensions are not necessarily based on fundamental differences but rather on the consequences of political maneuverings and power struggles.

    3. The speaker references various ethnic groups in the region, including those of Arab and Central Asian descent. What point is the speaker trying to make?

    The speaker uses the presence of Arab, Central Asian, Iranian, and Afghan ancestry to highlight the complex demographic makeup of the region. They suggest that the concept of a unified or pure identity is a myth, as the population is an amalgamation of various origins. This serves to challenge any singular or simplified narrative about ethnicity and origin in the region. They also suggest that the idea of a uniquely shared heritage is false and these origins are sometimes ignored, despite being the origins of large parts of the populace.

    4. The speaker mentions historical figures like Mahmud Ghaznavi. How does the speaker interpret this figure and what is the significance of the reference?

    The speaker presents a nuanced view of Mahmud Ghaznavi, whom they initially defended against claims of him being a robber, before then admitting they were wrong and that he was indeed a robber. This highlights an evolution in the speaker’s understanding and criticism, while also noting the general population’s perspective of him as a “robber” The reference to Mahmud Ghaznavi serves as a broader reflection on historical narratives, especially in the context of the region’s history.

    5. The speaker claims the current judicial, political and civil service systems are not original. What are the bases of these claims?

    The speaker argues that the current systems are not original to the people, pointing to the influence of colonial powers. They argue that these systems, along with other technologies and infrastructure (like railways, flush systems, cars and electricity) are imports, not things created locally. They claim they have been poorly adopted or that the people are merely imitating the systems of others, without any true understanding or ownership.

    6. The speaker brings up the issue of inheritance and corruption in the region. What’s the core of this issue according to them?

    The speaker criticizes the mismanagement and corruption related to inherited resources and systems. They point out instances where resources given by others (e.g., steel mills, funds from various countries) were squandered. This highlights a broader issue of inefficiency, a lack of accountability, and a tendency to misuse both material and systemic resources within the region.

    7. The speaker criticizes the way in which history is handled post-partition. What are they saying about this?

    The speaker references the ideas of Ayesha Jalal, who argues that the Pakistani state has replaced post-partition history with ideology. This shows a concern that objective history is being manipulated to fit an ideological agenda, resulting in a skewed understanding of the past. This suggests a critique of nationalistic narratives that prioritize ideological correctness over accurate historical representation.

    8. The speaker objects to the changing of names of places like Lyallpur to Faisalabad. What is the significance of this and what does it represent to the speaker?

    The speaker objects to the renaming of Lyallpur to Faisalabad and other places, viewing it as an attempt to erase history and replace it with symbolic figures or ideology. The speaker is a resident of Lyallpur, and feels that the practice of renaming is “shamelessness” and “obscenity”. The speaker believes that historical names and landmarks should be kept to remind people of their full history rather than just that of the most recent political iteration. This signifies that the speaker values the historical significance of original names and views the practice of renaming as an act of historical revisionism and sycophancy, and that names are a historical record, and that any re-naming is a form of rewriting history.

    A History of Governance in Pakistan

    Okay, here is a detailed timeline and cast of characters based on the provided text:

    Timeline of Events and Themes

    This timeline is structured more thematically, as the provided text jumps between historical periods and anecdotes without strict chronological order.

    • Ancient/Pre-Medieval Period (Pre-1000 AD):
    • Salati Delhi: Reference to a “glamorous treasure” of Delhi a thousand years ago. This likely alludes to a powerful, wealthy era of the city.
    • Arab & Central Asian Migrations/Incursions: Indication that a significant population in the region has ancestry from Arab, Central Asian, Iranian, and Afghan regions. This is presented as an important, although often glossed-over, aspect of the population’s heritage.
    • Medieval Period (1000 AD – 1700s AD)
    • Mahmud Ghaznavi: Mention of Mahmud Ghaznavi as a “robber”, an assessment that one narrator initially defended. This suggests a historical debate about Ghaznavi’s legacy.
    • Sultanate of Delhi & Mughals: These empires are mentioned as examples of past rulers, with a focus on their legacy in modern governance. There is a suggestion that current governance structures draw from this period. The speaker contrasts this with an idealized notion of rulers being “teachers.”
    • Ibrahim Lodi: Mentioned as having been killed by “brother Zahir Babar” (likely referencing Babur).
    • Muhammad bin Qasim: Mentioned as having been defeated twice in Sindh, then sent by Jaz bin Yusuf. The text mentions he died, and another Caliph was then appointed. The events here are meant to be indicative of the ruthlessness of the era.
    • Spoils of War: Reference to the distribution of spoils after conquests, specifically how bracelets of Kaiser-Kasra were divided among Muslims. This highlights the nature of conquest and early Islamic rule.
    • British Colonial Period (1700s-1947)
    • British Rule: The text argues that many modern systems and technologies weren’t created by the current inhabitants of the region and that modern infrastructure like railways and steel mills were gifts of previous colonizers.
    • British Judicial System: The text criticizes the contemporary judicial system by implying that it’s merely a continuation of the British system. Summer vacations are mentioned, which are said to be the result of the need of the British (coming from colder climes).
    • Sir James Lyall: Mention of Sir James Lyall (likely during his tenure as Lieutenant Governor of the Punjab), specifically in relation to the naming of Lyallpur (modern Faisalabad). An anecdote about him suffering in the summer heat is used to emphasize the history of Lyallpur.
    • Post-Partition Pakistan (1947-Present)
    • Post-Partition History as Ideology: Ayesha Jalal’s viewpoint is cited that the Pakistani state has replaced post-partition history with ideology. This suggests the state is using a skewed account of the past to fit its modern nationalistic goals.
    • Modern Governance and Legacy: The speaker asserts that Pakistan’s civil service, judicial, and political systems are not truly their own but carry the vestiges of past rulers (Sultanate/Mughal, then the British), and are not designed to properly serve the present populace.
    • Social Injustice: The text mentions ongoing social issues, such as people being “picked up” in certain areas, suggesting a critique of authoritarian trends.
    • Critique of Democracy and Dependence: The text is critical of the adoption of western democracy (seen as imitation) and highlights an ongoing reliance on foreign-made products and technologies.
    • Internal and External Problems: The text juxtaposes a call for “innocent children” and “citizens” who are not being treated well, while suggesting that the treatment was brought on by poor training and governance. This is implicitly related to current conflicts or perceived injustices.
    • Contemporary (2004-Present):
    • 2004 Conflict: There is a mention of “what our neighbor is doing to us in 2004” – suggesting a specific incident that impacted the author or community being discussed.
    • Naming of Places: Criticisms of renaming places from original names to names of leaders. The example given is the renaming of Krishna Nagar to Islam Pura, and Lyallpur to Faisalabad.
    • Status Updates: The speaker mentions that statuses are not done “like this,” implying that social media or public opinion is shaping historical discourse.

    Cast of Characters

    • Narendra Modi: Modern Indian politician mentioned as an example of rulers who exploit the populace. No further information is provided in this document about him.
    • Mahmud Ghaznavi: A controversial historical figure, an 11th-century Turkic ruler who is portrayed as a “robber” in the text, with a counterpoint that he was defended at some point.
    • Ibrahim Lodi: The last Sultan of the Delhi Sultanate, mentioned as being killed by “Zahir Babar” (Babur), highlighting the end of one dynasty and beginning of the Mughal rule.
    • Zahir Babar/Babur: Mentioned as the conqueror who killed Ibrahim Lodi. He was the first Mughal emperor.
    • Muhammad bin Qasim: 8th-century Umayyad general who led the Muslim conquest of Sindh. The text portrays him as someone who was defeated, replaced and whose death is part of the story of the ruthlessness of the era.
    • Jaz bin Yusuf: A person who sent Muhammad bin Qasim into Sindh after his defeat.
    • Ayesha Jalal: A scholar whose work is cited, who says the Pakistani state has replaced post-partition history with ideology.
    • Khawaja Asif: A Pakistani politician whose statement is cited. He is mentioned as being connected to the Ayesha Jalal statement.
    • Sir James Lyall: A British administrator, Lieutenant Governor of Punjab, referenced in connection with the naming of Lyallpur.
    • King Faisal: King of Saudi Arabia, after whom Faisalabad was named.
    • Unnamed “Maulana”: Referenced in the context of a confusing situation needing to be “sorted out,” suggesting religious authority or influence.

    Key Takeaways from the Text

    • The text presents a critique of the narrative of history and how it is used to shape national and political identity.
    • There is a strong emphasis on the idea that much of current structures and systems in Pakistan aren’t actually the product of the people but are either a carry-over from past empires or foreign powers.
    • The text raises concerns about social justice, exploitation, and the authenticity of current governance, using historical events to highlight contemporary issues.
    • There’s a sense of loss of originality and identity, as well as an argument that the populace is being kept in a state of dependence and disempowerment.

    This analysis should provide a solid framework for understanding the complex ideas presented in the text.

    Historical Injustices and the Manipulation of Narratives

    The source discusses historical injustices and their impact on the present, focusing on the exploitation and manipulation of populations by rulers and the distortion of historical narratives [1].

    Here’s a breakdown of the key points:

    • Exploitation by Rulers: The source asserts that rulers, such as Narendra Modi, exploit “illiterate, ignorant and emotional people” [1]. This echoes a broader historical pattern of rulers manipulating populations for their own gain. This claim is generalized by stating “these rulers ruled over Barr Sagir for 100 years” [1]. The text also claims this is part of a common history where “there was no difference between Hindus and Muslims” [1].
    • Distortion of History: The source claims that “the Pakistani state has replaced post partition history with ideology” [1], which suggests a deliberate manipulation of historical narratives to suit particular agendas. It is claimed that this is a result of a lack of actual history, “there is no such thing as history here” [1].
    • Colonial Legacy: The text points out that many of the systems and technologies used today are not of local origin, citing examples like the civil service, judicial, and political systems, machines, cars, electricity and even the flush toilet system [1]. These items are said to be not “yours,” indicating a lasting legacy of colonial rule and dependence [1]. The text also refers to a time when “there was no railway here, it was their kindness” [1] suggesting that even some of the beneficial developments are also products of colonial rule.
    • Internal Conflicts: The source touches on historical conflicts and betrayals, noting that many heroes were killed by their own people [1]. The source also discusses divisions between ethnic groups as a factor contributing to societal and political problems, claiming that the white people had a comfort in that “there was no Jat in it, no Gujjar, no Ra, no Fala, no check post, no way” [1].
    • Economic Exploitation: The text implies that resources and wealth have been squandered or misused [1]. It is claimed that “the Russians gave you the steel mill as charity and you ate up that money as well” [1].
    • Name Changes: The source uses the examples of Lyallpur/Faisalabad and Krishna Nagar/Islam Pura to illustrate a desire to rewrite the past by changing place names [1]. This suggests a deeper agenda to erase previous histories [1].

    In summary, the source presents a critical perspective on historical injustices, emphasizing themes of exploitation, manipulation, and the lasting effects of colonial rule. The source suggests that many of the systems and structures in place are not of local origin and that history has been manipulated for political and ideological purposes [1].

    Political Exploitation and the Distortion of History

    The source discusses political exploitation in several ways, highlighting how rulers manipulate populations and distort history for their own gain [1].

    • Manipulation of the Masses: According to the source, rulers exploit “illiterate, ignorant, and emotional people” [1]. This suggests a deliberate strategy of targeting vulnerable populations to maintain power. The source uses the example of Narendra Modi as a contemporary example and states “these rulers ruled over Barr Sagir for 100 years” implying it is part of a continuing historical pattern [1].
    • Historical Revisionism: The source asserts that “the Pakistani state has replaced post-partition history with ideology” [1]. This indicates a political strategy of manipulating historical narratives to serve a specific agenda, suggesting that the current political system is built on a foundation of distorted historical facts. The source claims this is due to a lack of actual history stating “there is no such thing as history here” [1].
    • Perpetuation of Colonial Systems: The source states that many systems, such as the civil service, judicial, and political systems, are not of local origin and are part of a colonial legacy [1]. The source also claims that “there was no railway here, it was their kindness” suggesting that even some of the beneficial developments are products of colonial rule [1]. This implies that these imposed systems can be tools of political exploitation, because they are not organically grown from the needs and values of the population being ruled.
    • Internal Conflicts and Divisions: The text mentions that the rulers of the past, “from the Sultanate of Delhi to the Mughals” and how they fought among each other. The text also points out how “your countless heroes whose names you chant were killed by their own people” [1]. Further, the text also says “the white people had one comfort that there was no Jat in it, no Gujjar, no Ra, no Fala, no check post, no way” [1]. This indicates how political systems use pre-existing social divisions to maintain power, even in the absence of overt foreign rule.
    • Resource Mismanagement: According to the source, resources and wealth have been squandered or misused. It is claimed that “the Russians gave you the steel mill as charity and you ate up that money as well”. This implies that rulers use political power to exploit the population for personal gain rather than using resources for the good of the people [1].
    • Erasure of the Past: The source cites name changes like Lyallpur to Faisalabad and Krishna Nagar to Islam Pura [1]. This act of renaming is indicative of a political effort to rewrite the past and impose a new identity, which is another way to maintain power over the population by controlling the narrative of history [1]. In summary, the source highlights various methods of political exploitation, including manipulation of the masses, distortion of history, the imposition of colonial systems, the utilization of social divisions, the mismanagement of resources, and the erasure of the past to consolidate power [1].

    Cultural Dispossession and the Illusion of Ownership

    The source discusses several aspects that relate to cultural appropriation, although it does not use the term directly. Here’s a breakdown of how the source addresses concepts related to cultural appropriation:

    • Imitation and Lack of Authenticity: The source suggests that many aspects of the current society are imitations of foreign systems and technologies. It is stated, “your entire civil service system, your judicial system, your political system, nothing is yours, like the MACHINE is not yours, the injection is not yours, the car is not yours, the camera is not yours, the electricity is not yours”. This implies that the country has adopted systems and technologies without fully integrating them into its own culture or context, thus lacking authenticity. This is reinforced with the examples “the car is not yours” and “the flush system, is it yours”. The text claims that even the adoption of democracy was in “imitation of them”. This suggests a surface level adoption without understanding the underlying values and principles.
    • Colonial Legacy and Imposed Systems: The source points out that many systems and technologies used today are not of local origin, indicating a lasting legacy of colonial rule. It is stated that “till date there was no railway here, it was their kindness”. The imposition of these foreign systems can be viewed as a form of cultural appropriation, where the colonizers’ ways of life and governance are imposed on the local population, supplanting or undermining their own traditions and systems.
    • Misuse and Mismanagement: The text implies that resources and wealth have been misused and squandered, “the Russians gave you the steel mill as charity and you ate up that money as well”. This suggests a failure to steward resources appropriately after they were adopted.
    • Name Changes as Cultural Erasure: The source cites the examples of Lyallpur being renamed Faisalabad and Krishna Nagar being renamed Islam Pura. This act of renaming is indicative of a political effort to rewrite the past and impose a new identity. The changing of names can be seen as an attempt to erase the cultural heritage associated with those places, replacing it with new, ideologically driven identities, which can be considered a form of cultural appropriation that leads to the erasure of the past. The source claims that this leads to a “change in the characters of those people”.
    • The idea that ‘nothing is yours’: The source repeatedly says that nothing is “yours,” such as the political system, the technologies and the resources. The source implies a kind of cultural dispossession, where a nation’s identity is so intertwined with what it has borrowed or been forced to adopt that it struggles to find or value what is truly its own.

    In summary, while the term “cultural appropriation” is not explicitly used, the source discusses many themes that relate to it. These include the adoption of foreign systems and technologies without integration or understanding, the imposition of colonial structures and cultural norms, the erasure of history through renaming and the sense of cultural dispossession.

    Historical Revisionism in Pakistan

    The source discusses historical revisionism by highlighting how historical narratives are manipulated for political and ideological purposes [1].

    Here are the key points related to historical revisionism from the source:

    • Rewriting History: The source states that “the Pakistani state has replaced post partition history with ideology” [1]. This suggests a deliberate and systematic effort to change the way history is understood and taught in order to serve current political agendas. This is further supported by the claim that “there is no such thing as history here” [1]. This implies a total rejection of the existing historical narrative and its replacement with an ideological one.
    • Name Changes: The source cites the examples of Lyallpur being renamed Faisalabad and Krishna Nagar being renamed Islam Pura [1]. This act of renaming is presented as a deliberate attempt to erase the past and replace it with a new identity that aligns with the current ideology [1]. This type of historical revisionism aims to reshape cultural identity by changing the names of places and thus their meaning and history [1]. The source claims that this leads to a “change in the characters of those people” [1].
    • Manipulation of Facts: The text also suggests that historical facts are often manipulated or ignored. For example, the text claims that the history of Muslim rule is exaggerated, with the claim that “it is a little less than a thousand in the governance of the people, we generally say that the rule of Muslims Year, it is not true, a few years, 100, 150 years are less but it is a lot, if you have spent 800 years, but you have not spent them as a Shari” [1]. This challenges the commonly accepted narrative of a long history of Muslim rule and suggests a manipulation of the historical timeline [1].
    • Creation of a New Narrative: The source suggests that the rewriting of history is not just about erasing the past, but about creating a new narrative that supports the current political order [1]. This is done by replacing historical facts with ideology and presenting this new narrative as the true history [1].

    In summary, the source highlights how historical revisionism is used to rewrite the past for political gain, through the manipulation of facts, the changing of names, and the replacement of historical narratives with ideological ones [1]. This process not only erases the past, but also shapes the present and future by imposing a new cultural identity and political system [1].

    Contested National Identity

    The source explores the complex and contested nature of national identity, highlighting how it is shaped by historical narratives, political agendas, and cultural influences.

    • Contested Historical Narratives: The source suggests that national identity is often built on manipulated or revised historical narratives [1]. The claim that “the Pakistani state has replaced post-partition history with ideology” [1] indicates that historical revisionism is a tool used to shape national identity. The text claims that “there is no such thing as history here” [1]. This suggests a rejection of existing historical narratives in favor of an ideologically driven one.
    • Imposed Identities: The source implies that national identity is not organically developed, but is often imposed or imitated from external sources [1]. The statement that “your entire civil service system, your judicial system, your political system, nothing is yours” [1] indicates that many of the structures that shape national life are not of local origin. The text also claims “the car is not yours, the camera is not yours, the electricity is not yours” [1] reinforcing the idea that the nation’s identity is built on systems and technologies that are not “yours” [1]. Even the adoption of democracy was in “imitation of them” [1] suggesting a lack of authenticity.
    • Cultural Erasure: The changing of place names, such as Lyallpur to Faisalabad and Krishna Nagar to Islam Pura, is presented as a deliberate attempt to erase cultural heritage and impose a new identity [1]. This shows how national identity is constructed by actively dismantling previous identities and replacing them with ideologically driven ones. The source claims that this leads to a “change in the characters of those people” [1].
    • Internal Divisions: The source highlights how existing social and ethnic divisions are used to manipulate and control populations, even in the absence of direct colonial rule. The text states that “the white people had one comfort that there was no Jat in it, no Gujjar, no Ra, no Fala, no check post, no way” [1]. This suggests how pre-existing divisions are used to maintain power. The text also notes that “your countless heroes whose names you chant were killed by their own people” [1] showing that divisions are not only social or ethnic, but also political, contributing to instability and preventing the development of a unified national identity.
    • Dependence and Lack of Agency: The source claims that there is a sense of cultural dispossession, where national identity is intertwined with what has been borrowed or imposed, leaving a struggle to find or value what is truly one’s own. The repeated claim that “nothing is yours” [1] emphasizes this lack of ownership and agency in the construction of national identity. The source uses the examples “the car is not yours” and “the flush system, is it yours” [1] to emphasize this point. The text also claims that “there was no railway here, it was their kindness” [1] implying that even beneficial developments are external.
    • Manipulation by Rulers: According to the source, rulers manipulate populations to maintain power [1]. The source claims that “rulers like Narendra Modi do this to exploit illiterate, ignorant and emotional people” [1]. This suggests that national identity can be manipulated to serve political purposes. It also claims “these rulers ruled over Barr Sagir for 100 years” [1] generalizing the claim that this is part of a broader historical pattern.

    In summary, the source portrays national identity as a constructed and contested concept, shaped by manipulated historical narratives, imposed systems, cultural erasure, internal divisions, a lack of agency and manipulation by rulers. The source suggests that many nations struggle with a sense of imposed identity, where the systems and narratives that define them are not organically grown but have been shaped by external forces and political agendas.

    By Amjad Izhar
    Contact: amjad.izhar@gmail.com
    https://amjadizhar.blog

  • Al Riyadh Newspaper: February 16, 2025

    Al Riyadh Newspaper: February 16, 2025

    The collection of articles covers a wide array of topics, predominantly focusing on Saudi Arabian news and perspectives. Several articles highlight economic developments, cultural events like book fairs and art exhibits, and the Kingdom’s role in regional diplomacy, particularly concerning peace efforts in Ukraine. Other articles examine Saudi Arabia’s advancements in technology, its efforts toward sustainability and local content development, and its investments in industries such as vaccine manufacturing and film. International news includes reports on conflicts in the Middle East and Ukraine, energy markets, and global economic trends. Finally, some pieces provide coverage of sports, social issues, and cultural identity. The coverage displays Saudi Arabia as a significant economic and cultural force in the Middle East, with a growing global reach.

    Study Guide: Analysis of Excerpts from “20691.pdf”

    I. Quiz: Short Answer Questions

    1. According to the text, what are the main pillars and foundations to which the Saudi government adheres, starting with King Abdulaziz bin Abdulrahman? The main pillars and foundations are the national principles and firm foundations. The text specifically highlights King Abdulaziz bin Abdulrahman’s commitment and that of succeeding leaders to creating a strong and prosperous nation.
    2. Who did the Foreign Minister meet with in Munich and what was the main topic of discussion? The Foreign Minister met with Senator Chris Van Hollen in Munich. The main topic of discussion was regional and international developments, and exchanging views on them.
    3. What is the significance of Saudi Arabia hosting the American-Chinese summit? Hosting the American-Chinese summit underscores the Kingdom’s position and ability to be a key player in international relations and diplomacy. The text suggests the Kingdom was uniquely chosen to host the important summit.
    4. What is the main focus of the Saudi Vision 2030 concerning the cultural sector, as mentioned in the context of the Jazan Book Fair? The main focus is to enhance cultural mobility in the Kingdom by spreading the values of knowledge and creativity, stimulating the local publishing industry, and highlighting the rich cultural heritage of the Jazan region.
    5. What efforts has Saudi Arabia made to help resolve the conflict between Russia and Ukraine? Saudi Arabia has expressed its readiness to make efforts to find a political solution to the crisis, including hosting several meetings related to the issue. This has been a consistent effort over the past three years.
    6. What role does the Saudi Arabian Monetary Authority (SAMA) play in achieving the goals of Vision 2030? SAMA, through its investments, aims to increase its contribution to local content by 60% by the end of 2025 and to raise the contribution of the private sector in the GDP to 65% by 2030, thereby fostering economic growth.
    7. According to the Saudi Ministry of Finance, what has been the general trend with non-oil revenues? Non-oil revenues have exceeded 502 billion riyals, indicating success in diversifying the economy. The goal is to increase these non-oil revenues to a trillion riyals by 2030 to reduce reliance on oil.
    8. What role does Saudi Aramco play in achieving Vision 2030? Saudi Aramco is working to transform its business model to become a fully integrated and globally leading energy and chemical company. It focuses on developing new projects in energy and petrochemicals with lower carbon emissions.
    9. How does the Saudi government support domestic industries through initiatives like the King Salman Economic City? The Saudi government announced the signing of 11 agreements worth 5.5 billion riyals with local companies to attract foreign and local investments to the strategic industry, provide opportunities, and stimulate global companies to manufacture their cars within the Kingdom in the King Salman Complex for Automobile Industry.
    10. How does the King Salman Humanitarian Aid and Relief Center assist other nations? The center provides various forms of assistance to countries in need around the world, including distributing essential goods like dates and supporting various sectors, thereby playing the Kingdom’s customary role in supporting nations facing difficulties.

    II. Answer Key

    1. The main pillars and foundations are the national principles and firm foundations. The text specifically highlights King Abdulaziz bin Abdulrahman’s commitment and that of succeeding leaders to creating a strong and prosperous nation.
    2. The Foreign Minister met with Senator Chris Van Hollen in Munich. The main topic of discussion was regional and international developments, and exchanging views on them.
    3. Hosting the American-Chinese summit underscores the Kingdom’s position and ability to be a key player in international relations and diplomacy. The text suggests the Kingdom was uniquely chosen to host the important summit.
    4. The main focus is to enhance cultural mobility in the Kingdom by spreading the values of knowledge and creativity, stimulating the local publishing industry, and highlighting the rich cultural heritage of the Jazan region.
    5. Saudi Arabia has expressed its readiness to make efforts to find a political solution to the crisis, including hosting several meetings related to the issue. This has been a consistent effort over the past three years.
    6. SAMA, through its investments, aims to increase its contribution to local content by 60% by the end of 2025 and to raise the contribution of the private sector in the GDP to 65% by 2030, thereby fostering economic growth.
    7. Non-oil revenues have exceeded 502 billion riyals, indicating success in diversifying the economy. The goal is to increase these non-oil revenues to a trillion riyals by 2030 to reduce reliance on oil.
    8. Saudi Aramco is working to transform its business model to become a fully integrated and globally leading energy and chemical company. It focuses on developing new projects in energy and petrochemicals with lower carbon emissions.
    9. The Saudi government announced the signing of 11 agreements worth 5.5 billion riyals with local companies to attract foreign and local investments to the strategic industry, provide opportunities, and stimulate global companies to manufacture their cars within the Kingdom in the King Salman Complex for Automobile Industry.
    10. The center provides various forms of assistance to countries in need around the world, including distributing essential goods like dates and supporting various sectors, thereby playing the Kingdom’s customary role in supporting nations facing difficulties.

    III. Essay Format Questions

    1. Analyze the role of Saudi Arabia in international diplomacy and conflict resolution, referring to specific examples provided in the text.
    2. Discuss the significance of Saudi Vision 2030 in transforming the Kingdom’s economy and society, using examples from various sectors highlighted in the source material.
    3. Evaluate the impact of Saudi Arabia’s investment in cultural and entertainment sectors on its national identity and global image.
    4. Assess the strategies Saudi Arabia is employing to diversify its economy away from oil, considering the challenges and opportunities involved.
    5. Explore the ways in which Saudi Arabia is balancing its traditional values with modernization and global engagement, as reflected in the initiatives and events described in the excerpts.

    IV. Glossary of Key Terms

    • Vision 2030: Saudi Arabia’s strategic framework to reduce the country’s dependence on oil, diversify its economy, and develop public service sectors such as health, education, infrastructure, recreation, and tourism.
    • Non-Oil Revenue: Income generated by a country through sources other than oil exports, such as investments, tourism, and various industries.
    • Saudi Aramco: The Saudi Arabian Oil Company, a state-owned petroleum and natural gas company playing a crucial role in the Kingdom’s economy and development.
    • King Salman Humanitarian Aid and Relief Center: A Saudi Arabian center dedicated to providing international humanitarian aid and relief to countries in need.
    • NEOM: A planned cross-border city in the Tabuk Province of northwestern Saudi Arabia, designed to incorporate smart city technologies and serve as a hub for innovation and sustainability.
    • Al-Qiddiya: A mega-project under construction in Saudi Arabia, envisioned as a global destination for entertainment, sports, and culture.
    • Red Sea Project: A tourism development project in Saudi Arabia focused on creating luxury resorts and promoting sustainable tourism along the Red Sea coast.
    • Cultural Mobility: In the text, enhancement of the presence and role of culture within Saudi Arabia by facilitating cultural exchange, cultural events, the publishing industry, and preservation of cultural sites.
    • Localization (Tawteen): Initiatives to increase Saudi citizen participation in the workforce, especially in specialized sectors like medicine, technology, and industry.
    • IFAT: A leading trade fair for water, sewage, waste and raw materials management.

    Saudi Arabia: Vision 2030 and Transformation Initiatives

    Frequently Asked Questions about Recent Developments in Saudi Arabia

    1. What key themes emerge from the provided sources regarding Saudi Arabia’s current direction?

    The documents highlight Saudi Arabia’s ambitious transformation across various sectors, guided by Vision 2030. Key themes include:

    • Economic Diversification: Reducing reliance on oil through investments in non-oil sectors such as tourism, manufacturing (especially electric vehicles), technology, and renewable energy.
    • Global Leadership: Asserting its role as a peacemaker and mediator in international conflicts, a stable force in the Middle East, and a contributor to global security and development.
    • Investment and Growth: Attracting foreign investment, developing domestic industries, creating jobs, and increasing the contribution of the private sector to the national GDP.
    • Social and Cultural Development: Promoting cultural heritage, supporting artistic expression (through events like book fairs), enhancing quality of life through recreational offerings, and addressing social needs through charitable initiatives.
    • Technological Advancement: Embracing digital transformation, promoting innovation, and leveraging technology to drive economic growth and improve public services.
    • Regional Influence: Maintaining strong relationships with allies, playing a central role in counter-terrorism efforts, and supporting stability in the region.

    2. How is Saudi Arabia working towards economic diversification, and what are some specific examples mentioned?

    Saudi Arabia’s economic diversification efforts involve:

    • Developing Non-Oil Sectors: Tourism (through projects like NEOM, Al Qiddiya, and the Red Sea Project), manufacturing (electric vehicles with the launch of the Ceer company), and technology.
    • Investing in Renewable Energy: Transitioning to cleaner energy sources to reduce carbon emissions and promote sustainability.
    • Expanding the Industrial Base: Supporting the development of local industries and attracting foreign investment in manufacturing.
    • Diversifying Revenue Streams: Increasing non-oil revenue to reduce vulnerability to oil price fluctuations. Specific projects contributing to diversification include gigaprojects like NEOM, development of the tourism industry, and efforts to increase domestic content in manufacturing.

    3. What role does Saudi Arabia play in international relations and conflict resolution, according to these sources?

    Saudi Arabia positions itself as a key player in:

    • Mediation and Peacemaking: Actively engaging in efforts to resolve the Russia-Ukraine conflict.
    • Counter-Terrorism: Leading and supporting the Islamic Military Counter Terrorism Coalition to combat extremism and terrorism.
    • Promoting Regional Stability: Maintaining strong relationships with allies and working towards security and stability in the Middle East.
    • Humanitarian Aid: Providing assistance to countries in need through organizations like the King Salman Humanitarian Aid and Relief Centre.

    4. How is Saudi Arabia promoting social and cultural development, and what initiatives are mentioned?

    Key social and cultural initiatives include:

    • Supporting Cultural Events: Hosting book fairs, festivals, and other cultural events to promote artistic expression and knowledge sharing.
    • Preserving Heritage: Emphasizing the importance of preserving Saudi Arabia’s cultural heritage and promoting it to the world.
    • Enhancing Quality of Life: Providing recreational and entertainment options for citizens and visitors.
    • Supporting Charitable Initiatives: Encouraging and supporting charitable organizations to address social needs and improve the well-being of communities.

    5. What is the significance of Saudi Arabia hosting events like IFAT and the LEAP Conference?

    Hosting international events signifies Saudi Arabia’s:

    • Global Hub Status: Positioning itself as a regional hub for trade, investment, and innovation.
    • Technological Leadership: Showcasing its commitment to technological advancement and promoting the adoption of new technologies.
    • Environmental Focus: Highlighting its efforts to address environmental challenges and promote sustainable solutions.
    • Knowledge Sharing: Facilitating knowledge sharing and collaboration among experts and industry leaders from around the world.

    6. How does Vision 2030 relate to the specific projects and initiatives discussed in the sources?

    Vision 2030 serves as the overarching framework that guides all the projects and initiatives mentioned. It provides a clear roadmap for economic diversification, social and cultural development, and global engagement. The initiatives highlighted are all designed to contribute to the achievement of Vision 2030‘s goals, such as increasing non-oil revenue, attracting foreign investment, creating jobs, and improving the quality of life for Saudi citizens.

    7. What efforts are being made to localize industries and develop local talent, particularly in the pharmaceutical sector?

    Saudi Arabia aims to localize critical industries through initiatives such as:

    • Attracting investments to manufacture pharmaceuticals locally.
    • Establishing vaccine and biologics industries.
    • Creating partnerships with international companies to transfer knowledge and technology.
    • Training Saudi nationals in specialized fields to support the local industry.

    8. How is Saudi Arabia addressing the challenge of balancing technological advancement with privacy and security concerns?

    The sources mention that Chinese tech companies face increasing scrutiny regarding privacy and security. While Saudi Arabia’s approach isn’t explicitly detailed in the provided text, the focus on cybersecurity during LEAP 2025 suggests a broader awareness of the need to address these issues as part of the country’s digital transformation strategy.

    Riyadh Peace Summit: US & Russia Dialogue for Global Stability

    The anticipated peace summit aims to make the Kingdom a focal point of global attention, closely monitored for how the American and Russian presidents will overcome their differences to enhance stability on Earth. The summit’s convocation in Riyadh underscores the Kingdom’s commitment to resolving conflicts and its belief in dialogue as the sole means to address crises.

    Key points regarding the peace summit:

    • It reflects the Kingdom’s অবিচল support for ending conflicts between nations, highlighting the importance of dialogue in resolving crises.
    • The summit is a continuation of efforts made since the early days of the Ukrainian war.
    • Crown Prince Mohammed bin Salman has shown the Kingdom’s readiness to contribute to reaching a political solution that leads to lasting peace.
    • The Kingdom is increasing optimism about the summit’s results, which is facilitated by the strong relationship between the Crown Prince and the American and Russian presidents, and confidence in his wisdom and sound judgment.
    • The summit showcases Saudi Arabia’s policy of promoting peace, moderation, and cooperation among nations to address global challenges.
    • Saudi Arabia is hosting the summit between the American and Russian presidents in an attempt to build a foundation for world peace, recognizing that the future of peace is linked to agreement and cooperation between major countries.
    • The Kingdom reiterated its ongoing efforts to achieve peace between Russia and Ukraine since the start of the crisis, with the Crown Prince expressing the Kingdom’s readiness to mediate and contribute to a political solution.
    • Saudi Arabia seeks to facilitate a peaceful resolution to the Ukrainian crisis through dialogue and leveraging its unique relationships with all parties involved.
    • The summit aligns with the commitment to support efforts aimed at ending the conflict between Russia and Ukraine to achieve a fair peace and sustainable security.
    • The selection of the Kingdom to host the summit reflects its international standing and role in addressing international crises.
    • Crown Prince’s personal influence contributes to the success of efforts and initiatives to resolve differences between the United States and Russia.
    • Saudi Arabia welcomes any international effort to hold peace negotiations between warring parties.

    Saudi Arabia’s Vision 2030: Non-Oil Revenue Surges in 2024

    The Saudi Ministry of Finance announced the actual budget figures for 2024, which showed that non-oil revenues exceeded 502 billion riyals. This is considered the most important item in the budget and the most significant indicator confirming the success of Vision 2030 in avoiding the effects of fluctuating oil prices on the Saudi economy.

    Here are some additional details pertaining to the Saudi budget:

    • The vision aims to increase non-oil revenues to one trillion riyals by 2030.
    • There are only six years left to achieve the ambitious target for non-oil revenues, so it remains questionable whether the few remaining years are enough to double the figure recorded by the end of 2024.
    • Vision 2030 programs are integrated to achieve the goal.
    • Capital expenditures in the 2024 budget amounted to 191 billion riyals.
    • Although the expenditure is less than the record figure registered in 2017, the efficiency of spending in the 2024 budget makes the return on capital expenditure multiple times the return of capital expenditure in 2017.
    • In the 2024 budget, capital expenditures reached 191 billion riyals, less than the record in 2017, but spending efficiency resulted in a higher return on capital.
    • The high efficiency in spending has made the economic impact greater, with non-oil GDP reaching 4.3% in 2024 and expected to reach 4.8% in 2025.
    • This growth contributed to lowering unemployment rates among Saudis to 3.7%, which is less than the global average of 5%.
    • Since the establishment of the government expenditure and projects efficiency authority in 2021, the authority obtained first place in the global CIPS awards for procurement and supply chains in 2023.

    Israel-Palestine Hostage Exchange: 6th Release Operation

    Here’s information about a hostage release, based on the sources:

    • Hamas and Islamic Jihad released Israeli hostages who had been held in the Gaza Strip since the October 7, 2023, attack.
    • In return, Israel released Palestinian detainees from its prisons, marking the sixth exchange operation.
    • A bus carrying released Palestinian prisoners arrived in Ramallah in the West Bank.
    • The Palestinian Red Crescent Society announced the arrival of four released prisoners to Ramallah.

    Jazan Book Fair: Culture, Arts, and Youth Engagement

    The Jazan book fair features a diverse exhibition of books from Pyramids, including international or translated works, novels, or business-related books suitable for children. These books are carefully prepared to suit their interests.

    Key features of the Jazan book fair:

    • Cultural Competitions: Activities aimed at fostering a love for reading and developing various skills and capabilities in children.
    • Educational Programs: Programs designed to teach human values and concepts to children in an enjoyable manner.
    • Professional Training: Craft and artistic programs that combine learning and practical experience.
    • Live Performances: Live plays and creative writing workshops to stimulate creativity among children.
    • Storytelling: Performances using puppet theater or live acting to present stories engagingly, enhancing listening skills and literary interaction.
    • Interactive Activities: Activities encouraging active participation, such as challenge and educational games to develop critical thinking skills.
    • Diverse Zones: Six zones offer programs for children, integrating learning and entertainment:
    • Tales Arch (قوس الحكايات)
    • Wonders Box (صندوق العجائب)
    • The Author (المؤلف): A creative writing workshop.
    • Grandparents’ Craft (حرفة الأجداد): A workshop creating a model of ancestral homes.
    • Literature Adventurer (مغامر الأدب): A workshop stimulating memory and enriching information.
    • Stars Theater (مسرح النجوم): A theatrical workshop.

    The Jazan book fair, along with accompanying events such as the Tabuk University delegation visit and art exhibitions, aims to enhance culture and arts, support creativity, and foster dialogue among youth. These initiatives contribute to building a sustainable society.

    Saudi Arabia: Technology Sector Growth & Vision 2030

    Here’s what the sources say about the technology sector:

    • The Saudi Ministry of Interior announced the enhancement of the efficiency of the security work system by developing the General Administration for Community Security to combat crime, especially trafficking crimes.
    • The “IHTM 2025” conference in Riyadh focuses on developments in healthcare, spotlighting digital transformation and innovation. It gathers experts and innovators to discuss the latest technologies in healthcare management and explore future opportunities. The conference aims to empower participants to explore new prospects for connection and build valuable professional relationships.
    • The “IFAT” exhibition and conference will be hosted in Riyadh in early 2026, in cooperation between the National Center for Waste Management and the German Messe Munich. It will gather international companies and governmental bodies working in waste management, water treatment, and North African sectors, with the goal of exchanging experiences and displaying the latest technologies.
    • Saudi Arabia’s Vision 2030 aims to increase non-oil revenues to one trillion riyals by 2030.
    • Digital transformation is not merely an option but a necessity, with the Kingdom investing in technology to enhance research and development and support entrepreneurs in technical fields. Events like the LEAP conference reflect this ambition, aiming to guide technology towards sustainable goals.
    • Saudi Arabia seeks to position itself as a leader regionally and globally by investing in technology and fostering innovation.
    • The technology sector in the Kingdom has recorded significant growth, with investments in startups exceeding $1.3 billion in 2024, a 40% increase from the previous year.
    • The Kingdom has invested billions of dollars in cloud computing and artificial intelligence projects.
    • The Kingdom aims to develop local content and manufacturing. For example, Sanofi and Seder Group have signed agreements with international pharmaceutical companies to transfer knowledge and enhance local production of insulin.
    • The establishment of the government expenditure and projects efficiency authority in 2021 obtained first place in the global CIPS awards for procurement and supply chains in 2023.
    • The “Leap” conference serves as an investment platform, shaping the new digital economy and reflecting ambitious visions.
    • NEOM and other projects draw investments to cloud computing, AI, and robotics, including direct investments from companies like Microsoft and Oracle.
    • The Kingdom’s digital transformation is not just a plan but a strategic project that changes the rules of the game.
    • The increasing reliance on technology also brings challenges related to privacy and security.
    • The Kingdom’s Vision 2030 is closely tied to progress in the technology sector.
    • The choice of Riyadh to host the IAAPA summit reflects the increasing role of the Kingdom as a pioneer and leading destination for entertainment and is in line with the goals of economic diversification that Vision 2030 aims to achieve.

    By Amjad Izhar
    Contact: amjad.izhar@gmail.com
    https://amjadizhar.blog