home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / tutsamp / inc / apputil.h next >
Text File  |  1997-08-30  |  45KB  |  1,344 lines

  1. /*+==========================================================================
  2.   File:      APPUTIL.H
  3.  
  4.   Summary:   Include file for the general application utility classes
  5.              and functions offered by the APPUTIL library.  APPUTIL is
  6.              meant to be statically linked to applications that want
  7.              to exploit it.
  8.  
  9.              For a comprehensive tutorial code tour of APPUTIL's
  10.              contents and offerings see the tutorial APPUTIL.HTM file.
  11.              For more specific details on the internal workings see the
  12.              comments dispersed throughout the APPUTIL source code.
  13.  
  14.   Classes:   CVirWindow, CVirDialog, CAboutBox, CDelayBox, CMsgBox, CMsgLog,
  15.              CSendLog, CThreaded.
  16.  
  17.   Functions: WindowProc, DialogProc, SkipAnsi, FileExist, MakeFamilyPath,
  18.              GetExeName, CmdExec, HrMsg, HrMsgId, ReadHelp, ReadTutorial,
  19.              GoWeb, ReadSource, OutputDebugFmt, DComOk, lRandom, AnsiToUc,
  20.              UcToAnsi, A_StringFromGUID2, A_WriteFmtUserTypeStg,
  21.              A_StgIsStorageFile, A_StgCreateDocfile, A_StgOpenStorage,
  22.              DelayBox, ErrorBox, CreateColorScalePalette, PaintWindow,
  23.              GetErrorMsg.
  24.  
  25.   Origin:    8-28-97: atrent - Revised (based on WINHLPRS by stevebl).
  26.  
  27. ----------------------------------------------------------------------------
  28.   This file is part of the Microsoft COM Tutorial Code Samples.
  29.  
  30.   Copyright (C) Microsoft Corporation, 1997.  All rights reserved.
  31.  
  32.   This source code is intended only as a supplement to Microsoft
  33.   Development Tools and/or on-line documentation.  See these other
  34.   materials for detailed information regarding Microsoft code samples.
  35.  
  36.   THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  37.   KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  38.   IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  39.   PARTICULAR PURPOSE.
  40. ==========================================================================+*/
  41.  
  42. // Don't allow recursive includes of this file.
  43. #ifndef APPUTIL_H
  44. #define APPUTIL_H
  45.  
  46.  
  47. /*--------------------------------------------------------------------------
  48.   The following pragma disables the C4355 warning which reads:
  49.  
  50.   "'this': used in base member initializer list."
  51.  
  52.   This warning is triggered by the nested interface implementation
  53.   classes--a coding technique used throughout the sample series. The
  54.   warning says: "The 'this' pointer is only valid within nonstatic member
  55.   functions, but was used in the initializer list for a base class. This
  56.   is a level 1 warning when Microsoft extensions are enabled (/Ze) but a
  57.   level 4 warning otherwise."  The initializer technique is necessary for
  58.   the coding of nested class interface implementations. See COMOBJ.HTM for
  59.   details on the technique.
  60. --------------------------------------------------------------------------*/
  61. #pragma warning( disable : 4355 )
  62.  
  63.  
  64. // Convenient typedefs.
  65. #ifndef PPVOID
  66. typedef LPVOID* PPVOID;
  67. #endif
  68.  
  69.  
  70. // Convenient macros.
  71.  
  72. #define DELETE_POINTER(p)\
  73. {\
  74.   if (NULL != p)\
  75.   {\
  76.     delete p;\
  77.     p = NULL;\
  78.   }\
  79. }
  80.  
  81. #define RELEASE_INTERFACE(p)\
  82. {\
  83.   IUnknown* pTmp = (IUnknown*)p;\
  84.   p = NULL;\
  85.   if (NULL != pTmp)\
  86.     pTmp->Release();\
  87. }
  88.  
  89. // An enumeration of persistent storage states for use in the
  90. // implementation of IPersistStorage.
  91. typedef enum
  92. {
  93.   PERS_UNINIT = 0,  // Uninitialized.
  94.   PERS_SCRIBBLE,    // Write     permitted; Read     permitted.
  95.   PERS_NOSCRIBBLE,  // Write NOT permitted; Read     permitted.
  96.   PERS_HANDSOFF     // Write NOT permitted; Read NOT permitted.
  97. } PERSTGSTATE;
  98.  
  99. // PCRTTHREADPROC is a type for pointer variables that hold addresses of
  100. // C-RunTime thread procedures.
  101. typedef unsigned (WINAPI *PCRTTHREADPROC)(LPVOID pThreadProc);
  102.  
  103. #define GETINSTANCE(hWnd)   (HANDLE)GetWindowLong(hWnd,GWL_HINSTANCE)
  104. #define GETCLASSBRUSH(hWnd) (HBRUSH)GetClassLong(hWnd,GCL_HBRBACKGROUND)
  105.  
  106.  
  107. // Some General defines for Message Boxes and Dialogs
  108. #define GUID_SIZE 128
  109. #define MAX_STRING_LENGTH 256
  110. #define MAXLOGST 128
  111. #define MAX_LOG_LINES 500
  112. #define DELAYBOX_DURATION 3000
  113.  
  114. #define COLOR_SCALE_RED     1
  115. #define COLOR_SCALE_GREEN   2
  116. #define COLOR_SCALE_BLUE    3
  117. #define COLOR_SCALE_GRAY    4
  118.  
  119. #define EDITOR_EXE_STR "notepad.exe "
  120. #define TUTORIAL_EXE_STR "tutorial.exe "
  121. #define OFN_SOURCEFILES_STR "Source Files (*.CPP;*.H;*.RC;*.C;*.MAK;*.TXT;*.)\0*.CPP;*.H;*.RC;*.C;*.MAK;*.TXT;makefile\0"
  122. #define OFN_SOURCETITLE_STR "Open Source File"
  123. #define NOTICE_TITLE_STR "-Notice-"
  124. #define ERROR_TITLE_STR "-Error-"
  125. #define NOCOM_ERROR_STR "Can't Init COM."
  126. #define NOEDITOR_ERROR_STR "Can't run editor."
  127. #define NOTUTORIAL_ERROR_STR "Can't run tutorial."
  128. #define NOTXT_ERROR_STR "Can't find .TXT file."
  129. #define NOHTM_ERROR_STR "Can't find .HTM file."
  130. #define NOBROWSE_ERROR_STR "Can't run browser."
  131. #define ASSERTFAIL_ERROR_STR "Assertion Failed."
  132. #define HELP_FILE_EXT    ".htm"
  133. #define HTML_FILE_EXT    ".htm"
  134. #define TXT_FILE_EXT     ".txt"
  135. #define LICENSE_FILE_EXT ".lic"
  136.  
  137.  
  138. #ifdef __cplusplus
  139. // If compiling under C++ Ensure that Windows callbacks are
  140. // undecorated extern C calls.
  141. extern "C" {
  142. #endif
  143.  
  144.  
  145. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  146.   Function: WindowProc
  147.  
  148.   Summary:  Standard WindowProc callback function that forwards Windows
  149.             messages on to the CVirWindow::WindowProc method.  This
  150.             Window procedure expects that it will receive a "this"
  151.             pointer as the lpCreateParams member passed as part of the
  152.             WM_NCCREATE message.  It saves the "this" pointer in the
  153.             GWL_USERDATA field of the window structure.
  154.  
  155.   Args:     HWND hWnd,
  156.               Window handle
  157.             UINT uMsg,
  158.               Windows message
  159.             WPARAM wParam,
  160.               First message parameter (word sized)
  161.             LPARAM lParam);
  162.               Second message parameter (long sized)
  163.  
  164.   Returns:  LRESULT.  Windows window procedure callback return value.
  165. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  166. LRESULT CALLBACK WindowProc(
  167.                    HWND hWnd,
  168.                    UINT uMsg,
  169.                    WPARAM wParam,
  170.                    LPARAM lParam);
  171.  
  172.  
  173. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  174.   Function: DialogProc
  175.  
  176.   Summary:  The general dialog procedure callback function.  Used by all
  177.             CVirDialog class objects.  This procedure is the DialogProc
  178.             registered for all dialogs created with the CVirDialog class.
  179.             It uses the parameter passed with the WM_INITDIALOG message
  180.             to identify the dialog classes' "this" pointer which it then
  181.             stores in the window structure's GWL_USERDATA field.
  182.             All subsequent messages can then be forwarded on to the
  183.             correct dialog class's DialogProc method by using the pointer
  184.             stored in the GWL_USERDATA field.
  185.  
  186.   Args:     HWND hWndDlg,
  187.               Handle of dialog box.
  188.             UINT uMsg,
  189.               Message
  190.             WPARAM wParam,
  191.               First message parameter (word sized).
  192.             LPARAM lParam);
  193.               Second message parameter (long sized).
  194.  
  195.   Returns:  BOOL.  Return of the CVirDialog::DialogProc method.
  196. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  197. BOOL CALLBACK DialogProc(
  198.                 HWND hWndDlg,
  199.                 UINT uMsg,
  200.                 WPARAM wParam,
  201.                 LPARAM lParam);
  202.  
  203.  
  204. #ifdef __cplusplus
  205. }
  206.  
  207.  
  208. /*C+C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C
  209.   Class:    CVirWindow
  210.  
  211.   Summary:  Abstract base class for wrapping a window.
  212.  
  213.             This class allows a window to be cleanly wrapped in a
  214.             c++ class.  Specifically, it provides a way for a c++ class
  215.             to use one of its methods as a WindowProc, giving it a "this"
  216.             pointer and allowing it to have direct access to all of its
  217.             private members.
  218.  
  219.   Methods:  Create:
  220.               Maps to Windows' CreateWindow function.
  221.             WindowProc:
  222.               Pure virtual WindowProc for the window.
  223.             Gethwnd:
  224.               Get the handle to the window.
  225.             CVirWindow:
  226.               Constructor.
  227.             ~CVirWindow:
  228.               Destructor.
  229. C---C---C---C---C---C---C---C---C---C---C---C---C---C---C---C---C---C---C-C*/
  230. class CVirWindow
  231. {
  232. public:
  233.   // Constructor
  234.   CVirWindow()
  235.   {
  236.     m_hInst = NULL;
  237.     m_hWnd = NULL;
  238.   };
  239.  
  240.   // Destructor
  241.   virtual ~CVirWindow(){};
  242.  
  243.   // Envelopes the Windows' CreateWindow function call.
  244.   HWND Create(
  245.          LPTSTR lpszClassName,   // Address of registered class name
  246.          LPTSTR lpszWindowName,  // Address of window name
  247.          DWORD dwStyle,          // Window style
  248.          int x,                  // Horizontal position of window
  249.          int y,                  // Vertical position of window
  250.          int nWidth,             // Window width
  251.          int nHeight,            // Window height
  252.          HWND hWndParent,        // Handle of parent or owner window
  253.          HMENU hmenu,            // Handle of menu, or child window identifier
  254.          HINSTANCE hinst);       // Handle of application instance
  255.  
  256.   // Get the protected handle of this window.
  257.   HWND GetHwnd(void)
  258.   {
  259.     return(m_hWnd);
  260.   }
  261.  
  262.   // WindowProc is a pure virtual member function and MUST be over-ridden
  263.   // in any derived classes.
  264.   virtual LRESULT WindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam) = 0;
  265.  
  266. protected:
  267.   // Application instance handle.
  268.   HINSTANCE m_hInst;
  269.   // Handle of this window.
  270.   HWND m_hWnd;
  271.  
  272.   // Tell the compiler that the outside WindowProc callback is a friend
  273.   // of this class and can get at its protected data members.
  274.   friend LRESULT CALLBACK ::WindowProc(
  275.                               HWND hWnd,
  276.                               UINT uMsg,
  277.                               WPARAM wParam,
  278.                               LPARAM lParam);
  279. };
  280.  
  281.  
  282. /*C+C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C
  283.   Class:    CVirDialog
  284.  
  285.   Summary:  Abstract base class for wrapping a Windows dialog box window.
  286.  
  287.             This class allows a dialog box to be cleanly wrapped in
  288.             a c++ class.  Specifically, it provides a way for a c++ class
  289.             to use one of its methods as a DialogProc, giving it a "this"
  290.             pointer and allowing it to have direct access to all of its
  291.             private members.
  292.  
  293.   Methods:  ShowDialog:
  294.               Maps to Windows' DialogBox function.
  295.             GetHwnd:
  296.               Get the handle to the dialog window.
  297.             DialogProc:
  298.               Pure virtual DialogProc for the dialog box
  299.             ~CVirDialog:
  300.               Destructor
  301. C---C---C---C---C---C---C---C---C---C---C---C---C---C---C---C---C---C---C-C*/
  302. class CVirDialog
  303. {
  304. public:
  305.   // Destructor
  306.   virtual ~CVirDialog(){};
  307.  
  308.   // ShowDialog creates the Dialog (using the DialogBoxParam API).
  309.   virtual int ShowDialog(
  310.                 HINSTANCE hInst,
  311.                 LPTSTR lpszTemplate,
  312.                 HWND hWndOwner);
  313.  
  314.   // DialogProc is a pure virtual member function and MUST be over-ridden
  315.   // in any derived classes.
  316.   virtual BOOL DialogProc(
  317.                  HWND hWndDlg,
  318.                  UINT uMsg,
  319.                  WPARAM wParam,
  320.                  LPARAM lParam) = 0;
  321.  
  322. protected:
  323.   HINSTANCE m_hInst;
  324.   HWND m_hWnd;
  325.  
  326.   // Tell the compiler that the outside DialogProc callback is a friend
  327.   // of this class and can get at its protected data members.
  328.   friend BOOL CALLBACK ::DialogProc(
  329.                            HWND hWndDlg,
  330.                            UINT uMsg,
  331.                            WPARAM wParam,
  332.                            LPARAM lParam);
  333. };
  334.  
  335.  
  336. /*C+C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C
  337.   Class:    CAboutBox
  338.  
  339.   Summary:  A class that implements a common About Dialog Box
  340.             functionality for the APPUTIL library.
  341.  
  342.   Methods:  DialogProc
  343.               Dialog procedure
  344. C---C---C---C---C---C---C---C---C---C---C---C---C---C---C---C---C---C---C-C*/
  345. class CAboutBox: public CVirDialog
  346. {
  347. public:
  348.   // This DialogProc method definition overrides the same-named pure
  349.   // virtual function in abstract base class CVirDialog thus giving
  350.   // AboutBox-unique message dispatching behavior to this derivation
  351.   // of CVirDialog.  The remaining behavior of CAboutBox is inherited
  352.   // from CVirDialog and is common to all CVirDialogs.
  353.   BOOL DialogProc(
  354.          HWND hWndDlg,
  355.          UINT uMsg,
  356.          WPARAM wParam,
  357.          LPARAM lParam);
  358. };
  359.  
  360.  
  361. /*C+C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C
  362.   Class:    CDelayBox
  363.  
  364.   Summary:  A class that implements a common Dialog Box functionality for
  365.             the APPUTIL library. This dialog box has no buttons and and
  366.             appears on screen for 8 seconds.
  367.  
  368.   Methods:  DialogProc
  369.               Dialog procedure
  370. C---C---C---C---C---C---C---C---C---C---C---C---C---C---C---C---C---C---C-C*/
  371. class CDelayBox: public CVirDialog
  372. {
  373. public:
  374.   // This DialogProc method definition overrides the same-named pure
  375.   // virtual function in abstract base class CVirDialog thus giving
  376.   // AboutBox-unique message dispatching behavior to this derivation
  377.   // of CVirDialog.  The remaining behavior of CAboutBox is inherited
  378.   // from CVirDialog and is common to all CVirDialogs.
  379.   BOOL DialogProc(
  380.          HWND hWndDlg,
  381.          UINT uMsg,
  382.          WPARAM wParam,
  383.          LPARAM lParam);
  384. };
  385.  
  386.  
  387. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  388.   Function: DelayBox
  389.  
  390.   Summary:  Uses the specified dialog template from the caller's resources
  391.             and shows a buttonless dialog message box that remains on
  392.             screen for about 3 seconds.
  393.  
  394.   Args:     HINSTANCE hInst,
  395.               Handle of the module instance.  Needed to specify the
  396.               module instance for fetching the dialog template resource
  397.               (ie, from either a host EXE or DLL).
  398.             LPTSTR pszTemplate,
  399.               Identifies the dialog box template.
  400.             HWND hwndOwner)
  401.               Handle of the owner window. NULL for desktop.
  402.  
  403.   Returns:  void
  404. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  405. void DelayBox(
  406.       HINSTANCE hInst,
  407.       LPTSTR pszTemplate,
  408.       HWND hWndOwner);
  409.  
  410.  
  411. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  412.   Function: ErrorBox
  413.  
  414.   Summary:  The ErrorBox function displays an error message dialog box. It
  415.             displays an error message string in the dialog that is
  416.             specified in the call by a resource ID.
  417.  
  418.   Args:     HINSTANCE hInst,
  419.               Handle of the module instance.  Needed to specify the
  420.               module instance for fetching the specified string resource.
  421.             HWND hwndOwner,
  422.               Handle of the owner window. NULL for desktop.
  423.             INT iStringID
  424.               Resource ID of the error message sting.
  425.  
  426.   Returns:  void
  427. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  428. void ErrorBox(
  429.       HINSTANCE hInst,
  430.       HWND hWndOwner,
  431.       INT iStringID);
  432.  
  433.  
  434. /*C+C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C
  435.   Class:    CMsgBox
  436.  
  437.   Summary:  Class for showing messages in a Message Box dialog.  Uses the
  438.             standard Windows MessageBox function but retrieves the box
  439.             title and message strings from the application's resources
  440.             using specified resource IDs.  These message boxes have only
  441.             an OK button.
  442.  
  443.   Methods:  Init
  444.               Initializes the owner window and the module instance.
  445.             Error
  446.               Shows a message string in an Error MessageBox Dialog.
  447.             ErrorID
  448.               Shows a resource message string in an Error MessageBox Dialog.
  449.             Note
  450.               Shows a message string in a Notice MessageBox Dialog.
  451.             NoteID
  452.               Shows a resource message string in a Notice MessageBox Dialog.
  453.             NoteFmt
  454.               Shows a printf-style formatted message string in a Notice
  455.               MessageBox Dialog.
  456.             NoteFmtID
  457.               Shows a printf-style formatted resource message string in a
  458.               Notice MessageBox Dialog.
  459. C---C---C---C---C---C---C---C---C---C---C---C---C---C---C---C---C---C---C-C*/
  460. class CMsgBox
  461. {
  462. public:
  463.   // Constructor.
  464.   CMsgBox()
  465.   {
  466.     m_hInst = 0;
  467.     m_hWndOwner = 0;
  468.   };
  469.  
  470.   BOOL Init(HINSTANCE hInst, HWND hWndOwner);
  471.   int  Error(LPTSTR szMsg);
  472.   int  ErrorID(UINT uMsgID);
  473.   int  Note(LPTSTR szMsg);
  474.   int  NoteID(UINT uMsgID);
  475.   int  NoteFmt(LPTSTR szFmtMsg, ...);
  476.   int  NoteFmtID(UINT uMsgID, ...);
  477.  
  478. private:
  479.   // Remember the App Instance Handle.
  480.   HINSTANCE m_hInst;
  481.   // Remember the Owner Window Handle.
  482.   HWND m_hWndOwner;
  483. };
  484.  
  485.  
  486. /*C+C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C
  487.   Class:    CMsgLog
  488.  
  489.   Summary:  Class for logging messages to a Listbox.  This is for tutorial
  490.             code samples that employ debug messages to announce internal
  491.             activity in the code being studied.  When used, this Message
  492.             Log listbox occupies the entire client area of the parent
  493.             window.  The various message output functions use string
  494.             resource IDs to retrieve the message strings from the app's
  495.             resources.
  496.  
  497.   Methods:  Create
  498.               Creates the Trace Message Log ListBox window.
  499.             Logging
  500.               Toggles logging on or off.
  501.             Msg
  502.               Logs a message as a separate line.
  503.             MsgFmt
  504.               Logs a printf-style formated message as a separate line.
  505.             Resize
  506.               Resizes the listbox to a new width and height.
  507.             Clear
  508.               Clears all logged messages from the message log.
  509.             CMsgLog
  510.               Constructor.
  511.             ~CMsgLog
  512.               Destructor.
  513. C---C---C---C---C---C---C---C---C---C---C---C---C---C---C---C---C---C---C-C*/
  514. class CMsgLog
  515. {
  516. public:
  517.   // Constructor.
  518.   CMsgLog()
  519.   {
  520.     m_hInstLog = 0;
  521.     m_hWndLog = 0;
  522.     m_bChild = FALSE;
  523.     m_bLogging = FALSE;
  524.     m_hLogData = 0;
  525.   };
  526.  
  527.   BOOL Create(HINSTANCE hInst, HWND hWndParent, BOOL bChild);
  528.   BOOL Logging(BOOL bLogging);
  529.   BOOL Msg(LPTSTR szMsg);
  530.   BOOL MsgFmt(LPTSTR szFmtMsg, ...);
  531.   BOOL MsgID(int iMsgID);
  532.   BOOL MsgFmtID(int iFmtID, ...);
  533.   BOOL Resize(int nWidth, int nHeight);
  534.   BOOL Clear(void);
  535.   BOOL Copy(void);
  536.  
  537. private:
  538.   // Remember the App Instance Handle.
  539.   HINSTANCE m_hInstLog;
  540.   // Remember the handle of the listbox window.
  541.   HWND m_hWndLog;
  542.   // Remember if CMsgLog was created as child window.
  543.   BOOL m_bChild;
  544.   // Remember whether logging or not.
  545.   BOOL m_bLogging;
  546.   // Remember the global handle to clipboard data.
  547.   HGLOBAL m_hLogData;
  548. };
  549.  
  550.  
  551. /*C+C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C
  552.   Class:    CSendLog
  553.  
  554.   Summary:  Class for logging messages to a CMsgLog facility in another
  555.             application process. This is for tutorial code samples that
  556.             employ debug messages to announce internal activity in the
  557.             code being studied.  Uses the WM_COPYDATA message of the
  558.             Win32 SendMessage API.
  559.  
  560.   Methods:  CreateServerLog
  561.               Initializes the SendLog facility and creates the Trace
  562.               Message Log ListBox window shown in the local server app.
  563.             SetClient
  564.               Sets destination client window handle.
  565.             LogToServer
  566.               Set whether logging is to local server or to client.
  567.             Msg
  568.               Logs a message as a separate line.
  569.             MsgFmt
  570.               Logs a printf-style formated message as a separate line.
  571.             Resize
  572.               Resizes the listbox to a new width and height.
  573.             Clear
  574.               Clears all logged messages from the message log.
  575.             CSendLog
  576.               Constructor.
  577.             ~CSendLog
  578.               Destructor.
  579. C---C---C---C---C---C---C---C---C---C---C---C---C---C---C---C---C---C---C-C*/
  580. class CSendLog
  581. {
  582. public:
  583.   // Constructor.
  584.   CSendLog()
  585.   {
  586.     m_hInstSender = 0;
  587.     m_hWndSender = 0;
  588.     m_hWndReceiver = 0;
  589.     m_hWndListBox = 0;
  590.     m_bLogToServer = FALSE;
  591.     m_bChild = FALSE;
  592.     m_hLogData = 0;
  593.   };
  594.  
  595.   BOOL CreateServerLog(HINSTANCE hInst, HWND hWndParent, BOOL bChild);
  596.   BOOL SetClient(HINSTANCE hInstSender, HWND hWndSender, HWND hWndReceiver);
  597.   BOOL LogToServer(BOOL bLogToServer);
  598.   BOOL Msg(LPTSTR szMsg);
  599.   BOOL MsgFmt(LPTSTR szFmtMsg, ...);
  600.   BOOL MsgID(int iMsgID);
  601.   BOOL MsgFmtID(int iFmtID, ...);
  602.   BOOL Resize(int nWidth, int nHeight);
  603.   BOOL Clear(void);
  604.   BOOL Copy(void);
  605.  
  606. private:
  607.   // Remember the Sender App Instance Handle.
  608.   HINSTANCE m_hInstSender;
  609.   // Remember the handle of the sending application main window.
  610.   HWND m_hWndSender;
  611.   // Remember the handle of the destination receiving window.
  612.   HWND m_hWndReceiver;
  613.   // Remember the handle of the server's listbox window.
  614.   HWND m_hWndListBox;
  615.   // Boolean for logging to client or logging to server.
  616.   BOOL m_bLogToServer;
  617.   // Remember if CMsgLog was created as child window.
  618.   BOOL m_bChild;
  619.   // Remember the global handle to clipboard data.
  620.   HGLOBAL m_hLogData;
  621. };
  622.  
  623.  
  624. /*C+C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C+++C
  625.   Class:    CThreaded
  626.  
  627.   Summary:  Derive a class from this class to provide multi-threaded
  628.             access to objects of the derived class. This is a utility
  629.             base class providing useful methods for achieving mutually
  630.             exclusive access to data in objects of the derived class.
  631.  
  632.   Methods:  OwnThis
  633.               Blocks executing thread until access to this object is
  634.               permitted at which point the thread "owns" this object.
  635.             UnOwnThis
  636.               Executed by owning thread to relinquish ownership of
  637.               this object.
  638.             CThreaded
  639.               Constructor. Creates mutex to govern mutually exclusive
  640.               access to data in this object by multiple threads.
  641.             ~CThreaded
  642.               Destructor. Destroys mutex.
  643. C---C---C---C---C---C---C---C---C---C---C---C---C---C---C---C---C---C---C-C*/
  644. class CThreaded
  645. {
  646.   protected:
  647.     // Variables for providing mutually exclusive access by multiple
  648.     // threads to objects of classes derived from this class.
  649.     HANDLE m_hOwnerMutex;
  650.     BOOL   m_bOwned;
  651.  
  652.   public:
  653.     // Methods.
  654.     CThreaded(void) :
  655.       m_hOwnerMutex(CreateMutex(0,FALSE,0)),
  656.       m_bOwned(FALSE)
  657.     {
  658.     };
  659.  
  660.     ~CThreaded(void)
  661.     {
  662.       // Close down the mutex.
  663.       CloseHandle(m_hOwnerMutex);
  664.     };
  665.  
  666.     // The following virtual functions have overriding definitions in
  667.     // the derived class to provide convenient trace logging. Rely on
  668.     // the below default definitions for non-tutorial applications.
  669.  
  670.     virtual BOOL OwnThis(void)
  671.     {
  672.       BOOL bOwned = FALSE;
  673.  
  674.       if (WAIT_OBJECT_0 == WaitForSingleObject(m_hOwnerMutex, INFINITE))
  675.         m_bOwned = bOwned = TRUE;
  676.  
  677.       return bOwned;
  678.     };
  679.  
  680.     virtual void UnOwnThis(void)
  681.     {
  682.       if (m_bOwned)
  683.       {
  684.         m_bOwned = FALSE;
  685.         ReleaseMutex(m_hOwnerMutex);
  686.       }
  687.  
  688.       return;
  689.     };
  690. };
  691.  
  692.  
  693. #endif //__cplusplus
  694.  
  695.  
  696.  
  697. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  698.   Function: AnsiToUc
  699.  
  700.   Summary:  Convert an ANSI 'multibyte' string into a UNICODE 'wide
  701.             character' string.
  702.  
  703.   Args:     LPSTR pszAnsi
  704.               Pointer to a caller's input ANSI string.
  705.             LPWSTR pszUc
  706.               Pointer to a caller's output UNICODE wide string.
  707.             int cch
  708.               Character count. If 0 then use length of pszAnsi.
  709.  
  710.   Returns:  HRESULT
  711.               Standard result code. NOERROR for success.
  712. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  713. HRESULT AnsiToUc(
  714.           LPSTR pszAnsi,
  715.           LPWSTR pszUc,
  716.           int cch);
  717.  
  718.  
  719. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  720.   Function: UcToAnsi
  721.  
  722.   Summary:  Convert a UNICODE 'wide character' input string to an output
  723.             ANSI 'multi-byte' string.
  724.  
  725.   Args:     LPWSTR pwszUc
  726.               Pointer to a caller's input UNICODE wide string.
  727.             LPSTR pszAnsi
  728.               Pointer to a caller's output ANSI string.
  729.             int cch
  730.               Character count. If 0 then use length of pwszUc.
  731.  
  732.   Returns:  HRESULT
  733.               Standard result code. NOERROR for success.
  734. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  735. HRESULT UcToAnsi(
  736.           LPWSTR pwszUc,
  737.           LPSTR pszAnsi,
  738.           int cch);
  739.  
  740.  
  741. /*---------------------------------------------------------------------------
  742.   Here are some surrogate API macro prototypes--all names begin with A_.
  743.   These are for use when the code sample is being compiled for ANSI
  744.   strings (the default) and the calls they stand in place of only support
  745.   UNICODE (thus forcing some string conversions from ANSI to UNICODE
  746.   before the real call is made inside the surrogate). For example, if
  747.   UNICODE is NOT defined during the compile then any calls in the samples
  748.   to the StringFromGUID2 function are actually changed (by the below
  749.   macros) into calls to an A_StringFromGUID2 function implemented in
  750.   APPUTIL. This function accepts the ANSI input string pointer, calls the
  751.   actual StringFromGUID2 call, and does the necessary Unicode to ANSI
  752.   conversion. Other A_ calls will convert input ANSI strings to Unicode
  753.   strings prior to calling the actual COM/OLE function.
  754. ---------------------------------------------------------------------------*/
  755. #if !defined(UNICODE)
  756.  
  757. STDAPI A_StringFromGUID2(REFGUID, LPSTR, int);
  758.  
  759. STDAPI A_WriteFmtUserTypeStg(IStorage*, CLIPFORMAT, LPSTR);
  760.  
  761. STDAPI A_StgIsStorageFile(LPSTR);
  762. STDAPI A_StgCreateDocfile(LPSTR, DWORD, DWORD, IStorage**);
  763. STDAPI A_StgOpenStorage(LPSTR, IStorage*, DWORD, SNB, DWORD, IStorage**);
  764.  
  765. #if !defined(_NOANSIMACROS_)
  766.  
  767. #undef StringFromGUID2
  768. #define StringFromGUID2(a, b, c) A_StringFromGUID2(a, b, c)
  769.  
  770. #undef WriteFmtUserTypeStg
  771. #define WriteFmtUserTypeStg(a, b, c) A_WriteFmtUserTypeStg(a, b, c)
  772.  
  773. #undef StgIsStorageFile
  774. #define StgIsStorageFile(a) A_StgIsStorageFile(a)
  775.  
  776. #undef StgCreateDocfile
  777. #define StgCreateDocfile(a, b, c, d) A_StgCreateDocfile(a, b, c, d)
  778.  
  779. #undef StgOpenStorage
  780. #define StgOpenStorage(a, b, c, d, e, f) A_StgOpenStorage(a, b, c, d, e, f)
  781.  
  782. #endif
  783.  
  784. #endif
  785.  
  786.  
  787. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  788.   Function: DComOk
  789.  
  790.   Summary:  Determine if DCOM (Distributed COM) can be used. It can if it
  791.             is installed and is enabled on the current machine.
  792.  
  793.   Args:     void
  794.  
  795.   Returns:  BOOL
  796.               TRUE - DCOM installed and enabled; FALSE - NOT.
  797. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  798. BOOL DComOk(void);
  799.  
  800.  
  801. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  802.   Function: lRandom
  803.  
  804.   Summary:  Simple random number generator. Returns a random DWORD.
  805.  
  806.   Args:     void
  807.  
  808.   Returns:  DWORD
  809.               Random number.
  810. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  811. DWORD lRandom(void);
  812.  
  813.  
  814. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  815.   Function: CreateColorScalePalette
  816.  
  817.   Summary:  This function creates a palette representing the scale values
  818.             of a particular RGB color.  A gray-scale palette can also be
  819.             created.
  820.  
  821.   Args:     HDC hDC,
  822.               Handle to device context.
  823.             int nColor
  824.               New color.
  825.  
  826.   Returns:  HPALETTE
  827.               Handle to new pallete.
  828. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  829. HPALETTE CreateColorScalePalette(HWND hDC, int nColor);
  830.  
  831.  
  832. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  833.   Function: PaintWindow
  834.  
  835.   Summary:  This function is used to wash the background of a window.
  836.  
  837.   Args:     HWND hWnd,
  838.               Window handle.
  839.             int nColor
  840.               New window color.
  841.  
  842.   Returns:  void.
  843. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  844. VOID PaintWindow(HWND hWnd, int nColor);
  845.  
  846.  
  847. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  848.   Function: SkipAnsi
  849.  
  850.   Summary:  Utility function to scan an input ANSI string and either skips
  851.             white characters or skips non-white characters.
  852.  
  853.   Args;     LPSTR psz,
  854.               Input ANSI string to be scanned.
  855.             BOOL bSkip)
  856.               Input boolean determining whether to skip white space
  857.               or not.  TRUE means skip white space; FALSE means skip
  858.               non-white chars.
  859.  
  860.   Returns:  LPSTR
  861.               String pointer after the skip (ANSI)
  862. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  863. LPSTR SkipAnsi(
  864.          LPSTR psz,
  865.          BOOL bSkipWhite);
  866.  
  867.  
  868. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  869.   Function: FileExist
  870.  
  871.   Summary:  Function to test for the existance of a file.
  872.  
  873.   Args:     TCHAR* szFileName
  874.               String pointer to file's path/name.
  875.  
  876.   Returns:  BOOL.  TRUE if file exists; FALSE if not.
  877. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  878. BOOL FileExist(TCHAR *szFileName);
  879.  
  880.  
  881. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  882.   Function: MakeFamilyPath
  883.  
  884.   Summary:  Function to make a family file/path/name string using the
  885.             detetected pathname of the current executable module.
  886.  
  887.   Args:     HINSTANCE hInst
  888.               Handle to the module intstance.
  889.             TCHAR* pszNewPath
  890.               String pointer to the new path/name.
  891.             TCHAR* pszFileExt
  892.               String pointer to the filename extension for the new path.
  893.  
  894.   Returns:  BOOL.  TRUE if success; FALSE if not.
  895. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  896. BOOL MakeFamilyPath(
  897.        HINSTANCE hInst,
  898.        TCHAR* pszNewPath,
  899.        TCHAR* pszFileExt);
  900.  
  901.  
  902. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  903.   Function: GetExeName
  904.  
  905.   Summary:  Function to get the executable file name of the current
  906.             module. Makes names like: MyApp.EXE or MyDll.DLL.
  907.  
  908.   Args:     HINSTANCE hInst
  909.               Handle to the module intstance.
  910.             TCHAR* pszExeName
  911.               String pointer to the new executable file name.
  912.               A char string allocated by user.
  913.  
  914.   Returns:  BOOL.  TRUE if success; FALSE if not.
  915. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  916. BOOL GetExeName(
  917.        HINSTANCE hInst,
  918.        TCHAR* pszExeName);
  919.  
  920.  
  921. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  922.   Function: CmdExec
  923.  
  924.   Summary:  Execute an EXE Win32 program by creating a process and
  925.             running the specified EXE in it.  A Unicode version of
  926.             WinExec that always has SW_SHOW.
  927.  
  928.   Args:     LPTSTR szCmd,
  929.               Entire command line (eg, "notepad.exe mytext.txt")
  930.  
  931.   Returns:  BOOL
  932.               TRUE if succeed; FALSE if fail.
  933. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  934. BOOL CmdExec(
  935.        LPTSTR szCmd);
  936.  
  937.  
  938. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  939.   Function: HrMsg
  940.  
  941.   Summary:  HRESULT Error Message box. Takes standard result code,
  942.             looks it up in the system tables, and shows a message
  943.             box with the error code (in hex) and the associated
  944.             system message.
  945.  
  946.   Args:     HWND hWndOwner,
  947.               Handle to owner parent window.
  948.             LPTSTR pszTitle
  949.               User message string (eg, designating the attempted function).
  950.               Appears in the dialog title bar.
  951.             HRESULT hr
  952.               Standard return code.
  953.  
  954.   Returns:  void
  955. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  956. void HrMsg(
  957.        HWND hWndOwner,
  958.        LPTSTR pszTitle,
  959.        HRESULT hr);
  960.  
  961.  
  962. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  963.   Function: HrMsgId
  964.  
  965.   Summary:  HRESULT Error Message box using string resource ID. Takes
  966.             standard result code, looks it up in the system tables, and
  967.             shows a message box with the error code (in hex) and the
  968.             associated system message. An additional user message string
  969.             (specified as a resource ID) is also shown.
  970.  
  971.   Args:     HINSTANCE hInst,
  972.               Handle of the module instance.  Needed to specify the
  973.               module instance for fetching the specified string resource.
  974.             HWND hwndOwner,
  975.               Handle of the owner window. NULL for desktop.
  976.             INT iStringID
  977.               Resource ID of error message string. Appears in the
  978.               dialog title bar.
  979.             HRESULT hr,
  980.               Standard result code.
  981.  
  982.   Returns:  void
  983. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  984. void HrMsgId(
  985.       HINSTANCE hInst,
  986.       HWND hWndOwner,
  987.       INT iStringID,
  988.       HRESULT hr);
  989.  
  990.  
  991. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  992.   Function: ReadHelp
  993.  
  994.   Summary:  The ReadHelp function is a general help reader for
  995.             applications. It uses the shell to run the reader application
  996.             associated with the extension of the specified file/path name.
  997.             For example, if the family-named file name is MYAPP.HTM, then
  998.             the web browser will be used to read the HTML help file.
  999.  
  1000.   Args:     HWND hWndOwner,
  1001.               Handle to owner parent window.
  1002.             LPTSTR pszHelpFile,
  1003.               Pointer to the help file/path name string.
  1004.  
  1005.   Returns:  void
  1006. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  1007. void ReadHelp(
  1008.        HWND hWndOwner,
  1009.        LPTSTR pszHelpFile);
  1010.  
  1011.  
  1012. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  1013.   Function: ReadTutorial
  1014.  
  1015.   Summary:  The ReadTutorial function is for use by tutorial code sample
  1016.             applications that study themselves. This function uses simple
  1017.             Hyperlinking to launch the web browser to read an HTML web
  1018.             page that contains a tutorial covering the sample. If no HTM
  1019.             file (in a sibling or parent directory) is specified, this
  1020.             function assumes a family-named <sample>.HTM tutorial HTML
  1021.             file that is located next to the main .EXE file of the
  1022.             application calling ReadTutorial. "Family-named" means that if
  1023.             the EXE program calling this function is MYAPP.EXE then the
  1024.             associated family-named HTML file is constructed as MYAPP.HTM.
  1025.  
  1026.   Args:     HINSTANCE hInst,
  1027.               Handle of the executable module instance.
  1028.             HWND hWndOwner,
  1029.               Handle to owner parent window.
  1030.             LPTSTR pszHTMLFile,
  1031.               Pointer to an optional HTML FileName string. If this pointer
  1032.               is NULL, then the family-named file is assumed for the HTML
  1033.               file and is assumed to be located next to the main .EXE file
  1034.               of the program executing this function. Non-NULL values are
  1035.               of the form "MySiblingDirectory\MyHTMLFile.HTM" or of the
  1036.               form "MyHTMLFileInTheParentDirectory.HTM". Special non-NULL
  1037.               values beginning with '.' (eg. ".HTM" or ".ASP") specify
  1038.               that the family-named file is assumed to be located in the
  1039.               parent directory. In this case, the specified file extension
  1040.               is used.
  1041.  
  1042.   Returns:  void
  1043. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  1044. void ReadTutorial(
  1045.        HINSTANCE hInst,
  1046.        HWND hWndOwner,
  1047.        LPTSTR pszHTMLFile);
  1048.  
  1049.  
  1050. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  1051.   Function: GoWeb
  1052.  
  1053.   Summary:  General utility function to launch a web browser on a
  1054.             specified HTML file via either a URL or a full file path/name.
  1055.  
  1056.   Args:     HINSTANCE hInst,
  1057.               Handle of the executable module instance.
  1058.             LPSTR pszTarget
  1059.               Pointer to the Target specification string (must be ANSI).
  1060.               If null then call the ReadTutorial function. If pszTarget
  1061.               starts with '//' then the target is assumed to be a www URL
  1062.               trailer of the form: //www.microsoft.com. If any other
  1063.               string, then it is assumed to be a full path/file name.
  1064.  
  1065.   Returns:  void
  1066. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  1067. void GoWeb(
  1068.        HINSTANCE hInst,
  1069.        LPSTR pszTarget);
  1070.  
  1071.  
  1072. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  1073.   Function: ReadSource
  1074.  
  1075.   Summary:  For use by code sample applications that study themselves
  1076.             as it were.  This function allows you to select one of the
  1077.             source files of this code sample and launch a reader to
  1078.             edit/read it.  NOTEPAD.EXE is the default editor/reader.
  1079.             You can change this by changing EDITOR_FILE_STR in
  1080.             APPUTIL.H above.
  1081.  
  1082.   Args:     HWND hWndOwner
  1083.               Handle of parent window.
  1084.             OPENFILENAME* pofn,
  1085.               Pointer to the Open File Name Common Dialog structure.
  1086.  
  1087.   Returns:  void
  1088. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  1089. void ReadSource(
  1090.        HWND hWndOwner,
  1091.        OPENFILENAME* pOfn);
  1092.  
  1093.  
  1094. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  1095.   Function: OutputDebugFmt
  1096.  
  1097.   Summary:  Wraps the Win32 OutputDebugString API call to provide
  1098.             printf-style formatted (and variable argument) output.
  1099.  
  1100.   Args:     LPTSTR szFmt,
  1101.               Format string.
  1102.             [...]
  1103.               Arguments to match those specified in the format string.
  1104.  
  1105.   Returns:  void
  1106. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  1107. void OutputDebugFmt(
  1108.        LPTSTR szFmt,
  1109.        ...);
  1110.  
  1111.  
  1112. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  1113.   Function: GetErrorMsg
  1114.  
  1115.   Summary:  Accepts a Win32 error code and retrieves a human readable
  1116.             system message for it.
  1117.  
  1118.   Args:     HRESULT hr
  1119.               SCODE error code.
  1120.             LPTSTR pszMsg
  1121.               Pointer string where message will be placed.
  1122.             UINT uiSize
  1123.               Max size of the msg string.
  1124.  
  1125.   Returns:  BOOL
  1126.               TRUE if hr was error; FALSE if not.
  1127. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  1128. BOOL GetErrorMsg(
  1129.        HRESULT hr,
  1130.        LPTSTR pszMsg,
  1131.        UINT uiSize);
  1132.  
  1133.  
  1134. #define TID GetCurrentThreadId()
  1135.  
  1136. #if defined(DEBUG)
  1137.  
  1138. //Basic debug and logging macros
  1139.  
  1140. // Output debug string; literal or variable.
  1141. #define ODS(sMsg) \
  1142. {\
  1143.   TCHAR szDebug[MAXLOGST];\
  1144.   OutputDebugFmt(TEXT("%s"),TEXT(sMsg));\
  1145.   wsprintf(szDebug, TEXT(" [%s, %u]\r\n"), (LPTSTR)__FILE__, __LINE__);\
  1146.   OutputDebugString(szDebug);\
  1147. }
  1148.  
  1149. // Output debug string formatted; one argument.
  1150. #define ODF1(sFmt,x) \
  1151. {\
  1152.   TCHAR szDebug[MAXLOGST];\
  1153.   OutputDebugFmt(TEXT(sFmt),x);\
  1154.   wsprintf(szDebug, TEXT(" [%s, %u]\r\n"), (LPTSTR)__FILE__, __LINE__);\
  1155.   OutputDebugString(szDebug);\
  1156. }
  1157.  
  1158. // Output debug string formatted; two argument.
  1159. #define ODF2(sFmt,x,y) \
  1160. {\
  1161.   TCHAR szDebug[MAXLOGST];\
  1162.   OutputDebugFmt(TEXT(sFmt),x,y);\
  1163.   wsprintf(szDebug, TEXT(" [%s, %u]\r\n"), (LPTSTR)__FILE__, __LINE__);\
  1164.   OutputDebugString(szDebug);\
  1165. }
  1166.  
  1167. // Output debug string formatted; three argument.
  1168. #define ODF3(sFmt,x,y,z) \
  1169. {\
  1170.   TCHAR szDebug[MAXLOGST];\
  1171.   OutputDebugFmt(TEXT(sFmt),x,y,z);\
  1172.   wsprintf(szDebug, TEXT(" [%s, %u]\r\n"), (LPTSTR)__FILE__, __LINE__);\
  1173.   OutputDebugString(szDebug);\
  1174. }
  1175.  
  1176. // Check condition and Output assertion failed message to debugger.
  1177. #define ASSERT(condition) \
  1178. {\
  1179.   if (!(condition))\
  1180.     ODS(TEXT("Assertion Failed"));\
  1181. }
  1182.  
  1183. // Check standard HRESULT for error and put up message box if error.
  1184. // Two arguments. Pfx = Prefix msg string; Ec = error code.
  1185. // Eg: CKHR("MyFunction:",hr);
  1186. #define CKHR(Pfx,Ec) \
  1187. {\
  1188.   TCHAR szMsg[MAX_PATH];\
  1189.   if (GetErrorMsg(Ec,szMsg,MAX_PATH))\
  1190.   {\
  1191.     HrMsg(NULL,TEXT(Pfx),Ec);\
  1192.     wsprintf(szMsg, TEXT(" [%s, %u]\r\n"), (LPTSTR)__FILE__, __LINE__);\
  1193.     OutputDebugString(szMsg);\
  1194.   }\
  1195. }
  1196.  
  1197. // Log debug string (output both to Message Log and to Debugger)
  1198. #define LOG(sMsg) \
  1199. {\
  1200.   TCHAR szDebug[MAXLOGST];\
  1201.   if (NULL!=g_pMsgLog)\
  1202.     g_pMsgLog->Msg(TEXT(sMsg));\
  1203.   wsprintf(szDebug, TEXT(" [%s, %u]\r\n"), (LPTSTR)__FILE__, __LINE__);\
  1204.   OutputDebugString(szDebug);\
  1205. }
  1206.  
  1207. // Log debug string (output both to Message Log and to Debugger).
  1208. // One argument.
  1209. #define LOGF1(sFmt,x) \
  1210. {\
  1211.   TCHAR szDebug[MAXLOGST];\
  1212.   if (NULL!=g_pMsgLog)\
  1213.     g_pMsgLog->MsgFmt(TEXT(sFmt),x);\
  1214.   wsprintf(szDebug, TEXT(" [%s, %u]\r\n"), (LPTSTR)__FILE__, __LINE__);\
  1215.   OutputDebugString(szDebug);\
  1216. }
  1217.  
  1218. // Log debug string (output both to Message Log and to Debugger).
  1219. // Two argument.
  1220. #define LOGF2(sFmt,x,y) \
  1221. {\
  1222.   TCHAR szDebug[MAXLOGST];\
  1223.   if (NULL!=g_pMsgLog)\
  1224.     g_pMsgLog->MsgFmt(TEXT(sFmt),x,y);\
  1225.   wsprintf(szDebug, TEXT(" [%s, %u]\r\n"), (LPTSTR)__FILE__, __LINE__);\
  1226.   OutputDebugString(szDebug);\
  1227. }
  1228.  
  1229. // Log debug string (output both to Message Log and to Debugger).
  1230. // Three argument.
  1231. #define LOGF3(sFmt,x,y,z) \
  1232. {\
  1233.   TCHAR szDebug[MAXLOGST];\
  1234.   if (NULL!=g_pMsgLog)\
  1235.     g_pMsgLog->MsgFmt(TEXT(sFmt),x,y,z);\
  1236.   wsprintf(szDebug, TEXT(" [%s, %u]\r\n"), (LPTSTR)__FILE__, __LINE__);\
  1237.   OutputDebugString(szDebug);\
  1238. }
  1239.  
  1240. // Log error message string (output both to Message Log and to Debugger).
  1241. // Two arguments. Pfx = Prefix msg string; Ec = error code.
  1242. // Eg: LOGERROR("MyFunction:",hr);
  1243. #define LOGERROR(Pfx,Ec) \
  1244. {\
  1245.   TCHAR szMsg[MAX_PATH];\
  1246.   if (NULL!=g_pMsgLog && GetErrorMsg(Ec,szMsg,MAX_PATH))\
  1247.   {\
  1248.     g_pMsgLog->MsgFmt(TEXT("%s Error=0x%X: %s"),TEXT(Pfx),Ec,szMsg);\
  1249.     wsprintf(szMsg, TEXT(" [%s, %u]\r\n"), (LPTSTR)__FILE__, __LINE__);\
  1250.     OutputDebugString(szMsg);\
  1251.   }\
  1252. }
  1253.  
  1254. // Log debug string (output both to Message Log and to Debugger).
  1255. // Use a string resource ID to retrieve the display string.
  1256. #define LOGID(id) \
  1257. {\
  1258.   TCHAR szDebug[MAXLOGST];\
  1259.   if (NULL!=g_pMsgLog)\
  1260.     g_pMsgLog->MsgID(id);\
  1261.   wsprintf(szDebug, TEXT(" [%s, %u]\r\n"), (LPTSTR)__FILE__, __LINE__);\
  1262.   OutputDebugString(szDebug);\
  1263. }
  1264.  
  1265. // Log assertion failure.
  1266. #define LOGASSERT(condition) \
  1267. {\
  1268.   if (!(condition))\
  1269.     LOGID(IDS_ASSERT_FAIL);\
  1270. }
  1271.  
  1272. #else  // !defined(DEBUG)
  1273.  
  1274. #define ODS(x)
  1275.  
  1276. #define ODF1(sFmt,x)
  1277.  
  1278. #define ODF2(sFmt,x,y)
  1279.  
  1280. #define ODF3(sFmt,x,y,z)
  1281.  
  1282. #define ASSERT(condition)
  1283.  
  1284. #define CKHR(Pfx,Ec)
  1285.  
  1286. #define LOG(sMsg) \
  1287. {\
  1288.   if (NULL!=g_pMsgLog)\
  1289.     g_pMsgLog->Msg(TEXT(sMsg));\
  1290. }
  1291.  
  1292. // Log debug string (output both to Message Log and not to Debugger).
  1293. // One argument.
  1294. #define LOGF1(sFmt,x) \
  1295. {\
  1296.   if (NULL!=g_pMsgLog)\
  1297.     g_pMsgLog->MsgFmt(TEXT(sFmt),x);\
  1298. }
  1299.  
  1300. // Log debug string (output both to Message Log and not to Debugger).
  1301. // Two argument.
  1302. #define LOGF2(sFmt,x,y) \
  1303. {\
  1304.   if (NULL!=g_pMsgLog)\
  1305.     g_pMsgLog->MsgFmt(TEXT(sFmt),x,y);\
  1306. }
  1307.  
  1308. // Log debug string (output both to Message Log and not to Debugger).
  1309. // Three argument.
  1310. #define LOGF3(sFmt,x,y,z) \
  1311. {\
  1312.   if (NULL!=g_pMsgLog)\
  1313.     g_pMsgLog->MsgFmt(TEXT(sFmt),x,y,z);\
  1314. }
  1315.  
  1316. // Log error message string (output both to Message Log and not to Debugger).
  1317. // Two arguments. Pfx = Prefix msg string; Ec = error code.
  1318. // Eg: LOGERROR("MyFunction:",hr);
  1319. #define LOGERROR(Pfx,Ec) \
  1320. {\
  1321.   TCHAR szMsg[MAX_PATH];\
  1322.   if (NULL!=g_pMsgLog && GetErrorMsg(Ec,szMsg,MAX_PATH))\
  1323.     g_pMsgLog->MsgFmt(TEXT("%s Error=0x%X: %s"),TEXT(Pfx),Ec,szMsg);\
  1324. }
  1325.  
  1326. // Log debug string (output both to Message Log and not to Debugger).
  1327. // Use a string resource ID to retrieve the display string.
  1328. #define LOGID(id) \
  1329. {\
  1330.   if (NULL!=g_pMsgLog)\
  1331.     g_pMsgLog->MsgID(id);\
  1332. }
  1333.  
  1334. // Log assertion failure.
  1335. #define LOGASSERT(condition)\
  1336. {\
  1337.   if (!(condition))\
  1338.     LOGID(IDS_ASSERT_FAIL);\
  1339. }
  1340.  
  1341. #endif // DEBUG
  1342.  
  1343. #endif //APPUTIL_H
  1344.