PowerVB.com Home

Exhaustive Corrections

This is an exhaustive list of all text errors (technical mistakes, typos, formatting and editing problems) for a list that includes technical errors only, see Corrections.


Page xvi
in order to find the corresponding IUnknown, BSTR, and SAFEARRAY, and VARIANT data types

You can useUse these programming techniques to enhance your everyday coding productivity by minimizingmaximizing code reuse

Page xx
CoRegisterClassObject and CoGetClassObject APIs to offerproffer your own application-level singleton objects

Page xxi
enabling a host of Win32 API calls from with VB, AddressOf also enables

Page xxiii
if you try to interact with windows at the level of creation and window procedures.

Page 5
string conversion issues (see Chapter 14), weI recommend that you use

Page 6

'Equivalent to Long12 = Long21

Page 7

Dim String1 As String
Dim String2 As String
Dim pString1 As Long
    String1 = "PowerVB"
    String2 = String$(7, 0)
    'These four operations all do the same thing

    'Try one: this requires a typelib CopyMemory declare
    CopyMemory ByVal String2, ByVal String1, 14

    'Try two: Use StrPtr to guarantee no ANSI/UNICODE munging
    CopyMemory ByVal StrPtr(String2), _
      ByVal StrPtr(String1), 14

    'Try three: Get the string's pointer from VarPtr
    CopyMemory pString1, ByVal VarPtr(String1), 4
    CopyMemory ByVal String2, ByVal pString1, 14

    'Try four: Demonstrate VBoost.Assign instead
    VBoost.Assign pString1, ByVal VarPtr(String1)
    CopyMemory ByVal String2, ByVal pString1, 14

Page 9
This file  registers with the name "VBoost Object Implementation (6.0)."

Page 16
appropriate descriptor to enable you to access array elements

Page 20

'Output (Intel uses biglittle-endian integer layout)

Page 21

        .fFeatures = FADF_AUTO Or FADF_STATIC Or _
          FADF_FIXEDSIZE

Page 23
Put your array in a structure and add a termination code to using lightweight objects.

The first blocksuses a lock count on the array

Page 39
You can also calculate the element countsize by using the formula VBoost.UDif(VarPtr(elem(1)), VarPtr(elem(0))).

SafeArrays use a rowcolumn-major layout, unlike C++, which uses a columnrow-major layout.

Page 40
SafeArrayCreate takes an array of SafeArrayBound elements in rowcolumn-major (VB) order, but the descriptor itself stores the list in reverse order, which is really columnrow-major (C++) order.

Page 42
In other words, VB makes your objects a persistable class, ActiveX control

Page 43
Second, if a reference supports an IID, the same IID must be supported by all references that the object returns.

The controlling IUnknown object then maps

Page 44
RHLS=LHS means that the type of the left-hand variable

Page 47
The QI that comes after the function call seems really bizarre because happens after the function returns. If the QI fails, then you will get a type mismatch error in the caller after the function has completed successfully. If the extra QI isn't enough to scare you away from such calls, the amount of code generated in order to handle them should be. In the case of ByVal calls, the AddRef/Release call happens in the callee, so there is no extra IUnknown work to be done by the caller. However, inIn the case of ByRef calls, the entire IUnknown burden falls on the caller, so theextra type checking code is generated everywhere the function is called with a mismatched type.

Page 51

Function GetDispatch(ByVal pUnkUR As IUnknownUnrestricted) _As
  As Object

Page 54
The first member of any COM object is a pointer to the vtable

Page 55
IDispatch uses an ID based system, where each function

Page 58
Remember that using a With statement against an object is equivalent to assigning the object to a local variable.

Page 60
See the November 19991998 Visual Basic Programmer's Journal for the article "Inspect Dynamic Objects."

Page 64
section of Chapter 3,using a QueryInterface for IDispatch can have

lose a key feature ParamArray feature: the ability to pass a ByRef vVariant.

Page 67
registered it with regsvr32. (Or run Setup on the book's CD.)

Page 70
you can access the native function's event prototypes directly

Page 71
the type library the UDTs are contained in is the OCA back on

Page 81
By breaking this procedure in two, suddenly the code suddenly becomes reusable.

Page 85
By simply pointing a variable in each class to the same data, we you can eliminate the notification

Page 91
With delegation code that runs against any vtable entry, we you can use the same vtable

Page 92
An IUnknown hook is very similar to a blind delegator, but an IUnknown hook modifies

Page 94 (sidebar)
VBoost releases the datareference and returns the E_NOINTERFACE error.

Page 95 (sidebar)
You may want to toggle in the C++ version of the DLLVBoost objects during debugging

Page 97
so the earliest you can aggregate the object is in the Class_Initialize.

AggregateData is defined in VBoostTypes6.TlbOlb and has four members

this object is treated as a blind aggregate; a: A QI call is forwarded

Page 98
The native interfaces supported by Class2 are not wrapped, and the _Class1 interface supported by _Class1 is wrapped with a blind delegator that makes it act like a native part of Class12.

Page 99
with the DrawImpl class and adds a native method, or Area, that calculates the area

Page 105
There are no circular references in this system, but there are a couple big

Page 111

        'long value
         VBoost.AssignSwap pObj, Obj
        .ItemData(.NewIndex) = pObj
    End With

Page 116

Friend Property Get ChildInternal( _ByVal Index As Long) As
  ByVal Index As Long) As Child   Child

    Set Child = InternalChildChildInternal(Index).GetExternalChild

Page 120
but the first instance in whichof each specific class of object you create a specific class of object.

Page 122
most-common values hidden in VBoostTypesObjCreate.

Page 126
adding capabilities to thea main application

dependent DLLs starting with the DLL's directory, not in the directory

Page 132
a reference to ObjCreate.oOlb and include the OcxLoader.Bas, COMDllLoader.Bas, and FunctionDelegator.Bas files.

'OcxLoader.Bas

Page 133

'fTargetAbsolute: An optional flag indicating that the
'                 TargetOCX argument is an absolute, not a
'                 relative path.


'not have run, so the VBoost object hasmay not have been
'been created.


        Set pCF = GetDllClassObject( _App.Path & "\" &
          App.Path & "\" &          TargetOcx, _

Page 135

        HookData.pIIDs(0) = IIDFromString( _
                  strIIDI__IQuickActivate)


    VBoost.AggregateUnknown _
      Wrapper, HookData.AggData, _HookData.pIIDs,
      HookData.pIIDs, LoadData.Hook

Page 137
If you havewant the form to support menus

The DynamicMDI sample also has sample code (contained in LookupCLSID.Bas) that registers a public context object (discussed in "Custom Class Objects" in this chapter) and code that determines a CLSID from an OCX or DLL based on a class name (contained in LookupCLSID.Bas).

Page 138
Once your project includes have a direct type-library reference

Page 139
publish the CLSID with which you registered instead.

Page 145
When you need a block of memory to create thean object, you call the heap's allocate function.

Page 154

    If m_PrevCursor <> vbHourGlass Then
        With Screen
            'Don't touch if someone else changed it.
            If MousePointer = vbHourGlass Then

Page 156
without turning the structure into a full-blown VB class.

Page 157

            .pVTablem_pVTable = VarPtr(.VTable(0))

Page 158

    StringFromGUID2 pguid, StrPtr(GuidString)

Page 164
the code in the calling function is approximately one-third the size of code for the non-HRESULT functions.

Page 174
If you specify adUseIIDs as one of the AggregateData flags, VBoost doesn't query

Page 184

  ByVal Index As Integer) As Linked Point

Page 188 (occurs three times)

    X As Single, Y As Single)

Page 189
(and the AutoRedraw solution doesn't go very far towards demonstrating lightweight objects.)).

Page 190 (occurs three times)

    X As Single, Y As Single)

Page 205
you can only guarantee that you gotget the same item back

Page 207
that you can call from the immediate paneby calling. ClearROT calls HideObject on all

Page 209

Dim strGuid As String * 38
    StringForromGUID2 _

Getting a reference to the object out of the ROT just became

Page 211
Errors in Figure 10.1: External Process should point to Mashaling Layer and ROT should point to ROTHook Object

hold strong references to the ROTHook objects, but the only

Page 231
Sample: DLLDllRegisterServer

Page 232

     [uuid(8F633501-459A-11d3-AB5C-D4123C10000), odl]
Once you have a function pointer--pfnDllRegisterServer--you can callpass the pointer to InitDelegator (pfnDllRegisterServer) and assign

Page 235
I have rarely seenrarely see a sort routine written in straight VB that didn'tdoesn't make me cringe. Sort routines, regardless of the algorithm used, compare and swap the elements in an array. Comparing elements in VB is straightforward, but itstraight VB requires a new sort routine for each type of array to be sorted. Having a new routine for each data type wasn'tisn't quite enough to evoke a shudder; the shudder generally requires an examination of the swapping code. Although swapping elements may seem straightforward, it iscan be extremely expensive for pointerString, Variant, and structure types because VB always performs a deep copy.

Page 239

    QuickSort VarPtr(Strings(LBound(Strings)), _
      UBound(Strings) - LBound(Strings) + 1, _
      4, AddressOf CompareStrings

Page 242

'Assembly code we're using to make aread the stack pointer.

Page 244
stack pointerframe before prolog (ebp points here)

Page 246
VB cannot handle the misaligned stack and Y crashes.

Page 247
However, with the FunctionDelegator object, you can now come very close.

get away with writing C code and letting the C compiler generate assembly.

Page 250
displays an addressof 00401033

Page 252

Public Function InIDE() As Boolean
    Debug.Assert Not TestIDE(InIDE)On Error Resume Next
End Function    Debug.Assert 1 \ 0
Private Function TestIDE(Test As Boolean) As Boolean    InIDE = Err
    Test = TrueOn Error GoTo 0
End Function

Function First( ByVal Value As Double, _

Page 253
pushed on the stack whenever you call a function, so the address of the next instruction

Page 255 (footnote)
See http://www.jprobbins.comhttp://www.wintellect.com/robbins for other article references.

Page 256
pointer to a class instance coded into the function, and a pointer to that function.

Page 271
If you let the QueryInterface sequence readreach the primary object

Base object is both the controlling IUnknown and the delegator fordelegatee of the wrapped object.

Page 285
QS = Queue size, then number of tasks queued per thread

ART = QS * b (QS b + 1) / 2 * Slice * PCO * b (1 + b TO / QS b ) b

Page 287
using CreateObject to create a worker thread runs Sub Main a second time.

Page 297

        CopyMemory WD, CacheWD, LenB(CacheWD)
        CacheWDm_Workers.Remove strKey

Page 303

  ByVal ReturnDataPtr As Long) As Long


    If fDoIncrement Then

Page 304
TheAccessing m_ReturnDataPtr access is safe if the ThreadData class

        If Not IsEmpty(m_ReturnData) Then


T:If Not IsEmpty(m_ReturnData) Then

Page 305

T:If Not IsEmpty(m_ReturnData) Then

Page 306

Public Function DoStuff(Data As Variant, _
  Data As Variant, ByVal ProgressPtr As Long, ByVal ReturnDataPtr As Long, _
  ByVal ReturnDataPtr As Long, ByVal CritSectPtr As Long) As Long


    LeaveCriticalSection m_pCritSect
End Sub


'ThreadData class., also pass Parent.CritSect to DoStuff If Not IsEmpty(m_ReturnData) Then

Page 307

T:If Not IsEmpty(m_ReturnData) Then



T:If Not IsEmpty(m_ReturnData) Then

Page 313
Second, it owns a handle to the callingworker thread.

providing an efficient mechanism for signaling- completion.

Page 317

  Optional ByVal fReturnThreadHandle As Boolean = False) _
    As Long

Page 319

    'The new thread should not own the controlling thread

Page 328
allocate the data in a memory block that lives longer than theCreateWorkerThread's stack.

Page 329
Error in Figure 13.4: The long dotted line should be extended to more clearly go from GetWorkerOutput to OutputData.

Page 331

'ThreadLaunch interface definition, ThreadLaunch.cls


'Called to create a new worker thread

Page 334


'ThreadStart procedure, ThreadProc.bas

Page 342

'ThreadControl class, in ThreadControl.cls

Page 343

  Optional ByVal fReturnThreadHandle As Boolean = False) _
    As Long

Page 344

    fSignaled As Boolean  '*TB.ThreadSignalPtr changed (CT:RW)

Page 349

        'Frees any leftover Variant information and
        'the controller.
        Erase .pSA

Page 374

        For iFields = 0 To _
                   .TokenizeLines(strLine, iStoppedAt, strFields) - 1

Page 386
extensive discussion of methods that don't return in an HRESULT.

Page 387
three pronged approach to gain this low-level of control of the typelibs

greater range of function and interface thatthan it can produce.

Page 389
These flags are primarily for marshaling interfaces,. Any ByRef type

Page 393
If you want to explicitly unload a DLL, either for memory reasons or to upgrade it dynamically enable upgrading it without closing your application, you need to perform

Page 394

End Type


'Typelib equivalent, UNICODE } TLibFLStringField;
'Calling code, UNICODE If cBytes > 3876 Then cBytes = 3876 CopyMemory FLSF.TheString(0), ByVal strData, cBytes

Page 395

} TLibFLStringField;

'Calling code, ANSI

Page 403

Private Sub IPersistHistory_SetPositionCookie ( _

Page 404

Private Sub UserControl_ReadProperties( _
  (PropBag  As PropertyBag)

Page 406
You must be very careful not to not use the oleautomation or dual

You have to worry about registry settings not only when you marshal

Page 407
Although the IRecordInfo is needed only for marshaling, thereto store a record in a Variant and to marshal an array. There is no way to know if marshaling will be required an array will be marshalled when the array or Variant it is created.

Page 416
The interface identifier is used during thea Set statement to verify that thea running objects supports the IID promised by its design-time typelib description.

Page 418
You can make VB register movemore (or less) typelib information

Page 420 (add as third bulleted paragraph)
You can add help information to enums, records, public properties, and other places where the VB IDE does not accept help text. You can also provide an external program that allows you to provide custom help information for every help field in the type library. This includes the ability to create localized satellite DLLs for your ActiveX components. See the CD for more information on implementing the IModifyHelpData interface.

Page 423
you have to replace only a single function instead of an entire multi-function entire vtable.

Page 428
Frozen events are generally not a problem with modal forms in a compiled application.

If you subclass using a control, you can actually hitsafely stop at a breakpoint while debugging.

Page 433

        Case WM_GETMINMAXINFO
            With g_DerefMinMaxInfo

Page 435
You don't need to show a fully functional control at design time.

Page 442
the HasDC property. ThisUse this property tellsto tell VB to borrow device contexts as needed instead of caching them

Page 443
HasDC includesis one of the two properties added to controls in VB6 to reduce resource usage.

Page 449
Objects to facilitate aggregating VB objects.

However, you are not freedo not need to redistribute the OLB (unless you send a gift copy of the book along with it).with the DLL. The OLB is needed at compile-time only.

Page 453

Dim pDst As Long, pSrc As Long
'(void*)pDst = (void*)pDstpSrc

Page 454
AssignZero is used to zero out a pointer.

One underhanded but highly convenient use of AssignAddRef is possible withapplicable to UserControl variables.

Page 455
VB's compiler does not allow you to assign the private base class to a variable or pass it to a normal parameter.

Page 459
Changing BufferBlocks does not automatically trigger a compaction; you must explicitly call Compact

Page 461
You can redirect IID_IDispatch with adPrimaryDispatch, with adMapIIDs, or in the QIHookMapIID function on the IQIHook interface.

Page 463
adDelayDontCacheResolved stops the aggregator from keeping the resolved reference, so IDelayCreation_Create iscan be called multiple times for multiple requests for the same IID. No request is made even if a reference for thisthe IID is currently in use.

Page 465

Dim AggData(0) As AggregateData

Page 470
IQIARHook adds uhAddRef and uhRelease. As you can with HookQI, you can use the Flags property