Share via


Detecting Security Settings, Printing from the WebBrowser Control, Hiding the Print Button, and More
Robert Hess
Q Is there a way to detect the security settings in Microsoft® Internet Explorer on the client machine? I would like to check if I can create an object (like Excel.application) on the client's machine, and if not I'd like to show a customized message.

A Gaining access to the security settings of a user's machine is not possible, and is considered a security violation. However, if your primary objective is to simply understand if your page is running in low security (which should never happen if the user is accessing your site via the Internet), and whether you are able to issue a CreateObject call in order to launch Microsoft Excel, then there is a way to do this. You can use code such as:
  <SCRIPT LANGUAGE="VBScript">
<!--
on error resume next
set oShell = CreateObject("Shell.Application")
set oFolder = oShell.NameSpace("NUL:\")
if err.number <> 0 then
    document.write "Unable to use CreateObject"
else
    document.write "Able to use CreateObject"
end if
-->
</SCRIPT>

And you could use any object here. The key is that the CreateObject call itself won't throw an error that you can catch, but trying to access that object will. So you could even use your example of Excel.Application here, and just make sure that on your first attempt to access that object you have appropriate error handling turned on so that you can determine if it worked.
      I can't stress enough that any user who has security set at a low enough level for you to be able to issue this call has greatly compromised the security of his system. Users should never set security so low, and no Web site should ever ask users to modify security settings to allow this level of access.

Q When I print from the WebBrowser control, the background colors don't print. I used the Media attribute to print and then I applied some background colors to tables, but the background colors still won't print. I'm using Internet Explorer 5.0.

A If you are having the problem I think you are, all you need to do is go to the Tools | Internet Options menu and then click on the Advanced tab. Scroll down to near the bottom and turn on the "Print background colors and images" checkbox.

Q I have a Web page that is produced dynamically from an ASP script. The page must have a Print button on it. When a user presses the Print button, the page should be printed, but I want the Print button to be hidden on the printed page.

A There are two issues here. One is to provide a button on a Web page that, when pressed, will cause the page to be printed; the other is to prevent that button from being printed along with the output. Each of these problems has two possible solutions. The one you adopt will depend on the browser your users have.
      For printing, one approach is to use the ExecWB function. Using the code in Figure 1, you would call the Print subroutine when your button is clicked. This will work in Internet Explorer 4.0 or Internet Explorer 5.x, but not in Netscape Navigator.
      The other option is to use the window.print method. This will work in Netscape 4.x or Internet Explorer 5.x, but not in Internet Explorer 4.0. Documentation for the print method can be found at https://msdn.microsoft.com/workshop/author/dhtml/reference/methods/print.asp.
      Note that while the code in Figure 1 provides a method to turn off prompting before printing, the print method does not. Also note that neither of these choices will allow you to assign the printer or modify the page count, orientation, or any other layout parameters. In order to get that level of functionality, you would need to write an application that embeds the browser in it.
      To prevent the button from being printed along with the content, you can try one of a few solutions. Using Cascading Style Sheets (CSS), you can set up a style that will control the layout and display on the screen and printer separately:
  <style>
@media screen {.PrintOnly {display:none}}
@media print {.ScreenOnly {display:none}}
</style>

      Here, I've defined two classes; one will only print, and the other will only display on the screen. So in your case, you would use something like this: FakePre-b378dbdd84364c52853bb1463b4b36d7-d4512f846cd846629ae5038a9784679cThen the Print button would only appear on the screen. Note that this will only work in Internet Explorer 5.x, and not in Internet Explorer 4.0 or Netscape Navigator.
      You could also use a frame-based set of pages, placing the Print button in another frame:
  <button onclick="parent.frames("Doc").window.print()">Print</button>

The <button> item will only work for Internet Explorer 4.0 or Internet Explorer 5.x, and not in Netscape Navigator. You could, of course, provide the same level of functionality with an <input> button, or with any element that supports an onclick event.

Q I'm having trouble using isClientConnected in my Web page. It always returns false when I expect there to be a connection.

A It has been pointed out to me that isClientConnected will always return false until at least one Response.Write has been called and flushed to the client. That is, until a datastream has been established back to the client, the client isn't considered connected. In the code you sent (see Figure 2) you haven't called Response.Write, so isClientConnected would be expected to return false. Add a Response.Write statement before you use isClientConnected.

Q I'm trying to sort records by three different field names from a dropdown box. Based on the name selected, the corresponding records from the recordset will be sorted and displayed in a table. Under the table I need navigation buttons or links such as:
  "Go to First page"
"Previous page"
"Next page"
"Go to last page"
"You are on page 3 of 10"

I know this can be done with design-time controls, but I can't use them. Do you have any sample ASP programs that could help?

A This should be relatively simple, and shouldn't require the use of design-time controls.
      The URL that generates the request will need to have the range embedded within it, so that the ASP code will know what part of the resultant recordset to return. Something like:
  tablereport.asp?recStart=30&recCount=15&queryString=...

      The following would allow you to easily provide a "Go to first page" link: FakePre-15191696574442be8be44020bb004fdc-6ba94991a3c94761a61388e9fdf90244      This will give you a "Previous page" link: FakePre-6c9a6136ec6445bab9066752bbedfbe9-5de86da3a2764235b9e13321046aa1f7      And here's how to create a "Next page" link: FakePre-32dacbacb8294d6eb613efa12e3fa97f-f2472024b602483b8a8c9486d2b474a3      For "Go to last page" and "You are on page 3 of 10", you only need to know how many total records are in the full query results. There are several ways to do this. The easiest, of course, is simply to do a full query each time, and then selectively report on only the records that were specifically asked for. Obviously for a large recordset, this could take a while.
      A quicker method would be to use COUNT in your query string:
  Set RS_item = Conn.Execute("SELECT COUNT (*) FROM ...
recCount = RS_item.fields(0)

This method will be faster than getting back the entire recordset results each time. However, this also takes time, so if you want to avoid that you could encode the recCount variable into your URL as well, once you knew what it was. This way, the first time you hit the database you would notice that either the recCount variable was not provided in the URL or that it was zero, and so you'd do a full (or counting) query, and from then on you'd automatically include the recCount variable in the URL so it could be retrieved from page to page.

Q I am creating a Web application using Visual InterDev® and SQL Server™ 2000. I have five dropdown boxes that I would like to be completely database-driven, rather than hardcoding their values. The application I am developing has dropdown values that change quite a bit, so hardcoding it would be a huge hassle.

A Using a combination of server-side scripting and database queries to dynamically generate HTML content is the cornerstone of Web applications. There are a variety of ways to do this, but the best choice depends on how comfortable you are interacting with your data services.
      I like handcoding from scratch, rather than relying on wizards or other forms of automated code generation. I'll show you some code that I've used in the past for dynamically generating a dropdown listbox based on entries in a database. In this particular example, my database had a table in it that identifies the names of categories that I want the user to select from. I need to enumerate through each record in the table, extracting the Name fields so I can use them as the values for my listbox.
      The first step is to open the database. In this example, dbPath is a variable that contains the fully qualified path of the Microsoft Access file you want to open. You would either change the path as appropriate, modify the format of the connection string in order to access some other database, or use some other data access driver or provider.
  <%
Set Conn = Server.CreateObject("ADODB.Connection")
myConnectionString = "DBQ=" & dbPath &
                     ";Driver={Microsoft Access Driver (*.mdb)};"
Conn.Open myConnectionString
%>

      Next, you want to create an array in which to store the category names. I've hardcoded the array size to 100, but this is perhaps not optimal for a robust solution. A better method is to first count the categories that the database contains, then redim the array to that size. I am also using the ID of the category to identify which array position to place the name into: FakePre-b03eaa28917e4228b849f50fc7adf082-1829ccf165684facb932c3061e596e87      Now that I've got the names in a tidy little array, I can publish them with code similar to the following. FakePre-4cef2105d3d048b58ca6bafecb1827ea-5c1fb3727fa04839892a4c6fd73a1a61Here I am also using the variable id_category to identify the default category to use, so if the one being written out as HTML is that category, I mark it as selected.

Q I'd like to know how applications like hotbar.com and Alexa install directly from the server to my system with just a single click. How can I do this in Visual Basic®?

A An application can be installed on your machine if it is an ActiveX® control that installs the program onto the user's system. For example, let's say you created a normal setup.exe that was a single executable containing all the necessary components to install. On your Web site you would provide the executable for download to the user like so:
  <a href="setup.exe">download</a>

      When the user clicks on this, he will be asked if he wants to run the program from its current location or download it (download is the default). Once the user downloads it, he would then need to manually execute this program in order to perform the installation. With the sort of setup that Alexa provides, you don't see that dialog box. Instead you see a dialog that asks if you want to install and run the app, which is essentially the same as asking if you trust the application. Once you say yes, the application downloads and installs immediately.
      This is possible because the application is an ActiveX control, and the installation is initiated because the control was embedded in the page using an <object> tag. Just follow the Visual Basic documentation instructions for creating an ActiveX control. It's a little tricky, but not too bad.
      If you really want to know how to create an application that has this kind of symbiotic relationship with Internet Explorer, you need to create what's known as a browser extension. There are a variety of possible extensions, including explore bars, toolbar bands, menu items, and toolbar buttons. You can get more information about how to develop these various extensions at https://msdn.microsoft.com/workshop/browser/ext/overview/overview.asp.

Q I have a Web site with frames. The top frame is my site navigation bar and the bottom frame displays third-party Web sites that my users can shop on. I want my top frame with the navigation bar to always be present, but unfortunately when users click on links on some of the sites I display in the bottom frame, the link loads a new page because its target is set to _top. Can you give me a suggestion to get around this problem?

A Targeting the top-level window is intended to allow a Web page to take over the full browser content area. If you had a way to prevent that, then they in turn would want a way to bump themselves to the top again, and you'd want a way to prevent that, and, well, you get the picture.
      One solution to this problem is to form a close alliance with the Web sites that you will be including within your frameset, and carefully arrive at a mutually agreeable way in which neither of you impose on the needs of the other. However, this is often impractical, if not difficult to achieve.
      Another solution is to simply accept the fact that some sites will target the top window and detect when that is happening. You can use the onbeforeunload event of the <body> element to notice when your page is about to be unloaded, and take an appropriate action at that time. For example, you could spawn an additional copy of your page as your page is being unloaded.
  <body onbeforeunload="window.open('myPortalPage.html',
 'myPortal', 'width=300, height=100')">

This code will cause the myPortalPage.html page to be opened in a new window any time the interior frame uses target=_top. This allows you to provide the user with a connection back to your portal. Of course, it will also occur whenever the user closes down the browser window or manually navigates to another site, so keep this in mind.

Q I need to create a popup window that remains on top of every other window even if I move focus to another window. I'd also like the code to be compatible with many different browsers.

A The only way to create a popup window that remains on top is to write a full-fledged Windows-based application. There isn't any way to do this with HTML. If there were, I could just imagine every site that I visit fighting to be on top.

Got a question? Send questions and comments to webqa@microsoft.com.
Robert Hess is a manager in the Platform Strategy Group, hosts "The .NET Show," and is a regular contributor to various areas of MSDN.

From the March 2001 issue of MSDN Magazine