65.9K
CodeProject 正在变化。 阅读更多。
Home

CTracerST v1.0

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.23/5 (3投票s)

2000年6月18日

viewsIcon

53537

downloadIcon

1364

一个灵活的跟踪类,用于一致的应用程序调试跟踪。

  • 下载演示项目 - 148 Kb
  • 下载源代码 - 8 KB
  • Sample Image - CTracerST.jpg

    SoftechSoftware 主页
    SoftechSoftware 电子邮件

    如果您编写商业或实时应用程序,您会熟悉跟踪字符串。这些跟踪是发送到屏幕或磁盘的那些神秘字符串,它们在程序员的工作调试阶段提供帮助。

    如果您编写的应用程序需要跟踪,并且不止一个,您就会寻找一个标准、易于集成且易于使用的跟踪系统。

    CTracerST 提供了一种在应用程序中实现和使用跟踪系统的一致方式。

    此类功能包括

    • 支持多达 10 个不同的跟踪级别(可增加到无限)

    • 缓冲跟踪字符串
    • 跟踪字符串可自动保存到磁盘
    • 自动写入预定义大小的文件
    • 跟踪字符串可以以任何期望的方式显示(由程序员决定)
    • 完全支持 UNICODE
    • 写入纯文本文件(UNICODE 兼容)

    此类已在以下环境中测试:

    • Visual C++ 6.0 sp3

    • Windows NT Workstation 4.0 sp6a
    • Windows 2000

    使用条款

    您可以随时随地使用 CTracerST,没有任何限制。

    您可以将此软件包含在 DLL、库、CD-ROM 集合等中。您只需向 SoftechSoftware 声明对这部分代码的贡献。

    如果您使用此类,欢迎提供您的应用程序截图或下载链接(如果是共享软件/免费软件)。

    如果您发现错误或进行了改进,请告知 SoftechSoftware

    摘要

    基本上,CTracerST 接受一个字符串和一个跟踪级别。如果级别已启用,则存储该字符串,否则将其丢弃。此外,如果启用了保存到磁盘,则会立即保存该字符串。

    为什么需要跟踪级别?

    您的应用程序可能会生成大量跟踪字符串。如果您为每种字符串分配特定类型的信息(信息/错误/致命错误...),您将能够以编程方式选择要生成的跟踪类型。例如,如果您在级别 0 跟踪所有信息,那么通过禁用级别 0 跟踪,可以打开和关闭所有信息。

    跟踪字符串以 STRUCT_TRACERST 结构的形式存储在内部

    typedef struct _STRUCT_TRACERST
    {
    DWORDdwLevel;
    TCHARszText[256];
    SYSTEMTIMEcsTime;
    } STRUCT_TRACERST;

    只有当您的应用程序需要显示跟踪字符串时,您才需要处理此结构。

    CTracerST 将字符串保存到纯文本文件中。如果您的应用程序是为 UNICODE 构建的,那么这些文本文件将是 UNICODE 的,即在文件顶部写入字符 0xFFFE。这个标记似乎是识别 UNICODE 文本文件的标准方法(记事本就是这样做的)。

    生成的文件的文件名形式为 ddmmyyyy_Tracexxx.txt,其中 xxx 是从 000 到 255 的数字。CTracerST 能够生成大小或多或少预定义的文件;每次创建一个新文件时,它都会按顺序编号从 0 到 255。默认情况下,编号从 0 开始。
    示例:07062000_Trace000.txt

    跟踪字符串的书写形式为 hh:mm:ss:ms [级别] <跟踪字符串>
    示例:09:26:03:0214 [0] 数据库已启动(大小 = 32672 字节)

    CSharedQueueST

    CTracerST 使用一个名为 CSharedQueueST 的类实现的队列来存储跟踪字符串。
    当一个元素被添加到队列时,这个类能够

    • 向窗口发送消息

    • 设置一个事件
    • 恢复一个线程

    通过以上任一方式,需要显示跟踪字符串的应用程序都可以检测到新字符串何时可用。

    CTracerST 获取跟踪字符串所需的正确步骤是:

    • 等待消息、事件或线程恢复

    • 读取第一个可用的跟踪字符串(一个 STRUCT_TRACERST 结构)
    • 根据应用程序需要准备字符串
    • 对字符串进行任何您想要的操作

    以下示例展示了如何使用列表框显示跟踪字符串

    STRUCT_TRACERST    csTracer;
    TCHAR szText[512];
    int nIndex;

    // Get the first string trace available
    COLOR="BLUE">if (m_Tracer.GetItem((char*)&csTracer) == TRACERST_OK)
    {
    // Prepare a human-readable version of the string
    ::wsprintf(szText, _T("%02d:%02d:%02d:%04d [%lu] %s"), csTracer.csTime.wHour,
    csTracer.csTime.wMinute,
    csTracer.csTime.wSecond,
    csTracer.csTime.wMilliseconds,
    csTracer.dwLevel,
    csTracer.szText);
    COLOR="GREEN"> // Add the string to our listbox
    nIndex = m_lbxTrace.AddString(szText);
    COLOR="GREEN"> // Hilight the just added string
    COLOR="BLUE">if (nIndex != LB_ERR && nIndex != LB_ERRSPACE)
    m_lbxTrace.SetCurSel(nIndex);
    } // if

    如何将 CTracerST 集成到您的应用程序中

    将以下文件包含在您的应用程序项目中

      <LI
           CLASS="mvd-PRE">TracerST.h
      <LI CLASS="mvd-PRE">TracerST.cpp
      <LI CLASS="mvd-PRE">SharedQueueST.h
      <LI CLASS="mvd-PRE">SharedQueueST.cpp
      <LI CLASS="mvd-PRE">Macros.h

    声明一个 CTracerST 对象

    CTracerST    m_Tracer;

    初始化您的对象

    m_Tracer.Create(250, 64, FALSE, this->m_hWnd, WM_APP + 1);

    就是这样!要使用您的跟踪器

    m_Tracer.Trace(0, _T("Trace string"));

    CTracerST 方法

    构造函数

    CTracerST();

    标准构造函数。它不执行任何操作。

    Create

    DWORD Create(DWORD dwMaxItems,
    DWORD dwMaxFilesize,
    BOOL bUseAlternateDateFormat,
    HWND hWndParent = NULL,
    UINT nMsgParent = NULL,
    HANDLE hEventParent = NULL,
    HANDLE hThreadHandle = NULL);

    初始化一个 CTracerST 对象。

    参数

    • dwMaxItems

      [输入] 对象可以持有的跟踪字符串的最大数量。

    • dwMaxFilesize

      [输入] 保存文件的大小(以 KBytes 为单位)。

    • bUseAlternateDateFormat

      [输入] 指示是否必须使用备用日期格式约定。
      如果为 TRUE,文件将以 mmddyyyy_Tracexxx.txt 的形式保存
      如果为 FALSE,文件将以 ddmmyyyy_Tracexxx.txt 的形式保存

    • hWndParent

      [输入] 窗口的句柄,该窗口将在每次跟踪字符串时接收消息。

    • nMsgParent

      [输入] 每次跟踪字符串时发送的消息。

    • hEventParent

      [输入] 每次跟踪字符串时设置的事件句柄。

    • hThreadParent

      [输入] 每次跟踪字符串时恢复的线程句柄。

    返回值

    • TRACERST_OK

      对象已成功初始化。

    • TRACERST_QUEUEERROR

      初始化队列时发生错误。

    示例

    DWORD    dwRetValue;
    dwRetValue = m_Tracer.Create(250, 64, FALSE, this->m_hWnd, WM_APP + 1);
    ASSERT(dwRetValue == TRACERST_OK);

    Trace

    DWORD Trace(BYTE byLevelNumber, LPCTSTR lpszText);

    跟踪一个字符串。

    参数

    • byLevelNumber

      [输入] 基于零的跟踪级别编号。

    • lpszText

      [输入] 要跟踪的字符串。最多允许 256 个 TCHAR。

    备注

    如果跟踪级别被禁用,字符串将被忽略并丢弃。也不会发送/设置/恢复任何消息/事件/线程。如果跟踪级别超出限制,字符串将被处理。您可以使用 SetTraceLevels 来启用/禁用跟踪级别。

    如果设置了保存标志,则字符串将被写入指定的目录。您可以使用 SetFlags 来设置/重置标志,使用 SetTraceDirectory 来设置保存跟踪文件的目录。

    CTracerST 默认提供 10 个跟踪级别。如果您需要更多级别,只需更改 TracerST.h 文件中的 TRACERST_MAX_LEVELS 定义。

    #defineTRACERST_MAX_LEVELS  10

    返回值

    • TRACERST_OK

      字符串已成功跟踪。

    • TRACERST_QUEUEERROR

      队列报告了错误。

    示例

    DWORD    dwRetValue; 
    // This string will be traced only if level 2 is enabled
    dwRetValue = m_Tracer.Trace(2, _T("Trace string"));
    ASSERT(dwRetValue == TRACERST_OK);
    COLOR="GREEN">// This string will always traced
    dwRetValue = m_Tracer.Trace(99, _T("Trace string 2"));

    GetItem

    DWORD GetItem(char* szpBuffer,
    BOOL bRemove = TRUE,
    LPDWORD lpdwNumBytesCopied = NULL);

    从 CTracerST 的队列获取第一个可用的跟踪数据。

    参数

    • szpBuffer

      [输入] 指向一个 STRUCT_TRACERST 结构,该结构将接收跟踪数据。
      它必须被转换为 char*

    • bRemove

      [输入] 指示是否必须从队列中移除跟踪数据。
      如果为 TRUE,跟踪数据将从队列中移除。
      如果为 FALSE,跟踪数据将保留在队列中。第二次调用 GetItem 将返回相同的跟踪数据。
      此值应始终为 TRUE。

    • lpdwNumBytesCopied

      [输出] 返回复制到 szpBuffer 的字节数。
      此值始终为 SIZE_STRUCT_TRACERST

    返回值

    • TRACERST_OK

      函数执行成功。

    • TRACERST_QUEUEERROR

      队列报告了错误。
      此值也表示队列为空(没有可用的跟踪数据)。

    示例

    STRUCT_TRACERST    csTracer;
    TCHAR szText[512];
    int nIndex;

    // Get the first string trace available
    COLOR="BLUE">if (m_Tracer.GetItem((char*)&csTracer) == TRACERST_OK)
    {
    // Prepare a human-readable version of the string
    ::wsprintf(szText, _T("%02d:%02d:%02d:%04d [%lu] %s"), csTracer.csTime.wHour,
    csTracer.csTime.wMinute,
    csTracer.csTime.wSecond,
    csTracer.csTime.wMilliseconds,
    csTracer.dwLevel,
    csTracer.szText);
    COLOR="GREEN">// Add the string to our listbox
    nIndex = m_lbxTrace.AddString(szText);
    COLOR="GREEN">// Hilight the just added string
    COLOR="BLUE">if (nIndex != LB_ERR && nIndex != LB_ERRSPACE)
    m_lbxTrace.SetCurSel(nIndex);
    } // if

    SetTraceDirectory

    void SetTraceDirectory(LPCTSTR lpszTraceDir);

    设置保存跟踪文件的目录。

    参数

    • lpszTraceDir

      [输入] 指向一个以 null 结尾的字符串,该字符串指定保存跟踪文件的目录。
      此目录必须存在并且必须以反斜杠结尾。
      最多允许 _MAX_PATH 个 TCHAR。

    备注

    默认情况下,跟踪文件保存在应用程序加载的目录中。

    示例

    m_Tracer.SetTraceDirectory(_T("c:\\traces\\"));

    GetTraceLevels

    void GetTraceLevels(LPBYTE lpbyTraceLevels);

    检索所有跟踪级别的状态(启用/禁用)。

    参数

    • lpbyTraceLevels

      [输出] 指向一个字节数组,该数组将接收跟踪级别状态。

    备注

    指定的字节数组必须足够大,以接收所有可用跟踪级别的状态。
    设置为 1 的状态表示已启用,设置为 0 的状态表示已禁用。

        byArray[0]                          ---   Trace level 0 state
    .
    .
    .
    byArray[TRACERST_MAX_LEVELS - 1] --- Trace level TRACERST_MAX_LEVELS - 1 state

    示例
    以下示例测试跟踪级别编号 0 的状态。

    BYTE    byTraceLevels[TRACERST_MAX_LEVELS];

    m_Tracer.GetTraceLevels(byTraceLevels);
    if (byTraceLevels[0] == 1) // Enabled
    {
    }
    COLOR="BLUE">else // Disabled
    {
    }

    SetTraceLevels

    void SetTraceLevels(LPBYTE lpbyTraceLevels);

    设置所有跟踪级别的状态(启用/禁用)。

    参数

    • lpbyTraceLevels

      [输入] 指向一个字节数组,该数组指定所有跟踪级别的状态。

    备注

    指定的字节数组必须包含所有可用跟踪级别的状态。
    设置为 1 的状态表示已启用,设置为 0 的状态表示已禁用。

    示例
    以下示例将所有跟踪级别设置为启用。

    BYTE    byTraceLevels[TRACERST_MAX_LEVELS];

    ::FillMemory(&byTraceLevels, sizeof(byTraceLevels), 1);
    m_Tracer.SetTraceLevels(byTraceLevels);

    GetFlags

    void GetFlags(LPBYTE lpbyFlags);

    获取 CTracerST 标志。

    参数

    • lpbyFlags

      [输出] 指向一个字节,该字节将接收标志。

    示例

    BYTE    byFlags;
    m_Tracer.GetFlags(&byFlags);

    SetFlags

    void SetFlags(LPBYTE lpbyFlags);

    设置 CTracerST 标志。

    参数

    • lpbyFlags

      [输入] 指向一个字节,该字节指定新的标志。

    备注

    字节的每个位指定一个单独的标志。

    目前只支持一个标志

    • TRACERST_FLAG_SAVE

      将跟踪保存到磁盘。

    示例
    以下示例设置保存到磁盘标志。

    BYTE    byFlags;

    m_Tracer.GetFlags(&byFlags);
    byFlags |= TRACERST_FLAG_SAVE;
    m_Tracer.SetFlags(&byFlags);

    GetVersionI

    short GetVersionI();

    CTracerST 版本作为短数字返回。
    除以 10 可获得实际版本。

    GetVersionC

    LPCTSTR GetVersionC();

    CTracerST 版本作为字符串返回。

    示例

    TCHAR    szText[128];

    ::wsprintf(szText, _T("Version is: %s"), CTracerST::GetVersionC());
    ::MessageBox(NULL, szText, NULL, MB_OK);

    备注

    CTracerST 受关键部分保护。这使得它可以同时从不同线程调用而不会出现问题(线程安全)。它目前在两个工业应用程序中使用,没有出现任何问题。

    应用程序必须注意的唯一区域是不要填满跟踪队列。此队列可缓冲的跟踪字符串数量有限,如 Create 函数(dwMaxItems 参数)中所指定。CTracerST 不会从队列中移除跟踪数据。即使应用程序不需要显示跟踪,也应该从队列中移除跟踪数据。这可以通过以下示例完成

    // The application handles the WM_APP + 1 message with the following function
    LRESULT MyApp::On_RM_TRACE(WPARAM wParam, LPARAM lParam)
    {
    m_Tracer.GetItem(NULL);
    COLOR="BLUE">return 0;
    } // End of On_RM_TRACE

    想将 CTracerST 包含在 DLL 中?

    CTracerST 已准备好在 DLL 中使用。您需要从 DLL 导出 CTracerST 以及 CSharedQueueST。将以下文件包含在您的 DLL 项目中

      <LI
           CLASS="mvd-PRE">TracerST.h
      <LI CLASS="mvd-PRE">TracerST.cpp
      <LI CLASS="mvd-PRE">SharedQueueST.h
      <LI CLASS="mvd-PRE">SharedQueueST.cpp
      <LI CLASS="mvd-PRE">Macros.h

    将以下定义添加到您的 DLL 项目设置中

      <LI
           CLASS="mvd-PRE">_CMLHTDLL_NOLIB_
      <LI CLASS="mvd-PRE">_CMLHTDLL_BUILDDLL_

    TracerST.h 中注释掉以下行

    #define _TRACERST_NODLL_

    然后根据您的 DLL 生成的 .lib 文件更新各种 #pragma comment(lib, "???")

    SharedQueueST.h 中注释掉以下行

    #define _SHAREDQUEUEST_NODLL_

    然后根据您的 DLL 生成的 .lib 文件更新各种 #pragma comment(lib, "???")

    历史

    • CTracerST v1.0

      首次发布

    © . All rights reserved.