home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / inole2 / errata.txt < prev    next >
Text File  |  1995-05-09  |  17KB  |  451 lines

  1. ===========================================================
  2.            INSIDE OLE BY KRAIG BROCKSCHMIDT
  3.                     COMPANION DISC
  4.        COPYRIGHT (C) 1995 BY KRAIG BROCKSCHMIDT
  5. ===========================================================
  6.  
  7.  
  8. Corrections to Printed Text of Inside OLE
  9.  
  10.  
  11. Acknowledgements:
  12.     My thanks also to Paul Gunn for reviewing some of the text.
  13.  
  14.  
  15. Addendum:  OLE And Unicode
  16.  
  17.     It may not be clear from the book text itself that the OLE
  18.     API functions and interfaces defined for Win32 operating
  19.     systems are 100% Unicode, even on an ANSI platform such as
  20.     Windows 95.  For this reason, ANSI applications have to
  21.     convert strings between the two character sets when working
  22.     with certain OLE APIs and interfaces.  You'll see such places
  23.     in the sample code, conditionally compiled using the
  24.     WIN32ANSI symbol. (If the symbol is not set, the compilation
  25.     is 100% Unicode.)
  26.  
  27.     In short, any string that comes back from OLE contains Unicode
  28.     characters, and any string you send to OLE has to contain the
  29.     same.  The samples convert strings on a case-by-case basis, as
  30.     needed.  There are, however, some cases where you will not
  31.     see an explicit conversion in the code, specifically where
  32.     an OLE API function is concerned.  The master header file
  33.     INC\INOLE.H, which is included with all the samples, will redefine
  34.     specific OLE API functions to redirect them to ANSI versions
  35.     implemented in the helper library found in the INOLE directory.
  36.     Functions found there inside ANSI.CPP will call the Unicode
  37.     OLE function converting input and output strings as necessary.
  38.  
  39.  
  40. Addendum:  A global comment about the printed code:
  41.     All the code as it appears in the printed text is oriented
  42.     around a native Unicode application for the sake of brevity.
  43.     The actual sample code compiles to ANSI as well as 16-bits,
  44.     so there will be a few minor differences where strings
  45.     and string manipulation functions are concerned.
  46.  
  47.     In addition, you'll see char, TCHAR, and OLECHAR used for
  48.     various character types.  char will force ANSI characters
  49.     regardless of all other conditions; TCHAR will conditionally
  50.     compile to ANSI or Unicode depending on the UNICODE symbol
  51.     (see BUILD.TXT); OLECHAR is always Unicode (equivalent to WCHAR)
  52.     even on ANSI-only platforms such as Windows 95.
  53.  
  54.     You'll see string literals wrapped in either the TEXT or
  55.     OLETEXT macro.  The TEXT macros conditionally create an
  56.     ANSI or Unicode string depending again on the compiler flags.
  57.     The OLETEXT macro, defined in INC\BOOK1632.H, always creates
  58.     a Unicode macro.  Both macros are defined as no-ops for
  59.     16-bit compilations.
  60.  
  61.     Finally, the INC\BOOK1632.H file contains macros to hide
  62.     the differences between Win16 and Win32 code.  This results
  63.     in cleaner samples.  So if you see a function call in the
  64.     code that you know is not available or part of the API for
  65.     the system you're working in, it's probably defined in this file.
  66.  
  67.  
  68.  
  69. Page xxiv:  A clarification
  70.  
  71.     The "Windows Software Development Kit (SDK)" included with
  72.     Visual C++ isn't the complete Win32 SDK that Microsoft
  73.     provides separately for Windows 95 and Windows NT (3.5 and
  74.     3.51).  A few of the book's samples require pieces of the
  75.     Win32 SDK, specifically the MIDL compiler used to compile
  76.     custom interfaces in Chapters 6 and 9.  You will need
  77.     the full Win32 SDK to compile CHAP06\IANIMAL, CHAP06\IKOALA,
  78.     and CHAP09\IDESCRIP.
  79.  
  80.     It is also important to note again that Visual C++ 2.0
  81.     and 2.1 do not include the header and import library for
  82.     the standard Windows 95 and Windows NT 3.51 OLE UI Library,
  83.     OLEDLG.DLL.  The files OLEDLG.H and OLEDLG.LIB, which are
  84.     used in the samples by default, are found in the Win32 SDK
  85.     products for either platform as well as later versions of
  86.     Visual C++ 32-bit.
  87.  
  88.  
  89.  
  90. Page 55:  Table 1-1 BUILD directory
  91.     The binaries included on the companion disc were compiled
  92.     and tested on Windows NT 3.51.  Perfect operation on Windows 95
  93.     is not guaranteed as Windows 95 was not yet released when
  94.     this book was published.
  95.  
  96.  
  97.  
  98. Page 137:  Second paragraph, end of second line in that paragraph
  99.     "RELEASEINTERFACE" should be "ReleaseInterface"
  100.  
  101.  
  102.  
  103. Page 145:  First paragraph
  104.     Lo and behold my wife and I bought another car after I wrote
  105.     this chapter, and I gave away the Datsun 610 as a trade in.
  106.     So I now drive an 82 Honda Accord.
  107.  
  108.  
  109.  
  110. Page 168:  Legend on Figure 3-2
  111.     The label for "*" should read "only available under 16-bits
  112.     with OLE 2.02 and later."
  113.  
  114.  
  115.  
  116. Page 199:  Note near top of page
  117.     In the future Microsoft will include these files as part of
  118.     the Win32 SDK outside of the CDK.  At the time of writing,
  119.     however, the CDK was the only source for these files.
  120.  
  121.  
  122.  
  123. Page 247:  Footnote 6
  124.     Windows NT 3.5 actually does allow a client to ask for any
  125.     class factory interface on a local server.  Windows NT 3.51
  126.     is no different.  However, an interface like IClassFactory2
  127.     does not have marshaling support at the time of writing.
  128.  
  129.  
  130.  
  131. Page 273:  CKoalaClassFactory::CreateInstanceLic
  132.  
  133.     This function should not call the classes' own RequestLicKey
  134.     because the latter will fail when the machine is not globally
  135.     licensed.  For this reason, replace this code:
  136.  
  137.  
  138.         hr=RequestLickey(&bstrTemp);
  139.  
  140.         if (FAILED(hr))
  141.             return hr;
  142.  
  143.     with this code:
  144.  
  145.  
  146.         OLECHAR     szLic[256];
  147.  
  148.         mbstowcs(szLic, g_szLic, sizeof(g_szLic));
  149.         bstrTemp=SysAllocString(szLic);
  150.  
  151.         if (NULL==bstrTemp)
  152.             return ResultFromScode(E_OUTOFMEMORY);
  153.  
  154.  
  155.  
  156. Page 316:  Reference to OLEDLG.DLL at end of second paragraph
  157.     The text says that the samples "attempt" to use OLEDLG.DLL.
  158.     If you do not have the necessary header files for this library,
  159.     see BUILD.TXT for information on using the version of the library
  160.     included with Visual C++ (which would apply to another compiler
  161.     for the most part as well).
  162.  
  163.  
  164.  
  165. Page 325:  Reference to [async] in the second paragraph after the code.
  166.     [async] actually doesn't do anything at the time of writing.
  167.     The marshaling code generated by MIDL will still generate
  168.     synchronous calls.
  169.  
  170.  
  171.  
  172. Page 380:  A clarification to association by bit pattern
  173.     GetClassFile processes all the FileType entries for a CLSID
  174.     separately such that any single match for any individual
  175.     pattern entry will associate the file with the CLSID.  This
  176.     is obviously what should happen, as it allows multiple file
  177.     formats to map to the same CLSID.  The pattern matching
  178.     process can easily be confused to mean that all patterns
  179.     must match instead of only one, which is incorrect.
  180.  
  181.  
  182.  
  183.  
  184. Pages 405-406:  Clarification to footnote and discussion in general
  185.     The reason that IPersistStreamInit is not derived from
  186.     IPersistStream (although it is still polymorphic) is that
  187.     some objects may need to treat the two interfaces exclusively.
  188.     That is, an object may very much require the
  189.     IPersistStreamInit::InitNew semantics such that it does not
  190.     want to give clients the impression that IPersistStream is
  191.     suitable.  In other words, an object that immplements
  192.     IPersistStreamInit may not support IPersistStream through
  193.     its QueryInterface.  Those objects that can handle the
  194.     lack of InitNew, using it only for optimization purposes,
  195.     can implement both interfaces and provide them both through
  196.     its QueryInterface.  The Polyline sample is such an object.
  197.  
  198.  
  199.  
  200. Page 471:  Concerning the samples and Windows 95
  201.     At the time of writing, these samples suffered from
  202.     "Invalid Page Fault" crashes on Windows 95 Build 460.
  203.     They do, however, work fine on Windows NT.  You may encounter
  204.     similar problems with beta versions of Windows 95
  205.     yourself, and if you find the problem to actually be in
  206.     the samples, please let the author know.
  207.  
  208.  
  209.  
  210.  
  211. Page 502:  Behavior of ReleaseStgMedium
  212.     When the STGMEDIUM structure contains an IStorage or
  213.     IStream, ReleaseStgMedium will call BOTH pUnkForRelease->Release()
  214.     if non-NULL as well as IStorage::Release or IStream::Release.
  215.     That means that a data source providing IStorage or IStream
  216.     types will need to call IStorage::AddRef or IStream::AddRef
  217.     in addition to supplying a pUnkForRelease if that source wants
  218.     to maintain ownership of the medium.
  219.  
  220.  
  221.  
  222. Page 507:  A note about STATDATA
  223.     The client that enumerates advise connections must be sure
  224.     to free any non-NULL DVTARGETDEVICE structure inside the
  225.     FORMATETC of STATDATA with CoTaskMemFree and must also call
  226.     IAdviseSink::Release.  The enumerator object that creates these
  227.     structures must allocate the DVTARGETDEVICE with CoTaskMemAlloc
  228.     and must create or AddRef the IAdviseSink pointer.
  229.  
  230.  
  231.  
  232. Page 562:  Code for Freeloader's CFreeloadDoc::Paste
  233.     The code, as printed, uses the data obtained from the clipboard
  234.     after CloseClipboard is called, which is incorrect.  The
  235.     code should appear as follows:
  236.  
  237.  
  238.     HGLOBAL             hMem;
  239.  
  240.     if (!OpenClipboard(hWndFrame))
  241.         return FALSE;
  242.  
  243.     /*
  244.      * Try to get data in order of metafile, dib, bitmap.  We set
  245.      * stm.tymed up front so if we actually get something a call
  246.      * to ReleaseStgMedium will clean it up for us.
  247.      */
  248.  
  249.     stm.pUnkForRelease=NULL;
  250.     stm.tymed=TYMED_MFPICT;
  251.     hMem=GetClipboardData(CF_METAFILEPICT);
  252.  
  253.     if (NULL!=hMem)
  254.         cf=CF_METAFILEPICT;
  255.  
  256.     if (0==cf)
  257.         {
  258.         stm.tymed=TYMED_HGLOBAL;
  259.         hMem=GetClipboardData(CF_DIB);
  260.  
  261.         if (NULL!=hMem)
  262.             cf=CF_DIB;
  263.         }
  264.  
  265.     if (0==cf)
  266.         {
  267.         stm.tymed=TYMED_GDI;
  268.         hMem=GetClipboardData(CF_BITMAP);
  269.  
  270.         if (NULL!=hMem)
  271.             cf=CF_BITMAP;
  272.         }
  273.  
  274.     stm.hGlobal=OleDuplicateData(hMem, cf, NULL);
  275.     CloseClipboard();
  276.  
  277.  
  278.  
  279.  
  280. Page 573:  Correction to IDataObject::GetData code
  281.     Because DATATRAN is using pUnkForRelease to maintain
  282.     ownership of its data, it has to call AddRef through
  283.     any IStorage or IStream pointer returned from GetData.
  284.     Accordingly, the code shown at the top of this page is
  285.     insufficient and should appear as follow:
  286.  
  287.  
  288.     for (i=0; i < cItems; i++)
  289.         {
  290.         cb=SendMessage(hList, LB_GETTEXT, i, (LPARAM)&pRen);
  291.  
  292.         if (LB_ERR!=cb)
  293.             {
  294.             /*
  295.              * Check if the requested FORMATETC is the same as one
  296.              * that we already have. If so, then copy that STGMEDIUM
  297.              * to pSTM and AddRef ourselves for pUnkForRelease.
  298.              */
  299.             if (pFE->cfFormat==pRen->fe.cfFormat
  300.                 && (pFE->tymed & pRen->fe.tymed)
  301.                 && pFE->dwAspect==pRen->fe.dwAspect)
  302.                 {
  303.                 /*
  304.                  * ReleaseStgMedium will Release both storage
  305.                  * and stream elements regardless of the value
  306.                  * of pUnkForRelease, so we have to AddRef the
  307.                  * element and bump our own ref count here.
  308.                  */
  309.                 if (TYMED_ISTORAGE==pRen->fe.tymed)
  310.                       pRen->stm.pstg->AddRef();
  311.  
  312.                 if (TYMED_ISTREAM==pRen->fe.tymed)
  313.                       pRen->stm.pstm->AddRef();
  314.  
  315.                 *pSTM=pRen->stm;
  316.                 AddRef();
  317.                 return NOERROR;
  318.                 }
  319.             }
  320.         }
  321.  
  322.  
  323.  
  324. Page 670:  Additional comments about dual and custom interfaces
  325.     Versions of Visual Basic later than 3.0 and many versions of
  326.     Visual Basic for Application support direct calling
  327.     of dual and vtable custom interfaces.  This eliminates most
  328.     of the advantages that dispinterfaces once enjoyed, that is,
  329.     the exclusive ability for VB to call that interface.  Now that
  330.     VB can call any interface, using dual interfaces and custom
  331.     vtable interfaces should be the typical mode of operation,
  332.     since much greater performance can be achieved with vtable
  333.     binding.  If you want to have dispID binding still, then
  334.     a dual interface is encouraged.
  335.  
  336.  
  337.  
  338. Page 677:  Concerning Beeper3.
  339.     Error objects (as described more below) also solve the problem
  340.     of returning exceptions from dual interfaces.  Beeper3 as it
  341.     exists does not return exceptions, so an additional sample,
  342.     Beeper3a, is provided to demonstrate the right way to use
  343.     error objects from vtable interfaces (including the vtable
  344.     portion of a dual interface)
  345.  
  346.  
  347.  
  348. Pages 701-706:  About error objects
  349.     Besides the multi-threaded issue, error objects were invented
  350.     to allow vtable interfaces, dual interfaces, and those implemented
  351.     using the standard dispatch object (demonstrated in Beeper 5) to
  352.     return exception information.
  353.  
  354.     As stated in the text, ITypeInfo::Invoke will call GetErrorInfo
  355.     to retrieve an exception, but it will do this only for vtable
  356.     functions that return an HRESULT and return DISP_E_EXCEPTION.
  357.     Beeper3, however, doesn't do this, as its vtable functions do
  358.     not return HRESULTs.  Therefore you will not see exceptions from
  359.     Beeper3.
  360.  
  361.     A modification of Beeper3 that does this correctly is the
  362.     sample CHAP14\BEEPER3A, whose custom interface does return
  363.     HRESULTs and will return DISP_E_EXCEPTION when it has filled
  364.     an error object.  Please refer to that example in preferance
  365.     to Beeper 3.
  366.  
  367.  
  368.  
  369.  
  370. Page 708:  Third paragraph, reason why HRESULT is returned.
  371.     HRESULT is needed as a return value from dual interface
  372.     members not only for marshaling but also for support of
  373.     error objects, as described above.
  374.  
  375.  
  376.  
  377. Page 710:  Concerning Beeper5
  378.     This sample could return exceptions through error objects if it
  379.     was modified to return HRESULTs from its vtable members instead
  380.     of other types.  In short, the same changes that took Beeper3 to
  381.     Beeper3a apply to Beeper5.  A code example for this is not,
  382.     however, provided, and is left as an exercise to the reader.
  383.     As it stands, Beeper5 doesn't return exception information.
  384.  
  385.  
  386.  
  387. Page 736:  Concerning the test program CHAP15\VBSQUARE
  388.     This test script works only with versions of Visual Basic
  389.     after 3.0.
  390.  
  391.  
  392.  
  393. Page 808:  Cosmo and the registry
  394.     If you encounter any registry trouble with Cosmo18 after
  395.     running Cosmo14, go to the registry and delete all entries
  396.     for Cosmo, then reregister Cosmo18.
  397.  
  398.  
  399.  
  400. Page 881:  CHAP18\COSMO1.0
  401.     This sample has not been thoroughly tested, as OLE 1 on 32-bit
  402.     platforms is officially not supported by Microsoft.  If this
  403.     sample fails to work under 32-bits, try a 16-bit compilation,
  404.     which will still interoperate with the 32-bit Cosmo18.
  405.  
  406.  
  407.  
  408. Page 997:  Code listing for CPatronDoc::Rename
  409.     The line at the top of the page should read:
  410.  
  411.          INOLE_RegisterAsRunning(this, pmk
  412.              , ROTFLAGS_REGISTRATIONKEEPSALIVE, &m_dwRegROT);
  413.  
  414.  
  415. Page 999:  Code listing for CPage::NotifyTenantsOfRename
  416.     The second conditional statement at the top of the
  417.     page should appear as follows:
  418.  
  419.  
  420.         if (NULL!=pmkWild)
  421.             {
  422.             INOLE_RegisterAsRunning(this, pmkWild
  423.                 , ROTFLAGS_REGISTRATIONKEEPSALIVE, &m_dwRegROTWild);
  424.             pmkWild->Release();
  425.             }
  426.  
  427.  
  428.  
  429. Page 1114:  IOleControlSite::FreezeEvents
  430.     When a container freezes events, it really tells the control
  431.     that the container will not process those events, but the
  432.     control is still allowed to fire them.  In other words,
  433.     this function tells a control to not expect any behavior
  434.     from the container when events are fired until FreezeEvents(FALSE)
  435.     is called.  A container has to robustly handle events that
  436.     it receives when events have been frozen
  437.  
  438.  
  439.  
  440. Page 1139:  Second paragraph under "Notes on Polyline..."
  441.     Polyline on 32 bits does not supply a ToolboxBitmap32,
  442.     nor does the 16-bit version supply a ToolboxBitmap.
  443.  
  444.  
  445.  
  446. Page 1164:
  447.     Make yourself a big "Yippee! You Made It!" note
  448.     on this page.  Give yourself a reward when you finish
  449.     reading this mighty tome.  You deserve it!  And thank
  450.     you for reading it as well!
  451.