VB4HT: Errata
 




Known Errors as of 1 January 1997


WaveMix Update:

Question:
Is there in existence a version of the WAVEMIX DLL that is capable of merging two (or more) 16 bit stereo sound samples.

Answer:
Regarding the WAVEMIX issue, it is what it is. As far as I know there is only one version of WAVEMIX and it works as advertised. For better sound mixing capabilities look to the future: DirectSound, part of the Game SDK.


Chapter 7.9 problem:
The fix to chapter 7.9 is in the EXECICON.CLS class file, in the PaintIcons routine. The code should be changed in text-code in the book and in the class file. Two lines need to be changed as marked below:

Private Sub PaintIcons(i As Integer, Optional c As Variant)
   '
   ' Limit the number of icons to paint to a single icon if the
   ' calling routine didn't set a limit. Otherwise limit it to
   ' the number requested or the number that will fit in the
   ' container, whichever is less.
   '
   Dim IconLimit As Integer
   If IsMissing(c) Then
      IconLimit = i
   Else
      If c > m_Container.ScaleWidth \ 32 Then
         IconLimit = i + m_Container.ScaleWidth \ 32
      Else
         IconLimit = c
      End If
   End If
   '
   ' And finally, paint one or more icons into the container!
   ' For each icon to be painted, extract the icon handle. Then
   ' draw it into the container starting at the left (0) edge of
   ' the container and always aligning at the top (0) edge.
   '
   ' * Replace these two lines
   Dim IconIndex As Integer
   Dim hIcon As Integer
   ' * With these two lines
   Dim IconIndex As Long
   Dim hIcon As Long
   For IconIndex = i To IconLimit
      DrawIcon m_Container.hDC, (IconIndex - i) * 32, 0, hIcon
      DestroyIcon hIcon
   Next IconIndex
 End Sub

Chapter 1 problems:

How To 1-5, P.20, Step 5
Change: "Add the following code to the General Section of Form1."
To: "Add the following code to the General Section of cGen."

How To 1-5, P.21, Step 10
Change: "Use the Insert Class Module menu item to insert a new module called Module 1."
To: "Use the Insert Module menu item to insert a new module called Module1."
Note: Remove space between "Module" and "1".

How To 1-6, P.34, Step 4
Change:

   Randomize
   Option1_Click (0)
   Picture1.ScaleMode = 3   ' Switch to Pixel mode

To:

   Private Sub Form_Load()
       Randomize
       Option1_Click (0)
       Picture1.ScaleMode = 3   ' Switch to Pixel mode

How To 1-6, P.38
Change: "Sprite(n). MoveTo X,Y"
To: "Sprite(n).MoveTo X, Y"

The following function can be used to copy data-structures passed in lParam:

   Private Declare Sub CopyMemory Lib "Kernel32" _
      Alias "RtlMoveMemory" (dst As Any, src As Any, _
      ByVal SIZE As Long)

The action variable is still used.

The result variable is still used as it was before, to set the value returned from the control to windows as the result of sending the message.


MsgHook.vbx Causing GPF

Problem:
Using msghook.vbx to hook messages to a control of an application other than the one containing the hook could cause a general protection fault.

To clarify, assume HOOK is the program that I use to initialize the msghook.Test is the program that I am observing. When I set the msghook.HwndHook property and move the mouse over the object that I have hooked, a GPF error occurs as soon as that object has focus.

Solution:
MsgHook cannot be used to hook windows belonging to applications other than the one owning the MsgHook control.


Auto3D Property:

Question:
There doesn't seem to be a "Auto 3D" form property.

Answer:
This is true. Late in the beta the Auto 3D property was replaced with Appearance which can have the values 0 - Flat or 1 - 3D.


Class Instancing Properties:

Question:
Also, in the class modules there is an instancing property which has three(3) possibilities and no Creatable property as indicated in the text.

Author's response:
There are lots of class modules and I have no idea which ones he's talking about. Here's what the help file says:

The Instancing property has these settings:

Setting Description
0 - Not Creatable (Default) You can create instances of the class inside the project only.
1 - Creatable SingleUse You can create instances of the class both inside and outside the project. Each request for an instance of the class by an OLE client outside the project causes a separate copy of the OLE server to be started.
2 - Creatable MultiUse You can create instances of the class both inside and outside the project. Requests for an instance of the class by an OLE client outside the project will be supplied by an already running copy of the OLE server, if any. If there are no copies of the OLE server running, a copy is started to supply the class.
Remarks
When a class is creatable, you can use any of the following techniques to create instances of the class from other applications:

Use the CreateObject function, as in:

Set MyInstance = CreateObject("MyProject.MyClass")

Use the Dim statement within the same project (or outside the project if the Public property is also set to True), as in:

Dim MyInstance As New MyClass

If the Public property is False, the setting of the Instancing property is ignored. You can always create instances of the class within the project that defines the class. If the Public property is True, the class is visible and therefore can be controlled by other applications once an instance of the class exists.


Runtime DLLs:

We struggled long and hard to avoid the runtime dll problem, to no avail. At the time I built the final versions MS had built controls for the release version of VB4 using a version of VC/MFC4.0 which was not, and never will be, available outside of MS ... so we couldn't use the dlls that shipped with VB4.

And, we couldn't build controls using the release version of MFC 4.0 since it wasn't released yet.

So, we did what major control vendors did: we used MFC3.0 and its runtime libs. If we were to rebuild now then users would have to ship new MFC4 dlls, the size would probably be somewhat greater because of this.

There is no getting around this problem, that's they way VB4 is. Crescent and Microhelp, for instance, have the same problem we do and require the programmer to ship the exact same large dlls we require.


Problem with How To 7.1 on NT 3.51:

Question:
I have run the example 7.1 on Windows 95 without any problems, but when I run the same project on Win NT 3.51 ( service pack 3 loaded ) , a job does not appear in the print manager. The program does not error. The machine I tested on is a dual boot machine.

Solution:
Yep, Microsoft changed things on us! This HT did work as written in NT 3.5, but it seems that in NT 3.51 and in Win95 the behavior of Both this HT (2.1), and the one about floating toolbars (2.4) use SetWindowWord to make one form the parent of another. In both, all references to "SetWindowWord" need to be modified to "SetWindowLong" (and references to "GWW_HWNDPARENT" need to be changed to "GWL_HWNDPARENT". A new declaration and constant are also required:

   Declare Function SetWindowLong Lib "user32" Alias _
      "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex 
      As Long, ByVal dwNewLong As Long) As Long

   Const GWL_HWNDPARENT = (-8)

If either of these was preceeded by Public or Private, those designations need to remain the same.


How To 7.1 - Missing ByVal:

Problem:
I have run the example 7.1 on Windows 95 without any problems, but when I run the same project on Win NT 3.51 (service pack 3 loaded) , a job does not appear in the print manager.

Solution:
Turns out there's a simple fix. Add a ByVal to the OpenPrinter call in the SpoolFileNow routine (in Spool.Bas). It should look like this:

   Call OpenPrinter(PrnName, hPrinter, ByVal vbNullString)

How To 7.2 - Missing ByVal:

Problem:
I discovered a minor error in the INI file program 7-2 caused by how the Win32 API calls for WritePrivateProfileString are declaired. The BYVAL was omitted in the data string. This omission makes it impossible to set values in INI files using the Win32 API.

Solution:
This isn't an error, per se. The ByVal can also be used in the call line, if it's omited from the declaration. James wrote this HT, and looking at the code, I see the reader is correct. As written, it won't work. The reader's suggested change would indeed be the correct one.


How To 7.3 is 32-bit Only:

The reality is, GetWindowThreadProcessId doesn't exist in Win16. However, I did cover this topic in my Sept '95 VBPJ Programming Techniques column. Here's the heart of the solution:

   Function GetHWndByInst (hInstFind%) As Integer
      Dim hWndTmp%
      '
      ' Find first window and loop through all subsequent
      ' windows in master window list.
      '
      hWndTmp = FindWindow(0&, 0&)
      Do Until hWndTmp = 0
         '
         ' Make sure this window has no parent.
         '
         If GetParent(hWndTmp) = 0 Then
            '
            ' Compare passed hInst against this window's hInst.
            ' If a match, then return hWnd for current window.
            '
            If hInstFind% = GetWindowWord(hWndTmp, GWW_HINSTANCE) Then
               GetHWndByInst = hWndTmp
               Exit Do
            End If
         End If
         '
         ' Get next window in master window list and continue.
         '
         hWndTmp = GetWindow(hWndTmp, GW_HWNDNEXT)
      Loop
   End Function

DLL Synch Question:

On the CD that comes with our book Visual Basic 4 How-To, we included some controls created by one of the authors. As I understand it, at the very last minute we discovered that there were some library DLL synchronization problems between the version of VC++ used to build VB4 and the version we used to build the controls, so we told people that they had to be sure that the OC30.DLL used to build the controls is placed in their WINDOWS/SYSTEM folder. If the OC30.DLL file is missing, the controls won't register, and the projects that run them won't run properly.

We've been receiving some complaints from people about having to put the OC30.DLL into their WINDOWS/SYSTEM folder. My question is, do they still need to do this or has the VC++/VB4 synchronization problem been fixed?

Here is your answer.

It has nothing to do with VB/VC. It depends on which version of VC the controls were built with. If controls were built with VC 2.x, then they will need OC30.DLL. If the controls were built with VC 4.0, then they will need MFC40.DLL. VB4 ships with MFC40, but they should ship their own version, since the one that ships with VB4 is not the final version that shipped with VC 4.0.


VB 4 returns an error code of 20000:

Problem:
I'm trying to run the first lesson that involves the use of Crystal Reports for printing records from a database.

However, the 16-bit version of AUTHORS.VBP that came on the CD with the book generates an error when I try to run the application. It accepts the two dates okay and calls the open report dialog box okay, but after I choose the Authors.rpt and press the OK button, Visual Basic 4 returns an error.

When I typed "error 20000" in the debug window, VB 4 deciphered it as an application-defined or object-defined error.

The program actually stops on the line of code that says:

   CrystalReport1.Action = 1

Solution:
This problem is a function of Crystal's relative inflexibility with a database's location, and particularly how hard they make it to change a database location. The file uses c:\vb\biblio.mdb. If this isn't the directory where the file is located, it'll have to be changed in the ..rpt file. This should clear up the problem. On pages 781-2, the hProcess and hProcessCur variables should be declared as Long, not Integer.


Operator Error:

Problem:
My problem is with an error message that I'm getting in section 1.3 on some code found on page 12 (a number generator). I'm getting error message 340 (Control Array does not exist).

Here is the problem code:

   Private Sub GenerateNums()
      Debug.Print
      For i = 0 to m_Limit
         Debug.Print i;
      Next i
   End Sub

When I checked on Microsoft's For Developers Only Site I found a reference to the error code and some code that appears similiar to the code found in your book. The reply to that question was that it was somethng that designed into VB4 or was something intentional and therefore was not correctible.

Solution:
An author suggests that you copy the code off of the CD-ROM as this generates no errors for him. He also states that the error message you are getting isn't a valid one, thus the suggestion to use the code from the CD. It is possible that the code from the CD and the book don't agree, and this may also be why you are encountering problems.


NT4 Support:

Problem:
When I installed NT4.0 on my machine, some examples didn't work.

Some of these examples were 2.2 Include rollup tools in my application 2.4 Make a floating Toolbar with a mini-title bar and 3.6 Create a more powerful Combobox

I found out that the API-Functions SetWindowWord (in 2.2 and 2.4) and SendMessage with some Parameters(Constants like CB_Showdropdown or CB_Limittext etc.) don't work as expected under NT 4.0.

These problems were in NT4.0 Beta1 and Beta2 too.

Solution:
On page xx in the front matter of the book, you will notice that this book was optimized for VB 4 running on either the Windows 95 or Windows NT 3.51 operating systems. I don't believe, given these parameters, that NT 4.0 was even a test machine during this process.


Main · Authors · Foreward · Contents · Introduction · Index · ReadMe · Errata