Unit 4

Published on January 2017 | Categories: Documents | Downloads: 80 | Comments: 0 | Views: 706
of 47
Download PDF   Embed   Report

Comments

Content

Visual Programming UNIT-IV 4.0 Introduction
The database applications and its effects is discussed. The database connectivity with the server is discussed. A component that supports in-place activation also supports embedding. A full server, on the other hand, can be fun both as a stand-alone program and from a container. In the world of OLE embedding, components create metafiles and containers play them. A single import library that contains information about multiple dynamic-link libraries (DLLs) can sometimes be useful. Defining a function in an import library more than once creates an ambiguity when the loader resolves references to functions exported by other modules

4.1 Objectives
 Mini Database application to show the connectivity at the backend database table is explained  Visual Editing is Microsoft's name for in-place activation. A component that supports in-place activation also supports embedding.  Some container applications support only embedded Components; others support both in-place and embedded components.  A single import library that contains information about multiple dynamiclink libraries (DLLs) can sometimes be useful  The dialog box, using the ClassWizard to link these controls to variables, and handle messages sent by the controls.  Many of the messages that are processed by that dialog box window procedure located within Windows are also passed to a function within your own program, called a "dialog box procedure" or "dialog procedure."  A system and method for transferring information resources over a network from one source to another that reduces latency and bandwidth requirements on the network  A component project has at least one public class from which client applications can create objects  Visual Basic provides you with a data access technique called ActiveX Data Object (ADO), which provides fast and easy access to all types of data.

4.2 Contents
4.2.1 Mini Data base Applications A database application in Visual Basic needs the Backend connectivity in order to retrieve data from the Database, which are stored in the backend. The database may be present in the web server, Hard disk of local system, Network server etc., So necessary

Page 253

Visual Programming
OLEDB is applied to provide connection with the database and establish contacts with the tables needed to fetch the data from the tables. A Model Mini Database Application in Visual Basic A program to access the Sales Table using ADO ( without using ADO control) Invoice No. Customer Name Product Name Price Quantity Invoice Daet First Last Previous Next Refresh Add Delete Clear Update Find

Coding DIM DIM CON as ADODB.connection RS as ADODB.Recordset

Private sub cmdfirst_click() Rs. Movefirst Disp End sub Private sub cmdfind_click() A = (int (Inputbox(“Enter Invoice No. to find”)) F= 0 RS.Movefirst While not RS.EOF If RS.fields(0).Value=A then DISP F=1 ENDIF RS.Movenext Wend IF F=0 then Msgbox “Record Not found”, Vbcritical

Page 254

Visual Programming
Endif End sub Private sub cmdrefresh_click() RS.close RS.open “Select * from Sales”, con Disp End sub Private sub cmdprevious_click() RS.moveprevious IF RS.EOF then RS.Movefirst Msgbox “You reach first record” Endif Disp End sub Private sub cmdadd_click() RS.addnew Clear Text1.setfocus End sub Private sub cmddel_click() RS.delete RS.movefirst Msgbox “Successfully deleted a record” End sub Private sub cmdlast_click() RS.movelast Disp End sub Private sub cmdnext_click() RS.Movefirst If RS.EOF then RS.movelast Msgbox “ You had reached last record” Endif DISP End sub Private sub cmdsave_click()

Page 255

Visual Programming
Save RS.Update Msgbox “Successfully inserted a record” End sub Private sub Exit_click() End End sub Private sub Form_load() Set CON = new ADODB.CONNECTION CON.open “Provider=Microsoft Jet.Oledb4.0” Datasource “c:\cargo\record.mdb;persist” Security info = false SET RS = new ADODB.Recordset RS.cursortype = adopendynamic Rs.Locktype = adlockoptimistic Rs.Open “Select * from sales”.com End sub Public sub Disp() Text1.text = RS.fields(0) Text2.text = RS.fields(1) Text3.text = RS.fields(2) Text4.text = RS.fields(3) Text5.text = RS.fields(4) Text6.text = RS.fields(5) End sub Private sub Save() Rs. Fields(0) = val(text1.text) Rs. Fields(1) = text2.text Rs. Fields(2) = text3.text Rs. Fields(3) = val(text4.text) Rs. Fields(4) = val(text5.text) Rs. Fields(5) = text6.text End sub Private sub Clear() Text1.text =” “ Text2.text =” “ Text3.text =” “ Text4.text =” “ Text5.text =” “ Text6.text =” “ End sub

Page 256

Visual Programming
4.2.2 Embedding Controls in view Embedding vs. In-Place Activation (Visual Editing) Visual Editing is Microsoft's name for in-place activation. A component that supports in-place activation also supports embedding. Both in-place activation and embedding store their data in a container's document, and the container can activate both. An in-place-capable component can run inside the container application's main window, taking over the container's menu and toolbar, and it can run in its own top-level window if necessary. An embedded component can run only in its own window, and that window has a special menu that does not include file commands. Some container applications support only embedded Components; others support both in-place and embedded components. Usually, an in-place container program allows the user to activate in-.place components either in place or in their own windows. You should be getting the idea that embedding is a subset of in-place activation. This is true not only at the user level but also at the OLE implementation level. Embedding relies on two key interfaces, IOleobject and IOleClientSite, which are used for in-place activation as well. Mini-Servers vs. Full servers (Components) – Linking A mini-server can’t be run as a stand-alone program. It depends on a container application to launch it. It can’t do its own file I/O but depends on the container’s files. A full server, on the other hand, can be fun both as a stand-alone program and from a container. When its running as a stand-alone program, it can read and write its own files, which means that it supports OLE linking. With embedding, the container document contains all the data that the component needs; with linking, the container contains only the name of a file that the component must open. Windows Metafiles and Embedded Objects Think of metafile as a cassette tape for GDI instructions. In the world of OLE embedding, components create metafiles and containers play them. Here’s some component code that creates a metafile containing some text and rectangle: CMetaFileDc dcm; // MFC class for a metafile Dc VERIFY(dcm.create()); dcm.SetMapMode(MM_ANISOTROPIC); dcm.SetWindowOrg(0,0); dcm.SetWindowExt(5000,-5000); //drawing code dcm.Rectangle(CRect(500,-1000,1500,-2000)); dcm.TextOut(0,0,m_strText); HMETAFILE hMF = dcm.Close(); ASSERT(Hmf != null);

Page 257

Visual Programming
The metafile contains a SetWindowExt call to set the x and y extents of the window, and the program that plays the metafile call SetViewportExt to set the extents of the viewport. 4.2.3 Creating User defined DLL’s A single import library that contains information about multiple dynamic-link libraries (DLLs) can sometimes be useful. One example in the Microsoft Windows graphical environment is LIBW.LIB, which serves as the single import library through which an application can link to the Windows system DLLs GDI.DLL, KERNEL.DLL, and USER.DLL. An import library for many DLLs can be created by supplying multiple module definition (DEF) files as input parameters to the IMPLIB utility. However, one must make sure that none of the exported functions is defined in more than one DEF file. IMPLIB issues an error message when a function name is defined more than once, which occurs most often with the Windows exit procedure (WEP) because each DLL must export its own WEP in its DEF file. To avoid an IMPLIB error indicating that the WEP routine is defined many times, create modified DEF files that do not contain EXPORT statements for the WEP routine and specify these files as input to IMPLIB. More Information Defining a function in an import library more than once creates an ambiguity when the loader resolves references to functions exported by other modules. For example, suppose two DLLs that share a common import library export an Open function. When an application refers to a function in a DLL, the loader resolves a reference to the function (known as a fix-up) to its true address (which is not known until run time). The DLL containing the function must be loaded to provide a true address for its functions. However, in this example, this poses a dilemma: because both DLLs contain an Open function, which one should be used? Because the application's source code makes no distinction between the two Open functions, the loader cannot resolve the reference correctly. To avoid the potential for ambiguity, IMPLIB issues an error message for each function that is defined in multiple DEF files and does not create a combined import library. Two DLLs that share a common function name cannot share a single import library. The one exception to this rule is the WEP function, which every DLL must export. Because an application does not call the WEP, the function need not be listed in the combined import library.

Page 258

Visual Programming
To create a single import library, MYIMPLIB.LIB, that can be used to link to the three DLLs (DLL1, DLL2, and DLL3), perform the following four steps in this order: 1. Compile and link all three DLLs as outlined in Chapter 20 of the "Microsoft Windows Software Development Kit: Guide to Programming" for versions 3.0 and 3.1. Use the original DEF file to link each DLL. Each file must list the WEP in its EXPORTS section with the RESIDENTNAME qualifier to properly export the WEP function. 2. Copy the module definition files for each DLL (DLL1.DEF, DLL2.DEF, and DLL3.DEF) into three dummy DEF files (DUMMY1.DEF, DUMMY2.DEF, and DUMMY3.DEF). These dummy DEF files are used to create the combined import library as outlined in Step 3 below. Do not link any DLL using its dummy DEF file. 3. Remove the WEP from the EXPORTS statement of each dummy DEF file. Only Windows calls the WEP procedure; the application does not. Therefore, the WEP does not need to be defined in the import library. Removing the WEP entries prevents an IMPLIB error about multiple definitions of the WEP routine. 4. Use DUMMY1.DEF, DUMMY2.DEF, and DUMMY3.DEF as input parameters to the IMPLIB utility, as follows: IMPLIB MYIMPLIB.LIB DUMMY1.DEF DUMMY2.DEF DUMMY3.DEF The four steps above build a combined import library that contains the linkage information required for all of the exported functions in each of the three DLLs. It does not contain any information about any of the WEP functions. Because applications do not call the WEP function, this omission does not cause any linkage problems. A dummy DEF file must not be used to link a DLL because a dummy DEF file does not export the WEP function. Every DLL must export a WEP that Windows can call before removing the DLL from memory. Visual Basic Syntax Requirements To declare a DLL procedure, add a Declare statement to the Declarations section of the code window. Visual Basic assumes that exported DLL functions have the same attributes as a Windows API function. The correct syntax for a Declare statement is shown below, followed by a list of Visual Basic syntax rules. Declare Function publicname Lib "libname" [Alias "alias"] _ [([[ByVal] var [As type] [, [ByVal] var [As type]]...])] As Type

• Public or private: DLL procedures declared in standard modules (.bas) are public by default and can be called from anywhere in your application. DLL procedures declared in any other type of module are private to that module, and must be identified by preceding the declaration with the Private keyword. • Sub or function: DLL procedures may be defined as either a Function or Sub. If a

Page 259

Visual Programming
procedure does not return a value, write the declare as a Sub. If the procedure returns a value, write the declare as a Function. • Using an alias: It is sometimes necessary to define a substitute name for an exported procedure in a Declare statement. Examples of where this can occur are: • Where an exported procedure uses strings. This is usually due to the DLL containing both ANSI and UNICODE versions of the procedures. • Where an exported function has a name that is not a valid Visual Basic identifier, such as a name that matches a Visual Basic keyword or that begins with an underscore. • Case sensitivity: Procedure names are case-sensitive in 32-bit versions of Visual Basic. In 16-bit versions, procedure names are not case-sensitive. • Passing arguments by value or by reference: By default, Visual Basic passes all arguments by reference. Many DLL procedures expect an argument to be passed by value. To pass an argument by value, place the ByVal keyword in front of the argument declaration in the Declare statement. • Empty argument list: Empty parentheses indicate that the Sub or Function procedure has no arguments and that Visual Basic should ensure that none are passed. For additional syntax information, see the following topics in Visual Basic Help: • Declaring a DLL Procedure • Declare Statement • Call Statement • Function Statement Visual Basic Data-Type Requirements Data type definitions vary between programming languages, and some parameters used in other languages are not supported in Visual Basic. To ensure that your exported procedures behave in the way you expect, you may need to append Visual Basic keywords to procedure parameters or convert parameters to those data types supported by Visual Basic. Common Visual Basic keywords are listed below: • Passing a parameter by value or by reference: As discussed above, Visual Basic passes all arguments by reference. To pass a parameter by value, place the ByVal keyword in front of the argument declaration. • Passing a function pointer as a parameter: To pass the address of a user-defined procedure as an argument to an exported procedure, precede the name of the userdefined procedure with the AddressOf keyword. For important additional information on this, see the "Passing Function Pointers to DLL Procedures and Type Libraries" Visual Basic Help topic. • Modifying data types: Use an As clause following the argument list to specify the return type of the procedure. Use an As clause within the argument list to specify the data type of any of the arguments passed to the procedure. In addition to specifying any of the standard data types, you can specify As Any to inhibit type checking and allow any data type to be passed to the procedure. Common conversions to Visual Basic data types are listed below: Page 260

Visual Programming
• 8- to 16-bit numeric parameters: Pass 8- to 16-bit numeric parameters (int, short, unsigned int, unsigned short, BOOL, and WORD) as Integer. • 32-bit numeric parameters: Pass 32-bit numeric parameters (long, unsigned long, and DWORD) as LONG. • Object handles: All handles are unique 32-bit integer values associated with a Window and are passed by value, so pass these parameters as Long. • Strings: Strings include the LPSTR and LPBYTE data types (pointer to characters or pointer to unsigned characters). Pass these parameters as (ByVal param As String) because Visual Basic passes a pointer to the beginning of the string. • Pointers to numeric values: Pass pointers to numeric values by not using the ByVal keyword. • Structures: If the Visual Basic user-defined type matches the structure expected by the DLL, the structure can be passed by reference. NOTE: Structures cannot be passed by value. • Pointers to arrays: Pass the first element of the array by reference. • Null pointers: If a DLL expects a Null pointer, pass it as (ByVal paramname As Any) or (ByVal paramname as Long). You can use 0& as the value of paramname when calling the DLL. Visual Basic Requirements for Creating Exported DLL Functions This section provides some information for creating an exported DLL that meets the Visual Basic requirements using Microsoft Visual C++. Other C++ compilers may or may not support the keywords used in this section. • Maintain the Stack: Visual Basic requires that the function receiving the arguments also maintain the stack. The Visual C++ keyword that can perform the correct stack maintenance is _stdcall. The _stdcall keyword decorates the function name with a preceding underscore and appends "@n" where n is the number of bytes required to contain the function's arguments and the return value. For example, if you create a function called GetWindowSize and use the _stdcall keyword to provide stack maintenance, the function is defined as follows: int GetWindowSize (int nIndex) The following is the exported name result: _GetWindowSize@4 Note the preceding underscore that is added by the _stdcall keyword. • Export the file: To export the file, you must use a .def file with an EXPORTS section. The _declspec(dllexport) keyword exports the function but maintains the name decoration. A .def file also exports the function names while removing the name decoration. The following example shows how the EXPORTS section of a .def file is implemented for a function called DisplayMessage: EXPORTS DisplayMessage @1

Page 261

Visual Programming
4.2.4 Dialog based applications

In this we are going to create a simple dialog based application. We will use Button, Edit Box, Combo Box, List Box and Static text controls to develop our project. We will be going through the process of adding these controls into their dialog box, using the ClassWizard to link these controls to variables, and handle messages sent by the controls. I am going to assume you have good knowledge in C++ and you are an absolute beginner to Visual C++. The first thing you need to do is load up your Visual C++ 6 software and create a new project. Creating a new Project To create a new project, start by clicking on File in the menu of the Visual C++ 6 window then on New. The view should look like the image below.

Write Dialog1 in the project name and choose an MFC AppWizard (exe) from the list of the available Wizards, then click OK. The MFC Application Wizard will start.
• • •

In Step 1 of the Wizard, click on Dialog based option, then click Next. In Steps 2 and 3 accept the default settings, just click Next to do this. In Step 4 click Finish, then you will get the project information. Click OK. Page 262

Visual Programming
Now the Wizard has created for you a simple empty Dialog Based application. You will need to make few changes and write the necessary code for your application to customise it to your specifications. Designing the Dialog Click on the text TODO : Place dialog controls here, then press Delete. This will remove the unwanted text label.

Click on bottom right edge of the dialog box. A rectangle appears around the edges of the box itself. Resize the dialog box using the sizing points as shown below. Click on the sizing point on the bottom-right corner, keeping the mouse button pressed. Move the mouse, keeping the button pressed. An outline of the new dialog box size is shown as the mouse is moved. Release the mouse button when the dialog box size is 230 x 126.

Page 263

Visual Programming

Click on the Cancel button and press Delete to remove the Cancel button, then right click the mouse on the OK button and a context menu will appear as shown below. Select Properties from the context menu.

The Push Button Properties dialog box appears. Select the General tab; then in Caption box replace the word OK with Close as shown below.

Page 264

Visual Programming

On the controls toolbar, select the static text control. Click the dialog box near the upper left corner. A static text control appears on the dialog box, with the default text Static. Static text controls can be used to display some information (we going to use few of them as labels). You need three static text controls. Therefore, you need to repeat the process of dropping static text control on to the dialog box make sure to drop each control next to each other. On the controls toolbar, select the edit control and as you did before with text control. Drop two edit controls. Select Combo Box from the controls toolbar and drop it into the dialog box. Then select List Box control and drop it to the dialog box. Select button control from the controls toolbar and drop it into the dialog box. Change the Caption of the new button to Add and its ID to IDC_ADD, then arrange the controls on the dialog box as show below. Right click static text control and change its properties change Caption to Title as shown below.

Page 265

Visual Programming

Change the Caption for each static text control as shown below. Change the ID in Edit Properties for first Edit Box control to IDC_FIRSTNAME and the second edit control to IDC_LASTNAME.

Change the ID in List Box Properties to IDC_NAMELIST and the ID Combo Box Properties to IDC_TITLE. Click on Data in Combo Box Properties and populate the Data as shown below. After each entry is added in the list remember to press Ctrl + Enter to go to a new line.

Page 266

Visual Programming

On the Styles tab, change the Combo Box's Type to Drop List. Position your mouse over the Combo Box dropdown button then left-click. Another rectangle will appear (see below) that allows you to specify the size of the open Combo Box's List.

Assigning Member variables to Controls Press Ctrl + W to start ClassWizard, or from the View menu select ClassWizard. The MFC ClassWizard dialog box appears as shown below. Select the Member Variables tab, then select the dialog class in the Class name : combo box; use CDialog1Dlg. Select IDC_FIRSTNAME, click Add Variable button. The dialog box appears (see below). Select Value from Category and select CString from Member variable type. Type m_strFirstName for Member variable name. Repeat the same process to add CString member variable m_strLastName for IDC_LASTNAME, and m_strTitle for IDC_TITLE.

Page 267

Visual Programming

For IDC_NAMELIST add a Member variable of Category Control and Variable Type CListBox as shown below. Select the ClassView tab from the project workspace pane. The class list will appear as shown below. Right click CDialog1Dlg class and select add member variable. The Add Member Variable dialog box will appear. Type CString in the variable and m_strFullName in Variable Name.

Adding message handlers for the controls

Page 268

Visual Programming
Press Ctrl + W to start the ClassWizard, or right click the Add button and select ClassWizard from the context menu. Open ClassWizard, select Message Maps tab. In Class name select CDialog1Dlg, on Object IDs select IDC_ADD , then choose BN_CLICKED from the Messages list as shown below. Click on Add Function. Click OK, then click Edit Code. The ClassWizard will write a new empty function called Add() with the proper prototype in the class header.

Add the code in bold - just below //TODO: Add your control notification handler code here: void CDialog1Dlg::OnAdd() { // TODO: Add your control notification handler code here CString strTitle ; int nIndex; UpdateData(); // Transfer data from controls to variables

//get currently selected text nIndex = GetDlgItemText(IDC_TITLE, strTitle); //assigning selected m_strFullName = strTitle + " " + m_strFirstName + " " + m_strLastName; m_NameList.AddString(m_strFullName); //Add string to list

Page 269

Visual Programming
UpdateData(FALSE); } Building and running the program. Click on the Title Combo Box and choose a Title. Write your first name in first name edit box and last name in last name edit box then click Add. If everything goes as planned, then you will get your full name and correct title in the list box as shown below. // Transfer data from variables to controls

This program could be part of a large database project, but for now we going to leave at that. I hope you enjoyed the tutorial Dialog boxes are most often used for obtaining additional input from the user beyond what can be easily managed through a menu. The programmer indicates that a menu item invokes a dialog box by adding an ellipsis (...) to the menu item. A dialog box generally takes the form of a popup window containing various child window controls. The size and placement of these controls are specified in a "dialog box template" in the program's resource script file. Although a programmer can define a dialog box template "manually," these days dialog boxes are usually interactively designed in the Visual C++ Developer Studio. Developer Studio then generates the dialog template. When a program invokes a dialog box based on a template, Microsoft Windows 98 is responsible for creating the dialog box popup window and the child window controls, and for providing a window procedure to process dialog box messages, including all keyboard and mouse input. The code within Windows that does all this is sometimes referred to as the "dialog box manager." Many of the messages that are processed by that dialog box window procedure located within Windows are also passed to a function within your own program, called a "dialog box procedure" or "dialog procedure." The dialog procedure is similar to a normal window procedure, but with some important differences. Generally, you will not be doing much within the dialog procedure beyond initializing the child window controls

Page 270

Visual Programming
when the dialog box is created, processing messages from the child window controls, and ending the dialog box. Dialog procedures generally do not process WM_PAINT messages, nor do they directly process keyboard and mouse input. Modal Dialog Boxes Dialog boxes are either "modal" or "modeless." The modal dialog box is the most common. When your program displays a modal dialog box, the user cannot switch between the dialog box and another window in your program. The user must explicitly end the dialog box, usually by clicking a push button marked either OK or Cancel. The user can, however, switch to another program while the dialog box is still displayed. Some dialog boxes (called "system modal") do not allow even this. System modal dialog boxes must be ended before the user can do anything else in Windows. The differences between this function and a window procedure are:


A window procedure returns an LRESULT; a dialog box procedure returns a BOOL, which is defined in the Windows header files as an int. A window procedure calls DefWindowProc if it does not process a particular message; a dialog box procedure returns TRUE (nonzero) if it processes a message and FALSE (0) if it does not. A dialog box procedure does not need to process WM_PAINT or WM_DESTROY messages. A dialog box procedure will not receive a WM_CREATE message; instead, the dialog box procedure performs initialization during the special WM_INITDIALOG message.





The WM_INITDIALOG message is the first message the dialog box procedure receives. This message is sent only to dialog box procedures. If the dialog box procedure returns TRUE, Windows sets the input focus to the first child window control in the dialog box that has a WS_TABSTOP style. In this dialog box, the first child window control that has a WS_TABSTOP style is the push button. Alternatively, during the processing of WM_INITDIALOG, the dialog box procedure can use SetFocus to set the focus to one of the child window controls in the dialog box and then return FALSE. The only other message this dialog box processes is WM_COMMAND. This is the message the push-button control sends to its parent window either when the button is clicked with the mouse or when the Spacebar is pressed while the button has the input focus. The ID of the control is in the low word of wParam. For this message, the dialog box procedure calls EndDialog, which tells Windows to destroy the dialog box. For all other messages, the dialog box procedure returns FALSE to tell the dialog box window procedure within Windows that our dialog box procedure did not process the message.

Page 271

Visual Programming
Invoking the Dialog Box A dialog box can be invoked using the DialogBox function. DialogBox (hInstance, szTemplate, hwndParent, DialogProc) ; This function requires the instance handle (saved during WM_CREATE), the name of the dialog box (as defined in the resource script), the parent of the dialog box (which is the program's main window), and the address of the dialog procedure. If you use a numeric identifier rather than a name for the dialog box template, you can convert it to a string using the MAKEINTRESOURCE macro. You can end this dialog box by clicking the OK button with the mouse, by pressing the Spacebar, or by pressing Enter. For any dialog box that contains a default push button, Windows sends a WM_COMMAND message to the dialog box, with the low word of wParam equal to the ID of the default push button when Enter or the Spacebar is pressed. That ID is IDOK. You can also end the dialog box by pressing Escape. In that case Windows sends a WM_COMMAND message with an ID equal to IDCANCEL. The DialogBox function you call to display the dialog box will not return control to WndProc until the dialog box is ended. The value returned from DialogBox is the second parameter to the EndDialog function called within the dialog box procedure. WndProc can then return control to Windows. Even when the dialog box is displayed, however, WndProc can continue to receive messages. In fact, you can send messages to WndProc from within the dialog box procedure. Modeless Dialog Boxes Modeless dialog boxes allow the user to switch between the dialog box and the window that created it as well as between the dialog box and other programs. The modeless dialog box is thus more akin to the regular popup windows that your program might create. Modeless dialog boxes are preferred when the user would find it convenient to keep the dialog box displayed for a while. For instance, word processors often use modeless dialog boxes for the text Find and Change dialogs. If the Find dialog box were modal, the user would have to choose Find from the menu, enter the string to be found, end the dialog box to return to the document, and then repeat the entire process to search for another occurrence of the same string. Allowing the user to switch between the document and the dialog box is much more convenient. As you've seen, modal dialog boxes are created using DialogBox. The function returns a value only after the dialog box is destroyed. It returns the value specified in the second parameter of the EndDialog call that was used within the dialog box procedure to terminate the dialog box. Modeless dialog boxes are created using CreateDialog. This function takes the same parameters as DialogBox:

Page 272

Visual Programming
hDlgModeless = CreateDialog (hInstance, szTemplate, hwndParent, DialogProc) ; The difference is that the CreateDialog function returns immediately with the window handle of the dialog box. Normally, you store this window handle in a global variable. Differences Between Modal and Modeless Dialog Boxes Working with modeless dialog boxes is similar to working with modal dialog boxes, but there are several important differences. First, modeless dialog boxes usually include a caption bar and a system menu box. These are actually the default options when you create a dialog box in Developer Studio. The STYLE statement in the dialog box template for a modeless dialog box will look something like this: STYLE WS_POPUP ¦ WS_CAPTION ¦ WS_SYSMENU ¦ WS_VISIBLE he caption bar and system menu allow the user to move the modeless dialog box to another area of the display using either the mouse or the keyboard. You don't normally provide a caption bar and system menu with a modal dialog box, because the user can't do anything in the underlying window anyway. The second big difference is that if you neither include WS_VISIBLE in CreateDialog call nor call ShowWindow, the modeless dialog box will not be displayed. hDlgModeless = CreateDialog ( . . . ) ; ShowWindow (hDlgModeless, SW_SHOW) ; The third difference is that unlike messages to modal dialog boxes and message boxes, messages to modeless dialog boxes come through your program's message queue. The message queue must be altered to pass these messages to the dialog box window procedure. Here's how you do it: When you use CreateDialog to create a modeless dialog box, you should save the dialog box handle returned from the call in a global variable (for instance, hDlgModeless). Change your message loop to look like while (GetMessage (&msg, NULL, 0, 0)) { if (hDlgModeless == 0 ¦¦ !IsDialogMessage (hDlgModeless, &msg)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } }

Page 273

Visual Programming
If the message is intended for the modeless dialog box, then IsDialogMessage sends it to the dialog box window procedure and returns TRUE (nonzero); otherwise, it returns FALSE (0). The TranslateMessage and DispatchMessage functions should be called only if hDlgModeless is 0 or if the message is not for the dialog box. If you use keyboard accelerators for your program's window, the message loop looks like this: while (GetMessage (&msg, NULL, 0, 0)) { if (hDlgModeless == 0 ¦¦ !IsDialogMessage (hDlgModeless, &msg)) { if (!TranslateAccelerator (hwnd, hAccel, &msg)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } } } Because global variables are initialized to 0, hDlgModeless will be 0 until the dialog box is created, thus ensuring that IsDialogMessage is not called with an invalid window handle. The hDlgModeless variable can also be used by other parts of the program as a test of the existence of the modeless dialog box. For example, other windows in the program can send messages to the dialog box while hDlgModeless is not equal to 0. The final difference: Use DestroyWindow rather than EndDialog to end a modeless dialog box. When you call DestroyWindow, set the hDlgModeless global variable to NULL. The user customarily terminates a modeless dialog box by choosing Close from the system menu. Although the Close option is enabled, the dialog box window procedure within Windows does not process the WM_CLOSE message. You must do this yourself in the dialog box procedure: case WM_CLOSE : DestroyWindow (hDlg) ; hDlgModeless = NULL ; break ; Note the difference between these two window handles: the hDlg parameter to DestroyWindow is the parameter passed to the dialog box procedure; hDlgModeless is the global variable returned from CreateDialog that you test within the message loop 4.2.5 Dynamic Data transfer functions
Visual Programming

A system and method for transferring information resources over a network from one source to another that reduces latency and bandwidth requirements on the network. The information resources are made up of at least a static and dynamic portion. A client Page 274

Visual Programming
requests information, and a server receives the request and then transmits to the requestor the desired information. The server may send both the static and dynamic portion of the information resource, or the server may sent only the dynamic portion of the resource, depending on the client's needs and the request made. By discriminating between the static and dynamic portions of an information resource in this way, less data must be sent from the server to the client on every access. Also, the computational load that is typical of servers on a network is shifted to the client, thereby reducing latency. Using the DDE_FLUSH String to Transfer Data Dynamically DDE also enables you to program when the DDE buffer is dumped during a DDE link. Normally, the data in the DDE buffer are transmitted when the DDE link is closed at the end of the DATA step. However, the special string 'DDE_FLUSH' that you issue in a PUT statement instructs the SAS System to dump the contents of the DDE buffer. This function gives you considerable flexibility in the way DDE is used, including the capacity to transfer data dynamically through the DATA step, as in the following example: /* A DATA step window is displayed. */ /* Enter data as prompted. */ /* When you are finished, enter STOP */ /* on the command line. */ filename entry dde 'excel¦sheet1!r1c1:r1c3'; dm 'pmenu off'; data entry; if _n_=1 then do; window ENTRY color=black #3 'This is data for Row 1 Column 1' c=cyan +2 var1 $10. c=orange #5 'This is data for Row 1 Column 2' c=cyan +2 var2 $10. c=orange #7 'This is data for Row 1 Column 3' c=cyan +2 var3 $10. c=orange; end; flsh='!DDE_FLUSH'; file entry; do while (upcase(_cmd_) ne 'STOP'); display entry; put var1 var2 var3 flsh; output; VAR1=''; VAR2=''; VAR3=''; end; stop;

Page 275

Visual Programming
run; dm 'pmenu on'; Reading Missing Data This example illustrates how to read missing data from an Excel spreadsheet that is called SHEET1. This example reads the data in columns 1 through 3 and rows 10 through 20. Some of the data cells may be blank. Here is an extract of what some of the data look like: 10 11 12 13 John Raleigh Cardinals Jose North Bend Orioles Kurt Yelm Red Sox Brent Dodgers

Following is the code that can read these data correctly into a SAS data set: filename mydata dde 'excel¦sheet1!r10c1:r20c3'; data in; infile mydata dlm='09'x notab dsd missover; informat name $10. town $char20. team $char20.; input name town team; run; proc print data=in; run; In this example, the NOTAB option tells the SAS System not to convert tabs that are sent from the Excel application into blanks. Therefore, the TAB character can be used as the delimiter between data values. The DLM= option specifies the delimiter character, and '09'x is the hexadecimal representation of the TAB character. The DSD option specifies that two consecutive delimiters should represent a missing value. The default delimiter is a comma. For more information, see the DSD option in SAS Language Reference: Dictionary. The MISSOVER option prevents a SAS program from going to a new input line if it does not find values in the current line for all the INPUT statement variables. When you use the MISSOVER option, values are set to missing if the INPUT statement reaches the end of the current record but does not find the expected values. The INFORMAT statement forces the DATA step to use modified list input, which is crucial to this example. If you do not use modified list input, you receive incorrect results. The necessity of using modified list input is not DDE specific; you would need it even if you were using data in a CARDS statement, whether blanks or commas delimited your data.

Page 276

Visual Programming
4.2.6 User Interface Classes A component project has at least one public class from which client applications can create objects. Any component may have numerous class modules that encapsulate its internal functionality. When you allow clients to create instances of a class, they can manipulate the objects of that class. The default interface of a class in your component is simply a set of all the public properties, methods and events of the class module. Properties and methods can be declared as Private, Public and Friend, which define the scope within which the properties and methods are accessible. A member declared as Private is accessible only to other members of the class, while one declared Public is accessible within the class and to any program using the object’s interface. A Friend member is accessible to all the objects within the component, but is invisible outside the component. From the Project menu, you can choose the Add Class Module to define a new class. Each public class you add will be the blueprint for one kind of public object in your object model. You can provide a class name, define interfaces for the class, and set the Instancing property to determine how objects will be created from the class. The Instancing property can be:       Private PublicNotCreatable MultiUse GlobalMultiUse SingleUse GlobalSingleUse

User Interface in Visual Basic Visual Basic is a Rapid Application Development tool. The Integrated Development Environment (IDE) of Visual Basic is easy-to-use and it takes just a few minutes to build your first Visual Basic application. Let us start by creating a user interface screen for Students details. Start Visual Basic and set Name and Caption properties of the form. A label control is required for displaying static text for the details Student ID, First Name, Last Name, Date of Birth and Branch. Similarly text box control is required to accept information for each. A Visual Basic application can access data from a variety of data sources such as text files, e-mail and database file. Assuming Student database is present in the database, we need to display appropriate information from the table in the text boxes. Visual Basic provides you with a data access technique called ActiveX Data Object (ADO), which provides fast and easy access to all types of data. Visual Basic also provides you with a data access control called ADO data control (ADODC). ADODC is used to quickly establish a connection between the Visual Basic application and the database. It hides most of the implementations of connectivity from users Page 277

Visual Programming
allowing them to concentrate on using the data. It also eliminates the need to write code for displaying data or navigating through the records.

ADO Data Control Add the ADODC from the toolbox to the form. Name the control and set the ConnectString, CommandType and RecordSource properties of the ADODC. The RecordSource property specifies the name of the table that contains the data for display. Set the DataSource and DataField properties of the textbox controls. For example, Control Name txtFirstName DataSource Property Students DataField Property FirstName

Now save the form and run the project.

Student Id First Name Last Name Date of Birth Branch An ADO data control The Student Details form with the ADODC To navigate through the data displayed, use the ADO data control. Select the scrolling buttons to move to the first, next, previous and last record.

Page 278

Visual Programming
Writing Codes to Maintain Data The task of maintaining the details of students in the database involves adding the details of new students, modifying and deleting the details of existing students. To enable the user to perform the required actions to add, modify and delete, an individual Command Button control for each operation is to be provided. The following table describes the controls required for the same. CommandButton to Add a record Save a record Update a record Delete a record Name cmdNew cmdAdd cmdUpdate cmdDelete Caption New Add Update Delete

Student Id First Name Last Name Date of Birth Branch An ADO data control New Add Update Delete

The Student Details form

d

Data maintenance can be done easily and with minimal programming using the ADO data control. Events are used to send messages to the application. To perform operations like add, modify and delete, you should send a message to the application, which can be done by using the Click event of the command buttons used. The Click event of a command button is typically used for starting, interrupting or terminating a process. The following events would be required for maintaining data. Activity Adding a new record Saving the record Modifying a record Deleting a record Event Click of the New button Click of the Add button Click of the Update button Click of the Delete button

Page 279

Visual Programming
Visual Basic provides a Code Editor window that can be used to write the required code to be executed. The code editor is a special word processor with a number of features that help you to write a Visual Basic code easily. To view the code editor window, select Code from the View menu or press F7 or just double-click the form. Visual Basic will open a code editor as shown below,

Code Editor for the cmdAdd Button Select the control and event for which you wish to write the code. Visual Basic prepares the start and end statements for you. You need to write the code between the Private Sub and End Sub statements. Each row of data stored in the table on the database is treated as a row. An ADO data control, while manipulating data, groups all such rows into one set called the recordset. A recordset is a collection of records from a database. A record pointer points to one record among its set, which is the current record. Adding New Data To add a new data to the database, use the AddNew and Save methods of the ADO data control. The AddNew method of the ADO control prepares recordset to add new data. This method clears the text box controls and allows the user to key in the new data. Syntax ADODataControlName.Recordset.AddNew You should use the Save method to allow the user to save the data to the database. This method picks up the data from the text box control and adds it to the database. Syntax ADODataControlName.Recordset.Save Modifying Existing Data To allow the user to modify the existing data, use the Update method of the ADO data control. This method picks up the data from the text box and updates the database.

Page 280

Visual Programming
Syntax ADODataControlName.Recordset.Update Deleting Unwanted Data To allow the user to delete a record from the database, use the Delete method of the ADO data control. Syntax ADODataControlName.Recordset.Delete Care must be taken while deleting a record. When you delete a record, the current record position becomes invalid, hence it must be moved to a valid position. As per the best industry practices, when you delete a record you should move the record pointer to the next record position. ADO data control has the MoveNext method to move the record pointer to the next record. Syntax ADODataControlName.Recordset.MoveNext The MovePrevious method of the ADO data control allows the user to go the previous record. Syntax ADODataControlName.Recordset.MovePrevious The MoveFirst method of the ADO data control allows the user to go the first record. Syntax ADODataControlName.Recordset.MoveFirst The MoveLast method of the ADO data control allows the user to go the last record. Syntax ADODataControlName.Recordset.MoveLast After having written the appropriate codes as shown in the table below, save and run the application. To confirm that the data have been maintained, browse through the records and check if the changes are reflected.. Control Name Event Code CmdNew Click adcStudent.Recordset.AddNew CmdAdd Click adcStudent.Recordset.Save CmdUpdate Click adcStudent.Recordset.Update cmdDelete click adcStudent.Recordset.Delete adcStudent.Recordset.MoveNext

Page 281

Visual Programming
4.2.7 Database Management with ODBC The MFC ODBC Classes – CRecordset and CDatabase With the MFC ODBC classes, you use objects instead of connection handles and statement handles. The environment handle is stored in a global variable and is not represented by a C++ object. The two principal ODBC classes are CDatabase and CRecordset. Objects of class CDatabase represent ODBC connections to data sources, and objects of class CRecordset represent scrollable rowsets. The Visual C++ documentation uses the “recordset” instead of “rowset” to be consistent with Microsoft Visual Basic and Microsoft Access. You seldom derive classes from CDatabase, but you generally derive classes from CRecordset to match the columns in you database tables. The important CRecordset member functions are summarized in the following table. Function Description Opens the recordset Prepares to add a new record to the table Completes an AddNew or Edit operation by saving the new or edited data in the data source Delete Deletes the current record from the record Edit Prepares to implement changes on the current IsBOF Determines whether the recordset has been positioned before the first record IsEOF Determines whether the recordset has been positioned after the last record MoveNext Sets the current record to the next record or to the next rowset MoveFirst Sets the current record to the first record in recordset MoveLast Sets the current record to the last record or to theI last rowset MovePrev Sets the current record to the previous record or to the previous rowset GetDefaultConnect Gets the default connect string for the data source on which the recordset is based GetDefaultSQL Gets the default SQL string DoFieldExchange Exchanges data between the recordset data fields and the corresponding record on the data source GetStatus Gets the index of the current record in the recordset and the final count status GetRecordCount Determines the highest-numbered record yet encountered as the user moves through the records GetODBCFieldCount Gets the number of fields in the recordset object GetODBCFieldInfo Gets information about the fields in the recordset Open AddNew Update

Page 282

Visual Programming
Counting the Rows in a Recordset It's difficult to know how many records are contained in an ODBC recordset. ODBC doesn't provide an accurate count of the rows in a recordset until you’ve read past the end. Until that time, the count returned from the CRecordset::GetRecordCount member function is a "high-water mark" that returns only the last row accessed by CRecordset::MoveNext. The function returns a CRecordsetStatus object, which has a CountFinal that indicates whether the count is final. The CRecordset::MoveLast function does not register the record count for you, even for dyansets. If you want to know how many records are included in a recordser, loop through the whole table with MoveNext calls. A faster alternative is to use the COUNT function. If your program adds or deletes a record or if another user adds or deleted a record, the record count is not adjusted. The Student Registration Database The Visual C++ Enroll tutorial uses a ready-made sample Access database (STDREF32.MDB) that tracks students, classes and instructors. Figure below shows the four database tables and the relationships among them. The boldfaced fields are indexed fields and the 1-? Relationships represent referential integrity constraints. If there is at least one section for the course MATH101, for example, Access prevents the user from deleting the MATH101 course record.

The Student Registration database schema

Page 283

Visual Programming
A Recordset Example The Example displays the rows from the student database table in a scrolling view. The student table is part of the Student Registration (Microsoft Access 97) sample database that's included with Visual C++.Here are the steps for building the example: 1. Copy the Student Registration database to your hard disk. You can find the file stdreg32.mdb in the \Samples\VC98\Mfc\Databasc\St directory on the Visual C+ + MSDN CD-ROM. Copy it to the new project directory on your hard disk, and make sure the copy does not have its read-only attribute set. 2. Run the ODBC Data Source Administrator to Install the Student Registration data source. Click the ODBC icon in the Windows control Panel. The Visual C++ Setup program should have already installed the required ODBC drivers on your hard disk. If you are running Windows 95, click the Drivers button to see whether the Microsoft Access driver is available. If you're running Windows 98, click the Drivers tab to see whether the Microsoft Access driver is available. If the Microsoft Access driver is not available, rerun Visual C++ Setup. Click the Add button choose Microsoft Access Driver in the Add Data Source dialog box (in Windows 98, select the Microsoft Access Driver in the Create New Data Source dialog box and click the Finish button), and fill in the ODBC Microsoft Access 97 Setup dialog box as shown here. Set the database to point to stdreg32.mdb using the Select button. Finally, click the OK button

The ODBC Data Source Name 3. Run the AppWizard to produce stu file. Specify an SDI application (Step 1) with CScrollView as the view’s class type (Step 6). Select the Header Files Only option from the AppWizard Step 2 dialog box as shown here.

Page 284

Visual Programming

AppWizard to produce Student File 4. Use the ClassWizard to create the CStuset Recordset class. Choose New from the Add class menu and then fill in the New class dialog box as shown below

Creating a new class 5. Select the Students Registration database’s Student table for the CStuset class. When you click the OK button in the New Class dialog box, ClassWizard displays the Database Options dialogs box. Select the Student Registration data source, and select the Dyanset option as shown here.

Page 285

Visual Programming

Database Option After you select the data source, Class Wizard prompts you to select a table. 6. Examine the data members that ClassWizard generates. Click on the Member variables tab for the newly generated CStuset class. ClassWizard should have generated data members based on student column names as shown below 7. Declare an embedded recordset object in stuDoc.h. Add the following public data member in the CStuDoc clas declaration: CStuSet m_stuSet;

8. Edit the StuDoc.cpp file. Add the line # include “stuSet.h” # include “stuDoc.h” 9. Declare a recordset pointer in stuView.h. Add the following private data member in the CStuView Class declaration CStuSet* m_pSet; 10. Edit the OnDraw and OnInitialUpdate functions in stuView.cpp. following code: void CStuview::OnDraw(cDc* PDC) { TEXTMETRIC tm; pDC->GetTextmetrics(&tm); int nLineHeight=tm.tmHeight+tm.tmExternalLeading; CPoint pText(0.0); Page 286 Add the just before the line

Visual Programming
int y = 0; CString str; if (m-pSet->IsBOF()) { // detects empty recordset return; } m-pSet->MoveFirst(); // fails if recordset is empty while (!m-pSet->IsEOF()) { str.Format("%ld'. m-pSet->m-StudentID); pDC->TextOut(pText.x, ptext.y, str); pDC->TextOut(pText.x+1000, ptext.y, m-pSet->m-Name); str.Format('%d'. m-pSet->m-GradYear); pDC->TextOut(pText.x+4000, ptext.y. str); m-pSet->MoveNext(); ptext.y -= nLineHeight; } } void CStuView::OnInitialUpdate() { CScrollView::OnInitialUpdate(); CSize sizeTotal(8000, 10500); SetScrollSizes(MM_HIENGLISH. sizeTotal); m_pset = &GetDocument()->m_stuSet; // Remember that documents/views are reused in SDI applications if (m-pSet->IsOpen()) { m-pSet->Close(); } m-pSet->Open(); } Also in stuView.cpp, add the line #include "stuSet.h" just before the line #include 'stuDoc.h" 11. Edit the stu.cpp file. Add the line #include "stuSet.h" just before the line #include "stuDoc.h" 12. Build and test the application.

Page 287

Visual Programming
Adding ODBC capability to an MFC application If you need to add ODBC capability to an existing MFC application, make the following changes to the project 1. Add the following line at the end of StdAfx.h” #include <afxdb.h> 2. Edit the RC file in text mode. After the line # include “”afxprint.rc”” // printing preview resources add the line # include “”afxdb.rc”” // database resources Open Database Connectivity (ODBC) is a standard developed by Microsoft to simplify the development of applications that may have to target a variety of database platforms. Microsoft and third-party vendors implement ODBC through a collection of database drivers that are provided. ODBC database drivers provide your application with the capability to utilize a variety of database formats through the use of driver libraries. In order to switch databases, you would only need to switch the ODBC drivers. The primary benefit of ODBC is that it enables your application to be database independent. ODBC allows the developer to create an application using a locally available ODBC-compliant database such as Oracle. After the application has been created, the process to move the application to another ODBC database such as SQL Server becomes very simple. ODBC is an SQL-based standard that accepts all its query information through SQL command strings. Visual Basic provides three ways to access ODBC:    Data Access Objects (DAOs) Remote Data Objects (RDOs) ODBC API

ODBC works by using a series of connections. Each connection defines a data source and contains the name of a default database to load. The connection provides the pathway between the API calls and the data source. An ODBC system consists of the following components:     ODBC API – is what an application accesses ODBC Driver Manager – is the DLL that loads the drivers ODBC Drivers – are the database-specific drivers ODBC Administrator Applications – are used to maintain the registered data sources.

ODBC uses two .INI files to track information about the state of the driver setup on the machine. Page 288

Visual Programming

 

ODBC.INI : contains all the connection information for all data sources. Entries are added to the INI file each time an additional data source is added. ODBCINST.INI : contains information on all the installed ODBC drivers. If ODBC has not been installed on your machine, this file does not exist. An entry is created for each ODBC driver that can be used to create a data source connection.

Utilizing the data control or data access objects, you can manipulate an ODBC data source. However, before any application can access an ODBC database, the ODBC drivers must be installed and a Data Source Name (DSN) created using the Control Panel. This DSN is used whenever you refer to an ODBC database. Data Access Methods  Data Access Objects DAO enables you to use a programming language to access and manipulate data in local or remote databases and to manage databases, their objects and their structure. DAO supports two different environments or workspaces. The first is the Microsoft JET workspaces, which include databases created in Microsoft Access. You can also connect to JET databases via ODBC drivers. The second is the ODBCDirect workspaces. With this option you can bypass the Microsoft JET database engine and go directly to the back-end server to execute queries against the database. The ODBCDirect workspace provides an alternative when you only need to execute queries or stored procedures against a back-end server, such as Microsoft SQL Server or Oracle. One of the powerful features of Visual Basic since data access was introduced to the language is the data control. This control encapsulates basic functionality for creating applications that display, edit and update information. One of its key functions is providing an interface for data bound controls. This functionality in certain situations can save hours of database interface programming.

Page 289

Visual Programming
 Remote Data Objects RDO provides an information model for accessing remote data sources through ODBC. RDO offers a set of objects that make it easy to connect to a database, execute queries and stored procedures, manipulate results and commit changes to the server. The RDO programming model is similar to the DAO programming model in many respects. However, far more emphasis is focused on handling stored procedures and their result sets and less emphasis is places on data access retrieval methods.  ActiveX Data Objects ADO “flattens” the object model used by DAO and RDO, meaning that it contains fewer objects and more properties, methods and events. Much of the functionality contained in the DAO and RDO models was consolidated into single objects in the model, making for a much simpler object model. ADO consists of three primary objects. The Data Connection object defines the connection to the database. The Data Command object defines access to database objects such as tables, stored procedures or SQL queries. The Recordset object contains the set of records returned from the database server.  OLE DB A key addition in ADO is OLE DB support. OLE DB is a set of COM interfaces that provide applications with uniform access to data stored in a wide variety of information sources, both relational and nonrelational. These interfaces support the amount of DBMS functionality appropriate to the data source, enabling it to share its data through a standard database interface format. Thus ADO can potentially access data in fairly unstructured formats. The idea behind OLE DB is universal data access. There are no restrictions to JET, relational database sources and so on. With this type of data access, you can access unstructured data such as text files and Excel spreadsheets. The key to its flexibility is using ADO – the programmatic interface to OLE DB. OLE DB supports ODBC connections and JET connections and it provides a wide-open specification for database management system developers to provide connectivity to their software. Using DAO to Build Simple Database Let us build a simple address management system. Our database, created in MSAccess97 will contain name, address and phone contact details. The following table outlines the fields.

Page 290

Visual Programming
Field Name IdAddress txtFirstName txtLAstName txtAddress txtCity txtState txtZipCpde txtPhone txtFax Data Type Auto Number Text Text Text Text Text Text Text Text Description Primary Key that increments automatically First Name of the contact Last Name of the contact Address of the contact City where the contact lives. State where the contact lives Zip code for the contact Phone number for the contact Fax number of the contact

Name the database as address.mdb. We shall build the application using bound controls with the data control. We will need command buttons for adding new addresses and updating the database. We also will need one data control and several text boxes to display the data. Place all the necessary controls on the form.

Sample data access project at design time It is important to place the data control and set its property before placing the data bound text and label controls on the form. Each of these requires binding to the data control by setting its data source property. The Update button should not be visible upon startup of the form. It can only be used after the Add button has been clicked and the user is entering a new record. Page 291

Visual Programming
Let us put some code behind our application. For the click event of the Add button, we will want to tell the data control to add a new record. This is done be accessing the Recordset property and calling the AddNew method. Once this is done, the bound controls are automatically cleared and ready for data entry. To ensure the user does not try and add a new record in the middle of adding a new record, we hide the Add button. Then to provide a method for updating the database with the new data, the Update button is displayed. ‘Click event of the add command button Private Sub cmdAdd_Click() ‘Add a new record to the record ser Data1.Recordset.AddNew ‘Hide the add button cmdAdd.Visible = False ‘Display the update button cmdUpdate.Visible = True End Sub When the user clicks the Update button, the Update method of the Recordset object for the data control in invoked. That will cause the data control to insert the new data into the database. After this is done, the Add button is displayed again, and the Update button is hidden. ‘Click event of the Update command button Private Sub cmdUpdate_Click() ‘Update the data control Data1.Recordset.Update ‘Make the add command button visible cmdAdd.Visible = True ‘Hide the update button cmdUpdate.Visible = False End Sub Now we have code for initiating an insert into the database and then finishing the insert with an update of the data to the database. We did not have to write any code for browsing the data in the database or any code for updating records. Visual Basic’s data bound controls and data controls provide a significant amount of functionality right out of the box.

Page 292

Visual Programming
Making Reports One of the new report designer available in Visual Basic 6.0 is the data report designer, using which you can add simple and easy reporting to your application. This report designer is quite similar to the Access report engine interface. Let’s start out with an example. Start a new data project. A data project is one of the new types of projects for Visual Basic. In reality, it is like a Standard EXE project, but is set up for database development. The project includes a form, a data environment designer and a data report designer. In order to build reports, we need access to data. Assume that we have a sports database consisting of Team and Players tables. Now we can build two commands to out sports database. The first command will simply return all the teams in the Team database. The second will return a join of the Team and Player tables. Set up the connection properties of the data environment to access the sports database. If you set up the ODBC connection, then make sure to reference the DSN in the connection. Once this is done, create two commands from the connection. Name one of them “Teams” and the other “Players”. For the Teams command, set the properties to retrieve a “Database Object” and set the object to be the “Team” table. That will automatically retrieve all the rows in the team table. For the Players command we need to build a SQL query. Follow these steps: 1. 2. 3. 4. Right-click on the command object and select properties. Select the SQL statement option. Go to the SQL builder to build the query. Add both the Team and Player tables to the query builder by double-clicking on each. 5. Ensure that there is a link between the idTeam field in the Team and idTeam field in the Player. If not drag one field onto the other to create the link. When you do this, the SQL builder will create a query joining the two tables. 6. Add * in all fields, for both tables, by double-clicking on the * symbol in the field listing for the tables. Close the query. Below is the SQL code Select Player.*, Tea,.* from Player, Team where Player.idTeam = Team.idTeam Let’s now create a report. Double-click on the data report in your project and rename it as “rptTeams”. As with forms, you will find a set of properties for the report. Reports also have several components. There are the headers that only display at the top of the report or the top of the page. And there are footers that display only at the bottom of each page. There are also report headers and footers that only display at the top and bottom of the report. The Detail section is where you build the fields to be reported for each row in your recordset.

Page 293

Visual Programming

Team report at design time Some basic controls are outlined Control RptLabel RptTextBox RptImage RptLine RptShape RptFunction Deacription Label control for the report interface Text box control, which can be data bound Image control for placing images on your report. Ability to draw lines on the report Shape control for drawing shapes on the report Can only be placed in the report footer. This function can calculate sums, mins, maxs averages, standard deviation, standard error, value count and row count. This is useful for automatically summing up a field.

Report controls Add labels and text boxes for each field in the players and teams database. Make sure that the data source for the report is set to the data environment in your project. Then set the data member for the report to be “Teams”. Now set each of the text boxes to point to the appropriate “teams” data member. Now tie each appropriate text box to the proper field. The second report, “rptPlayers”, will be tied to the Players command we created. As with the Teams report, you will need to set the data source property to the data environment and the data member is set to players. Set up the report as shown in Fig 3.26.

Page 294

Visual Programming

Players report at design time Now we have to create a interface to call our reports. On the form in the project, add the command buttons as shown below Command/Property Form Caption Command button Caption Command button Caption Settings frmReports “Data Reporting” cmdTeams “Show Teams” cmdPlayers “Show Player”

The report is simply shown by calling the Show method. In each click event, the appropriate report is called. When that happens, the report are displayed in a separate window. Following is the code for the application. Private Sub cmdPlayers_Click()

Page 295

Visual Programming
‘Show the players report rptPlayers.Show End Sub Private Sub cmdTeams_Click() ‘Show the teams report rptTeams.Show End Sub Visual Basic provides flexible reporting capabilities. Do some formatting on the reports with shapes and other graphics. Also place a min and max function to calculate the tallest and shortest player in the team. 4.2.8 Communicating with other applications Embedding vs. In-Place Activation (Visual Editing) Visual Editing is Microsoft's name for in-place activation. A component that supports in-place activation also supports embedding. Both in-place activation and embedding store their data in a container's document, and the container can activate both. An in-place-capable component can run inside the container application's main window, taking over the container's menu and toolbar, and it can run in its own top-level window if necessary. An embedded component can run only in its own window, and that window has a special menu that does not include file commands. Some container applications support only embedded Components; others support both in-place and embedded components. Usually, an in-place container program allows the user to activate in-.place components either in place or in their own windows. You should be getting the idea that embedding is a subset of in-place activation. This is true not only at the user level but also at the OLE implementation level. Embedding relies on two key interfaces, IOleobject and IOleClientSite, which are used for in-place activation as well. Mini-Servers vs. Full servers (Components) – Linking A mini-server can’t be run as a stand-alone program. It depends on a container application to launch it. It can’t do its own file I/O but depends on the container’s files. A full server, on the other hand, can be fun both as a stand-alone program and from a container. When its running as a stand-alone program, it can read and write its own files, which means that it supports OLE linking. With embedding, the container document contains all the data that the component needs; with linking, the container contains only the name of a file that the component must open.

Page 296

Visual Programming
Windows Metafiles and Embedded Objects Think of metafile as a cassette tape for GDI instructions. In the world of OLE embedding, components create metafiles and containers play them. Here’s some component code that creates a metafile containing some text and rectangle: CMetaFileDc dcm; // MFC class for a metafile Dc VERIFY(dcm.create()); dcm.SetMapMode(MM_ANISOTROPIC); dcm.SetWindowOrg(0,0); dcm.SetWindowExt(5000,-5000); //drawing code dcm.Rectangle(CRect(500,-1000,1500,-2000)); dcm.TextOut(0,0,m_strText); HMETAFILE hMF = dcm.Close(); ASSERT(Hmf != null); The metafile contains a SetWindowExt call to set the x and y extents of the window, and the program that plays the metafile call SetViewportExt to set the extents of the viewport. 4.2.9 Object Linking and embedding The MFC OLE Architecture for Component Program You need to know about three new MFC base classes-COleIPFrameWnd, COleServerdoc, and COleServerItem. When you use AppWizard to generate an OLE component, AppWizard generates a class derived from each of the base classes, in addition to an application class, a main frame class, and a view class. The COleIPFrameWnd class is rather like CFrameWnd. It's your applications main frame window, which contains the view, It has a menu associated with it, IDR_ SRVR_ INPLACE, which will be merged into the container progam's menu, When your component program is running in place, it's using the in-place frame , and when it's running stand-alone or embedded, it's using the regular frame, which is an object of a class derived from CFrameWnd, The embedded menu is IDR_SRVR_EMBEDDED, and the stand-alone menu is IDR_MAINFRAME, The COleServerDoc class is a replacement for CDocurnent. It contains added features that support OLE connections to the container, The COleServerltem class works with the COleServerDoc class., If components never supported OLE linking, the functionality of the two classes could be combined into one class. Because stand-alone component programs do support linking, the architecture dictates that both classes be present in all components. Together, the COleServerltem class and the COleServeDoc class implement a whole series of OLE interfaces, including IOleObject, IDataObject, IPersistStorage, and I0leInPlaceActiveObject. These classes make container, using interface pointers

Page 297

Visual Programming
that the container passes to them. CView class draws the component's in-place-active window and the derived COleServerItem class draws in the metafile on command from the container.

4.3 Revision points
• • In order to build reports, we need access to data Visual Editing is Microsoft's name for in-place activation. A component that supports in-place activation also supports embedding. • When you use AppWizard to generate an OLE component, AppWizard generates a class derived from each of the base classes, in addition to an application class, a main frame class, and a view class

4.4 Intext Questions
1. How to build reports from a Visual application ? 2. What is an ADO data control ? 3. What is known as dialog based applications ?

4.5 Summary
 The Microsoft Windows device context is the key GDI element that represents a physical device. Each C++ device context object has an associated Windows device context, identified by a 32-bit handle of type HDC.  Microsoft Foundation Class (MFC) Library version 6.0 provides a number of device context classes. The base class CDC has all the member functions  A program reads a record and then formats and prints selected information as a line in a report. The Print Preview program examines each character individually, determining its position based on the printer's device context.  Embedding relies on two key interfaces, IOleobject and IOleClientSite, which are used for in-place activation as well.  A mini-server can’t be run as a stand-alone program. It depends on a container application to launch it.  An ActiveX control is an interactive object that can be located on any form in any application that supports ActiveX controls, including Web pages.  Open Database Connectivity (ODBC) is a standard developed by Microsoft to simplify the development of applications that may have to target a variety of database platforms.

Page 298

Visual Programming
 OLE DB is a set of COM interfaces that provide applications with uniform access to data stored in a wide variety of information sources, both relational and nonrelational.

4.6 Terminal Exercises
1. Explain the various device context classes provided by MFC library version 6.0 2. Explain how to add ODBC capability to an MFC application.

4.7 Supplementary Material
 See Vb5dll.doc, "Notes for Developing DLLs for Use with Microsoft Visual Basic," included with Visual Basic

4.8 Assignments
1. Write an Mini database application

4.9 Reference Books
 Gary Cornell, “Visual Basic 6 from the ground up”, Tata McGraw Hill, 1999.  Noeal Jerke, “Visual Basic 6 – The Complete Reference”, Tata McGraw Hill, 1999.  John W. Franchowian, David J.Helda, “Visual Basic 6 Database Programming for SQL Server 7 & Oracle 8”, IDG Book India (Pvt) Ltd, 2000.  Siler and Spotts, “Special Edition using Visual Basic 6”, PHI, 2001.

4.10 Learning Activity
1. Explain the usage of database management with ODBC

4.11 Keywords.
DLL - Dynamic Linked Library OLEDB – Object Linking and Embedding Database WEP – Windows Exit Procedure ODBC – Online Database Connectivity ADO – ActiveX Data Object IDE – Integrated Development Environment

Page 299

Sponsor Documents

Or use your account on DocShare.tips

Hide

Forgot your password?

Or register your new account on DocShare.tips

Hide

Lost your password? Please enter your email address. You will receive a link to create a new password.

Back to log-in

Close