Documente Academic
Documente Profesional
Documente Cultură
Preface
This manual provides supporting materials for the course Building Applications with SQLWindows. This preface provides the following information: Who should read this manual? The notation conventions used in this manual.
Audience
This manual is intended for: Application Developers building client/server applications in SQLWindows. Project Leaders managing development teams or evaluating development tools. This manual assumes you have an understanding of programming concepts and some programming experience in other languages. It does not assume you have Windows programming experience although it does assume that you have experience using the Windows interface.
Notation conventions
Before you start using this manual, it is important to understand the typographical conventions we use in this manual:
Formatting Convention
You User bold type A developer who reads this manual
Type of Information
The end-user of applications that you write Menu items, push buttons, and field names. Things that you select. Keyboard keys that you press. Programming Code Program names and file names
Table of Contents
Chapter 1: Introduction ...................................................................................................... 7 Course Objectives .......................................................................................................... 7 Team Developer............................................................................................................. 7 SQLWindows Features .................................................................................................. 8 Information (Data) Access ............................................................................................. 9 Database Terminology ................................................................................................... 9 Course Files ................................................................................................................. 10 HOLLYWD Data Model.............................................................................................. 10 Suggested Reading ....................................................................................................... 11 Chapter 2: SQLWindows Overview ................................................................................. 12 What We Will Cover.................................................................................................... 12 SQLWindows User Interface........................................................................................ 12 SQLWindows User Interface........................................................................................ 12 Outline View................................................................................................................ 13 Layout and Preview View ............................................................................................ 14 Controls Palette............................................................................................................ 14 Coding Assistant .......................................................................................................... 15 Active Coding Assistant ............................................................................................... 16 Attribute Inspector ....................................................................................................... 17 User Mode ................................................................................................................... 17 SQLWindows Processes............................................................................................... 18 Build Process ............................................................................................................... 18 Application Properties.................................................................................................. 18 Database Explorer ........................................................................................................ 19 Demo 2.1: SQLWindows Environment ........................................................................ 19 Demo 2.2: Active Coding Assistant.............................................................................. 19 Demo 2.3: Active Debugging Assistant ........................................................................ 20 Chapter 3: SQLWindows Objects..................................................................................... 21 What We Will Cover.................................................................................................... 21 Types of Window Objects ............................................................................................ 21 Form Windows ............................................................................................................ 22 Table Windows ............................................................................................................ 22 MDI Windows ............................................................................................................. 23 Dialog Boxes ............................................................................................................... 23 Standard Windows Dialog Boxes ................................................................................. 24 Creating Child Objects ................................................................................................. 24 Application Menus....................................................................................................... 27 Windows Message Boxes............................................................................................. 28 SQLWindows Outline Syntax ...................................................................................... 28 Mnemonics and Accelerators ....................................................................................... 29 Exercise 3.1: SQLWindows Objects............................................................................. 29 Application ToolBars ................................................................................................... 30 Exercise 3.2: Using Dockable Application Toolbars..................................................... 31 Chapter 4: Event/Message Programming.......................................................................... 32
What We Will Cover.................................................................................................... 32 A World of Windows Objects ...................................................................................... 32 SQLWindows Objects.................................................................................................. 33 Event/Message/Action Flow......................................................................................... 33 Where Messages are sent ............................................................................................. 34 Who Sends Messages ................................................................................................... 34 Event/Message/Action Examples ................................................................................. 35 Message Sequence ....................................................................................................... 35 Using Return in Message Actions................................................................................. 36 Initialization of Child Object Values ............................................................................ 37 Object Validation ......................................................................................................... 37 Exercise 4.1: Event/Message Programming .................................................................. 38 User-Defined Messages................................................................................................ 39 Additional Message Information .................................................................................. 39 Sending versus Posting Messages................................................................................. 40 Good Programming Technique..................................................................................... 41 Exercise 4.2: An OO Approach to Event/Message Programming.................................. 42 Chapter 5: A Simple Event-Based Application................................................................. 44 What We Will Cover.................................................................................................... 44 Demo 5.1: SALCulator ................................................................................................ 44 Demo 5.2: Defining User Messages ............................................................................. 44 Using the Case Statement ............................................................................................. 46 Using Simple Assignments........................................................................................... 46 Using Message Boxes .................................................................................................. 47 Using Case, Assignment and Message Boxes ............................................................... 47 Closing a Parent Window............................................................................................. 47 Exercise 5.1: A Simple Event-Based Application ......................................................... 48 Chapter 6: SAL Components............................................................................................ 50 What We Will Cover.................................................................................................... 50 What is SAL?............................................................................................................... 50 SAL Data Types........................................................................................................... 50 Variable Declarations................................................................................................... 51 System Variables ......................................................................................................... 52 Variable Qualification .................................................................................................. 53 Window Handles.......................................................................................................... 54 Arrays .......................................................................................................................... 55 Array Functions ........................................................................................................... 56 Command Line Arguments .......................................................................................... 56 Operators ..................................................................................................................... 57 Variable Expressions.................................................................................................... 58 Constants ..................................................................................................................... 58 System Constants ......................................................................................................... 58 Chapter 7: SAL Language Statements .............................................................................. 59 What We Will Cover.................................................................................................... 59 SAL Statements ........................................................................................................... 59 SQLWindows Function Types ..................................................................................... 64 Demo 7.1: External Functions ...................................................................................... 65
Internal Functions ........................................................................................................ 66 Receive Parameters ...................................................................................................... 67 Demo 7.2: Receive Parameters..................................................................................... 68 Top-Level Window Parameters .................................................................................... 68 Exercise 7.1: SAL Functions ........................................................................................ 69 Chapter 8: SQL Basics ..................................................................................................... 70 What We Will Cover.................................................................................................... 70 What is SQL?............................................................................................................... 70 SQLTalk and Database Explorer .................................................................................. 71 Demo 10-1: SQLTalk................................................................................................... 71 SELECT Statement ...................................................................................................... 71 Pattern Matching .......................................................................................................... 73 Sorting Data................................................................................................................. 74 Aggregate Functions .................................................................................................... 74 Retrieving Data from Multiple Tables .......................................................................... 75 Complex Joins ............................................................................................................. 76 INSERT Statement....................................................................................................... 78 UPDATE Statement ..................................................................................................... 78 DELETE Statement...................................................................................................... 78 COMMIT Statement .................................................................................................... 79 Exercise 8.1: SQL Basics ............................................................................................. 79 Chapter 9: Working with SQL Databases ......................................................................... 80 What We Will Cover.................................................................................................... 80 Connecting to a Database ............................................................................................. 80 Demo 11.1: Connecting to a Database .......................................................................... 80 Sql Handles.................................................................................................................. 81 OLE DB Constructs/Session Handles ........................................................................... 81 Disconnecting from a Database .................................................................................... 82 BIND Variables - Data Output ..................................................................................... 82 INTO Variables - Data Input ........................................................................................ 82 INSERT, UPDATE, DELETE ..................................................................................... 83 SQL Command Cycle .................................................................................................. 83 SqlPrepare.................................................................................................................... 84 SQLBase Stored Commands ........................................................................................ 84 SqlExecute................................................................................................................... 84 SqlPrepareAndExecute................................................................................................. 85 Fetching Data............................................................................................................... 85 Using SqlPrepare ......................................................................................................... 86 Using SqlStore and SqlRetrieve (SQLBase) ................................................................. 86 What is a Transaction? ................................................................................................. 86 Exercise 9.1: Working with SQL Databases ................................................................. 87 Chapter 10: SQLError Handling and Infrastructure .......................................................... 89 What We Will Cover.................................................................................................... 89 Demo 12-1: Login Dialog Box ..................................................................................... 89 Functions for Forms and Dialog Boxes......................................................................... 90 Types of Dialog Boxes Review ................................................................................. 91 Library Files ................................................................................................................ 92
Exercise 10.1: Login Dialog Box.................................................................................. 92 SQL Error Handling ..................................................................................................... 93 When SqlError ............................................................................................................. 95 Demo 12.2: Handling SQL Errors Locally.................................................................... 95 Global Error Handler.................................................................................................... 96 Default Error Handling................................................................................................. 97 Exercise 10.2: Handling Known Connection SQL Errors ............................................. 97 Chapter 11: Getting Started with Table Windows............................................................. 99 What We Will Cover.................................................................................................... 99 What is a Table Window? ............................................................................................ 99 Table Window Terminology ........................................................................................ 99 Result Set/Table Window Cache ................................................................................ 101 Populating a Table Window ....................................................................................... 101 Dynamic vs. Defined Columns................................................................................... 102 Table Window SAM* Messages ................................................................................ 102 Other SAM* Messages............................................................................................... 102 Demo 13.1: A Table Window for Browsing Data ....................................................... 103 Exercise 11.1: Getting Started with Table Windows ................................................... 104 Demo 13.2: Selecting Data......................................................................................... 105 Exercise 11.2: Selecting Data with a Combo Box....................................................... 107 Populating Combo Boxes ........................................................................................... 108 Demo 13.3: Loading Lookup Data from the Database ................................................ 108 Exercise 11.3: Populating a Combo Box..................................................................... 108 Chapter 12: SQLWindows and Reports.......................................................................... 110 What We Will Cover.................................................................................................. 110 Classic Report Interface ............................................................................................. 110 Report Builder Functions ........................................................................................... 111 Creating and Manipulating Reports ............................................................................ 111 Demo 16.1: Creating & Viewing Report Data ............................................................ 112 Report Builder Messages............................................................................................ 113 Function Details ......................................................................................................... 114 Demo 16.2: Using Report View ................................................................................. 115 More Function & Message Details ............................................................................. 115 Demo 16.3: A Simple Classic Interface Report........................................................... 116 Exercise 12.1: SQLWindows and Reports .................................................................. 118 Tasks...................................................................................................................... 118 Report Builder Errors................................................................................................. 119 Query/Report ............................................................................................................. 120 Report Objects ........................................................................................................... 121 Demo 16.4: Creating a Crosstab Report Demo 16.5: Printing Images ......................... 122 Integrating Report Builder with ActiveX .................................................................... 123 Demo 16.6: Report Builder Automation ..................................................................... 123 Exercise 12.2: Creating an RB Automation App......................................................... 124 Tasks...................................................................................................................... 124 Chapter 13: Team Developer 6 New Controls ................................................................ 125 Team Developer 6 NEW Controls .............................................................................. 126 Application Demonstration ........................................................................................ 128
Chapter 1: Introduction
Course Objectives
. . . . . Become familiar with the Team Developer product and its components Become proficient with the SQLWindows development environment Learn Scalable Application Language (SAL) Use SQLWindows to build client/server applications Using Report Builder with SQLWindows
Team Developer
An integrated family of tools for building database-centric business applications.
SQLWindows
The development environment (discussed in detail later in this chapter).
Report Builder
. . . . Full featured graphical report designer Graphical query builder Design time interface Run time interface
Object Compiler
Translates internal functions in an application outline into external functions in a Dynamic Linked Library (DLL) Speed-up performance Native compilation before deployment Up to 80% of object oriented code is compiled!
Object Nationalizer
Easily customize applications for specific locales
SQLBase Desktop
Desktop (single user) version of SQLBase is included. Here are some advantages to using SQLBase: . . . . . . . Better enterprise integration and scalability through MTS Support. Simplified administration with enhanced SQLBase Management. Better IDE integration through enhanced ODBC and OLEDB. Easier maintenance through descriptive identifiers. Improved database searching with new SQL features. Better management capabilities for larger databases. Completely automated upgrade process from previous versions of SQLBase.
SQLWindows Features
SQLWindows is a Windows based prototyping and development tool.
SAL
The language it uses is called Scalable Application Language (SAL). SAL is a productive 4GL programming language.
Class Libraries
Third party libraries are available. Create your own class libraries Embbed classic, OCX, ActiveX and other controls
SQL Interface
A number of SQL* functions provide SQL access to SQL based databases.
Windows functionality
. . . . . . Easy and open access to Windows functionality Drag and drop OCX and ActiveX Controls COM servers and Object Linking and Embedding (OLE) DLL (Dynamic Linked Libraries) Full-featured, context-sensitive Help - (F1 key)
Top-level windows
Create Form Windows...
Class Wizard
Quickly guides you through building multi-level class hierarchies three-tier class libraries
Database Explorer
. . . . . . . The Database Explorer can: Manage any database schema from a single tool Database Objects: tables, views, indexes Stored procedures SQL scripting tool -hoc query/report tool View and edit table contents
ActiveX Explorer
The ActiveX Explorer allows you to manage any components needed for your application.
Mail Systems
MAPI compliant (Microsoft) Note In many of the exercises throughout this course you will be working with information contained in a database that has been created for you. On the next few pages you will be introduced to some database concepts and terminology to help you better understand how the data is organized.
Database Terminology
What is a Database?
A database is a collection of information or data that is related or integrated in some fashion usually shared amongst several users. A database management system (DBMS) is a set of utilities and tools to create and maintain databases. A relational database (RDB) stores the data in a database as tables (relations). Tables are accessed via columns (attributes) and rows.
Terminology
Base Table is a collection of data on a single topic that is organized into rows and columns (Relation). Row contains information about a single instance or occurrence of the data. Column contains the data values that describe the properties of a table (Attribute) each column has a name. Cell is where a row intersects a column and is where each data element is stored (Field). Relational Database Management System (RDBMS) manages tables containing data organized in accordance with the relational model. In
this course work, we will use the informal terms of tables, rows and columns.
Normalization
In a relational database, a data model is subjected to a process called normalization. Normalization ensures that each table contains information about a single entity. Normalization guarantees the integrity and accuracy of the data by ensuring that there are primary keys assigned to each base table. Primary
keys may be a single column or a combination of several columns that uniquely identify any given row in a table. Examples of primary keys are: Employee Number Job Code Normalization also ensures that proper foreign keys are established. A foreign key is created when a primary key of one base table is included in another base table. The use of primary (PK) and foreign (FK) key relationships provides a way that data stored in multiple tables can be brought together again by matching the primary key of one base table with the foreign key in another base table.
Course Files
Installed in \40-6201\STUDENT They contain information used in the course exercises Application files, where xx is the chapter and yy is the exercise . Templates - Chapter xx Template yy.app . Solutions - Chapter xx Solution yy.app Demonstration -Chapter xx Demo yy.app Databases used in the exercises and demonstrations . HOLLYWD database is used for instructor demonstrations User: HOLLYWD Password: HOLLYWD . PRESIDNT database is used for Student exercises User: PRESIDNT Password: PRESIDNT
Suggested Reading
. Developing SQLWindows Applications By David Gugick SAMS, 1995 . Using SQLWindows 5 By David Holmes-Kinsella QUE, 1995 . Using SQL By James R. Groff and Paul N. Weinberg Osborne McGraw-Hill, 1990 ISBN 0-0708811524-X . Windows API Bible By James L. Conger Waite Group
Application windows
SQLWindows has an interface similar to Windows Explorer. It provides multiple views of the same application. There are two main panes, which are separated by an adjustable splitter.
Left pane
. . . . Tree view (outline) of application (or selected parts of an application) Eases code navigation Expanding the outline Selecting a folder
Right pane
Different ways of viewing application objects, using tabs. The content of the right pane is dependent upon the selected folder in left pane. To navigate in the right pane, you can either select from the tabs at the bottom of the pane or Scroll the tab list
Note. Multiple views of a dialog box (dlgQOLogin) as displayed in the right pane of the design-time environment.
Outline View
There is an outline view for every object in the left pane. This is where application code is added and edited. It contains SAL statements. When you are viewing the outline or outline subset in the right pane, there are a number of sections in the outline. . . . . . . Outline Constants Libraries Message actions Parameters Variables
SQLWindows applications are physically stored in a form known as the Application Outline. To display the application outline for a window object, use the following steps: Click on the window object (in the left pane), which represents the window Click on the Outline view tab in the View window
The application code for the window is now displayed in the View Window.
Preview Window
Can be invoked from the Layout menu (Ctrl+L) Can be used to add and edit child windows (see following) Can also be used to set the runtime position of a window Bi-directional selection
Layout View
To display the application layout for a window object, use the following steps: . . . Click the Explorer window object, which represents the window Click on the Layout view tab in the View window
Controls Palette
The controls palette contains all the tools and objects that you'll need to add and customize child objects on top-level windows. To identify the function of each of these controls, simply rest the mouse pointer on each of the icons and their identity will be displayed via tool tips.
Accessibility
Alt+4 Tools | Controls Dockable
Coding Assistant
Lists valid coding options for the Outline View. Every coding option is accessible via the Coding Assistant with the following exception: Objects from data sources (databases), for example, database tables and columns. In this case, you may use Database Explorer to obtain this information. It can be used to: Define functions, constants, and variables Code SAL statements Define events for COM objects Create Class definitions Create objects It is searchable and context-sensitive.
Accessibility
Alt+2 Tools | Coding Assistant Dockable
Components
Depending upon the context you will see
Combo Box
Permits you to select the type of objects you want to see in the list box
List boxes
The Coding Assistant has one or two lists depending on what is selected in the outline. These list boxes have associated push buttons:
Set to Function
Add the highlighted function to the statement selected in the outline
Data Field
A data field for searching the list box. Type the first few characters of a name in the data field at the top of the palette to scroll to the item that begins with them.
Accessibility
Automatic.
Components
Depending uponthe context you will see
Activation Properties
Located as an additional tab in Team Developer Preferences. The following is a list of each of the optional settings used to activate the Active Coding Assistant:
. . . .
Enable Features Turns the Active Coding Assistant on and off Quick Info Displays the complete declaration for any identifier in your code. List Members is a floating/modeless dialog box with a list box containing all members of the class or scope that has focus. Parameter Info Opens the parameters list to give you information about the number, names, and types of parameters required by a function or attribute. . Complete Word Types the rest of a variable, command, function, or symbol name once you have entered enough characters to disambiguate the term. . Automatic Quick Info/List Members/Parameter Info . These three options can be set to appear automatically if enabled. Otherwise you can activate them manually with hot keys, menu choices, or toolbar clicks.
Attribute Inspector
Parent and child window objects have many customizable attributes. The list of attributes is different for each type of object.
Accessibility
Alt + 3 Tools | Attribute Inspector Dockable
User Mode
User mode is when you are executing applications from design mode. You can easily switch between design and user mode.
Accessibility
Press F7 Or Project | Go (or Debug | Go)
Break points
You can set/clear breakpoints You can stop program execution
SQLWindows Processes
Build Settings
The Build Settings dialog sets options for building a target object
Build Target
The target of the build can be of several types
Executable (*.EXE)
Use for deployment of completed applications Binary
Dynalib (*.APD)
Dynamic include library Shares compiled code during runtime
Accessibility
Project | Build Settings
Build Process
Design time
. . . . Design the window objects Customizing Create/edit code in the Application Outline Coding Assistant can be used to assist . Check In/Check Out applications with Team Object Manager (if being used)
Test
User mode can be used for initial testing and debugging.
Deployment
Can be deployed with the Team Developer deployment file. This is part of the SQLWindows deployment package, which is not discussed in this course. Remember to include all deployment files including connectivity files
Application Properties
Information about the contents of applications.
Accessibility
Select the application folder in the left pane Right-click on the application folder, select Properties Select Edit | Properties... Alt+Enter
Database Explorer
Supports multiple database vendors. Provides a consistent user interface. Work with any database object Browsing tables, columns or views Creating and modifying stored procedures Interactive SQL scripting interface
Accessibility
Tools | Database Explorer
Next we see what is displayed if you are trying to insert a function from an object.
And here we see the pop up message describing parameters of the function we just added.
Features
Are containers for child objects May be a child of an MDI Window (except dialog boxes) May have a System Control menu May or may not be resizable, minimizable, or maximizable May contain Dockable toolbars
Components
Popup Menus folder Windows menu Tool Bar Functions folder Child Windows folder
Tabs to view
Components Actions Description Layout Parameters Variables
Outline
Components
Columns Functions Variables Message Actions
Tabs to view
Components Actions Variables Outline
note
Form Windows
Often used for data display/entry. May be automatically created/not created at runtime. Contain menus, child windows May have an icon file
Table Windows
Child and Parent Table Windows permit tabular format for data from any source. User area can only contain columns. The optional tool bar may have all types of children.
MDI Windows
The Multiple Document Interface (MDI) is used for creating a desktop or frame for your application. It is useful for managing a number of other windows you may want to display simultaneously. An MDI Window can contain MDI Child Windows such as Form Windows and Parent Table Windows.
Dialog Boxes
Often used to prompt for data from user Typical uses are for Errors/Warnings: Message Boxes Has child objects (in the same fashion as Form Windows) Cannot be automatically created at runtime No resizing at runtime All have titles Absolute screen locations: Yes/No Can be Used as a toolbar with the option to dock it to a parent.
Modal
Stops application processing. For Example: File/Open Dialog Box
SysModal
Stops system processing. For Example: a system error Dialog Box
Modeless
Has System Control menu and Close button Does not halt processing Example: Search/Find Dialog Box To Create/destroy use the following functions: SalCreateWindow() / SalDestroyWindow() Owner/no owner behavior Function as a toolbar, with the option to dock and un-dock with a parent
The boxed area identifies various classes of the object selected, or available ActiveX controls and objects
Active
Tree Control Navigation Bar Navigation Pane WPF Custom ActiveX Custom Control Report
Yes No Yes
Pushbuttons
Can be used to create both Standard Pushbuttons and Flat Look Pushbuttons
Application Menus
A SQLWindows application can have a number of different types of menus.
Menu Types
Window Menus
Menu Item: top-level menu Popup Menu: menu with sub-menu items (the sub-menu items could be menu items and/or other popups)
Named Menus
Defines a shared popup among windows Floating Popup: creates a popup at application runtime
Menu Components
Menus are made up of the following components
Menu Row
Forces a new menu row to appear
Menu Column
Forces a new sub-menu column in a popup menu
Menu Separator
Adds a horizontal line in a popup to separate unlike sub-menu items
Windows determines:
Position and size of the message box Push button titles
Return Results:
IDOK (1), IDCANCEL (2), IDABORT (3), IDRETRY (4), IDIGNORE (5), IDYES (6), IDNO (7)
In this example, a Form Window frmMain contains child objects dfMessage, pbSet, pbExit and a frame. Code indented under On SAM_Click in pbSet is executed when the user clicks the button. Statements indented under If/Else form blocks to be executed based on the result of the conditional expression. The variable bValueSet is declared in the window.
Creating mnemonics
Create a mnemonic by typing an ampersand character (&) before the character, in the title of the object, which you want to be the mnemonic. A mnemonic character appears in an object's title with an underscore.
Creating accelerators
An accelerator is assigned to a Push Button using the Attribute Inspector. A drop down list contains valid keystrokes. An accelerator is assigned to a Menu Item in the outline. Possible keystrokes and combinations are listed in the Coding Assistant
Preview
Templates
None. This exercise requires you to start a NEW application.
Steps
Step 1: Step 2: Save any previous work. Start a new application.
Save it as Chapter 03 Exercise 1.app. Step 3: Create a Form Window (right click on the Windows folder in left pane, select New | Form Window). Give it a name frmHello. Step 4: Step 5: Using the Attribute Inspector, make the title of the form Hello World Application'. Using the Controls Palette, drop a Data Field onto the Form Window. Give it a name dfMessage. Step 6: Step 7: Using the Attribute Inspector, customize it so that it is Editable | No and Justify | Center. Drop two Push Buttons onto the Form Window. Give one a name of pbSet and a title of Set with the S as the mnemonic. Give the other a name of pbExit and a title of Exit with the x as the mnemonic. Step 8: Step 9: Step 10: Write the code for the pbSet Push Button to assign a value of 'Hello World' to the data field dfMessage. Write the code for the pbExit Push Button to quit the application. Save and test your application.
Optional Tasks
Step 10: Place a frame around the child objects. Step 11: Modify the push button pbSet to alternately clear or set the value of dfMessage.
Application ToolBars
A rectangular area, at edge of window, where you can place objects for frequently used functions. Can be defined for all top-level windows.
As you can see from the Attribute Inspector, you have additional settings for the Tool Bar: You can also specify weather the toolbar is Dockable and what locations the toolbar can be docked. This is where you can specify which edge the toolbar is on (top/bottom/left/right).
You can also create dialog boxes to be used as toolbars that are Dockable with Form Windows, MDI Windows, and/or Table Windows. The dialog box has to have the new property of Allow Dock to Parent set to Yes and the Parent Window must had its property of Allow Child Docking set to Yes.
Preview
Templates
Use template Chapter 03 Template 2.app or if you completed Chapter 03 Exercise 1.app, you may use that.
Steps
Step 1: Step 2: Save any previous work. Open the Template or previous exercise. Save it as Chapter 03 Exercise 2.app Step 3: Set Properties of the Window: Allow Child Docking = Yes Docking Orientation = All Accessories Enabled = Yes Docking Tool Bar = Yes Step 4: Move the two Push Buttons (Set & Exit) to the Toolbar) (hint, you will have to expand the toolbar to see them if you cut and paste) Step 5: Save and test your application. Try and making it a floating toolbar
Optional Tasks
Step 6: Change the properties of the form window to allow the toolbar to be docked on the sides
Event-driven
Microsoft Windows is an event-driven environment Windows waits for an event and alerts active application The user determines events Generally speaking, it is the end-user who controls events and as such it is the end-user who drives the application. For example, the user may click on a set of push buttons in a specific order to obtain one result. By clicking the push buttons in a different order, the application may produce a different output.
Hardware Events
At the most basic level, MS Windows has three hardware events. These events are keyboard events (key down, key up...), mouse events (clicking on the mouse buttons, moving the mouse...) and timer events (a form of hardware system clock).
SQLWindows is non-procedural
3GLs like C or Pascal are procedural based languages. SQLWindows, being event/message based, uses objects that 'listen' for a message. When they receive the message they carry out an action, hence the term non-procedural. Events and messages control the flow of the program.
SQLWindows Objects
What is an object?
Each SQLWindows object has a corresponding Outline section.
Active
Active objects are a second type of Windows object and have a message actions section defined in the object outline. An active object can receive a message and can handle that message if required to do so. To handle a message, the object performs an action block (which could involve sending another message). For example, when a user clicks on a push button a SAM_Click message is sent to the Push Button.
note
note
Event/Message/Action Flow
An event causes a message to be sent to an object
An event generates a message, the message is sent to a window object and, if the object is instructed to handle the message, an action results. If a message is handled, the object processes it by performing some action(s). An action can involve generating more messages. If the action involves issuing a Return statement then processing for the message will cease. If no Return is issued, the actions will continue until the end of the code block is reached.
To a window object
button will appear 'grayed out' on the screen and will not accept any messages. The push button needs to be enabled before it will start to receive messages. The push button is a child object of the form window called frmMain. The form also has a message action section that handles specified messages. In this case, the form is handling a SAM_Close message, which is sent to the form when a user wishes to close the form down.
MS Windows
Event-driven messages such as WM_KEYUP
Microsoft Windows messages are event-driven. For example, when a key is released after being depressed, a WM_KEYUP message is sent. Similarly, when a key is depressed a WM_KEYDOWN message is generated.
SQLWindows run-time
SQLWindows application
Sent via SAL functions to a window object SalPostMsg() adds a message to the object's message queue Message transmittal is asynchronous SalSendMsg() sends a message immediately to the object Message transmittal is synchronous SalSendMsgToChildren() sends a message immediately to the children of the object
Event/Message/Action Examples
Event
Application startup Check box creation Click on a push button Type character in a field Close a form window Application exit An SQL error SAM_Create SAM_Click SAM_AnyEdit SAM_Close SAM_AppExit SAM_SqlError
Message
SAM_AppStartup Connect to the database Disable selection Assign a data field value Enable a push button
Action
Prompt for application to terminate Disconnect from database Display error to the user
Message Sequence
As Windows programmers, we rarely control the sequence of hardware events and their resulting messages. It is important to understand which events spawn which messages. This is particularly true for top-level window create and destroy.
SAM_Create is sent to each child object, in the order they appear in the outline (usually) After all windows objects on the form window have been created, SAM_CreateComplete is send to the form window.
In this example, the value on the Return statement is actually not relevant! The mere execution of the Return statement blocks window close processing. The MS Windows OS never receives the close message and never acts on it.
Object Validation
Child objects receive SAM_AnyEdit as the user alters their value (key stroke by key stroke.) Altered data fields, multi-line fields, combo boxes and table window columns have their internal field edit flag set to TRUE. The state of a child object's field edit flag can be tested with SalQueryFieldEdit, and set or cleared with SalSetFieldEdit.
SAM_Validate message
When the user attempts to switch the focus a way from an altered child object, a SAM_Validate Message is set to it.
In the SAM_Validate message action, the application may return one of these constant values: VALIDATE_Ok - Allows focus to move as the user intends VALIDATE_OkClearFlag - Allows focus to move as the user intends and sets the object's field edit flag to false VALIDATE_Cancel - Forces focus back to the current field SAM_Validate processing is not suitable for mandatory field processing. If the user never goes into the field, it will remain empty and no SAM_Validate will ever be sent to it.
SalSendValidateMsg
SAM_Validate is sent to a child object when its value has been altered, and the user attempts to switch focus to another object. Clicking on a menu item or the parent window's close icon (upper right corner) does not switch focus. A well-written SQLWindows application will call SalSendValidateMsg prior to the close of menu triggered save processing. SalSendValidateMsg identifies and sends a SAM_Validate message to that child object which has been altered but not yet messaged. Typically, the return value is tested, as in the example below.
Preview
Template
None. This exercise requires you to start a NEW application.
Tasks
Step 1: Save any previous work. Step 2: Start a new application. Save it as Chapter 04 Exercise 1.app.
Step 3: Create a new Form Window. Name it frmCustomerEntry and title it 'Customer Entry'. Step 4: Add data fields dfName, dfAddress, dfCity, dfState, dfZipCode, dfCountry and dfCreditLimit. Step 5: Set the input mask on dfZipCode to 99999. Step 6: Set the data type on dfCreditLimit to numeric. Step 7: Set the format on dfCreditLimit to #,##0.00. Step 8: Add ON SAM_Create processing to initialize fields as follows: dfCity - 'Redwood Shores' dfState - 'CA' dfCountry - 'USA' dfCreditLimit - 5000
Step 9: Add SAM_Validate processing to dfCountry to ensure that it is either USA' or 'Canada'. Similarly, validate to ensure that dfCreditLimit is between 0 and 100,000. Step 10: Add SAM_Close processing to the form window to refuse a close request if SalSendValidateMsg() returns VALIDATE_Cancel. Step 11: Save and test your application.
User-Defined Messages
A message is simply a number and both Microsoft ans SQLWindows reserve the use of sets of message numbers. SAM_User is an internally defined constant, which marks the end of Microsofts, and SQLWindows reserved messages and the beginning of the messages, which are available to users of SQLWindows. We recommend that you prefix user message names with PAM_ or PM_. If you do, these messages will appear as such in the Coding Assistant.
Additional numeric information may be sent with a message. This is by means of two variables: wParam and lParam.
Using wParam
Here is an example of the use of wParam:
SalSendMsg(dfStatus,PAM_Clear,TRUE,0)
In this example the message is sent to dfStatus; the message being sent is PAM_Clear. When dfStatus receives this message, wParam is TRUE and lParam is 0. When dfStatus receives the PAM_Clear message, if wParam is set to TRUE, the field is cleared.
This example demonstrates the ability to test Booleans by simply checking their existence. 'If wParam' equates to 'If wParam = TRUE' and 'If wParam = 1'.
Posting
Posting is asynchronous and deferred. A call to SalPostMsg() does not transfer flow of program execution. Instead it places the requested message on the windows message queue for the receiving object. The receiving object will react to the message when the application falls into an idle state. This is typically after the 'post' message action completes but could be much later. Post is preferable to send as it uses the underlying windows architecture to provide better object separation. However Post cannot check for a return value.
Preview
Templates
Use template Chapter 04 Template 2.app or if you completed Chapter 03 Exercise 1.app, you may use that.
Tasks
Step 1: Step 2: Step 3: Step 4: Step 5: Save any previous work. Open the Template or previous exercise. Save it as Chapter 04 Exercise 2.app. Create a global user defined constant PAM_AppMessage. If you did not complete the optional exercise in Chapter 3, create a window variable of Boolean data type and call it bValueSet. Modify the code for pbSet: Remove the code, which sets the value in dfMessage. Send your new message to all the children of the form with a wParam value that may be either TRUE or FALSE (the best way
to do this is send bValueSet). Step 6: Modify the code for dfMessage: Handle the message PAM_AppMessage. When the message is received, evaluate wParam. If wParam is TRUE, set the data field value = "Hello World". If wParam is FALSE, clear the data field. Hint: You might want to use MyValue here. Step 7: Step 8: Step 9: Step 10: Save and test your application. Resize the form and the optional frame to be a bit longer, similar to the one in the Preview. Duplicate the data field three times making sure that each instance has a unique Object Name. Save and test your application again. Each data field you duplicated should behave exactly the same as your first. If so, you have completed the exercise correctly. If not - ask your instructor for ideas to fix the problem.
Notice the use of the user defined constant ADD. It is being passed as wParam. The above screen capture illustrates the code that resides in the Message Action section of the push button pbAdd. With the exception of the constant (ADD) being passed in wParam, the code is identical for push buttons pbSub, pbMult and pbDiv. The parent receives the message and passes the message on to its children
note
This illustrates the code that resides in the message actions section of the push button pbClear
The following sergment of code resides in the Form Window Message Actions section.
The remaining data fields, dfVar2 and dfnResult have the same code residing under their actions section as well. The reason we use a function is to provide a generic piece of code that will work regardless of the data type of the object.
Call SalSendMsg(hWndForm,SAM_Close,0,0)
Sends a SAM_Close statement to the parent window. If the parent does not handle SAM_Close the parent window will close automatically. If the parent does handle SAM_Close it can check to see if the user has any changes that were not saved. If so, it may prompt them to return and save those changes. Otherwise, the user may choose to close the window and lose the changes.
Example
Push Button pbExit
Preview
Templates
None. This exercise requires you to start a NEW application.
Tasks
Step 1: Step 2: Step 3: Step 4: Step 5: Save any previous work. Start a new application. Save it as Chapter 05 Exercise 1.app. Create all necessary PAM constants and user constants. Create a parent Form Window. Create three numeric data fields: One for the first value; One for the second value;
One for the result of any calculation - this data field should not be editable. Step 6: Step 7: Create Background Text item(s) for clarity. Create Push Buttons: One for Add; One for Subtract; One for Multiply; One for Divide; One for Exit; One for Clear. Step 8: You have now completed with the visual attributes and it is time to start programming the functionality. Turn to the Message Actions sections of the objects just created. Step 9: Step 10: Step 11: Code at the Form Window level to pass messages along (including wParam) to all child object that may handle the message. Code at the Data Field level to act upon the message(s) they receive such as Clear or calculate. Save and test your application.
What is SAL?
SAL -Scalable Application Language consists of: Data types Arrays Expressions Variables Operators Constants All of the above will be covered in this chapter. The following items will be covered in following chapters: Language statements Functions Object-oriented programming features
Date/Time
Date/Time can be a date variable, a time variable or a datetime variable.
File Handle
File Handle a 32-bit number used to uniquely reference a file. When a file is opened, the function, which opens that file, returns a file handle, which is used to determine the drive, path, filename and extension of the file.
Binary
This data type, introduced in TD 5.2, provides better support for binary data within SAL, including data from BLOB columns. To assign a value to a BINARY variable, use SalPicSetBinary, the BINARY_Null constant, or another BINARY variable. Example
Variables BINARY: binInput BINARY: binPic Set bOk = SalPicGetBinary(hWndPic,PIC_FormatObject,binInput) if (bOk) Set binPic=binInput
Long String
Long String is used when reading and writing LONG data (greater than or equal to 255 characters) with SQL databases.
Number
Number is used to store a number of any type. Specification of the number as a float, integer and so forth is not required. SQLWindows automatically allocates memory required for numeric data types and will also handle precision. If the result of a computation is numeric, SQLWindows will also automatically resolve any data type issues. For example, if an integer is divided by a float, SQLWindows will assign the result to a float.
Session Handle
Session Handle is similar to a File Handle but it is used to reference a session with a SQL database.
SqlHandle
SqlHandle is similar to a File Handle, but used to uniquely reference a connection to a SQL database.
String
String is a string data type, having no size limit other than available memory.
Window Handle
Window Handle is also similar to a File Handle. When a window is created, Microsoft Windows automatically assigns a Window Handle for that object. The Window Handle is unique for each object and is valid for the life of the object. Once the window has been closed, the handle can be re-used. Note: an object, which is minimized, is not closed.
Functional classes
Functional classes can be used as User Defined Variables and are covered in a later chapter.
Naming Conventions
The uses of prefixes for the data types are industry standard for Windows applications and are called Hungarian notation (in honor of the legendary Microsoft programmer Charles Simonyi). They are highly recommended. Using this notation will make it easier for other developers to read and maintain your applications. An example of Hungarian notation for a Boolean data type is bVariable.
Variable Declarations
SQLWindows is case sensitive so following a naming convention is important. As suggested earlier, the Hungarian notation is probably the best naming convention to use.
Syntax
<data type>: <variable_name>
The declaration location in the outline depends upon the scope of the variable.
Global Declarations
Variables
Form Window
The form frmBrowsePresidents has a child object of type Child Table called tblPresident. tblPresident has a Window Variables section where variables are declared within its scope.
System Variables
Variable
hWndForm hWndItem hWndMDI SqlDatabase SqlUser SqlPassword SqlResultSet wParam lParam nArgCount Window Handle Window Handle Window Handle String String String Boolean Number Number Number
Data Type
Number Number Boolean Boolean String array String <current item reference>
MyValue has no set data type and is useful for defining classes and class message handlers. bStaticsAsWindows has a default value of FALSE. When bStaticsAsWindows is set to FALSE, any passive objects being created on a form are painted. This saves system resources and provides better performance. However, passive objects can be created as separate objects and accessed using the SalGetFirstChild() and SalGetNextChild() functions. For this to happen, bStaticsAsWindows must be set to TRUE. STRING_Null is included here (arguably) as a system variable. Even though its value is constant (" "), its data type dynamically changes to string or long string, depending on usage.
Variable Qualification
There are three ways to reference a variable, not including referencing class and instance variables. The referencing of class and instance variables will be covered in a later chapter.
Syntax
<variable/object_name>
Qualified reference
A qualified reference uses the form name (or template) and the object or variable name to identify the object or variable. This method of referencing is used when two or more top-level objects have variables or objects of the same name.
Syntax
<form_name>.<variable/object_name>
Syntax
<parent_window_handle>.<qualified_reference>
Window Handles
When a window is created, a unique window handle value is established by Microsoft Windows for that object. The window handle is used for accessing that window. The window handle value remains for the life of that window. A window handle is a number value (range: 1 to 4,294,967,295). Window object names can be used as function parameters requiring a parameter of type window handle. How is dfField being used in each of the following?
hWndItem
The item which currently has the focus, or which is currently receiving a message. hWndItem refers to the child object which currently has focus or which is currently receiving a message. In the case of a table window, hWndItem refers to the column, which currently has focus. In the event of a form having no child objects, or a Table Window having no columns (e.g. On SAM_Create for the objects), then hWndForm = hWndItem until the first child object is created.
hWndMDI
The current MDI parent window handle
Arrays
SQLWindows supports three types of array declarations. The arrays can be of any valid variable type, including an array of functional classes instances (UDVs). Elements start at position zero (by default). The first element is at position zero (unless a range is declared other than zero)
Syntax
<data type>:<variable name>[ <array_size> ]
Array_size options
Arrays can be expressed as either a number of elements or as a range of elements, where the start and end of the range is supplied. Arrays can also be dynamically sized. Arrays can be multi-dimensional. However, only the first dimension can be dynamic. Consult your SQLWindows manual or on-line help document for more details. However, only the first dimension of a multi-dimensional array can be dynamic
Number of elements
[n]
A range of elements
[ n:m ]
A dynamic range
[*]
A 2-dimensional array
[ n, m ]
A 4-dimensional array
[ *, n, m, p ]
Array Examples
The array dtMonth[1:12] is an array of datetime variables, which starts at element 1 and goes to element 12. The array could have been specified as dtMonth[12]. This would give an array with 12 elements, but the range would have been from dtMonth[0] to dtMonth[11]. It is probably easier to use 1 to 12 as we do in every day life.
The array nID and has a dynamic range. The elements of this array begin at zero.
Questions
How many elements are there in the array sError? What is the range of sError?
Array Functions
Array functions are available for querying and changing the size of an array.note
note
The second parameter of the SalArray*Bound( ) functions are the dimension of the array. For standard single dimension arrays this will be one (1).
nArgCount
nArgCount is the number of command line arguments. The number of command line arguments always includes the name of the .exe or .run file. This means nArgCount will always be >=1.
strArgArray[ * ]
strArgArray[ * ] is an array of command line arguments. strArgArray[0] will always represent the name of the application (including any specified path). Elements 1, 2, ..... are subsequent arguments passed to the application.
Operators
Numeric
+, -, *, /
Unary
The unary operation - negates a value and hence needs only one operand
Relational
=, !=, >, <, >=, <=
Parentheses
( )
Parentheses ( ) are used the same as in all major languages. In the case of nested parentheses, the inner most parentheses are evaluated first and then evaluation takes place as the level of nesting reduces.
Boolean
AND, OR, NOT These are the only case-insensitive words in SAL.
Bitwise
The bitwise AND operator is & and the bitwise OR operator is |.
String Concatenation
||
Variable Expressions
Variable expressions (which may consist of a function; a variable, including a field or another window; a constant or a combination of expressions and operators) always equate to a single value.
Examples
Set dfDate = SalDateCurrent()
The function returns a single value, which is assigned to the dfDate data field.
Constants
May be defined for these SQLWindows data types Boolean Date/time Number String
Syntax
<data type> : <constant name> = <constant expression>
A constant expression is similar to a variable expression except that it may not contain references to variables.
System Constants
SQLWindows has a number of pre-defined system constants TRUE FALSE NUMBER_Null DATETIME_Null OBJ_Null hWndNULL hWndNULL is the null window handle. A window handle is simply a number, therefore hWndNULL can be tested to equal zero. If the SalCreateWindow() function returns hWndNULL, this means the window was not created successfully. SAM_User STRING_Null In some databases, a Null string differs from a zero length string. In SQLBase they do not.
SAL Statements
SAL has the following statements. We will discuss each one of them in more detail in the following pages. Call If ... Else If ... Else Loop ... Break On Return Select Case ... Case ... Default Set When SQLError While ! Comments
Call Statement
The Call statement invokes a function. Functions can be invoked either explicitly via the Call statement or implicitly in another statement.
Syntax
Call <function_name( [ parameter1[, ] ] )>
Example
In this example we see both explicit and implicit invocation of functions. SalQuit, SalNumberToStr and SalMessageBox are invoked explicitly, whereas SalStrLeftX and SalStrLength are invoked implicitly as part of an expression. Functions can be nested and called recursively, assuming the logic within the function accommodates recursive calling. In the example, SalStrLeftX( sErrorString, SalStrLength( sErrorString ) - 4) we see nested calling of functions. Also, you will note the use of the exclamation mark (!) at the beginning of a line for comments.
IF Statement
The 'If' statement is used to control logic by testing the value of a variable. If the test returns TRUE, all code underneath and indented below the If statement is executed.
Syntax
If <expression1> statement(s)... [ Else If <expression2> ] statement(s)... [ Else If <expression3> ] statement(s)... [ Else ] ...statement(s)...
Notes
If NOT <expression> can also be tested. The Else and Else If are optional, although very often used. The logic is controlled by the indentation of the code. There is no need for the Begin...End, or { } statements to control the execution of the code.
Example
The application has two numeric constants declared, RESET = 1 and SAVE = 2. There is also a numeric window variable declared as nValue. The Actions section is from a menu of the form.
LOOP Statement
The Loop and Break statements are used in conjunction to loop through a block of code until a required breakpoint is reached. If there is no Break then the application will continue to loop forever!
Syntax
Loop [loop_name] Break [loop_name]
Example
If Break is executed in a nested loop then the application will break out of the current level of loop. That is to say, it will break back one level. In this example, the loop is performed 100 times. Once n = 100 then the Break is encountered and we break out of the current loop.
Named Loops
When a loop is defined it can optionally be given a name. The loop name can be used to break out from any level of nested loops by using Break name, where name is the name assigned to the loop.
Example
ON Statement
The On statement is used to define a message handler.
Syntax
On <message_name>
Example
The example shows the code executed when the form is created. The code defines the Database, user name and password for the database connection. The connection to the database is made using the SqlConnect(hSql), where hiSql is a variable declared elsewhere. The SalFileGetCurrentDirectory(siCurrentDirectory) assigns the value of the current directory to the variable siCurrentDirectory.
RETURN Statement
The Return statement can often be confusing because of its various meanings and uses. In some cases it is used to return a value to the calling statement. In other cases it is used to stop further processing.
Syntax
Return <return_value>
Return a value
Here, the function is simply returning a value for a variable. The return section of the function specifies the data type to be returned, not the variable name. The function performs some processing and returns the value of the variable. To work correctly, this example ought to have defined the variable nValue as a Static Variable in order to preserve its value between calls. Otherwise (as in this code), nValue will always have a value of 100 when it is returned.
Halt processing
In this example, the Menu Return is being used to halt processing. Return does not stop the application itself, but it will stop processing the current message loop. We could return anything, so return StopProcessingMessage might be another example, provided StopProcessingMessage had been declared as a constant.
Syntax
Select Case <number expression> Case <number constant1> ...statement(s) Break [Case ... ...statement(s) Break ...] [Default ...statement(s)]
The Default case should always be included to account for the situation when the numeric expression does not match any of the Case conditions.
NOTE
Example
In this example, the constants for CLOSE, DELETE, OPEN_READ & OPEN_WRITE are declared elsewhere. When the DoFileHandling() function is called it takes four parameters: a file handle (hFile), a string holding the name of the file (sName), a number for the command (nCommand) and a number (nOpenFlag) containing the OF_* constant which is used by the OPEN_READ and OPEN_WRITE command to indicate whether a READ or WRITE open is required. The Actions Section has a Select Case, which checks the value of nCommand (the third parameter passed to the function). If nCommand = CLOSE then the SalFileClose() function is called. If nCommand = DELETE the SalFileOpen() function, with the OF_Delete is called to delete the file.
If nCommand = OPEN_READ or OPEN_WRITE the same block of code is executed. This is because there is no Break indented and underneath the Case OPEN_READ statement. If nCommand NOT = CLOSE, DELETE, OPEN_READ or OPEN_WRITE, then the default action is executed. In this example, a message box is displayed with the error message.
NOTE
The Break statement may be required. Otherwise program flow continues into the next block.
SET Statement
Set is used to assign a value to a variable, including setting the 'visible string attribute' of a window object. The variable must be declared before it can be used. If a variable is not declared then an error will occur during compilation.
Syntax
Set <variable/field name = expression>
Example
In this example, the following two lines of code result in the same thing:
Syntax
When SQLError [statement] [statement] Call <Sql* function>
Example
WHILE Statement
The While statement is an alternative to the Loop statement. Any code indented and following the While statement will be executed each time the loop is entered.
Syntax
While <expression> [statement]
Example Questions
What is the difference between the Loop and the While statements? Which is better: a Loop or a While statement?
External Functions
External functions only contain the argument template information for the function in the application's Global Declaration > External Functions section. There is no code to define the logic of the function within the application. External functions which are stored in DLLs ( Dynamic Linked Library) for Microsoft OS or LIBs for Linux. USER32.DLL, for example, is a DLL used extensively by Microsoft Windows. They can be defined either by Function Name or by Export Ordinal. If you use the correct function name you can specify 0 for the export ordinal. Each function has an ordinal number declared in the library's *.DEF file. You can determine a function's export ordinal by running a utility such as QuickView.
The Library name is the name of the DLL containing the function(s) you intend to use in your application. The Function name is the name by which you are going to reference the function from within your application. The function name does not have to be the same name as the function within the DLL, as long as the correct ordinal number is specified. The Ordinal number is a unique positive integer, which identifies each function within the exports section of the module definition file. It can be 0 if the correct function name is specified. The ordinal numbers for all of the functions within a DLL should be well documented, along with the return type for the function, the parameters for the function and a description of what the function does.
The lines of code above determine the Window Handle of the menu and call the external function below to append a menu item to the system menu.
In the Parameters section, a mapping is provided between the SAL data types we will use in our program, and the C data type employed by the external function. There is no logic within the SQLWindows application; it is all contained within the DLL. The DLL being used is USER32.DLL, which is used by Microsoft Windows to define both the user interface and windowing. The application used in this demonstration is Chapter 07 Demo 1.app. The function call in this example is from the USER32.DLL found in the SYSTEM sub-directory of your WINDOWS directory.
Internal Functions
An Internal function has the code for the logic of the function contained within the application itself and is written purely in SAL. Argument template information is provided for each function by the Coding Assistant.
In Global Declarations
Internal Functions section
In Class Definitions.
(Also to be discussed in a later chapter.)
Receive Parameters
A reveive parameter is a data type that lets you pass data to a function by reference rather than by value. Receive variables allow the called function to change the variable passed by the calling function. Receive parameters may be any valid SQLWindows data type As the fourth parameter we are passing the name of dfnResult. Because this is defined as a receive parameter on the next page, we are actually passing the address of dfnResult, not a value.
You will now create and implement an internal function. The internal function will resolve this problem and the code will be more reusable and portable as a result.
Preview
Templates
Use template Chapter 07 Template 1.app or if you completed Chapter 05 Exercise 1.app, you may use that.
Tasks
Step 1: Step 2: Step 3: Step 4: Save any previous work. Open the Template or previous exercise. Save it as Chapter 07 Exercise 1.app. Create a push button named pbError with a title of Test Error that will send a PAM_Calc message to the Form Window and in wParam send the number 10. Create an Internal Function at the Form Window level. Name the function fnMyCalc and define parameters for each of the following: One to determine the type of mathematical operation to be performed; one each for the first and second arguments; and a receive parameter to place the result in. Step 5: Additionally, you should find a way to implement an error checking routine using the Default portion of the case statement. For example, what if some value other than 1 through 4 were sent to the function? It would execute the Default case. This really would be an error since we only planned on Add, Subtract, Multiply and Divide. Modify the On PAM_Calc section of code for the data field dfnResult so that it calls your function. Save and test your application.
Step 6: Step 7:
What is SQL?
SQL stands for Structured Query Language, a relational (set-oriented) database language that is made up of statements, which allow the defining, manipulating and controlling of data. It was originally developed by IBM and is now the industry/ANSI standard. It is English-like and non-procedural.
Manipulate data
SELECT INSERT UPDATE DELETE
SELECT Statement
SELECT is used to retrieve rows of data SELECT can be used to Retrieve a subset of columns Retrieve a subset of rows Sort the retrieved data Retrieve data from more than one table Group the retrieved data rows Summarize data for groups of rows All data is returned in the form of a result table
Syntax
SELECT [ALL | DISTINCT] expression {,expression}
Unconditional Retrievals
Retrieving all rows
Query
SELECT film_name, release_year FROM hollywd.film;
Examples
SELECT character_name FROM role WHERE first_name = 'Humphrey';
SELECT * FROM prod_company WHERE country = 'France'; SELECT film_name, genre, star_rating FROM film WHERE run_time_mins >= 120 AND run_time_mins <= 180;
Arithmetic
+, - (sign) *, / +, - (addition/subtraction)
Logical
NOT AND OR
Pattern Matching
The LIKE predicate searches for strings that match a specified pattern. It can only be used with CHAR or VARCHAR data types. These searches are case sensitive.
Syntax
columnname [NOT] LIKE pattern
There are two pattern match characters. Underscore (_) matches any single character . Percent (%) matches 0 or more characters.
Sorting Data
ORDER BY specifies the ordering, or sorting, of rows in a result set. Rows can be sorted on more than one column. The major sort is on the first column specified in the ORDER BY clause with the minor sorts on columns specified after that.
Syntax
SELECT ... FROM tablename [WHERE search_condition] [ORDER BY columnname [ASC | DESC] {,columnname,}]
Example
SELECT film_name, director, genre, release_year FROM film WHERE release_year > 1978 ORDER BY release_year DESC;
Aggregate Functions
An aggregate function computes one summary value from a group of values. Can be applied to the data values of an entire table or to a subset of the rows in a table Sometimes known as 'Set functions'
Available functions
AVG COUNT
Examples
SELECT AVG(run_time_mins) FROM film;
A Simple Join
Task
Find which production company made the film 'Casablanca' and also which country.
Query
SELECT prod_company.company_name, prod_company.country FROM film, prod_company WHERE film.film_name = 'Casablanca' AND film.prod_comp_id= prod_company.prod_comp_id;
Task
Find the film name, and the roles in those films, for all films starting with letters S through Z - using a simple join.
Query
SELECT film.film_name, role.character_name FROM film, role WHERE film.film_name = role.film_name AND film.film_name >= 'S%';
Complex Joins
Consider the situation where two tables are to be joined, but the second table does not always contain a row for every row in the first table. By default, SQL only returns rows where data exists in both tables (this is a standard, 'Equi Join') To get all rows from the first table, regardless of the existence of any corresponding rows in the second table, it is necessary to perform an 'Outer Join'
Syntax
Syntax is to place a bracketed plus sign (+) after the column where nulls may exist.
Example
SELECT film.film_name, role.character_name FROM film, role WHERE film.film_name = role.film_name(+) AND film.film_name >= 'S%';
Correlation Names
A correlation name is simply an abbreviation for a table name used in an SQL statement. It can also be used whenever you need to refer to a table more than once in the same sub-select.
Example
SELECT p.company_name, p.country FROM film f, prod_company p WHERE f.film_name LIKE 'Cas%' AND f.prod_comp_id = p.prod_comp_id;
INSERT Statement
Inserts new rows of data into a table. There is a one-to-one correspondence between column and expression. Any unspecified columns will default to base table definitions.
Syntax
INSERT INTO tablename ([column {,column,}]) VALUES (expr {,expr})
Example
INSERT INTO film (film_name, prod_comp_id, release_year, run_time_mins) VALUES ('Magnificent Seven', 'MA', 1960, 128);
UPDATE Statement
Syntax
UPDATE tablename SET columnname = expr {,columnname = expr} WHERE search_condition
Example
UPDATE film SET director = 'Sturges', star_rating = 4 WHERE film_name = 'Magnificent Seven';
Warning: If you do not include a WHERE clause you can update ALL rows in a table.
DELETE Statement
Syntax
DELETE FROM tablename [WHERE search_condition]
Example
DELETE FROM film WHERE film_name = 'Magnificent Seven';
Warning: If you do not include a WHERE clause you can delete ALL rows from a table.
COMMIT Statement
The COMMIT statement makes permanent any changes to a database in a transaction, and also releases most locks acquired during the transaction. If you do wish to undo any changes made by a transaction, use the ROLLBACK statement. We will talk in more depth about transactions in the chapter 'Working with SQL Databases'.
Template
None. In this exercise you will write your own SQL statements.
Tasks
Step 1: Invoke Database Explorer (or SQLTalk for Windows). Step 2: Connect to the PRESIDNT database. Step 3: What are the names of Presidents born in the state of Texas? Step 4: What are the names of those Presidents with more than four children. Step 5: What was the name and party of the President elected in 1972? Step 6: Congratulations! You have just been elected the next president of the United States. Insert your own personal details into the President table. Be sure to leave the death_age blank as it is needed for the next step. Step 7: Generate a list of all Presidents that are still alive, along with any wives that they have had. Try this as an equal-join (notice that you ought not to appear because you don't have an entry in the Pres_marriage table). Now try this as an outer join (then you should appear in the list). Step 8: Unfortunately, there has just been a recount. You have lost the election to Arnold Schwarzenegger, who is now demanding that you delete your name from the President table. Please do this now. Step 9: Don't forget to COMMIT your changes. Step 10.Exit
Connecting to a Database
In the Client/Server environment, a database is uniquely identified by its database name. Knowledge of the operating system and network interface is not needed by a programmer or end-user. An application simply connects to a database with a username and a password.
SqlConnect (hSql)
The following system variables are used when SqlConnect is called SqlDatabase - Identifies the database, independent of DBMS or platform Default is ISLAND SqlUser - Identifies the user Default is SYSADM SqlPassword - Specifies the password Default is SYSADM Variables can be changed during application execution in your application, you may want to connect to a different database or with different user names. In this case, simply change the relevant system variable before issuing a SqlConnect() call and the appropriate connection will be established.
Sql Handles
An application is connected to a database via a Sql Handle. A Sql Handle is similar in concept to a file handle or a pipe in that it establishes the connection to a data source. Similar concepts are a cursor, a pipe, and a file handle. Sql Handles may be initialized either explicitly (via SqlConnect) or implicitly (via SqlImmediate()). A Sql Handle can accommodate only one SQL statement at a time. Anytime you expect to execute the same SQL statement repeatedly, use different Sql Handles for other SQL statements. Generally, it is wise to use a different Sql Handle for each of the following operations: Populating a table window Routine inserts updates and deletes Ad hoc updates and deletes in the course of error processing
Create a Session
SqlCreateSession ( hSessionHandle, sSessionProperties )
If you are not connecting to the database through OLE DB, the second parameter must be Null.
Commit a Session
SqlCommitSession ( hSessionHandle )
The SQL operations currently active on all the statements belonging to this session get committed.
Free a Session
SqlFreeSession ( hSessionHandle )
If there are any open statements belonging to this session, they are closed before the session is freed.
Message
On SAM_AppExit
Function
bOk = SqlDisconnect( hSql )
Example
Example
Prefix the variable or field with a colon (:) A maximum of 255 INTOs variables are allowed in a SQL statement
Example
SqlPrepare
SQLWindows parses out the INTO clause of a SELECT statement and sets up the INTO and BIND variables. The DBMS clears the cursor workspace and input and output buffers. The statement is parsed, privileges, tables and columns are checked. The execution plan is generated. Buffers are allocated. Statement is compiled and stored in cursor workspace.
note
Declaration
bOk = SqlPrepare( hSql, sCommand )
Any illegal BIND or INTO variable is caught here by SQLWindows as a run-time error. However, SQLWindows doesn't search for existence of the variables at this point; that happens in the next step.
note
SQLBase allows storage of a SQL command directly into the database Command is compiled/prepared and stored Stored Commands can later be retrieved for execution Using stored commands is generally faster than calling SqlPrepare() to prepare the command
Declarations
bOk = SqlStore( hSql, sCmdName, sCommand ) bOk = SqlRetrieve( hSql, sCmdName, sBindList, sIntoList ) bOk = SqlDropStoredCmd( hSql, sCmdName )
note
SqlExecute
SQLWindows locates the BIND and INTO variables, and sends off any BIND data.
Database executes prepared/retrieved SQL statement, after binding any data. For a Query, a result set is generated. For SQLBase, result set is kept as a list of ROWIDs on the server. For foreign backend's, if result set mode is ON the result set is maintained by the client-side router; called Front-End Result Sets (FERS). Result set mode is OFF by default. In SQLWindows it is changed by SqlResultSet ( ).
Declaration
bOk = SqlExecute( hSql )
SqlPrepareAndExecute
Combination of SqlPrepare() and SqlExecute() Prepares, binds and executes a SQL statement If no bind variables, uses one API call rather than two If already prepared will only execute the statement
Declaration
bRtn = SqlPrepareAndExecute( hSql, sCommand )
Fetching Data
A prepared/executed SQL SELECT command is required A SqlFetch* ( ) retrieves a row of data from the result set, and populates INTO variables with database table column values from the current result set row. For all the SqlFetch* ( ..., nIndicator ) functions: Function returns TRUE if there was a row to fetch, and nIndicator = FETCH_Ok Function returns FALSE if it could not fetch a row, and nIndicator = one of the following: FETCH_EOF FETCH_Update FETCH_Delete
SqlFetchNext()
Moves Sql Handle to the next row in the Result Set.
SqlFetchPrevious()
Moves Sql Handle to the previous row in the Result Set. A FETCH_* constant is returned in the Receive Number parameter nIndicator
Declarations
bOk = SqlFetchNext( hSql, nIndicator ) bOk = SqlFetchPrevious( hSql, nIndicator)
Using SqlPrepare
The Actions for a function - DoSelect
What is a Transaction?
Most DBMSs have the notion of a transaction. A transaction is defined as a logical series of operations, which belong together. At the end of the process, all changes made to the database are either committed or rolled back. A transaction consists of all Sql Handles to a given database and for a given user. If you are using Session Handles, a transaction consists of all SqlHandles to a given Session Handle. The rest of this discussion does not apply directly to Sessions.
Transaction begins when the first SqlConnect() is issued (implicitly or explicitly) either at beginning of execution or after a previous COMMIT/ROLLBACK. Transaction ends when a COMMIT or ROLLBACK is issued
COMMIT
Make permanent any changes. Transactions begin when an application instance connects the first Sql Handle and end (and begin again) when a program/user COMMITs or ROLLBACKs the work done within the transaction by use of either SqlCommit() or SqlImmediate(). Transactions will be implicitly committed when you disconnect the last Sql Handle from a database. Be careful; this may not always be what you intend. Note You need to understand the transaction behavior of the server that you are working with.
ROLLBACK
Discard any changes (be aware, ROLLBACK is generally a costly process no matter what the RDBMS)
Functions
SqlImmediate( 'COMMIT' ) SqlCommit( hSql ) SqlImmediate( 'ROLLBACK' ) SqlPrepareAndExecute( hSql, 'ROLLBACK' )
Locks
During the course of a transaction, the database engine may need to acquire locks on data, which may affect other users' access to data. A detailed discussion of transaction design is beyond the scope of this course. However, it is important that you realize the need to COMMIT changes. In general, write locks are held for the duration of a transaction, whereas the duration of read locks depends upon the DBMS being used (and the isolation level).
Preview
In this exercise we are concentrating on the SQL query cycle. However, in a real world situation, one might make this application more message driven as you learned in a previous chapter. If you have completed this exercise early, you might start implementing messaging as an additional exercise.
Templates
None. This exercise requires you to start a NEW application.
Tasks
Step 1: Step 2: Step 3: Step 4: Save any previous work. Start a new application. Save it as Chapter 11 Exercise 1.app. Define two Global Variables to manage a database connection. The first is a Sql Handle, g_hSqlSelect, and the second is a Boolean variable, g_bConnected, to track your success or failure in getting a connection Create a Form Window (see Preview) with data fields and their associated background text for the following: Name, Death Age, Birth date, Party, Yrs Served and State Born. Check and make sure you have specified the correct data types for each data field in the Attribute Inspector. Step 5: Step 6: Create two push buttons on the form: one to allow the user to see the next record, the second to see the previous record. These should initially be disabled (SalDisableWindow()) Create a numeric Window Variable nInd to track where we are in the data set. We use this as a return variable in our SQL statements. Its pool of possible values are: Error! No se encuentran elementos de tabla de ilustraciones.
Constant FETCH_Ok FETCH_EOF FETCH_Update FETCH_Delete Step 7: Step 8: Step 9: Step 10:
Value 0 1 2 3
Meaning OK End Of File (EOF) Rows were updated since last fetch unsuccessful fetch Row was deleted unsuccessful fetch
In Application Actions (when the application starts), connect to the PRESIDNT database. You will connect the global Sql Handle to this database. If the connect is successful, set our Boolean variable g_bConnected to TRUE. In Application Actions (when the application ends), if the Sql Handle was successfully connected, it should be disconnected at this time. It will be necessary to create one pop-up menu with an option to exit the application and one menu item to populate the data set and retrieve the first row of data. Write the code required for the Select_All! menu option. The code should prepare and execute a SQL Statement that selects all presidents from the database. Fetch the first row and, if this is successful, enable the Next push button (SalEnableWindow()).
Step 11:
Write the code required for the pbNext push button. It should fetch the next record. If the fetch reaches the end of the set, inform the user and disable this button. Always enable the Previous push button.
Step 12: Write the code required for the pbPrevious push button. Fetch the previous record. If the fetch reaches the start of the set, inform the user and disable this button. Always enable the Next push button. Step 13: Save and Test your application.
Syntax
hWndCreated = SalCreateWindow(tWndToCreate,hWndOwner{,Param})
tWndToCreate is the name of the window to create
SalDestroyWindow
Use the function SalDestroyWindow( ) to close a form window programmatically.
Syntax
SalDestroyWindow(hWndCreated)
SalModalDialog
SalModalDialog( ) is used to show a modal dialog box. A modal dialog box is a type of form that suspends the application (or entire system) until the user closes the dialog box. This means that any code that appears after the call to SalModalDialog does not execute until the user closes the dialog. If an input value is required from the user in order to continue processing, SalModalDialog should be used. SalModalDialog can be used with Modal Dialog Boxes and System Modal Dialog Boxes. Optionally passes data to/from window
Syntax
hWndModal = SalModalDialog(tDlgBoxToCreate,hWndOwner{,Param})
tDlgBoxToCreate - the name of the dialog box to use
SalEndDialog
Destroys a modal dialog box and returns control to the caller
Syntax
SalEndDialog(hWndModal,nReturn)
SalWaitCursor
Displays or removes the hourglass cursor
Syntax
SalWaitCursor( bOn )
TRUE turns on hourglass FALSE turns off hourglass
Variables
tWndToCreate and tDlgBoxToCreate
Where you place the name of the template from which to create the form window or dialog box. The object name of a top-level window object is also known as the template name (i.e. frm1, or dlgLogin).
hWndOwner
The window handle of the form or dialog that will own the object you create. Usually, this will be the object from which you call the function SalCreateWindow or SalModalDialog. The form or dialog you create will always stay on top of its owner, even if the focus is put back on the owner. A call to SalParentWindow( ) from within the form or dialog you created will return the window handle of its owner. If you close the owner, the form or dialog you created will automatically be closed as well. If you don't want the form or dialog to be owned by any other window, specify the constant hWndNULL for hWndOwner.
Modal Dialog
A modal dialog box must be created with a call to SalModalDialog( ). This type of dialog box suspends any execution (after the call to SalModalDialog) until the user closes the dialog box. The user cannot put the focus on any other form or dialog within the current application. They can still switch to another application in the system if they wish, but when they return to your application, the focus will still be on the dialog box. This type of dialog is typically used when user input is required before processing continues.
Modeless
A modeless dialog box must be created with SalCreateWindow( ). It behaves in much the same way as a form window except it cannot have a menu. With this type of dialog box, code execution in the calling routine continues as soon as the form is created. This type of dialog might be used as a tool palette that floats on top of its owner at all times. The user could switch focus back and forth between the owner and the dialog as they wished.
Library Files
A library file is like any other SQLWindows program. It may be saved in either normal or text format. A library file is referenced in the Libraries Section. The included code appears in the parent application in a different color or font. The code cannot be edited in the referencing program. To change the code you must edit the Library itself. A quick way to achieve this is to highlight the line in question and right-click | Go to library item (or <F5>). A new copy of SQLWindows is started with the Library file opened within it. The same library file can be used by many programs.
Preview
Templates
Part 1: None Part 2: Use template Chapter 10 Template 1.app or if you completed Chapter 9 Exercise 1.app, you may use that.
Tasks
Step 1: Step 2: Step 3: Step 4: Save any previous work. PART 1: Start a new application. Save it as Chapter 10 Exercise 1.apl. Create a Dialog Box dlgLogin. Add a Receive Window Parameter, hSqlParam, which will be passed in when the dialog is created and will return the connected Sql Handle to the calling routine. Step 5: Step 6: Step 7: Add data fields for: Database, UserID, & Password Initialize the Database to 'PRESIDNT' and UserID and Password fields to 'PRESIDNT' when they are created. Add a Cancel push button - pbCancel. This button will be used to quit the application if the user does not want to login, or cannot login for some reason. Set the keyboard accelerator to the <Esc> key. When the user clicks pbCancel, create code that closes the dialog box and returns FALSE (SalEndDialog). Step 8: Create two variables local to the dialog box: bConnect & hSqlLocal.
Step 9:
Add a Connect push button, pbConnect. This button will be used to connect to the database. Set the keyboard accelerator to be the <Enter> key. When the user clicks pbConnect, create code to display the Hourglass, set the SQL database parameters and then connect the handle, hSqlLocal, to the database. If the connect succeeds, set the window parameter hSqlParam equal to hSqlLocal, close the dialog and return TRUE
Save the Library file. Part 2: Open the template or your previous completed exercise. Save it as Chapter 10 Exercise 1.app. Add a line in the Libraries section to include Chapter 10 Exercise 01.apl. Notice that the code for dlgLogin now appears in this program, but in a different font or color. Also notice that you cannot edit the code here. If you need to edit the code, you can highlight the code and right-click then select Go to library item. Modify the SAM_AppStartup code to use your Dialog Box (SalModalDialog). Pass it the global Sql Handle g_hSqlSelect . The dialog box replaces the hard-coded database, user name and password assignments, as well as the call to SqlConnect that we coded earlier. If the call returns FALSE, quit the APP like we did if SqlConnect returned FALSE. If the return is TRUE, create frmMain (SalCreateWindow). Change the 'Automatically Create' property of frmMain to be NO. Previously, frmMain was automatically created by SQL Windows when the program started. Now, with this code, we control the creation of it from within the program. Save and test your application. Try entering an invalid parameter to see the behavior of the default error handler.
Step 13:
Step 14:
Step 15:
When SQLError
A local error handler, for any specific error handling; special-case certain local errors.
On SAM_SqlError
A global error handler, for more general error handling; special-case general errors.
wParam
Sql Handle, which generated error
lParam
Contains the error position in the SQL statement and the error number.
When SqlError
A local error handler. Must be located above and at the same indent level as the Sql* ( ) statement(s) you are trapping.
Question
Why will the code on the bottom NOT work if there is an error in execution of the SqlPrepare call?
Preview
Template
Use template Chapter 10 Template 2.app and Chapter 10 Template 2.apl or if you completed Chapter 10 Exercise 1.apl and Chapter 10 Exercise 1.app, you may use that.
Tasks
Step 1: Step 2: Step 3: Save any previous work. Open the library file; the template ( .apl) or your previous completed exercise (.apl). Save it as Chapter 10 Exercise 2.app. Now open the applications file: the template (.app) or your previous completed exercise (.app). Save it as Chapter 10 Exercise 2.app. Step 4: Step 5: Step 6: Change the Libraries section to reference Chapter 10 Exercise 2.apl. Save this change. Open the library file Chapter 10 Exercise 2.apl again. Define global constants for the errors: SQL_Err_NoDatabase = 401 SQL_Err_InvalidPassword = 404 SQL_Err_InvalidUserName = 405 Step 7: Define Dialog Box Window Variables: Sql Handle: hSqlError Number: nSqlError Number: nSqlErrorPosition Step 8: Modify the click action for pbConnect, to include local error handler code (When SqlError). Ensure this code appears before the call to SqlConnect and at the same level of indentation. The code in the error handler should extract the error parameters, test them against the constants above and display appropriate messages. If the error is one of these three, return FALSE. If not, do nothing (so that the error falls through to default error processing). Step 9: Step 10: Step 11: Save the library and return to your application. Re-run your application to test your new error handler. Return to the library and remove the maximum character length constraint in the properties of the Database data field. Save the library and return to your application. Test that default error processing occurs if you enter a nine-character database name. Step 12: Add your own global error handler to your application. Capture the message SAM_SqlError and display a message saying 'An unknown database error occurred. Quit the application?'. Offer the user the opportunity to click Yes or No. If the user clicks Yes, quit the application. If the user clicks No, let the program fall through to default error processing.
Step 13:
Save the program and test. Try entering a nine-character database name to test the behavior of your global error handler.
Data Driven
Data can come from any source(s) SQL databases Flat files Other external sources (Internet, TP Monitors, SAP, and so on) Several features simplify working with SQL databases. Can perform bulk DML (SQL UPDATE, INSERT or DELETE) based on marked rows SQLWindows supports automatic population from a SQL database via the function, SalTblPopulate. In addition, the programmer can manually populate a table from any other source. Table Windows maintain their own dynamic memory cache to locally buffer their data (this is covered in more detail later in this chapter).
A Column is a vertical content item and is the only child object allowed in a Table Window.
Cell
A Cell is the intersection of a row with a column
Focus Frame
The Focus Frame is the bold outline (top and bottom), which identifies the focus row, or the row, which contains the focus cell
Focus Row
That row most recently selected by the user (can also be set programmatically). Bounded by the focus frame, it is the row, which will receive user input or affected by user actions
Focus Cell
note2
The Focus Cell is the cell, which has the input focus (with the blinking I-beam cursor)
Selected Row
The Selected Row is the row shown in reverse video. A row can be selected by a user by: Clicking on the row using the right mouse button Clicking on the row header Clicking on a non-editable column in the row To select multiple rows use: Click and drag Shift + Click (multiple contiguous rows) Ctrl + Click (multiple non-contiguous rows) Keyboard interface: Shift + up/down arrow keys To select programmatically, use SalTblSetFocusRow( ).
Visible Range
Visible Range is the number of rows, which can be visible at the same time in the Table Window
Row Header
The gray non-editable column at the far left-hand side of the Table Window (the row header may be hidden)
Column Header
The Column Header is the gray non-editable title at the top of every column.
note1 note2
A blinking I-beam in a cell identifies it as the focus cell (not shown on this diagram.) A top-level Table Window can have a Toolbar, Status Bar and Menu Items.
Default: 100
nFillMethod
TBL_FillNormal
Populates visible range, displays Table Window, then dynamically fetches additional rows as the Table Window is scrolled
TBL_FillAllBackground
Populates visible range, displays Table Window, then populates rest in background. Currently, the background population is equivalent to 4 rows per second. When all rows have been populated, a SAM_FetchDone message is sent to the Table Window.
TBL_FillAll
Populates entire range before displaying Table Window If TBL_FillNormal or TBL_FillAllBackground is employed, the Sql Handle used must be dedicated to the Table Window. The recommended starting point is TBL_FillNormal. If you know that the result sets will be small, you may want to use TBL_FillAll. TBL_FillAllBackground is suitable for some applications. If a Table Window is being populated from a database with other than TBL_FillAll, the programmer must ensure a valid Sql Handle will be maintained for the duration of the Table Window's existence. For example, with TBL_FillNormal, user scrolling will cause the SQLWindows Table Window Engine to fetch additional rows. The engine will expect to use the same Sql Handle, and presumes that it retains the same result set and column binding.
SAM_FetchRowDone
Requested row has been populated into table, lParam has the fetched row number. Use this message to execute code after a row has been fetched. For example, calculating a derived value.
SAM_CacheFull
Cache cannot grow and no row can be discarded
SAM_CountRows
Table Window needs to get range.
SAM_FetchDone
Completed background SQL fetch for Table Windows populated with TBL_FillAllBackground.
SAM_RowValidate
Allows for row level validation. Sent when you set the focus to a different row (or a cell in a different row) and changes were made to the previous row.
SAM_Click
In a non-editable column only
SAM_DoubleClick
In a non-editable column only
We will demonstrate the execution of the application. We will show how the features were developed: Create a new Form Window-based application. Add a Table Window. Define Table Window columns. Include the Login dialog box library. Connect to a database. Populate the Table Window from the database.
Previously we connected to the database during AppStartup. The decision on where to place the database connection is purely a design decision.
Preview
Templates
None. This exercise requires you start a NEW application. It requires the library file Chapter 11 Exercise 2.apl.
Tasks
Step 1: Step 2: Save any previous work. Create a new application. Save it as Chapter 11 Exercise 1.app. Step 3: Create a parent Form Window.
Add a Child Table Window and an "Exit" push button to the form. Create columns for the president's name, state born, birth date, party, spouse, spouse's age and number of children. Add the library file for the Login dialog box you created in the previous chapter to the application. You should have saved it as Chapter 10 Exercise 2.apl
Step 7: Step 8:
In the Form Window's variable section, add a Sql Handle variable. Add Message Actions to the Form Window to: connect the Sql Handle, using the Login dialog box, in the SAM_Create message handler; disconnect the handle in the SAM_Destroy message handler.
Step 9:
In the functions section of the Child Table Window, add a Populate function which when called, will use SalTblPopulate to fill
the Table Window with columns from the president and spouse tables, joined by pres_name. Step 10: Step 11: Call your Populate function from an On SAM_CreateComplete action on the Child Table Window. Save the program and test.
Defining a Message
Preview
Templates
Use template Chapter 11 Template 2.app or if you completed Chapter 11 Exercise 1.app, you may use that.
Tasks
Step 1: Save any previous work.
Step 2: Open the template or your previous completed exercise. Save it as Chapter 11 Exercise 2.app.
Step 3: Add a combo box for the state column. Set list initialization to three or four states (you should include Virginia, since we know it
Step 5: In the Child Table Window, change the On SAM_CreateComplete action that called the table's Populate function to On
PAM_Populate.
Step 6: In the Child Table Window's Populate function, include a reference to the Combo Box in the where clause of the
SalTblPopulate() function. Step 7: Add a "Query" pushbutton. Include a SAM_Click action to post a PAM_Populate message to the form. Step 8: Add an On PAM_Populate message handler to the form, which sends a PAM_Populate to the form's children. Step 9: Save the program and test.
SAM_DropDown
Received by combo boxes when the user clicks on the drop down icon.
SalListPopulate( )
A SAL function, which populates list boxes and combo boxes.
SalListQueryCount()
Returns the number of items currently in a combo box or list box.
Preview
Templates
Use template Chapter 11 Template 3.app or if you completed Chapter 11 Exercise 2.app, you may use that.
Tasks
Step 1: Step 2: Save any previous work. Open the template or your previous completed exercise. Save it as Chapter 13 Exercise 3.app. Step 3: Step 4: Step 5: Remove the list initialization items from the Combo Box. Add an On SAM_DropDown Message Action to populate the Combo Box if the list count is 0. Save the program and test.
Run time
At run time, SQLWindows invokes Report Builder to display or print the report via a call to SalReportView or SalReportPrint. The SalReportView/Print call identifies the template file, and provides a mapping between the template's input items, and bind variables in the SQLWindows program. Report Builder sends SAM_Report* messages to the invoking program, keeping it up to date on report progress. In particular, Report Builder sends a SAM_ReportFetchNext message whenever it needs a row of detail line data for the report. The invoking program loads the requested data into the specified bind variables, and does a Return TRUE from the message action. When no more data remains, the invoking program does a Return FALSE, terminating the report. In this architecture, the SQLWindows program acts as a data server for Report Builder. Data may come from any source, but typically a SQL database server provides the data.
SQL Database
SQLWindows
Report Builder
Application
SalReportFileInfo Function
Get the file information a report template
SalReportGetPrinter Functions
Get Printer name, paper orientation, paper type, paper size, and paper tray information at run time
bOk = SalReportGetPrinterSettings( WndReport, sPrinterName, nOrientation, nPaperType, nWidth, nHeight ) bOk = SalReportGetPrinterTray( hWndReport, nPage, strTray )
note
Gets the information about the printer & Gets the information about which trays Used to print/view the report
On SAM_ReportStart
Do a SqlConnect() for each of the SQL handles your application will require. Return TRUE if it succeeds, Return FALSE if it fails. To stop the report, Return FALSE
On SAM_ReportFetchInit
SqlPrepareAndExecute() an appropriate SELECT statement. Return TRUE if it succeeds, Return FALSE if it fails.
On SAM_ReportFetchNext
SqlFetchNext(). Return TRUE if it succeeds, Return FALSE if it fails. Return TRUE from the message to continue, FALSE if end of data
On SAM_ReportFinish
SqlDisconnect() any Sql Handles you were using.
On SAM_ReportNotify
lParam = a RPT_Before* notify code
Function Details
SalReportCreate
Creates a new default report template (not based on Table Windows)
Declaration
bOk = SalReportCreate(sFilename,sVariables,sInputs,bDefaultReport,nReceiveError)
sVariables
String list of SQLWindows fields or variables, which will contain data for the report
Example
'nID, sName'
sInputs
String list of Report Builder input item field names in the report template
Example
'ID, NAME'
SalReportView
Preview a created report using Report Builder. Returns a window handle to Report Builder.
Declaration
HWndReport = SalReportView(hWndServer,hWndDisplay,sFilename, sVariables,sInputs,nReceiveError)
sVariables
String list of SQLWindows fields or variables, which will contain data for the report
sInputs
String list of Report Builder input item field names in the report template
nReceiveError
Set nReceiveError = RPT_NoPrint or RPT_NoToolbar
Parameters
Variable List
String list of SQLWindows fields or variables, which contain data for the report
Inputs List
String list of Report Builder field names in the report
Options
RPT_PrintAll or RPT_PrintRange RPT_PrintDraft (flags can be OR'ed)
First/Last Page
(if RPT_PrintRange is used)
Declaration
hWndReport = SalReportPrint(hWndServer,Filename,sBinds,sIntos, nCopies,nOptions,nFirstPage,nLastPage,nReceiveError)
SAM_ReportNotify
The Report Builder sends SAM_ReportNotify messages as the report blocks are formatted and output into the page buffer. The lParam code sent in the SAM_ReportNotify message indicates which part of the Report Builder is ready to format.
lParam Codes
Report Header: Page Header: Break Header: Detail: Break Footer: Page Footer: Report Footer: RPT_<xxxx>ReportHeader RPT_<xxxx>PageHeader RPT_<xxxx>BreakHeader1 - 8 RPT_<xxxx>Detail RPT_<xxxx>BreakFooter1 - 8 RPT_<xxxx>PageFooter RPT_<xxxx>ReportFooter
<xxxx> is Before or Output or Done. (i.e. RPT_BeforeReportHeader) The Before notifications are sent before any formatting occurs, the Output notifications are sent when the first line of the report is output and the Done notifications are sent when the entire block is output. An application can keep track of the sequence of these notices to detect when a page break (page footer/header blocks) has been inserted into the flow of the report blocks.
Preview
Templates
None. This exercise requires you to start a NEW application.
Tasks
Step 1: Step 2: Save any previous work. Start a new application. Save it as Chapter 12 Exercise 1.app.
Step 3:
Launch Report Builder and import the blank classic template newrep.qrp. Save it as Chapter 12 Exercise 1.qrp
Define input items PRESNAME (string), BIRTH (date) and STATE (string) Set a break group on STATE Define the report layout, and re-save your template In your application, define a SAM_AppStartup message action to set SqlDatabase to 'Presidnt' Create a form window called frmSimpleReport, titled Simple Classic Report, add a push button called pbRunReport Add a SAM_Click Message action to pbRunReport, to call a function RunReport() At the form window level, declare these variables: Sql Handle: hSql String: sSelectPres Number: nFetchResult Number: nRptErr String: sPresName Date/Time: dBirthDate String: sStateBorn
Step 11:
At the form window level, declare the function RunReport() . Add code to set the value of the sSelectPres to a suitable SELECT statement, and then call SalReportView() At the form window level, code message actions for SAM_ReportStart, SAM_ReportFetchInit, SAM_ReportFetchNext and SAM_ReportFinish Save and test your application.
Step 12:
Step 13:
RPT_ErrBind
Incorrect bind information
RPT_ErrCount
Incorrect number of bind or into variables
RPT_ErrFilenameLength
File name too long
RPT_ErrFileOpen
Could not open specified report file
RPT_ErrInput
A mismatch between input and bind variables
RPT_ErrLoadDLL
Could not load needed DLL
RPT_ErrMaxRpts
The maximum number of reports was exceeded Maximum number of reports = 10
RPT_ErrPrtOpen
A report function was unable to open the printer
RPT_ErrRptOpen
A report function was unable to open the specified report for printing
RPT_ErrRptWindow
A report function was unable to open the Report Builder
RPT_ErrType
The data type of an input variable did not match the data type of the associated bind variable
Query/Report
At design time, Report Builder can be used to query data and create a file with both data selection & report template. This type of template can be saved as a CQT.
Define a Query
You can use the define query dialog box to select data from a database. It is a graphical process that allows you to select the source, conditions, sort clause, group by clause, and group by conditions. It will also allow you to display the SQL statement generated by your query along with the results of your selection.
Report Preview
After defining a query and selection the OK button, you are presented with an automatically generated report. This processing creates a generic heading along with headings for each column selected in the query. You can now use the Report Designer to change the layout/data to something more specific to your needs.
Report Objects
Reports have several Objects associated with them: Input Items, Input Variables, Formulas, Totals, Crosstabs, & Break Groups. In this section we will look at Break Groups, Totals, and Crosstabs.
Break Groups
The break group dialog box (Format Break Groups) allows you to define a break group for a report. A report template has the ability to display data in broken up into groups, up to 8 levels. When formatting a break group of have an option to reset pages when a break occurs in the data. For example: Printing a invoice with multiple pages on it, if printed one company at a time you would have pages starting from 1 to the max printed, this works fine. But if you printed a batch of company invoices the page numbers would normally start with the first invoice printed and end with that last company/page printed. So if the second company in the batch had more then one page on an invoice the starting page number could be starting at page 2. To solve this problem you can use the Reset Pages on the break group of company to reset the page number back to zero each time the company changed.
Totals
You can create total objects that can be used on reports by using the Totals dialog box (Format Totals). When creating a total you have several options, from what you are trying to total (input items, input variables, other formulas), to what kind of total are you trying to create (Average, Count, Maximum, Minimum, ), to whether you what to restart the total on an event, as well as whether the data needs to be preprocess.
Crosstabs
You can create total objects that can be used on reports by using the Totals dialog box (Format Totals). When creating a total you have several options, from what you are trying to total (input items, input variables, other formulas), to what kind of total are you trying to create (Average, Count, Maximum, Minimum, ), to whether you what to restart the total on an event, as well as whether the data needs to be preprocess.
Preview
Templates
Use template Chapter 12 Template 2.app.
Tasks
Step 1: Step 2: Save any previous work. Open the template. Save it as Chapter 12 Exercise 2.app. Step 3: Launch Report Builder Create a query using the following tables and columns: Parties: President: Step 4: Step 5: Step 6: Step 7: Step 8: Party Pres_name, Birth_Date, Yrs_Serv, Death_Age
Set a break group on PARTY Define the report layout. Save it as Chapter 12 Exercise 2.cqt (a Query/Report template type) In your application, define a function ( OpenReport) as a global internal function. Save and test your application.
Tree
A Tree control is a rich and compact way of representing hierarchical data. It allows end-users to navigate and interact with data. Each element in a Tree is called a Tree Item. Depending on the nature of the data that you might want to represent, tree items can be static or dynamically created the application used in this document builds a Tree control based on the result set of two SQL SELECT statements. To implement this control, create a top level window and look for the Tree Control icon () in your Controls screen; click on this icon and draw it on the window of your selection. Team Developer 6 provides a new set of SalTree* functions that have been properly docu-mented to ensure that you gain the flexibility and control that you will need to manipulate this object in any way for details about Tree Control new API please refer to Team Developer 6 Help and type the keyword: SalTree
Navigation Bar
The Navigation Bar is a container used primarily to control the navigation within your programs. To understand how a Navigation Bar behaves it is important for you to be aware that within a Navigation Bar you might find one or more Navigation Panes and Groups . Each of these Navigation Panes and Groups will help you get the screen layout you look for. To implement this control create a top level window and look for the Navigation Bar icon () in your Controls screen; click on this icon and draw it on the window of your selection. Team Developer 6 offers a vast num-ber of SalNav* functions that you are able to use to manipulate this control for details on Navigation Bar new API please refer to Team Developer 6 Help and type the keyword: SalNav
Tab Control
The Tab Control in Team De-veloper 6 is a brand new object that behaves pretty much like what you are accustomed to with QuickTabs in previous ver-sions of Team Developer. If you have QuickTabs applica-tion and you want to convert them to use Team Developer 6 new Tab Control, you can use the Quick Tab Migration Wi-zard that comes with Team Developer 6. With this Tab Control you are able to associate child object by simply selecting a Tab Page and then dropping any object in it.
l
To implement this control create a top level window and look for the Tab Bar icon () in your Controls screen; click on this icon and draw it on the window of your selection. If you want to add a new Tab Page to this control, please look for the Tab Page icon () in you Controls screen; click on this icon and then drop the Tab Page on the Tab Control. Team Developer 6 offers a new set of SalTab* functions that you are able to use to manipulate this control for details on Tab Control API please refer to Team Developer 6 Help and type the keyword: SalTab The application used for the purpose of this document illustrates the imple-mentation of a WPF Control: Microsoft .NET WebBrowser. You will find a more advanced WPF Control example in: C:\...\Unify\Team Developer 6.0\Samples\60Demos\Demo2.
Application Demonstration
Once you have installed Team Developer 6 Samples look for the following folder location: C:\...\Unify\Team Developer 6.0\Samples\60Demos\Demo1 Inside this folder you will find two *.APP files: a. Win32DemoApp.app In this file you will find an implementation of the Navigation Bar, Tree Control and SalMail Class for a Win32 application.
b. WPFDemoApp.app In this file you will find an implementation of the Navigation Bar, Tree Control, SalMail Class and the WPF Control
Set hRoot = SalTreeGetFirstItem( treeDemo, 0 ) the returned value for hRoot will be the one that belongs to the Root ele-ment. You can show or hide the Root element from a Tree Control by changing the Show Root attribute from the Attribute Inspector window to Yer or No. The following code illustrates how the Tree Control implemented in dlgLeft was populated based on the SQL Result Set of two SQL SELECT statements.
If you are familiar with cQuickTabs you will have no trouble to get use to Team Developer 6 new Tab Control. Existing applications that currently use cQuickTabs can be converted to Tab Controls by using Team Developer 6 Quick Tabs Migration Wizard.
Creating a Tab Control is as easy as creating any other Team Developer con-trol. Just click on the Tab Bar icon () in the Controls window and drop the object on a top-level window. Tab Page controls can be added to an existing Tab Control by clicking on the Tab Page icon () and then dropping them in it. Adding child objects to a Tab Page can also be achieved by directly dropping these objects on them or by editing the outline. Tab Page controls can be dynamically created by using the SalTabAddPage( ) function If you like to see an example of this procedure please look at the code below the frmContacts.PAM_SetLayout:
Receiving emails using POP3 protocol 1. Define User and Mail Server settings as follows: Call oPOP3.SetUser( sUserName, sPassword ) Call oPOP3.SetMailServer( sServerName, nPort, bSSL1, bSend 2)
1) bSSL will be TRUE if the Mail Server requires an SSL connection, otherwise se it to FALSE. 2) bSend will always be FALSE when using SalMail Class instance to receive emails.
2. Connect to your Mail Server. To connect to your Mail Server use the fol-lowing call: Set nPOP3Connect = oPOP3.Connect( ) If the function succeeds nPOP3Connect will always be zero (0) for a list of the different return values for SalMail.Connect( ) function please look at Team Developer 6 Help and type the keyword: Connect - SalMail Method. 3. Retrieve envelope(s) information as follows: Set nPOP3ReturnGetEnvelopes = oPOP3.GetEnvelopes( bPOP3First, nPOP3Count, a_nPOP3MessageIDs, a_sPOP3DatesReceived, a_sPOP3Subjects, a_sPOP3Originators ) If SalMail.GetEnvelopes( ) succeeds (this will happen when its return is zero) run through the following arrays: a_nPOP3MessageIDs, a_sPOP3DatesReceived, a_sPOP3Subjects and a_sPOP3Originators. If you want to retrieve email body use: SalMail.GetMail( ) or Sal-Mail.GetNextEmail( ) respectively. 4. Once you finish downloading all your emails proceed to disconnect from the Mail Server as follows: Set nPOP3ReturnDisconnect = oPOP3.Disconnect( ) If SalMail.Disconnect( ) function succeeds the function will return zero (0).
The code under gridEmail.PAM_Get illustrates how to receive emails and then store then inside a database table. Sending emails using SMTP protocol 1. Define User and Mail Server settings as follows: Call oSMTP.SetUser( sUserName, sPassword ) Call oSMTP.SetMailServer(sServerName, nPort, bSSL3, bSend 4)
3 bSSL will be TRUE if the Mail Server requires an SSL connection, otherwise se it to FALSE. 4 bSend will always be TRUE when using SalMail Class instance to send emails.
2. Connect to your Mail Server. To connect to your Mail Server use the fol-lowing call: Set nreturnConnect = oSMTP.Connect( ) If the function succeeds nreturnConnect will always be zero (0) for a list of the different return values for SalMail.Connect( ) function please look at Team Developer 6 Help and type the keyword: Connect - SalMail Method. 3. Invoke SalMail.SendMail( ) function to deliver a email: Set nreturnSendMail = oSMTP.SendMail( nMailFormat, dfSubject, dfFrom, dfTo, dfCc, mlEmailContent, sAttachments, bDeliveryRecipient, nMailPriority ) sAttachments. This is a list of fully qualified file. If you want to attach more than one file use a semicolon to separate each file. For a full description of the SalMail.SendMail( ) function please use Team Developer 6 Help and type the keyword SendMail - SalMail Me-thod. 4. Once you have finished sending an email proceed to disconnect from the Mail Server as follows: Call oSMTP.Disconnect( ) In case you want to get a better sense of how to implement Team Devel-oper 6 SalMail Class to send emails please refer to the application used in this document and look the code under dlgEmailSend.pbSend.SAM_Click you will find everything you will need to implement this functionality yourself.
The application used in this document illustrates how to implement Microsoft .NET WebBrowser Control. You will find this control implementation in WPFDemoApp.app under dlgEmail.SAM_CreateComplete.
For a complete description of Microsoft .NET WebBrowser Control please re-fer to the following link:
http://msdn.microsoft.com/en-us/library/cc491147.aspx
Note: For more information about the use of WPF Controls in Team De-veloper 6 please refer to the white paper titled: WPF Container and con-trol in TD 6.0