龙仪的家

导航

<2006年4月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

随笔分类

文章分类

收藏夹

随笔档案

文章档案

统计

我的常用网址

代码库之八-信息输出类

信息输出类
在写程序的时候如果不想中断代码的运行(多线程调试困难就在于此,你F9中断会影响其他线程)就需要输出信息,TRACE可以输出OutputDebugString也可以输出但终究感觉不爽,于是写了这个类,有了这个类,你可以很方便的输出信息到控制台窗口、文件、调试窗口、邮槽等等,你还可以采用其他方式输出,希望它能让你结束调试的痛苦。


///////////////////////////////////////////H///////////////////////////////////////////////////////////

#ifndef LGLIB_DEBUG_H
#define LGLIB_DEBUG_H

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <stdio.h>
#include "Lg_SyncLock.h"

#define DYNA_STRING 2048
#define MAX_PATH 260
#define _countof(array) (sizeof(array)/sizeof(array[0]))

namespace lglib
{
 typedef enum _OUTPUTTYPE
 {
  Output_Console = 0,
  Output_Trace,
  Output_File,
  Output_Mailslot
 }OutputType;

 /************************************************************************/
 /* 调试信息输出类,象上面枚举所描述的那样通过这个类你可以有四类输出
 /* 1,控制台输出,2,Output窗口输出,3,输出到文件,4,输出到邮槽
 /* 至于其他输出类型你可以自行添加
 /************************************************************************/
 class __LGLIB__ lg_Debug
 {
 public:
  lg_Debug(BOOL isconsole = TRUE,BOOL ismailslot = FALSE);
  virtual ~lg_Debug();
 public: //define

 public: //var
  void SetDebugFilePath(const char * filepath = NULL);

  BOOL SetDebugMailslot(const char * mailslot);

  void SetDebugColor(uint16 ForeColor = (/*FOREGROUND_RED | */FOREGROUND_GREEN | FOREGROUND_BLUE|FOREGROUND_INTENSITY) ,uint16 BackGroundColor = 0);

  BOOL outdebug(OutputType type,const char* lpFormat,...);
 private:
  void StartConsoleWin(int16 width, int16 height);
  BOOL SaveDataToFile(const char* data,const long DataLen);
  BOOL SendMailslot(const char* data);
 private:
  HANDLE m_hStdOut;
  BOOL m_bIsConsole;
  BOOL m_bIsMailslot;
  BOOL m_bIsFirstIn;

  char m_chBuffer[DYNA_STRING];
  char m_chFilePath[MAX_PATH];
  char m_chMailslot[MAX_PATH];
  //互斥为了保证多线程访问的同步
  lg_Mutex m_mutex;
 };
 extern lg_Debug _LGDEBUG;
}
#define LGTRACE _LGDEBUG.outdebug

//由于要捕获行号和文件名,所以只能用宏定义了
//如果不需要行号和文件名的话,在异常类的构造部分输出即可
//开始捕获异常
#define  LGTRY  try {

//捕获自定义异常
#define  OWCATCH \
 }catch(const lg_Exception & e){ \
  LGTRACE(Output_File, \
  "<异常!!----------------------------------\r\n" \
  "\tMethod = %s\r\n" \
  "\tMessage = %s\r\n" \
  "\tfile = %s\r\n" \
  "\tline = %u\r\n" \
  "----------------------------------异常!!>\r\n", \
  e.getMethod().c_str(),e.getMessage().c_str(),__FILE__,__LINE__ );

//捕获其他异常
#define  PBCATCH \
 }catch(...){

//异常体结束
#define  ENDCATCH }

#endif // LGLIB_DEBUG_H

///////////////////////////////////////////////CPP////////////////////////////////////////////////////

#include "stdafx.h"
#include "lg_Debug.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
namespace lglib
{
 lg_Debug _LGDEBUG;

 lg_Debug::lg_Debug(BOOL isconsole,BOOL ismailslot)
  : m_hStdOut(NULL) ,m_bIsFirstIn(TRUE),
  m_bIsConsole(isconsole) , m_bIsMailslot(ismailslot)
 {
  memset(m_chBuffer,0,DYNA_STRING);
  memset(m_chFilePath,0,MAX_PATH);
  memset(m_chMailslot,0,MAX_PATH);

  StartConsoleWin(800,600);
  SetDebugColor();
 }

 lg_Debug::~lg_Debug()
 {

 }
 void lg_Debug::SetDebugFilePath(const char * filepath)
 {
  if(filepath == NULL)
   strcpy(m_chFilePath,"d:\\debuginfo.txt");
  else
   strcpy(m_chFilePath,filepath);
 }
 BOOL lg_Debug::SetDebugMailslot(const char * mailslot)
 {
  if(!m_bIsMailslot || NULL == mailslot)
   return FALSE;
  strcpy(m_chMailslot,mailslot);
  return TRUE;
 }

 void lg_Debug::SetDebugColor(unsigned short ForeColor,unsigned short BackGroundColor)
 {
  SetConsoleTextAttribute(m_hStdOut,ForeColor|BackGroundColor);
 }

 BOOL lg_Debug::outdebug(OutputType type,const char* lpFormat,...)
 {
  BOOL Ret = FALSE;
  m_mutex.lock();

  va_list args;
  va_start(args, lpFormat);
  _vsnprintf(m_chBuffer, _countof(m_chBuffer), lpFormat, args);
  va_end(args);
  strcat(m_chBuffer,"\r\n");

  switch(type){
  case Output_Console:
   {
    DWORD cCharsWritten;
    Ret = WriteConsole(m_hStdOut, m_chBuffer, strlen(m_chBuffer), &cCharsWritten, NULL);
   }
   break;
  case Output_Trace:
   {
    OutputDebugStr(m_chBuffer);
    Ret = TRUE;
   }
   break;
  case Output_File:
   {
    Ret = SaveDataToFile(m_chBuffer,strlen(m_chBuffer));
   }
   break;
  case Output_Mailslot:
   {
    if(m_bIsMailslot)
     Ret = SendMailslot(m_chMailslot);
    else
     Ret = FALSE;
   }
   break;
  }
  m_mutex.unlock();
  
  return Ret;
 }

 void lg_Debug::StartConsoleWin(int16 width, int16 height)
 {
  AllocConsole();//分配
  SetConsoleTitle("Debug Window");
  m_hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);//指明句柄为标准输出HANDLE
  COORD co = {width,height};
  SetConsoleScreenBufferSize(m_hStdOut, co);//指明缓冲区大小
 }
 
 BOOL lg_Debug::SaveDataToFile(const char* data,const long DataLen)
 {
  DWORD numtowrite = 0;
  HANDLE hFile = CreateFile(m_chFilePath,
   GENERIC_WRITE,
   FILE_SHARE_WRITE,
   NULL,
   m_bIsFirstIn?CREATE_ALWAYS:OPEN_ALWAYS,
   FILE_ATTRIBUTE_NORMAL,
   NULL);

  if(m_bIsFirstIn)
   m_bIsFirstIn = !m_bIsFirstIn;

  if(INVALID_HANDLE_VALUE == hFile){
   return FALSE;
  }
  if(0xFFFFFFFF == SetFilePointer(hFile,0,0,FILE_END)){
   CloseHandle(hFile);
   return FALSE;
  }
  if(FALSE == WriteFile(hFile,data,DataLen,&numtowrite,NULL)){
   CloseHandle(hFile);
   return FALSE;
  }
  if(FALSE == CloseHandle(hFile))
   return FALSE;
  return TRUE;
 }
 BOOL lg_Debug::SendMailslot(const char* data)
 {
  DWORD cbWritten;
  
  HANDLE hFile = CreateFile(m_chMailslot,
   GENERIC_WRITE,
   FILE_SHARE_READ,
   (LPSECURITY_ATTRIBUTES)NULL,
   OPEN_EXISTING,
   FILE_ATTRIBUTE_NORMAL,
   (HANDLE) NULL);

  if (hFile == INVALID_HANDLE_VALUE)
   return FALSE;
  
  if(FALSE == WriteFile(hFile, data,(DWORD)lstrlen(data),&cbWritten,(LPOVERLAPPED) NULL)){
   ::CloseHandle(hFile);
   return FALSE;
  }
  if(FALSE == ::CloseHandle(hFile))
   return FALSE;
  return TRUE;
 }
}

posted on 2006-04-30 14:42 longest 阅读(1686) 评论(0)  编辑 收藏

评论

标题  
姓名  
主页
验证码 *
内容   
  登录  使用高级评论  Top
[使用Ctrl+Enter键可以直接提交]