Visual Basic Online

Questions & Answers October 1996

 

Quick tip for VB4 users: before running the setup wizard open your project and select TOOLS and then CUSTOM CONTROLS from the VB4 menu. Un-check all items that you are not using in the project (you can try to un-check all items -- VB will yell if you try to remove too much). Repeat this process using TOOLS and then REFERENCES. Recreate your EXE file (save it in the same directory as the project source or the setup wizard will redo it again) and save the project. This can reduce the number of files included in the distribution dramatically.


Q: I'm a new VB4 programmmer, and puzzled: How does the BackColor for Command Buttons get utilized? It's in the properties list for the control but when I set it to another color, nothing happens at either design or run time, or when it's set in code. If it doesn't work, why is it there? K.K. Whipple
kkwhippl@ix.netcom.com
A: I think this is one of life’s mysteries... like why 24-hour convenience stores have locks on the doors. Command buttons are always the same background color and this property is, as far as I can tell or find, ignored. Think of it as a handy place to store a color code.


Q: I’m using VB 4.0, Enterprise Edition, 32-bit. I've got a slider control on a form. I can read from the Min and Max properties just fine. However, when I try to assign a value to either the Min or Max properties, I get a run-time error #380, "Invalid property value". Why, when the Min and Max are valid for reading is it all of a sudden invalid to modify?
Rod Falanga
rfalanga@unm.edu
A: The only way I can duplicate this is by setting the MIN greater than the current MAX or the MAX less than the current MIN. For example, if Slider1.Min=0 and Slider1.Max=10 then the statement Slider1.Min=50 is illegal. To set a new range you need to be careful to keep a valid range at all times. (In a follow-up message Rod Falanga wrote: I found that if I performed the assignment in a different event (I can't remember which one) then the slider's Min and Max properties were "visible", so to speak. I think I was doing it originally in the Initialize event, but I had better success in either the Load or Activate events. In VB3 there was no ‘Initialize’ event. When you referenced a form-level variable or used Load or Show on an unloaded form the form was loaded and the Load event triggered. In VB4 the data portion, with all form-level variables loads first, the Initialize event fires, the form itself (code and controls) then loads and the Load event fires. For a Load or Show the difference is minimal. The advantage is that you can set the value of form-level variables (e.g. Form2.Status="Open") and get the form’s data component loaded and the Initialize event fired without loading the entire form or triggering the Load event.)


Q: I am trying to write an application using VB4 Pro (32-bit) that will allow the user to search through their hard drive for files that are duplicates of each other so they can delete them if necessary. I also want to show them the file's size, and date modified. I know this is asking a lot, but I'd really appreciate any help you can give. Also is there any way to search from one drive/partition to another for those duplicate files?
Steve McNair
bravhaart@relia.net
A: In last month’s column I posted a routine to search the drive for a specific file using Dir$ and GetAttr. You would need to modify it to save the names in a listbox or string array and sort them to find the duplicates. To search other partitions you can just run through A:\, B:\, etc to do all drives. For each file the FileLien and FileDateTime functions will get you the other info you are looking for.


Q: I have made a small program that fills forms, I have created it under win 3.1 with vb4.0 pro 16, I used the setup wizard to produce distribution disks, (3 total). Every time I try to install it on another computer running win 3.1 or 3.11, I get the following error: Language ....N16.DLL not found. What is that N16.DLL? I could not find it anywhere on my system either, yet no other problems are apparent on the systems. I have also tried to install it on a computer running WIN95, no problem at all, every thing went as planned.
Daniel Riverin
driverin@consulan.com
A: My guess is that it is trying to find VB4EN16.DLL and the name is corrupted somehow. Try adding that to your setup and/or copying it to the target system first and see if it makes a difference. (from a follow-up message I know my response did not help... anybody have any suggestions?)


Q: I faced a problem on how to produce a printout based on below:



                 A B C D E F G  -> Gothic font

  line spacing  {

                 1 2 3 4 5 6 7  -> Arial font

                  ~

                 character spacing

I want to print them individually according to different fonts,different font size, different line spacing as well as different character spacing. How am I going to do that, please advise.
may
vogmep@epvx03.nsc.com
A: It should be as easy as doing something like this: 

Printer.FontName = "Gothic"

Printer.FontSize = 12

Printer.Print "A B C D E F G"

Printer.Print

Printer.FontName = "Arial”

Printer.FontSize = 10

Printer.Print "1 2 3 4 5 6 7"

Printer.EndDoc

You can use the Printer.Fonts collection to find out what fonts are available on the current Printer object. 

Q: If I have a grid that contains more than 1 screen of data, thus creating the vertical and horizontal scroll bars at runtime. My question is: When I remove the last record in the grid using the RemoveItem method the screen is repositioned to the first cell in the grid. Is there a way to have the screen remain as is with the cursor positioned on the new last record of the grid? Another question is why does the column you're positioned on when you execute the RemoveItem method get highlighted?
Yue Wu
ywu@amherst.com
A: To prevent the repositioning you need to retain the value of the TopRow and reset it:


    Dim x As Integer

    x=Grid1.TopRow

    Grid1.RemoveItem n

    Grid1.TopRow=x

You will also need to adjust the value down by 1 to keep a full screen and check for the last row being deleted. I can not duplicate the highlighting problem you mentioned, but you control the automatic highlighting with the SelStartRow, SelEndRow, SelStartCol and SelEndCol properties. You can save and restore them at the same time, also adjusting for any delete from within the range. 

Q: I am writing a program that has wizard type screens where the user can either move forward to the next screen or backward to the previous screen. My question is: How do I control the windows close button "X", so the user isn't sent back to the beginning but moved to the immediate previous screen? I tried using the MSGBLAST vbx but to no success. From what I read about MSGBLAST it's only for the 16-bit environment anyway and I'm using a 32-bit environment.
Yue Wu
ywu@amherst.com
A: I have two suggestions for handling this:

  1. Set the form’s ControlBox property to False which will disable the X in the upper right corner of the window frame.
  2. Add code to the form’s QueryUnload event. You can set Cancel=True to ignore the user’s unload directive and then do whatever you need to do to show the previous screen.

Q: I've been doing a lot of dos programming for a while, not exactly sure about the switch to windows! But, I'm doing OK and have written a few small utilities. My program requires being able to open a file from the dialog box. I set it up as such:



Private Sub mnuopenfile_Click()

  cmdialog1.Filter = "All Files (*.*)|*.*"

  cmdialog1.FilterIndex = 1

  cmdialog1.Action = 1

  cmdialog1.Flags = READONLY

  Key.Show

END SUB

With that I can open the box,change directories and highlight a file. How do I open that file and how is that information passed back to VB?
Scott Turchin
Computer Creations Software
BBS #: (360)-698-3610
nitehawk@tscnet.com
A: Welcome to Windows! The dialog box justs lets the user select the file. It appears when the ACTION property is set so you need to move the cmdialog1.Flags=READONLY line up at least one line of code to make it effective. After the user closes the dialog box the next line of code will run and at that point CMDIALOG1.FILENAME will be the selected path. 

Q: How can I catch the MouseMove event for ComboBox in VB?
Rajesh Vijayakumar
vijayk@cswl.com (this rejected when I tried to reply)
A: I don't think you can unless you get MSGHOOK or some other third-party add-on to intercept windows messages.


Q: Can I possibly place elements of a control array for say checkbox, into different tabs of a SSTab control? That is, Tab 0 may have 2 checkboxes, Tab 1 may have 3 checkboxes, etc considering that all checkboxes belong to a control array (say check1). The number of tabs and the number of checkboxes can only be determined during run-time (of course, at least 1 tab in SSTab control and 1 checkbox control).
Dennis Ang
dennisan@nyp.ac.sg
A: Not automatically. You must draw the controls on the tabs in design mode to have the SSTab control handle it automatically. The best option I can think of would be to set the TAG property to the value for the tab and when you switch tabs run through the checkboxes and set the visibility property appropriately.


  Load CheckBox1(x)

  CheckBox1(x).Tag=format$(SSTab1.Tab)

  CheckBox1(x).Top=....etc...



  Sub SetTabNumber(intTab As Integer)

  Dim x As Integer

  For x=0 To CheckBox1.Count-1

    If Val(CheckBox1(x).Tag)=intTab Then

       CheckBox1(x).Visible=True

    Else

        CheckBox1(x).Visible=False

    End If

  Next ‘x

  SSTab1.Tab=intTab

  Exit Sub


Q: Can you please tell me how I could select the current line that I am on automatically (by using code) on the Rich Text Box?
Semin Nurkic
hyped@geocities.com
A: Try something like this:


Sub SelectLine(rtb As RichTextBox)

Dim lngStart As Long

Dim lngEnd As Long

Dim x As Long

lngEnd = InStr(rtb.SelStart + 1, rtb.Text, vbCr) ' find end of line

If lngEnd <1 Then lngEnd="Len(rtb.Text)" lngStart="0" default to first For x="rtb.SelStart" To Step back up to start of line If Asc(Mid$(rtb.Text, x, Then lngStart="x:" Exit For Next x rtb.SelStart="lngStart" rtb.SelLength="lngEnd" lngStart End Sub pre>


Q: I am writing an application involving sending a simple text file or a database through a modem. I am using the mscomm control to do that and I would like to know what are the function calls to send my data ?
lewyawi@mailposte.ca
A: The VB Professional Features manual that comes with VB has all the documentation on the MSCOMM control, as does the on-line help and the ‘books-on-line’ section of the CD. The commands I think you are looking for are mscomm1.input and mscomm1.output (if you must send or receive NULL characters use the .comminput and .commoutput instead).


Q: I ran the example on the CARDS.DLL that was in the Tips and Tricks and also mentioned in your Q&A section in August. I can print the cards to a form, but how do I drag and drop them? Do I have to put them in a picturebox? if so how? I want to be able to write a card game program using the CARDS.DLL library. Also, what books would be good to define the usage of other MS supplied DLL files? (I have VB 3.0 standard edition, Win 3.1)
Frank David
Frank.David@Carrier.WLTK.Com
A: You could use any control with an ‘HDC’ property easily and the picture control is fine. The CDTDRAW calls have an hdc argument so to draw to the picture box just use "Picture1.HDC" instead of "Form1.HDC". Drag & Drop can be done automatically but you can have much finer control if you handle it yourself. Try the following code for some idea of how this might be done. Start with a new project that has one form and add a picture box in the upper left-hand corner of the form and set the INDEX property of the picture box to zero while in design mode (to create a control array with a single element). Then add the following code:


(in the general/declaratives section)

Option Explicit

Const C_FACES = 0	‘ for drawing card faces

Const ONTOP = 0	‘ for setting z-order

Const ONBOTTOM = 1

Const DRAGSTART = 1	‘ for controlling drap & drop

Const DRAGSTOP = 2

Const PIXEL = 3	‘ for setting scalemode

Declare Function CdtInit Lib "CARDS.DLL" _

	(nWidth As Integer, nHeight As Integer) As Integer

Declare Function CdtDrawExt Lib "CARDS.DLL" _

	(ByVal hDC As Integer, ByVal xOrg As Integer, _

	ByVal yOrg As Integer, ByVal nWidth As Integer, _

	ByVal nHeight As Integer, ByVal nCard As Integer, _

	ByVal nDraw As Integer, ByVal nColor&) As Integer

Declare Function CdtTerm Lib "CARDS.DLL" () As Integer

Dim xoff As Single	‘ have to know where the mouse is in

Dim yoff As Single	‘ relation to top-left corner of card

Dim intCard As Integer	‘ have to know what card is moving

Sub Form_Load ()

 Dim x As Integer

 Dim intRet As Integer

 Me.ScaleMode = PIXEL	‘ set scalemode to pixel on form

 Me.Show

 x = CdtInit(75, 100)	‘ init card drawing

 For x = 0 To 51		‘ 52 cards in the deck

   If x Then			‘ element 0 already exists

     Load picture1(x)	‘ create new control array element

     picture1(x).Top = picture1(x - 1).Top + 7

     picture1(x).Left = picture1(x - 1).Left + 7

   End If

   picture1(x).ScaleMode = PIXEL	‘ keep all as pixel

   picture1(x).AutoRedraw = True	‘ and draw card face 

   intRet = CdtDrawExt(picture1(x).hDC, 0, 0, _

		picture1(0).ScaleWidth, picture1(0).ScaleHeight,_

		x, C_FACES, &HFFFF&)

   picture1(x).ZOrder ONTOP	‘ make it on top of others

   picture1(x).Visible = True	‘ and show it!

 Next

 intRet = CdtTerm()	‘ don’t need to draw any more

 intCard = -1		‘ no card selected

End Sub

Sub Form_Unload (Cancel As Integer)

 Set Form1=Nothing	‘ just to be clean

End Sub

Sub Form_DragDrop (source As Control, X As Single, _

	Y As Single)

 If intCard <0 Then Exit Sub should not happen move card to dropped position keeping relative mouse picture1(intCard).Top="Y" yoff If picture1(intCard).Top Then picture1(intCard).Top="0" picture1(intCard).Left="x" xoff If picture1(intCard).Left Then picture1(intCard).Left="0" picture1(intCard).Drag DRAGSTOP turn off drag mode intCard="-1" nothing selected now End Sub Sub Picture1_DragDrop index As Integer, source As Control,_ X As Single, Y As Single) if drop on another card pretend drop on form instead Call Form_DragDrop(source, X picture1(index).Left, Y picture1(index).Top) End Sub Sub picture1_MouseDown index As Integer, Button As Integer, Shift As Integer, X As Single, Y As Single) If Button="2" Then button will flash’ the card picture1(index).ZOrder ONTOP Exit Sub End If xoff="X" remember where mouse is relative to top-left yoff="Y" of the selected card if already dragging anything forget it t
his should not happen but.... If intCard>= 0 Then picture1(intCard).Drag DRAGSTOP

 intCard = index	‘ remember what card is being dragged

 picture1(index).Drag DRAGSTART	‘ start drag mode

 picture1(index).ZOrder ONTOP		‘ make sure he sees it

End Sub

Sub Picture1_MouseUp (index As Integer, _

	Button As Integer, Shift As Integer, x As Single, _

	Y As Single)

 ‘ if ‘flashing’ a card then hide it again

 If intCard <0 Then picture1(index).ZOrder ONBOTTOM End Sub pre>

As for documentation on other DLL files, the Microsoft Knowledge Base on 

Microsoft’s WWW site has a lot of information.  The various Software Developer 

Kits and the Microsoft Developer’s Network also provide lots of info on what’s 

out there.  For general access to the Windows API I always recommend the 

Visual Basic Programmer’s Guide to the Windows API (and the same to the Win32 

API) by Daniel Appleman.


Q: Using VB 4.0 Pro 32-bit, how do I dynamically hide and show the title bar of my application. I want the title bar to act similarly to the one used for the clock.exe program with Windows 3.x. In one of my applications, the user is allowed to change the bitmap of a picture box. This is acceptable while I run this program in Visual Basic itself. After I create an .exe and setup the program, I get a runtime error that the image is not found. Where am I supposed to put the bitmaps for this? I have tried putting it in the same directory as the program itself - such as C:\Program Files\program_name but it doesn't work.
How do I read the current name of Windows 95's Recycle Bin from the registry?
Steve McNair
bravhaart@relia.net
A: Unfortunately, some Windows style bits are set when the window is created and can not be modified on the fly. If you can live without the ControlBox, MinButton and MaxButton then set those properties to False in design mode. The Caption property will then determine if a title appears or not. If the caption is a null string (Me.Caption="") the title bar will disappear. Setting a caption (Me.Caption="My Application") will restore it. If you need the control box or the min/max buttons then the only way I know of to do this is to have two forms and show only the one you want. To find the bitmap files, check into the APP.PATH property. This will give you the directory path that your application was run from and allow you to specify the fully qualified path.
The path to the recycle bin is < driveletter >:\RECYCLED and there is one for every local hard drive. This is not found in the registry since it is always the same. In the September column I included code to empty it or invoke the Explorer to view it. The files there are renamed and the original information is stored in a hidden INFO file with a proprietary format for which I have no documentation.


Q: I'm using VB 4.0 Pro and WIN 95. I want to know where to look for an example of how to save a file with a long filename using a Common Dialog box. Also, is it possible to change the text on the command buttons in a Common Dialog box?
G. Curry
pcdept@nwinfo
A: It isn’t feasible to try to change the text on the common dialog box buttons. Getting the filename back is pretty straightforward:


CommonDialog1.DialogTitle = "Save"

CommonDialog1.Flags = cdlOFNOverwritePrompt And cdlOFNLongNames

CommonDialog1.Filter = _

	"Word Docs|*.DOC|Text Files|*.TXT|All Files|*.*"

CommonDialog1.FilterIndex = 2

CommonDialog1.CancelError = True

On Error Resume Next

CommonDialog1.ShowSave

If Err Then

  MsgBox "save cancelled"

Else

  MsgBox "Save as: " & CommonDialog1.filename

End If

Note that this does do anything with the selected file. It is your responsibility to open the returned filename and read or write the contents as needed. 

Q: Is there anyway to render the entire screen part of your application? For example, in File Manager, you can drag and drop a file into program manager... How do you do that? Also, is there anyway to load a GIF file into Visual Basic ( I'm writing a Net Browser ) without using any custom controls.....
Lua Choon Ngee
962a21@chs.edu.sg
A: You can drag and drop into file manager because that application supports the ‘DragDrop’ event. The same is true for the Windows 95 Desktop and Start button and other things which you can drag to. You can do it programmatically only by using a series of API calls to set up the list of items being dragged and send a WM_DROPFILES message to the window of the target application. In general, it would be much simpler to either allow the user to drag the item in question or to perform the action (creating a file, printing a document, adding it to the start menu...) yourself.
VB does not have any built-in functions to handle GIF files. Without an add-on product your only option is to read the GIF file yourself and convert it to a format that can be set into a VB control.


Q: I am trying to develop an in house custom program that is capable of scanning all the drives on a PC and make a list of all the programs that can be executed on that particular PC. For example, if MS Office, Word Perfect, Visual Basic, CorelDraw etc. are installed on a PC, the custom program must be capable of listing all of those in addition to the standard programs like WRITE, WORDPAD, PAINTBRUSH, GAMES etc. that come with the Operating System. It should also be capable of giving a breakup list of executable programs in a bundled packages like MS Office into -- Excel, Access, Word etc. If I look for all the .EXE files, some of those are called by other .EXEs and cannot run by themselves. I would like to have a list of only those programs that can be executed either by double clicking on the icon or filename thru Windows explorer, or by using the RUN command. This program must be capable of running in all windows environments (windows 3.x, windows 95 and windows NT). Which files contain the information about the installed application programs? Is there a way to read and make sense of .LNK, .GRP, .EXE and .DLL files. Please indicate any books, literature or references that might be of help. I want to develop this program in Visual Basic 4.0. There may be some shareware out there, but we need this to be a custom program.
Prasad.
raju@usuhsb.usuhs.mil.
A: As you mention, you can search for .EXE and .COM files although not all executables will be flagged with one of those (screen savers, for example, are ..SCR files). The Microsoft Developer’s Network includes information on the format of DOS executable files and Windows NE (New Executable) format executables. I’m sure the same can be found in any number of Windows internals books available in many computer stores and larger bookstores. It’s not something I’ve searched for specifically but I have run across references to it from time to time. The Windows 95 and NT registries contain some information, as does the WIN.INI and SYSTEM.INI files on Windows 3.x (and Win95). The problems are (1) not everything is included, (2) some of what is there may not be valid and (3) it is spread out throughout the files in whatever place and format the particular application uses. If you do manage to locate the executables it would be impossible to identify which are stand-alone and/or what the relationship is. Some will use command line arguments and some will use DDE or OLE to interact and some may run sstand-alone or as driven components. I wish I could be more definite and more positive, but the more I think about this the more I think it is not going to be possible to be accurate.


Q: I've recently installed VB4 (32 bits) in my machine, but my project is to be coded in VB4 (16 bits). Can I install both of these in my machine. Will there be any incompatibility problem?
105075.313@compuserve.com
A: You can install both and use them both with no problems. The one minor catch is taht whichever is installed second becomes the default. If, for example, you run Windows 95 and double-click on a .BAS or .FRM file it will invoke whichever version was most recently installed because the file associations in the registry will have been updated.


Q: I have a problem and before I pursue a solution, I would like to know if it is possible and if so, if someone could help me out. I have several menus on my form, they are "Control", "Services", "Work", and "Tray". The "Tray" menu is only visible when you right-click the icon on the system tray. I would like to be able to add the "Control", "Services" and "Work" menus to the "Tray" menu as sub-menus without actually having duplicates of the menus. Johnny Thrash
Webmaster/Technical Support
Internet Solutions, Inc.
http://misnet.com/~johnny
johnny@mail.misnet.com
A: You can’t have two menu items that bring up the same sub-menu. Your best bet would be to do one of the following:


1) Add ‘Control’, ‘Services’ and ‘Work’ items to the ‘Tray’ menu and have 

these sub-items use:

	Sub TrayControl_Click()

		PopupMenu Control

	End  Sub

2) Duplicate the ‘Control’, ‘Services’ and ‘Work’ sub-menus completely under 

the ‘Tray’ menu and then use code like:

	Sub TrayControlSubItem1_Click()

		Call ControlSubItem1_Click()

	End Sub

The advantage to the first is minimal duplication but the original ‘Tray’ menu will disappear when the sub-menu item is selected. The advantage to the second approach is that the menus behave more normally and you do not dupliacte the actual code, but you do have to duplicate the menu structure. 

Q I've gotten the Extract Icon and Draw Icon calls figured out in an App I'm writing. I'm running into a problem though. When I use the draw Icon call, I need a control with an hdc. The picture box is a likely candidate. However, once the icon is drawn in the picture box, I can't figure out how to transfer it to an image control without losing the transparency.
Jason Lee Stenklyft
jls@masterpiece.com
A: As far as I can tell, you can’t. When you draw to the PictureBox the transparency is respected but when you transfer the image you get the BackColor from the PictureBox. If this matches the BackColor of the form, and nothing else overlaps, that may be good enough. The only other suggestion I have is to use DrawIcon directly to the HDC of the form (Me.HDC). The AutoRedraw property must be False and you must re-draw it during the Form_Paint event but it may work better for you.


Q: I am working with VB 3 & Win95 and I have a little problem that I hope you can help me with. Is it possible, when you save a file as a bitmap, to change the dpi so that you can print your file with the new dots per inch? The file is not a picture at the beginning but a code that makes that drawing. I'll like to save that drawing in a file with a new dpi.
Barbara Spence
barbara_spence@mitel.com
A: I’m not sure I understand the question, and I know I don't understand the reference to ‘a code that makes that drawing’. There are some API calls which will let you stretch a bitmap but I’d need to know more about what you are trying to do to identify what might work best. Please take a look at the September Q&A column -- there were a couple of questions about printing forms and picture controls and sizing them to match the page size. Some of that may be relevent.


Q: How can I have a grid empty without blank lines ??? Do you have a example of using the grid in a program ???
Luis Patroni
Curitiba - Parana - Brazil
patroni@netway.com.br
A: If I understand what you want, the only way I have ever been able to make the white lines disappear is to do something like:


	Grid1.BackColor=Me.BackColor

	Grid1.Rows=1

	Grid1.GridLines=False

	Grid1.Highlight=False

I have only used the grid control a couple of times. Two extremely simple routines that I have found useful are: 

	Sub SetGrid(intRow As Integer,intCol As Integer,strValue As string)

	  Grid1.Row=intRow

	  Grid1.Col=intCol

	  Grid1.Text=strValue

	End Sub

	Function GetGrid(intRow As Integer,intCol As Integer) As String

	  Grid1.Row=intRow

	  Grid1.Col=intCol

	  getGrid=grid1.Text

	End Function

This allows me to set and retrieve items easily by using code like: 

	SetGrid 1,2,”Place at row 1 column 2”

	strContent=GetGrid(3,4)

If you want to get fancy and allow in-place editing of the grid contents you can use the Grid1_KeyPress event to trap keystrokes and edit the currently selected cell by using the above routines to get the contents, then apply the keystroke, and put the new value back. Note that you have to keep track of the current position within the field if left/right arrows are used and watch for the DELETE, TAB and ENTER keys! 

Q: I use Visual BASIC 4.0 Professional Edition to write CGI programs for my company's intranet server, which runs on a Windows NT Server 3.51 platform. I need to send data to different printers, and have two questions about doing so:
1. How does one change the default printer in the registry using VB?
2. Will I encounter problems with simultaneous tasks wishing to access different printers? If so, is there a better way? Cody Johnson
Scantron-FPC
cody@omnilinx.com
A: I’ll have to try this on NT, but under Windows 95 and Windows 3.x the default printer is specified in the WIN.INI file and you would have to broadcast a WININICHANGE message after updating the settings. From what you describe, however, I’m not sure why you would need to change the default printer. VB4 has a PRINTERS collection that you can access to find all defined printers and their specifications (e.g. Printers(0).DriverName, Printers(0).DeviceName, etc). When you find the one you want, use SET PRINTER=PRINTERS(x) and the selected printer will be your default until you change it. Doing this will allow each process to set it’s own printer and that will not cause interference. If you change the system default and rely on that then you will have problems with printouts going to the wrong place.


Using the API Q: How can I add items to the shortcut menus on the taskbar button when my VB program is minimised and allow my program to respond to click events?
Richard French
frenchr@dep.sa.gov.au
A: I’m not sure I understand the reference to ‘Shortcut menus’. If you want to put an icon in the system tray then check the January ‘96 Q&A column. I posted a routine there which does this from VB4 using the API and no third-party additions.


Q: I am attempting to convert a color bitmap to grayscale using VB4 and Win16 without having to scan the entire thing one pixel at a time and adjusting the RGB values. I have found multiple functions in the Win32 API that deal with bitmap manipulation/conversion, but few are supported in Win16. It seems that this conversion could be performed by the Win16 API if the correct mixture of calls was applied, but the solution escapes me. If you have any insight via Win16 API calls, a routine that could be written in C/C++ and inserted into a DLL, or any hints or tips, the help would be greatly appreciated.
Jason Barkes
jbarkes@mail.cpbx.net
A: (Courtesy of Michael Kulik - mkulik@ampksoft.ca) Just a guess here... First, you might want to drop the colour depth to 256. then, you should adjust the colours (Canadian Spelling.. eh.) in the palette rather than one pixel at a time in the image. Copy the palette, modify it, an then apply the new palette to the image. This will correct all the pixels in the bitmap at once. I suppose this is pretty obvious. Regarding the win16 problem, you might want to check the VB3 methods. A great book is Scott Jarol's "Visual Basic Multimedia Adventure Set". Check out the Advanced Imaging chapters. Oh yeah, You might want to check if Media Architects have a new OCX for ImageKnife... Iknow that their VBX can handle what you are looking for.


Q: I'm quite new to VB and VBA programming. I'm using Excel 7.0 VBA and VB 4.0 (32-bit). I'm trying to get the Window Handle of an opened Excel document back to the calling application. In my case, it's a VB 4.0 (32 bit) app. I was able to find the window of the calling app and send messages from Excel back to the VB app. But now what I am looking for is to get the window handle of the Excel opened document and send it back to the VB app. I think using FindWindow() is ok except that what happens when there are multiple Excel documents opened? Ivan Siew
ICM (Integrated Computer Management, Inc.)
isiew@icmus.com
http://www.icmus.com
A: You can use FindWindow or you can search all active Windows using GetWindow and GetWindowText (the September Q&A had some code to do this in refernece to another question). It is virtually impossible to guarantee a match.... off the wall thought -- can you make Excel open a message box with a unique title that VB can search for and then use GetWindowParent to find the owner and SendMessage to post a WM_CLOSE request? It’d be ugly, but it might be workable.


Q: I am using VB 4.0a 32 bit under Windows 95. I am trying to use the DrawAnimatedRects API call without much success. Do you have any sample code that demonstrates the use of this function.
Tony Gray
MostlyMatter_oa@msn.com
A: Sorry, but after trying everything I can think of, I can not get this function to do anything on any system. I get a return value indicating success, but no visible results. I have searched all the resources I have and can not find anything beyond the declaration format and no sample code that uses the call.


Q: Have you heard of any problems with mciSendString in VB4 32Bit? I was able to declare the mciSendString function from the WINMM lib, but upon trying to execute a simple open command, I received an error 453, "Specified DLL function not found". Here is a quick cut of the code:



    CommandStr = "Open " & FileName & SPACE & ALIAS

    MCIError = mciSendString(CommandStr, ByVal ReturnString,Len(ReturnString) 

- 1, 0)

Michael Kulik
mkulik@ampksoft.ca
A: I'd have to see the Declare statement. It should be: 

Private Declare Function mciSendString Lib "winmm.dll" _

	Alias "mciSendStringA" (ByVal lpstrCommand As String, _

	ByVal lpstrReturnString As String, ByVal uReturnLength As Long,_

	ByVal hwndCallback As Long) As Long

My guess would be you do not have the 'alias' phrase. 

Q: I found your listings on accessing WinSock from VB in the March Q&A column. I got gethostbyname() working and I also extracted the official host name from the returned structure. I'm kind of hung up on the aliases - could you tell me the format for the entire hostent structure. In the process I also extracted something by accident. some string data came back saying something about the local operating system for the requested hostname. is this another field in the hostent structure? the winsock.h file also defines the fields h_addrtype and h_length. Did I access one of these by mistake - (i assume all the fields are stored in memory)
John J O'Keefe Jr.
john.okeefe@gdc.com
A: The documentation I was workign from at the time defined the alias pointer as the "address of a list of null-delimited names". I found that pretty ambiguous and, unfortunately, I only had access to a DNS server that did not have any hosts with aliases defined. Since then I have found that the alias pointer is like the IP address pointer. The value returned points to a memory block consisting of pointers to the actual strings. A pointer of zero is the end of the list. The hostent structure is not directly usable from VB so I use the pointer returned by GetHostByName() and the hmemcpy API call to copy the various values into local strings and numeric variables. I then use hmemcpy to copy the data that the various pointers reference. It is confusing because it is pointers to pointers to data and VB doesn’t handle any of it directly. The other info you saw was probably the result of copying the wrong area of memory and you came up with whatever happened to be there. I’ve seen similar results lots of times. h_addrtype is the address type and should always be AF_INET for an internet address. h_length is the length of the address in bytes and should always be 4. These parameters are there to allow winsock calls to be entended to handle other types of networking protocols. The "resolve_name" routine that I was using last March has been replaced by this routine:


Global strHostName As String ' structures for NameLookup

Global intAliasCount As Integer

Global strAlias() As String

Global intAddressCount As Integer

Global strAddress() As String



Function NameLookup (strName As String) As Integer

Dim x As Long ' scratch

Dim nbytes As Integer

Dim strTarget As String ' null-delimited hostname

Dim lngHostEnt As Long ' address of hostent structure

Dim lngHEName As Long ' address of name pointer

Dim lngHEAlias As Long ' address of alias pointer

Dim lngHEAddress As Long ' address of address pointer

Dim lngIPpointer As Long ' address of IP address

Dim lngAPointer As Long ' address of Alias



strHostName = strName' default values

intAliasCount = 0

intAddressCount = 0

NameLookup = WSAEFAULT

If Left$(strName, 1) >= "0" And Left$(strName, 1) <= Then x="inet_addr(strName)'" convert input to hostname If x="-1" Then Exit Function strTarget="String$(4," scratch area lngHostEnt="addressofstring(strTarget)" lngHEName="addressoflong(x)" hmemcpy ByVal lngHostEnt, ByVal lngHEName, ReDim strAddress(1) strHostName="strName" intAddressCount="1" strAddress(0)="strTarget" NameLookup="0" assuming he knows what he's doing! Exit Function End If strTarget="strName" Chr$(0) lngHostEnt="gethostbyname(strTarget)'" do actual winsock call If lngHostEnt="0" Then NameLookup="wsagetlasterror()" Exit Function' failed! End If lngHEName="lngHostEnt'" set pointer addresses lngHEAlias="lngHostEnt" lngHEAddress="lngHostEnt" x="addressoflong(lngHEName)'" get pointer values hmemcpy ByVal x, ByVal lngHEName, x="addresso
flong(lngHEAlias)" hmemcpy ByVal x, ByVal lngHEAlias, x="addressoflong(lngHEAddress)" hmemcpy ByVal x, ByVal lngHEAddress, nbytes="lstrlen(ByVal" lngHEName)' Get resolved hostnam
e If nbytes> 0 Then

  strHostName = Space$(nbytes)

  x = addressofstring(strHostName)

  hmemcpy ByVal x, ByVal lngHEName, nbytes

Else

  strHostName = ""

End If



x = addressoflong(lngIPpointer)' get all IP addresses

hmemcpy ByVal x, ByVal lngHEAddress, 4

Do While lngIPpointer

  ReDim Preserve strAddress(intAddressCount + 1)

  strAddress(intAddressCount) = Space$(4)

  x = addressofstring(strAddress(intAddressCount))

  hmemcpy ByVal x, ByVal lngIPpointer, 4

  intAddressCount = intAliasCount + 1

  lngHEAddress = lngHEAddress + 4' move to next IP

  x = addressoflong(lngIPpointer)' get all IP addresses

  hmemcpy ByVal x, ByVal lngHEAddress, 4

Loop



x = addressoflong(lngAPointer)' get any/all aliases

hmemcpy ByVal x, ByVal lngHEAlias, 4

Do While lngAPointer

  ReDim Preserve strAlias(intAliasCount + 1)

  nbytes = lstrlen(ByVal lngAPointer)

  strAlias(intAliasCount) = Space$(nbytes)

  x = addressofstring(strAlias(intAliasCount))

  hmemcpy ByVal x, ByVal lngAPointer, nbytes

  intAliasCount = intAliasCount + 1

  lngHEAlias = lngHEAlias + 4' move to next IP

  x = addressoflong(lngAPointer)' get all IP addresses

  hmemcpy ByVal x, ByVal lngHEAlias, 4

Loop



If intAddressCount > 0 Then

  NameLookup = 0' success

Else

  NameLookup = WSAEFAULT' weird!

End If

End FunctionFunction addressoflong (x As Long) As Long

‘ lstrcpy copies a string from one memory address to another and returns the

‘ target address as the result.  By copying something onto itself it 

effectively

‘ does nothing but I get the address back.  

addressoflong = lstrcpy(x, x) 

End Function

Function addressofstring (x As String) As Long

addressofstring = lstrcpy(ByVal x, ByVal x)

End Function


Q: Where can I get a list of ftp, gopher, telnet, and www commands and how I would actually implement them in send() so that they will work? (i.e. I noticed sent "GET /" to a www server to get the html document back - it's actually commands like this and how to implement them that I'm interested in.)
A: Information on the various protocols can be found in RFC (Request For Comment) documents at a number of sites on the web. The ds.internic.net site is excellent for this. The FTP protocol can be found, for example at http://ds.internic.net/rfc/rfc959.txt. Telnet is basically just sending and receiving data between two systems, usually with the ‘client’ side doing simple terminal emulation based on the data stream. The ‘telnet’ protocol is used by FTP and others such as LPR/LPD printing to exchange data as well. The best starting point for information on the HTTP (HyperText Transfer Protocol) and HTML (HypeText Markup Language) used by www servers is at http://www.w3.org/ and the docs there will explain the "GET /" (get top-level/default document) and other options that you see if you monitor the traffic.


Q: I would like to be able to read and write to the registry. Say, for instance, I wanted to get the directory for "Favorites" or want to make my application use:



   HKEY_CURRENT_USER\Software\My Application\

instead of: < pre? HKEY_CURRENT_USER\Software\VB and VBA Program Settings\My Application\ pre > Can anyone post an example of reading and writing?
Johnny Thrash
Webmaster/Technical Support
Internet Solutions, Inc.
http://misnet.com/~johnny
johnny@mail.misnet.com
A: From VB4 32-bit this is fairly easy with a set of API calls: 

Private Type SECURITY_ATTRIBUTES

  nLength As Long

  lpSecurityDescriptor As String

  bInheritHandle As Boolean

End Type

Private Type FILETIME

  dwLowDateTime As Long

  dwHighDateTime As Long

End Type

Private Type ACL

  AclRevision As Byte

  Sbz1 As Byte

  AclSize As Integer

  AceCount As Integer

  Sbz2 As Integer

End Type

Private Type SECURITY_DESCRIPTOR

  Revision As Byte

  Sbz1 As Byte

  Control As Long

  Owner As String

  Group As String

  Sacl As ACL

  Dacl As ACL

End Type

Private Declare Function RegConnectRegistry Lib "advapi32.dll" Alias  _

	"RegConnectRegistryA" (ByVal lpMachineName As String, _

	ByVal hKey As Long, phkResult As Long) As Long

Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) 

As Long

Private Declare Function RegCreateKeyEx Lib "advapi32.dll" Alias 

"RegCreateKeyExA" _

	(ByVal hKey As Long, ByVal lpSubKey As String, ByVal Reserved As Long, _

	ByVal lpClass As String, ByVal dwOptions As Long, ByVal samDesired As Long,  

_

	lpSecurityAttributes As SECURITY_ATTRIBUTES, phkResult As Long, _

	lpdwDisposition As Long) As Long

Private Declare Function RegDeleteKey Lib "advapi32.dll" Alias "RegDeleteKeyA" 

_

	(ByVal hKey As Long, ByVal lpSubKey As String) As Long

Private Declare Function RegDeleteValue Lib "advapi32.dll" Alias 

"RegDeleteValueA" _

	(ByVal hKey As Long, ByVal lpValueName As String) As Long

Private Declare Function RegEnumKey Lib "advapi32.dll" Alias "RegEnumKeyA" _

	(ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpName As String, _

	lpcbName As Long) As Long

Private Declare Function RegEnumKeyEx Lib "advapi32.dll" Alias "RegEnumKeyExA" 

_

	(ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpName As String, _

	lpcbName As Long, lpReserved As Long, ByVal lpClass As String, _

	lpcbClass As Long, lpftLastWriteTime As FILETIME) As Long

Private Declare Function RegEnumValue Lib "advapi32.dll" Alias "RegEnumValueA" 

_

	(ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpValueName As String,  _

	lpcbValueName As Long, lpReserved As Long, lpType As Long, lpData As Any, _

	lpcbData As Long) As Long

Private Declare Function RegFlushKey Lib "advapi32.dll" (ByVal hKey As Long) 

As Long

Private Declare Function RegGetKeySecurity Lib "advapi32.dll" (ByVal hKey As 

Long, _

	ByVal SecurityInformation As Long, pSecurityDescriptor As 

SECURITY_DESCRIPTOR,  _

	lpcbSecurityDescriptor As Long) As Long

Private Declare Function RegNotifyChangeKeyValue Lib "advapi32.dll" (ByVal 

hKey As Long,  _

	ByVal bWatchSubtree As Long, ByVal dwNotifyFilter As Long, ByVal hEvent As 

Long, _ 	ByVal fAsynchronus As Long) As Long

Private Declare Function RegLoadKey Lib "advapi32.dll" Alias "RegLoadKeyA" _

	(ByVal hKey As Long, ByVal lpSubKey As String, ByVal lpFile As String) As 

Long

Private Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" 

_

	(ByVal hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, _

	samDesired As SECURITY_ATTRIBUTES, phkResult As Long) As Long

Private Declare Function RegQueryInfoKey Lib "advapi32.dll" Alias 

"RegQueryInfoKeyA" _

	(ByVal hKey As Long, ByVal lpClass As String, lpcbClass As Long, _

	lpReserved As Long, lpcSubKeys As Long, lpcbMaxSubKeyLen As Long,  _

	lpcbMaxClassLen As Long, lpcValues As Long, lpcbMaxValueNameLen As Long,  _

	lpcbMaxValueLen As Long, lpcbSecurityDescriptor As Long, _

	lpftLastWriteTime As FILETIME) As Long

Private Declare Function RegQueryValueEx Lib "advapi32.dll" Alias 

"RegQueryValueExA" _

	(ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, _

	lpType As Long, lpData As Any, lpcbData As Long) As Long

Private Declare Function RegReplaceKey Lib "advapi32.dll" Alias 

"RegReplaceKeyA" _

	(ByVal hKey As Long, ByVal lpSubKey As String, ByVal lpNewFile As String, _

	ByVal lpOldFile As String) As Long

Private Declare Function RegRestoreKey Lib "advapi32.dll" Alias 

"RegRestoreKeyA" _

	(ByVal hKey As Long, ByVal lpFile As String, ByVal dwFlags As Long) As Long

Private Declare Function RegSaveKey Lib "advapi32.dll" Alias "RegSaveKeyA" _

	(ByVal hKey As Long, ByVal lpFile As String, _

	lpSecurityAttributes As SECURITY_ATTRIBUTES) As Long

Private Declare Function RegSetKeySecurity Lib "advapi32.dll" (ByVal hKey As 

Long, _

	ByVal SecurityInformation As Long, _

	pSecurityDescriptor As SECURITY_DESCRIPTOR) As Long

Private Declare Function RegSetValueEx Lib "advapi32.dll" Alias 

"RegSetValueExA" _

	(ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long, _

	ByVal dwType As Long, lpData As Any, ByVal cbData As Long) As Long

Private Declare Function RegUnLoadKey Lib "advapi32.dll" Alias "RegUnLoadKeyA" 

_

	(ByVal hKey As Long, ByVal lpSubKey As String) As Long

‘ Values for Hives - these are always open

Private Const HKEY_CLASSES_ROOT = &H80000000

Private Const HKEY_CURRENT_CONFIG = &H80000005

Private Const HKEY_CURRENT_USER = &H80000001

Private Const HKEY_DYN_DATA = &H80000006

Private Const HKEY_LOCAL_MACHINE = &H80000002

Private Const HKEY_PERFORMANCE_DATA = &H80000004

Private Const HKEY_USERS = &H80000003

Private Const ERROR_SUCCESS = 0

‘ values for data types

Private Const REG_BINARY = 3

Private Const REG_CREATED_NEW_KEY = &H1

Private Const REG_DWORD = 4

Private Const REG_DWORD_BIG_ENDIAN = 5

Private Const REG_DWORD_LITTLE_ENDIAN = 4

Private Const REG_EXPAND_SZ = 2

Private Const REG_FULL_RESOURCE_DESCRIPTOR = 9

Private Const REG_LINK = 6

Private Const REG_SZ = 1

Private Const REG_MULTI_SZ = 7

Private Const REG_NONE = 0

‘ flags for special functions

Private Const REG_NOTIFY_CHANGE_LAST_SET = &H4

Private Const REG_NOTIFY_CHANGE_NAME = &H1

Private Const REG_NOTIFY_CHANGE_SECURITY = &H8

Private Const REG_OPTION_BACKUP_RESTORE = 4

Private Const REG_OPENED_EXISTING_KEY = &H2

Private Const REG_OPTION_CREATE_LINK = 2

Private Const REG_OPTION_NON_VOLATILE = 0

Private Const REG_OPTION_RESERVED = 0

Private Const REG_OPTION_VOLATILE = 1

Private Const REG_REFRESH_HIVE = &H2

Private Const REG_RESOURCE_LIST = 8

Private Const REG_RESOURCE_REQUIREMENTS_LIST = 10

Private Const REG_WHOLE_HIVE_VOLATILE = &H1

Private Const KEY_CREATE_LINK = &H20

Private Const KEY_CREATE_SUB_KEY = &H4

Private Const KEY_ENUMERATE_SUB_KEYS = &H8

Private Const KEY_EVENT = &H1

Private Const KEY_NOTIFY = &H10

Private Const KEY_QUERY_VALUE = &H1

Private Const KEY_SET_VALUE = &H2

Private Const KEYEVENTF_EXTENDEDKEY = &H1

Private Const KEYEVENTF_KEYUP = &H2

Private Const STANDARD_RIGHTS_ALL = &H1F0000

Private Const STANDARD_RIGHTS_REQUIRED = &HF0000

Private Const READ_CONTROL = &H20000

Private Const SYNCHRONIZE = &H100000

Private Const STANDARD_RIGHTS_EXECUTE = (READ_CONTROL)

Private Const STANDARD_RIGHTS_READ = (READ_CONTROL)

Private Const STANDARD_RIGHTS_WRITE = (READ_CONTROL)

Private Const KEY_ALL_ACCESS = ((STANDARD_RIGHTS_ALL Or KEY_QUERY_VALUE _

	Or KEY_SET_VALUE Or KEY_CREATE_SUB_KEY _

	Or KEY_ENUMERATE_SUB_KEYS Or KEY_NOTIFY _

	Or KEY_CREATE_LINK) And (Not SYNCHRONIZE))

Private Const KEY_READ = ((STANDARD_RIGHTS_READ Or KEY_QUERY_VALUE _

	Or KEY_ENUMERATE_SUB_KEYS Or KEY_NOTIFY) And (Not SYNCHRONIZE))

Private Const KEY_WRITE = ((STANDARD_RIGHTS_WRITE Or KEY_SET_VALUE _

	Or KEY_CREATE_SUB_KEY) And (Not SYNCHRONIZE))

Private Const KEY_EXECUTE = ((KEY_READ) And (Not SYNCHRONIZE))

To create a key you do something like this:

  Function CreateKey(strNewKey As String) As Long

  Dim lngError As Long

  Dim lngKey as Long

  Dim lngSAM As SECURITY_ATTRIBUTES

  If  RegCreateKeyEx(HKEY_CURRENT_USER, strNewKey, 0, "",  _

	REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, lngSAM, lngKey, lngError) Then

	CreateKey=lngKey

  Else

	CreateKey=0

  End If

  End Sub

To open a key so that you can work with the named values under it use:

  Function OpenKey(strKey As String) As Long

  Dim secSAM As SECURITY_ATTRIBUTES

  Dim lngKey As Long

  secSAM.lpSecurityDescriptor = String$(2048, 0)

  secSAM.nLength = Len(secSAM.lpSecurityDescriptor)

  If RegOpenKeyEx(HKEY_CURRENT_USERS, strKey, Len(secSAM), secSAM, lngKey) 

Then

	OpenKey=lngKey

  Else

	OpenKey=0

  End If

  End Function

(Don’t neglect to call RegCloseKey when done to release the reference to the key) To change a named value (string format) under a key use: 

  Sub SetValue(lngKey As Long, strName As String, strValue As String)

  Dim lngSize As Long

  Dim lngResult As Long

  Dim strTemp As String

  strTemp = strValue & vbNullChar ‘ append trailing null

  lngSize = Len(strTemp) 

  lngResult=RegSetValueEx(lngKey, strName, 0, REG_SZ, ByVal strTemp, lngSize)

  End Sub

A similar routine can be used to set Dword and Binary values. The RegQueryValueEx routine retrieves a value in much the same way. From VB3 or VB4 16-bit these calls are not directly available. You can use a VB4 32-bit OLE server to provide access or you can check into the CALL32.DLL rouine available on the Microsoft web site to allow 16-bit applications to access most 32-bit calls. Note that this is not supported software although it seems to work fine from the tests I have made using it. 

Q: Is there a way to reliably create and display a transparent Bitmap in VB4 16? For use with toolbars and command buttons and such?
Jeremy Gaines
jeremy.gaines@corbel.com
A: The VB Picture control and forms generally deal well with transparent backgrounds. The Image control fills in the background color and negates their functionality. I’ve simulated command buttons using the picture control with a fair amount of success. You lose some things (like the automatic ‘Default’ and ‘Cancel’ properties) but a little extra work with the form’s KeyPreview property and KeyPress event can make up for it. You will have much finer control by using the various Bitmap manipulation API calls directly. My best advice is to get the Visual Basic Programmer’s Guide to the Windows API by Daniel Appleman and check the call descriptions and code samples in chapter 8.


Q: We are presently using VB 3.0 on a Novell 3.11 network. We would like to make a call to the api allowing a dump of all id's located on each server. I have looked at Novell and MSN and not found the code. We have accomplished other calls using NWNETAPI.dll but do not know the syntax for finding the user id's. If it is easier to use VB 4.0 for this purpose, we would also appreciate the code for this as well.
William Nolte
ec4542@wepco.com
A: Unfortunately, we do not use Novell at my shop and I have no documentation on any of the network APIs that relate to netware.


Accessing DataBases Q: I am a very, very new user of Visual Basic 4.0. I must write a program which will enable me to start Adobe Exchange and run it. I must also be able to access and index database tables stored in Oracle 7 database. My program should be able to scan very large number of documents using Adobe capture and then convert them into 'PDF' files. These files then have to be stored using Oracle 7 database and manipulated. These PDF files should also be made available to a large number of users on my company's network. The users should be able to query and print whole or part of these PDF files. I would greatly appreciate any help anyone could kindly provide. I searched for some information, but have not been able to find much.
John K. Daniel
jkdaniel@buttercup.cybernex.net
A: readers?


Q: I developed an app that used both DAO and ODBC API to access an Access 2.0 database.(The reason for using ODBC API is that the app consisits of a search engine which has to be very fast and support muttle backends). I developed the app using VB4-16bit under Windows NT 3.51. I created setup disks and setup the apps on other NT machines...it works perfectly. Now i use the set up disks to setup the app on Windows 3.1 and windows 95. All the DAO code works. But in 3.1 and 95, the calls to the ODBC API fails. Speciffically, in 3.1 the SQLCONNECT() function fails with the following message. Error 1023 : [Microsoft][ODBC Access Driver]'' isn't a valid path. In 95, it gets pass the sqlconnect but fails on some statements which retrieves the data from a sqlexecute statement. I haven't deteremined which one it fails on but it is either: SQLNumResultCols,SQLFreeStmt(to unbind variables) ,SQLDescribeCol, SQLBindCol,SQLFetch,SQLFreeStmt(to close statement handle). I am using the ODBCJT16.dll (access 2.0 odbc driver) and suspect that this may be the problem...but am not sure
Mahendra Singh
Mahendra.Singh@bankerstrust.com
A: I know under Win95 you need to have the ODBC drivers installed (it is an option in the VB4 setup, as well as other places). That will place an icon on the Control Panel to let you set up ODBC access for various connects. Unfortunately, I have not toyed with this enough to know if it is likely to be your problem. Beyond that I’ll have to leave it to the readers. (In a follow-up message Mahenda Singh wrote: the problem, as i suspected was due to an outdated driver (though not that much outdated). Apparently there are two versions of the odbcjt16.dll and odbctl16.dll, one dated 8/94 and one dated 11/94. the one dated 8/94 does not work well under 95 and 3.1. Also, some more info in case some one else runs into this: when using SQLBind with Memo fields....the function will return a huge number, something like 1666666....so when you try to initialize variable like: szVarToBind=string(16666666,0) you get and invalid procedure call. What you need to do is to check this returned number and, under 3.1, if it's greater than 32K, set it equal to 32K)


Q: I would like to know about some tool that permit me to acces an Informix Database that is running on Unix since Windows-95 using VB4.
Jorge
jorge@info.rec.uabc.mx
A: readers?


Q: I have constructed a database using Access. I also designed a report for that database using Access. Is there a way to print an Access report using VB? Scott A. Flaherty
SARCOM, Inc.
fsc@ix.netcom.com


Q: I've been using VB for quite a while but have never used crystal reports. I have been requested to write some reports in Crystal due to compatability with another application that uses Crystal also. My problem is I have designed the reports and can view them in Crystal but if I update the database with some selection criteria and sql statements from VB and then request to print the crystal report (ie report1.action= 1) the report does not contain the updated data from the database. How can I get VB to REFRESH the data everytime I envoke the report to be printed.
Phillip Kennedy
pkennedy@magna.com.au
pkennedy@fairfax.com.au
A: Not using Crystal, I can not say. Your problem could be the database is not up to date and may also be that Crystal is using an old buffer. I would try possible re-specifying the database or query in Crystal and/or closing and re-opening the database in VB. There is also a flag in Crystal to ‘Save Data with Report’ and that should not be selected.


Operating System Quirks Q: How would I go about sending a message to another computer / user on a Windows NT network? I have been searching for an answer to this for some time now, but I can find no resources specifically about VB and Windows NT and not very much about networking. My hunch is that I somehow access both computers' Messenger Service to do this. An few examples of applications that do this are the Server Manager (File | Send Message), and the Print Spooler (notifies user of completed print jobs).
Robert Munroe
Robert@bee.net
A: I found this on a VB newsgroup that I recently started reading.... I have not had a chance to try it yet... It is apparently for VB3 (unfortunately, I have misplaced the name of the person who posted it so I can not give credit):


Option Explicit

Declare Function NetMessageBufferSend Lib "NETAPI.DLL" _

	(ByVal pszServer As String, ByVal pszRecipient As String, _

	pbBuffer As Any, ByVal cbBuffer As Integer) As Integer

Sub Command1_Click ()

Dim wRes As Integer

Dim buf As String

Dim szReceiver As String, szMessage As String

szReceiver = txtName

szMessage = txtMsg

wRes = NetMessageBufferSend("", szReceiver, ByVal szMessage,Len(szMessage))

End Sub


Q: When a user double-clicks a filename in Windows 95 Explorer, the associated program (if registered) will activate and display that file. How is this accomplished? I would like the sample project MDI NotePad to display text (*.txt) files.
Michael Caruso
mcaruso@ix.netcom.com
A: File associations are stored in the registry. The safest way to set up new ones is to go into Explorer and click View, then Options, then FILE TYPES and NEW TYPE. You can specify an extension and set up command lines for various actions (e.g. Open="MyNotePad.EXE %1" and Print="MyNotePad.EXE /P %1"). If you want to see them in the registry run RegEdit.exe and you will find entries like:


    HKEY_CLASSES_ROOT\.txt="TextFile"

    HKEY_CLASSES_ROOT\TextFile\Shell\Open\Command="MyNotepad.exe %1" 

    HKEY_CLASSES_ROOT\TextFile\Shell\Print\Command="MyNotepad.exe /P %1"


Q: I have a problem with VB 4.0 SetupWizard: When I'm installing my programs into the new computer that never have installed the V.B 4.0 the follow messages appear at the end of installation:



                  AN ERROR OCCURRED WHILE REGISTERING THE FILE

                  'C:\WIN95\SYSTEM\MSRDO32.DLL'

                        ABORT       RETRY        IGNORE

The same message appear to the file: MSRD2X32.DLL If I choice 'IGNORE' the SetupWizard go to the end of installation without show any error, but when I run the program the follow message appear: 


        RUN-TIME ERROR '53':

        FILE NOT FOUND

Marco Spinella
softmidi@truenetrn.com.br
softmidi@net2000.com.br
A: From what you describe, it sounds like at least one DLL is not being installed properly. Look at SETUP.LST and make sure everything specified is there. Check for the SETUP LOG file that should be created, probably in your C:\WIN95 directory. This may have more specific information about the error encountered. If you have REGSVR32.EXE try using ‘REGSVR32 C:\WIN95\SYSTEM\MSRD2X32.DLL’ and see what that returns. It should tell you that the DLL self-registration succeeded. Last, the source for the VB4 setup is under your "C:\PROGRAM FILES\MICROSOFT VISUAL BASIC\SETUPKIT\SETUP1" directory (or under wherever you installed VB4). Copy that directory over and you can edit SETUP1.VBP to add code to help trace the problem (Don’t edit the original code or you may have trouble with future projects). You can either compile this to SETUP132.EXE and use the COMPRESS utility to replace SETUP132.EX_ in the distribution files or run it interactively and debug the setup. T
o do that you’ll have to copy SETUP.LST to C:\WINDOWS and execute the application with a specified command line (see the ProcessCommandLine routine for information on the arguments expected). 

Q: When I use Pkunzip with the command SHELL, after the pkunzip execution, the Shell Windows stay open... How I can close this window??
Bernard Boulay
"bboulay@total.net"@total.net
A: I assume Windows 95 is in use here -- if so, use explorer to locate PKUNZIP.EXE and right-click on the icon by it and select PROPERTIES. On the PROGRAM tab check the 'close on exit' box. To make this the default behavior for all DOS apps create _DEFAULT.BAT (the leading underscore is intentional) in your WINDOWS directory and set the properties as described above. These take effect for any DOS app that does not have specific properties set. This process creates a .PIF file to hold the settings.


Q: I've loaded windows '95 but I can’t find clipboard anywhere. There’s no clipboard viewer in the accessories group too. I searched for *.clp, but couldn’t find any. I am able to do the normal edit operations. How can I view the clipboard? Also how can I view the windows 95 registry.
sujatha subramanian
105075.313@CompuServe.COM
A: Look for CLIPBOOK VIEWER under SYSTEM TOOLS under ACCESSORIES. If that is not there, go to ADD/REMOVE PROGRAMS from the control panel and click on the WINDOWS SETUP tab. Highlight the ACCESSORIES option and click DETAILS. If the Clipboard viewer is not checked, check it (do NOT un-check anything else or it will be removed!). Windows 95 will ask for the setup diskettes or CD to add the component.
To work with the registry run REGEDIT.EXE (there is no icon for it because Microsoft wants the users to stay away from it as it can VERY easily make your system unusable if you modify it wrong).


Q: am using an OLE server(.EXE) to share forms between 2 applications. Application1----------->OLE Server<-------------| Application2 br> A class defined in the OLE server is instantiated by Application1 and it invokes a method. The method displays a form. This form resides in the OLE server, not the Application1. Using SetParent(childfrm.hwnd, mdiform.hwnd) WIn API I set the form to be the child of the MDI form residing in Application1. When I display the form I see an an interesting problem. When I click on the title bar to move the form, the mouse pointer gets displaced by about half an inch and then I can move the form (In other words when I am moving the window the mouse pointer is not on the window but about an inch above it). Is there any way to get rid of this displacement? Should I use any other win API call to set the parent property of the child form?
nirmal bajoria
nbajo@ctp.com
A: That may be the most interesting use of an OLE application I’ve seen yet. Your problem is basically because there is more to the MDI/child relationship than the simple Parent/Child relationship that most windows have. The VB runtimes have quite a bit of internal information about the relationship that can only be set in VB design mode. I managed to get rid of the offset by creating Application1 as an MDI Form with a child and using SetParent from Application2 to ‘steal’ the child form from Application1. Unfortunately, the WindowList menu property still applied to Application1 as did minimize/maximize/show requests and it was very ugly. The bottom line is that I do not believe you can do this reasonably within MDI applications.


Miscellaneous Q: We are currently thinking about introducing MS Project for MACs in our office,in order to improve our Project Management and Controlling. But therefore we have to access data from EXCEL spreadsheets. What I wanna know is, if there is a special literature about this subject (VBA for MS Project). I have already seen the Microsoft Press release, but that's only a reference. What I would need is handbook, that introduces me step by step into VBA for MS Project. Please let me know, if there is a publisher offering this kind of book.
market@marchand.com
A: Not that I know of... anybody?


Q: I am using using VB 3.0 currently, and I will go to VB 4.0 within a couple of weeks. I would like to be able to import/read/somehow get a MS word (version 6.0) document into my code so I can write some of it if not all of it to a Access 2.0 form. MS Word ".doc" files have a large unreadable header for the most part, and I wish to accomplish this function with code and not with saving the document as a different type of ".txt" file. Can you help me with this?
Willie Baria
wlba@tco.infonet.com
A: The most appropriate method would be to use OLE to control MS Word and get the data. Unfortunately, I do not have any documentation on that and have only managed to figure out a few things by playing with the Word macro editor and general hacking. For short documents you can potentially use the clipboard like this:


Dim xyz As String

Dim oWord As object

Set oWord = CreateObject("Word.Basic")

oWord.FileOpen "C:\pathtomyworddoc.DOC"

oWord.EditSelectAll

oWord.EditCopy

oWord.FileClose

Set oWord = Nothing

xyz=Clipboard.GetText(0)

For anything longer than the available string space in VB you will get an error trying to read the clipboard. In that case you would need to extract the data piecemeal but I don’t know enough of the Word interface to do that. 

Q: I can't find a new VB_IO.DLL for 32 bit. Even in Delphi 2 for 32 bit are the inport and outport - commands not yet existent. Do you have an URL, where I can find a new VB_IO32.DLL?
Wolfgang Back
Redaktion Computerclub
P.S. Computerclub is a German TV-Show since 15 years.
A: Sorry, I have gone through my references and do not see anything about any VB_IO.DLL, any inport or outport commands, or any 32-bit upgrades for them. What does VB_IO.DLL come with? I do not have it on any system that I have VB on.


Q: I would like to know if when shelling out to run the calculator that comes with win95, can I get it to return the value of the computations performed on the calculator?
Mark Bader
baderms@erols.com
A: Sounds like the hard way to do it to me and that it would be a lot simpler to just do the calculations in VB. To the best of my knowledge, the only way to do this would be to use the FIndWindow, GetWindow, and GetWindowText API calls to search for the calculator window and then search all sub-windows for the handle of the result. The biggest problem is that if more than one calculator is open you couldn’t be sure which you had. In last month’s column I posted some code for searching windows for text in a chat room window. The logic would be the same for this.


Q: I am just getting into VB, and I am an owner of VB4 pro (32-bit). If you could help, I have a question for you whose answer has eluded me in my searchings of the web. I want to know how to incorporate 3d objects into my program, and be able to rotate and move them with code, having them displayed to the user. If you know any code, books, add-ons, or API's that could accomplish this, please let me know, as it would be a big help.
dlrushing@kali.nas.com
A: There isn’t anything within VB for working with 3D images. If you have a series of bitmaps showing the object from various angles you can use the ImageList control in VB4 to load them all in memory and display each in turn. You can also store the images in individual Image or Picture controls and manipulate them or use the LoadPicture or LoadResource functions to read images from disk as needed. I went through my references and found several third-party vendors advertising 3D add-ons -- note that I have never tried any of these so I can not recommend getting or avoiding any of them in particular. Excluding the references to 3D graphing, he names I found include Bennet-Tec Information Systems Inc (http://www.bennet-tec.com/), Micro System Options (206-868-5418) and Template Graphics Software (http://www.tgs.com/) as well as ones with CAD capaibilities including Cimmetry Systems Inc (800-361-1904) and Numera Software Corp (http://www.numera.com/). The only other suggestion I have is to check any of the larger bookstores or computer outlets in your area for references on the WinG API and specifically for 3D image processing. I have seen quite a few books in this topic area, but have never had the need to work with it.


Q: I have written a simble DLL to add numbers and return the result to VB. This works just fine if the number is an Integer or a Long, but when I try and return a Float(single) or a Double, VB reports a "Bad DLL Calling Convention". My C function looks like this.



	double add_numbers(double num1, double num2)

	{

	  return(num1 + num2);

	}

My VB declaration looks like this 


	Declare Function add_numbers Lib "my.lib" _

		(ByVal Num1 as Double, _

		ByVal Num2 as Double) as Double

Also, how can I get my DLL to change the value of any arguments passed to it. I can change strings by using "lstrcpy", but how can I change the value of an integer etc.
Phil Moroney
moronry@gil.com.au
A: What you describe is theoretically correct, but the convention in some compilers is to pass floating point values either in registers or as pointers to temporary areas on the stack. If your C compiler is using that convention then you may not be able to pass these values directly. The ‘Bad DLL calling convention’ error indicates that VB sensed a mismatch in the stack size so this is probably the problem. You can potentially work around it by copying the values to a string and passing that. As far as changing values is concerned, you need to code your C routine with pointers in the declarations: 

	void changenum(int *numval)

	{

		*numval++;

	}

And then drop the ByVal keyword in VB: 

	Declare Sub changenum Lib "myown.dll" (num1 As Long)

	Call changenum x

The ‘ByVal’ keyword on numeric values tells VB to pass the current value on the stack which is, of course, discarded on return. With no ‘ByVal’ VB will pass the address of the variable on the stack. The address is discarded on return but any changes you made via the pointer stay. Note that this is different for string variables. If ‘ByVal’ is used on a string parameter it flags VB to copy the string contents to s scratch area, append a null to the end to simulate standard C format and pass the address of the temporary area. When the call returns VB will copy the contents of the temporary area, up to the first null, back to the "real" string variable. If the ‘ByVal’ keyword is omitted, VB passes a pointer to the internal VB string structure and assumes the target routine knows how to interpret that. Doing so is risky because it may restrict you to a particular rev of VB even if you figure out how to manipulate it safely. 

Q: I have been trying to use the Crystal Reports Custom Control to print out a report from within a program, and can't get it to work. I have seen examples on how to do this, but they don't work either. All the examples that I have seen have used the Action property within the control. The Crystal Reports Custom Control that I have doesn't have an Action property. I am using VB4 16-bit Enterprise edition. What is the problem here, and is there another way to print out a Crystal Report within a program?
Darren Apitz
9050556@aardvark.mur.csu.edu.au
A: I will post this for the readers if anybody can help. never having looked at Crystal Reports, I can’t even hazard a guess.


Q: I’m from Mexico City and I've got a question about VB4: Why are the EXE files in VB4.0 bigger than the EXE files that VB3 makes if the application is the same, and how can I reduce the EXE file size in VB4?
juanguti@gfi.invermexico.com.mx
A: VB4 is designed heavily around OLE communications which adds a significant amount of code to the various components. It also supports more properties and methods on the various objects and controls. Your source code may be identical, but the objects (forms, text boxes, etc) that it operates on require a lot more supporting code under VB4 than they did under VB3 even if you are not using any of the extended options. The first thing that you should do is save your project, exit VB, restart VB, load the project and make the EXE without running it in design mode. This can produce a smaller EXE than compiling after working in the design environment. Beyond that it is a matter of re-using and simplifying code wherever possible. You can also consider removing pre-loaded pictures and icons and loading them at run time although that removes size from the EXE at the expense of creating other files that must be included with the application. You can also build any control arrays at run time although unles sthey are very simple to generate the extra code may offset most or all of the gain. The bottom line is just that VB4 goives you more than VB3, but requires more disk and memory to do it. If you can do what you need in VB3 and size is an issue then you can always consider staying with that.


Q: I have a problem that I have been struggling with for quite some time now, and I really hope that someone can give some hints & tips. I'm using VB4.0 professional and I want my program to print text documents (produced in a separate word processor, like Word) using Crystal Reports. I also need to put database fields into the text document, like names and adresses. The only way I've found to do this is to insert the text document into Crystal Reports as an OLE object, and then put database fields on top of the OLE object. This works fine, except that if the text document spans over more than one page, Crystal will only print the first page (OLE objects can't span over several pages ?). Am I missing something here, or is there maybe a completely different way of doing this...
Bjorn Storo
bjorn.storo@fauske.vgs.no
A: I will post this for the readers if anybody can help. never having looked at Crystal Reports, I can’t even hazard a guess. What I may be missing here is why you need to use CR at all for this... it sounds like something that could be done with just the VB PRINTER object or by using OLE activation of MS Word (provided all target systems have Word installed).


Q: I would like to Know how use "Print Key" in Visual Basic 4.0
Fain Davide
scp@sunrise.it
A: Sorry, but I do not understand the reference.


Q: I'm trying to create an application that logs the time it is run and then stopped and save those times to a database. Then I would like to print a report (using Crystal Reports) which lists the in and out times and then uses a formula to calculate the total time. I've tried this, but I only get the time from the seconds (not minutes or hours) how do I go about doing this?
I'm using VB 4.0 pro.
Eric Sawyer (asecc@ici.net)
A: I can’t answer about Crystal Reports as I have never used that. For getting the times you can consider doing something like:


	Dim dblStart As Double

	dblStart=Now

and at the end of the program: 

	Dim strRunTime As String

	strRunTime=Format$(Now-dblStart,”hh:mm:ss”)

and then recording or displaying the string. 

Q: I have been working on a Visual Basic application that displays data from a Mainframe counterpart (termed screen-scraping). Basically, we have an existing Mainframe application that the users want to see in GUI format and eliminate the terminal emulator. This has become tedious as the screens have to be developed twice. I have questioned why we don't access the data and eliminate the hidden terminal emulator which is running behind the scenes completely. The answer was that when writing to the Mainframe table(s) there wasn't a clear way to have this data filter thru the Business Rules, which are written in CICS. My question is is there a way that, from Visual Basic, a CICS program(s) can be invoked directly, without the need for an emulator and its .dll's (WHLLAPI)? I realize that this may not be something that you may know so if you can point out where I might gain access to this kind of information that would be great. I'm also looking for some decent newsgroups (VB related) that I could post this on as well.
Frank Shultz
A: If any reader knows and respoinds, I will post the definitive answer. My guess would be that you would need a CICS application on the mainframe to apply the business rules and update the database and have this communicate with the PC front-end using your own protocols. With regard to screen-scrapers, there are some decent commercial ones available and that may be more expedient than designing your own. I recently saw a demo by Attachmate (www.att.com) of one that looked nice. In asking around I was also referred to Wall Data, Dynacomm and Reflections.


Q: I'd be very grateful if you could answer two questions for me... 1. A client is interested in front ending AS400 mainframe systems with a GUI front end? How well can AS400 be used to build a client server system using VB as the application builder? Is it difficult and how much does it depend on the network involved and the ease of use of ODBC? 2. How can I run executable 4ge files from Visual Basic when the network involved is PC/NFS based and the files are built from Informix 4GL and run on a Solaris 2 UNIX box ?
Tim McDonagh
tmcdonagh@linkcafe.co.uk
A: If the AS400 has a compatible network and supports an ODBC connection then it should be relatively easy to do this. The whole intent of ODBC is to hide the back end from the front end so that you code your GUI app the same way and let ODBC worry about getting the actual queries straight. If you can not do this directly to an AS400 then your choices are implementing your own database server on the mainframe or using a screen scraper to run AS400 programs indirectly. As far as your second question goes, I don’t think I understand what you are trying to do. If you want to start an application on the remote system you would need to use some sort of logon or remote shell application to start it. PC/NFS, to the best of my knowledge, provides only file access services so you could execute PC applications stored on the remote system. It would not let you run anything on the remote CPU.


Q: I'd like to know any info or sources where I could find out about passing data back and forth between VBScript on the client side and CGI (written in PERL) on the server side. Do you know of any of this?
Mark Alan Pruitt
m.a.pruitt@pobox.com
howlin.hobbit@pobox.com
A: There is information about VBScript, along with sample code, on Microsoft’s web site. There is more at http://www.vb-bootcamp.com/


Q: I have VB3 apps which I wanted to distribute using the VB3 SETUP.EXE and SETUP1.EXE (the later of which I've modified to pick up the files I want). All works well on WIN3.1 machines, but on WIN95 SETUP.EXE hangs. It copies SETUP1.EXE into the \WINDOWS directory etc,as expected, but then doesn't seem to start the SETUP1.EXE file. You can start it manually and the rest of the setup works fine. Any ideas? I'd expect there are many VB3 apps which people would be trying to install onto WIN95 machines. Also, is there anyway of distributing an app which has itself got the ability to compile? You could do a command line compile under a shell, from the program, but I believe you would need to distribute VB.EXE which is not allowed?
Alex Kudrasev
horak@ozramp.net.au
A: I’m assuming that when you changed SETUP1 you did not change the application title when you created the EXE file... If the default SETUP application tries to invoke another application that is also titled SETUP, or whose name matches any other running application, you will probably get a ‘Wrong version of Runtime DLL’ error and abort. If that is not the case, check the target system for anything else called SETUP1.* and look for a LOG file in WINDOWS and the install directory to see if any other errors are apparent. Last thought is that you did not edit SETUP.LST correctly to update the file size and date for SETUP1.EXE... I install VB3 apps on Win95 systems all the time using both standard and customized setups so it should work for you. With regard to a compiling application, you are correct that the end user would need to have VB installed to do this which means that they require the license and all of the VB files.


Q: Is there a way to disassemble a VB exe?? Or perhaps a method for recreating a missing form. We have the source code but are missing the main form of an application.
Felicia A. Hemingway
faha@eci-esyst.com
A: I’m not sure I understand how you have the source code, but not the form since the form definition is generally the start of the source listing.... in any event, I do not know of anything that will do this but it may be possible to recreate manually if you can run the EXE and try to duplicate it in design mode using the code as a guide for the names/etc.


Q: I registered a .VBX for VB3 called LEDDISP.VBX, an excellent utility for making 7 segment LED's. I've already written a nice clock program with it. But, with VB4 it will not work except in 16 bit mode. The author is Syncom (as in the floppy disk maker, not sure if it is the same) Do you know if he is still in business, how to get ahold of him, or if a 32 bit .OCX is out for this product?
Scott Turchin
nitehawk@tscnet.com
A: I don’t know about that control, but according to the latest VB Programmer’s Journal you can download an LED control by Northeast Data Corp from http://www.windx.com


Q: I am using VB for my honours project but I have hit a snag. I have designed a text editor and a device to play multimedia files (thank god for the mci.vbx). Anyway, my question is, How can i create a compound document that allows the user at run time to insert text and MM files, and then save the entire form/document ? I know that if you place an ole object on the form it automatically asks you to decide what that object will be. I have had a look at the ole examples that come with VB, however they dont do what I want. The closest thing is the container example, but it really does not help. Are there any sites on the WWW that have sample code of creating a saveable compound document in VB? My honours project is to create a multimedia authoring tool that will aid the development of tertiary MM CBT products. if anyone has any ideas I would be happy to hear them.
Scott Hebbard
sah@deakin.edu.au
A: My suggestion would be check out the ActiveX controls available at Microsoft’s web site (http://www.microsoft.com/ -- if anybody hasn’t alreayd been there a few thousand times). You could also use a control array (text boexs, picture boxes, command buttons, whatever looks best to you) so that, for example, when the user clicks on the form you load a new instance of the control and use the TAG property or keep an internal array denoting what the new control does (show video, play wav file, etc). When the control is clicked you do what it says... I’m sure there are other, and probably better, ways but I hope these ideas help.


************************ Reader Help ********************** Q: There was an unanswered question concerning wildcards in a SQL-string. Instead of using "...Where name =*a*' ...", you should try the keyword Like. The correct code would be: "...Where name Like '*a*'...". Using the "All" keyword in the second part of the SQL-string is not possible, so "...Where All=.." can't work. "All" can only be used after Select. The 'best' solution is the one you suggested: using a lot of or's.
Steven Van Hoof
avanhoof (this is what my e-mail gave as the reply address!)
A: Thanks. My only regret is that when I pasted the original item I apparently cut off the e-mail address so I can’t notify whoever it was!

Q&A Assistance If there are any questions that you can help us answer for the other VB Online readers, please feel free to offer any input/advice that you can.
Bob our "Questions&Answers" expert does his best to answer as many questions as possible. We will all appreciate any help in this regard
Atholl
VB Online Editor

All E-mail for this column should be directed to b_butler@msn.com and I'll try to respond as best I can.

Click here to go back to the October '96 Article Index

Copyright © 1996 VB Online. All rights reserved.