Extensions Hit
Light Speed
![]() |
| SCREEN 1: |
| Displaying the Comment and
Suggestion fill-in form |
Part 1 showed how to create an ISAPI Extension that responds to a fill-in form. The code did not do anything except display a default message. This article shows how to modify an ISAPI Extension that the MFC Wizard generates. I cover the Wizard-generated ISAPI Extension additions you need for the example form in Part 1. The additions let you initially display the Comment and Suggestion form shown in Screen 1 as the default and display the second page with the return email address and link to the all-records page. The HTML that produces the Comment and Suggestion fill-in form is in Listing 1.
ISAPI Wizardry Revisited
After you prepare the HTML for the fill-in form, as in Listing 1, create an ISAPI Extension with the Visual C++ ISAPI Extension Wizard. The Wizard creates an ISAPI Extension with the entire MFC ISAPI framework, but little else. We'll extend this framework to display the Comment and Suggestion form shown in Screen 1 and handle the CGI request generated when a user enters a comment (as you see in Screen 2) and clicks Send on the form.
To generate the initial ISAPI Wizard, start Visual C++, select the File menu, and click New. Double-click the Project Workspace option. The New Project Workspace dialog appears. From the Type list, select ISAPI Extension Wizard. In the Name text box, type comment as the name of your project. Click Create to pull up the ISAPI Extension Wizard - Step 1 of 1 dialog you see in Screen 3. Select Generate a Server Extension object to specify that you want an MFC-generated class--an ISAPI Extension--to handle ISAPI Extension, or CGI, requests. Click Finish to display the New Project Information dialog. Click OK to complete the task.
![]() |
| SCREEN 2: |
| Entering and sending a comment |
Modifying the MFC Wizard ISAPI Extension
So let's walk through a simple, standard methodology to finish the ISAPI Extension created in Part 1 of this series. The ISAPI Extension will display the Comment and Suggestion form for a URL that points to the ISAPI Extension with no arguments (http://spain.winntmag.com/comment.dll?). You must add a method, postComments, to the class created by the MFC Wizard, CCommentExtension, to process the values passed to the ISAPI Extension DLL when someone selects Send on this form. Listing 2 shows the prototype for the CCommentExtension::postComments method.
![]() |
| SCREEN 3: |
| Generating the initial ISAPI Wizard |
![]() |
| SCREEN 4: |
| Creating a custom resource
for HTML before final "OK" |
First, incorporate two class methods from this example into your ISAPI Extension class: Copy the WritePage Title and LoadLongResource methods from the WWWQUOTE example and change the class names from CWWWQuote to CCommentExtension to match your class name in the method declarations and definitions. You'll use this codelater in this example for reading whole HTML pages from custom HTML resources. You can put this code into a separate file and call it helper.cpp for future use in other ISAPI Extension projects.
![]() |
| SCREEN 5: |
| Creating a custom resource
for HTML after final "OK" |
Get the HTML code into a resource that you will use to display the full comment and suggestion form: Copy all the HTML code in Listing 1 into the comment.htm file. Now select Comment resources again, click the right mouse button, and select Import to display the Import Resource dialog. Select the file comment.htm, shown in Screen 6, and click OK to bring up the Custom Resource Type dialog shown in Screen 7. Select the HTML resource, and click OK. Screen 8 shows that you have imported the file, idr_html2, into the project as an HTML custom resource that you can edit.
![]() |
| SCREEN 6: |
| Importing a custom resource for HTML |
Now change the resource ID to something more meaningful. Select idr_html2, click the right mouse button, and select Properties to display the Custom Resource Properties dialog shown in Screen 9 (on page 110). Select the ID: field, and change the ID to idr_html_comment_form.
To store resources for the two pages that result from clicking Send, you'll need to create two other HTML files and the custom HTML resources for them. Listing 4 shows two HTML strings. Copy the first HTML string into a file named comsent.htm and the second into sugsent.htm. Use the technique described above to import these two other HTML files as custom HTML-type resources (idr_html_comsent_form and idr_html_sugsent_form). Next, add the resources (HTML titles) shown in Table 1 to the string table resource shown in ResourceView.
![]() |
| SCREEN 7: |
| Defining a resource type |
This routine writes the form title by calling the WritePageTitle() method and then uses the custom HTML resource idr_html_comment_form to call the LoadLongResource() method to load the HTML fill-in form. You also see calls to the StartContent() and EndContent() methods at the beginning and end of this routine. The calls write out the initial CGI line that specifies content type (Content-Type:text/html\r\n) and the end of the HTML (</body></ html>), respectively. For the CCommentExtension::postComments to process the CGI request that the form will produce, you need to add the code in Listing 6.
![]() |
| SCREEN 8: |
| Displaying the imported file |
Once you compile, you've completed the basic tasks for modifying the MFC Wizard-generated ISAPI Extension. Your ISAPI Extension will now display and process the Comment and Suggestion fill-in form.
Adding Complexity to Your Code
![]() |
| SCREEN 9: |
| Modifying the ID in the
Custom Resources Properties dialog |
You add the call to this method, shown in Listing 7 (on page 108), at the end of the postComments method. Make certain that two CGI requests do not try to write to the file at once. Two CGI requests can occur simultaneously because IIS can process more than one request asynchronously by creating a separate thread for each CGI request. Two or more threads attempting to write to the same file at the same time might result in garbled text in the file at the very least. Listing 8 (on page 108) ensures that only one thread executes the code at a time. If a thread is in the middle of this method and a second thread starts to execute it, the second thread hits the EnterCriticalSection() function and waits until the first thread passes the LeaveCriticalSection() function before the second thread can continue.
![]() |
| SCREEN 10: |
| The comment received notification with the added hyperlink |
Wrapping It Up
You've modified an ISAPI Extension to append to the All Records HTML file--and in a safe way. The ISAPI Extension also provides a hyperlink to this page in its reply to the form request. You can compile this ISAPI Extension, copy it into the \wwwroot directory, and run a browser with the URL http://yourmachine/comment? to see it in action, as in Screens 1, 2, 10, and 11.
![]() |
| SCREEN 11: |
| Showing all the comments
and suggestions received |
You can use the example you just completed as a guide for further extensions. ISAPI Extensions are easy to write, extend, and maintain. Try adding another object class method, writing an HTML file with a fill-in form that references the new class method as the default did (dll?method), and experiment. It's a snap!
ABOUT THE AUTHOR
Daniel F. Wygant is a senior software analyst with Intergraph in Huntsville, Alabama. He is a regular contributor to Windows NT Magazine and has written two chapters in a Sams.net book, Presenting ActiveX. You can reach him at dfwygant@ingr.com.