c++中 SetTimer的应用

来源:互联网 发布:淘宝在哪里找删掉 编辑:程序博客网 时间:2024/06/05 14:50

#pragma once
#include "VideoSourceServer/IVideoSourceServer.h"
#include "ConformRtmp/IRtmpConform.h"
#include "Buffer.h"
#include "TVCritSec.h"
#include "DrawVideoGDI.h"
#include "BitmapInfoHelpFunc.h"
#include "WaveFormatExHelpFun.h"
#include "ListboxInsertString.h"
#include "FormatString.h"
#include "StreamNumDef.h"
#include "StreamDataUnpackerUnpress.h"
#include "LogTool.h"
#include <atlconv.h>
#include <string>
#include <queue>
using namespace std;

#define TIMER_ID_PROCESS_MSG   (100)
#define TIMER_ID_DRAW_VIDEO    (101)
#define TIMER_ID_CONNECT_FMS   (102)
#define TIMER_ID_UPDATA_INFO   (103)

#define TIME_PROCESS_MSG    (200)
#define TIME_DRAW_VIDEO     (80)
#define TIME_CONNECT_FMS    (1000)
#define TIME_UPDATA_INFO    (1000)

class CMainDlg
 : public CDialogImpl<CMainDlg>
 , public CMessageFilter
 , public IStreamCapNotfiy
 , public IRtmpClientListen
{
private:

 //
 //视频数据
 //
 CTVCritSec   m_lockBufVideo;   //CTVAutoLock lockBufVideo(&m_lockBufVideo);
 CBuffer    m_bufVideo;    //视频数据
 int     m_iVideoWidth;
 int     m_iVideoHeight;

 bool    m_bHaveVideo;   //有新的视频数据,用于描画


 //
 //消息显示
 //
 CListboxInsertString m_listboxInsertStr;
 CTVCritSec   m_lockQueueStr;   //CTVAutoLock lockQueueStr(&m_lockQueueStr);
 queue<wstring>  m_queueStr;    //字符串消息队列,用于消息的显示


 //
 //音视频参数
 //
 WAVEFORMATEX  m_audioFormat;
 BITMAPINFO   m_videoFormat;
 UINT    m_uFramePerSec;
 wstring    m_strVideoDevName;
 wstring    m_strAudioDevName;
 DWORD    m_dwVideoEncoderBitRate;
 DWORD    m_dwAudioEncoderBitRate;
 double    m_dVolum;
 bool    m_bMute;
 wstring    m_strCmdshow;

 IStreamCap*   m_pStreamCap;

 

 //
 //虚拟视频数据发送端
 //
 IVideoSourceServer* m_videoSourceServer;

 

 

 //
 //fms连接
 //
 //PCONN_INFO   m_rtmpConInfo;
 CTVCritSec   m_lockFlash;
 string    m_strFmsAddr;    //fms地址


 //
 //是否已经启动
 //
 bool    m_bStart;


 //
 //控件变量
 //
 CComboBox   m_comboxVideoDev;   //视频设备
 CComboBox   m_comboxAudioDev;   //音频设备
 CTrackBarCtrl  m_trackBarVolum;   //音量

 //
 //信息显示
 //
 int     m_iAudioAvgBitrate;
 int     m_iCountPerSecAudio;
 int     m_iVideoAvgBitrate;
 int     m_iCountPerSecVideo;
 bool    m_bNeedUpdataInfoShow;


 //
 //时间戳计算
 //
 __int64    m_rtLastVideoSampleTime;
 __int64    m_rtLastAudioSampleTime;

 bool    m_bFirstSample;     //是否是第一帧数据

public:
 enum { IDD = IDD_DIALOG };

 CMainDlg(
  wstring &strCmdshow,
  int iVideoWidth,
  int iVideoHeight,
  int iFps,
  int iVideoBitrate,
  int iAudioBitrate,
  wstring &strVideoDev,
  wstring &strAudioDev,
  int iAudioSampleRate,
  wstring &strRtmpAddr
  )
  : m_bHaveVideo(false)
  , m_iVideoWidth(0)
  , m_iVideoHeight(0)
  , m_pStreamCap(NULL)
  , m_uFramePerSec(iFps)
  , m_strVideoDevName(strVideoDev)
  , m_strAudioDevName(strAudioDev)
  , m_dwVideoEncoderBitRate(iVideoBitrate)
  , m_dwAudioEncoderBitRate(iAudioBitrate)
  , m_dVolum(100.0)
  , m_bMute(false)
  , m_videoSourceServer( CreateVideoSourceServer() )
  , m_strFmsAddr( "" )
  //, m_rtmpConInfo(NULL)
  , m_bStart(false)
  , m_iAudioAvgBitrate(0)
  , m_iCountPerSecAudio(0)
  , m_iVideoAvgBitrate(0)
  , m_iCountPerSecVideo(0)
  , m_bNeedUpdataInfoShow(false)
  , m_strCmdshow(strCmdshow)
  , m_rtLastVideoSampleTime(0)
  , m_rtLastAudioSampleTime(0)
  , m_bFirstSample(true)
 {
  SetBitmapInfo(m_videoFormat, iVideoWidth, iVideoHeight, 24);
  SetWaveFormat(m_audioFormat, iAudioSampleRate);

  USES_CONVERSION;
  m_strFmsAddr = W2A( strRtmpAddr.c_str() );

//   CLogTool::m_sAppName="MediaCapAssistForFlash";
//   CLogTool::WriteLog(LOG_LEVEL_DEBUGGING,__FILE__,__LINE__,"MediaCapAssistForFlash start record...");
 }

 ~CMainDlg()
 {
  if (m_videoSourceServer)
  {
   m_videoSourceServer->Release();
   m_videoSourceServer = NULL;
  }
 }


 virtual BOOL PreTranslateMessage(MSG* pMsg)
 {
  return ::IsDialogMessage(m_hWnd, pMsg);
 }

 BEGIN_MSG_MAP(CMainDlg)
  MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
  MESSAGE_HANDLER(WM_TIMER, OnTimer)
  MESSAGE_HANDLER(WM_PAINT, OnPaint)
  COMMAND_ID_HANDLER(IDOK, OnOK)
  COMMAND_ID_HANDLER(IDCANCEL, OnCancel)
  COMMAND_ID_HANDLER(IDC_BUTTON_START, OnStart)
  COMMAND_ID_HANDLER(IDC_BUTTON_STOP, OnStop)
  COMMAND_ID_HANDLER(IDC_CHECK_MUTE, OnMute)
  MESSAGE_HANDLER(WM_HSCROLL, OnHScroll)
 END_MSG_MAP()

 LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
 {
  USES_CONVERSION;

  // center the dialog on the screen
  CenterWindow();

  // register object for message filtering
  CMessageLoop* pLoop = _Module.GetMessageLoop();
  pLoop->AddMessageFilter(this);


  m_listboxInsertStr.SetListboxHWND( this->GetDlgItem(IDC_LIST_INFO).m_hWnd );

  this->SetTimer(TIMER_ID_DRAW_VIDEO, TIME_DRAW_VIDEO, NULL);
  this->SetTimer(TIMER_ID_PROCESS_MSG, TIME_PROCESS_MSG, NULL);
  this->SetTimer(TIMER_ID_UPDATA_INFO, TIME_UPDATA_INFO, NULL);
  this->SetTimer(TIMER_ID_CONNECT_FMS, TIME_CONNECT_FMS, NULL);


  IDeviceList* pDeviceList = CreateDeviceList(NULL);

  //
  //视频输入设备
  //
  m_comboxVideoDev.Attach( GetDlgItem(IDC_COMBO_VIDEO_INPUT_DEVICE).m_hWnd );
  vector<wstring>* pVecString = pDeviceList->GetDeviceList(DeviceCategory_VideoInput);
  for (vector<wstring>::size_type i = 0; i < pVecString->size(); i++)
  {
   m_comboxVideoDev.InsertString( m_comboxVideoDev.GetCount(), pVecString->at(i).c_str() );
  }
  this->SetDlgItemText( IDC_COMBO_VIDEO_INPUT_DEVICE, m_strVideoDevName.c_str() );

  //
  //音频输入设备
  //
  m_comboxAudioDev.Attach( GetDlgItem(IDC_COMBO_AUDIO_INPUT_DEVICE).m_hWnd );
  pVecString = pDeviceList->GetDeviceList(DeviceCategory_AudioInput);
  for (vector<wstring>::size_type i = 0; i < pVecString->size(); i++)
  {
   m_comboxAudioDev.InsertString( m_comboxAudioDev.GetCount(), pVecString->at(i).c_str() );
  }
  this->SetDlgItemText( IDC_COMBO_AUDIO_INPUT_DEVICE, m_strAudioDevName.c_str() );

  if (pDeviceList)
  {
   pDeviceList->Release();
   pDeviceList = NULL;
  }


  this->SetDlgItemInt(IDC_EDIT_AUDIO_SAMPLERATE, m_audioFormat.nSamplesPerSec);
  this->SetDlgItemInt(IDC_EDIT_VIDEO_WIDTH, m_videoFormat.bmiHeader.biWidth);
  this->SetDlgItemInt(IDC_EDIT_VIDEO_HEIGHT, m_videoFormat.bmiHeader.biHeight);
  this->SetDlgItemInt(IDC_EDIT_VIDEO_BITRATE, m_dwVideoEncoderBitRate);
  this->SetDlgItemInt(IDC_EDIT_AUDIO_BITRATE, m_dwAudioEncoderBitRate);
  this->SetDlgItemInt(IDC_EDIT_VIDEO_FPS, m_uFramePerSec);

  this->CheckDlgButton(IDC_CHECK_MUTE, m_bMute ? TRUE : FALSE);

  m_trackBarVolum.Attach( GetDlgItem(IDC_SLIDER_VOLUM).m_hWnd );
  m_trackBarVolum.SetRange(0, 100);
  m_trackBarVolum.SetPos( int(m_dVolum) );

  this->SetDlgItemText(IDC_EDIT_FMS_ADDR, A2W(m_strFmsAddr.c_str()));


  if ( m_strCmdshow == L"hide" )
  {
   this->Start();
  }
  return TRUE;
 }

 LRESULT OnOK(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
 {
  return 0;
 }

 LRESULT OnCancel(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
 {
  CloseDialog(wID);
  return 0;
 }

 void CloseDialog(int nVal)
 {
  
  

  this->KillTimer(TIMER_ID_DRAW_VIDEO);
  this->KillTimer(TIMER_ID_PROCESS_MSG);
  this->KillTimer(TIMER_ID_UPDATA_INFO);
  this->KillTimer(TIMER_ID_CONNECT_FMS);
  Sleep(1000);
  Stop();


  DestroyWindow();
  ::PostQuitMessage(nVal);
 }

 LRESULT OnStart(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
 {
  UpdataPara();
  Start();
  return 0;
 }

 LRESULT OnStop(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
 {
  Stop();
  return 0;
 }

 LRESULT OnMute(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
 {
  m_bMute = this->IsDlgButtonChecked(IDC_CHECK_MUTE) > 0;
  if (m_pStreamCap)
  {
   m_pStreamCap->SetMute(m_bMute);
  }
  return 0;
 }

 LRESULT OnHScroll(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
 {
  if ( SB_THUMBPOSITION == LOWORD(wParam) )
  {
   m_dVolum = double( m_trackBarVolum.GetPos() );
   if (m_pStreamCap)
   {
    m_pStreamCap->SetVolum(m_dVolum);
   }
  }
  return 0;
 }
 


 LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
 {
  //
  //消息处理
  //

  if (TIMER_ID_DRAW_VIDEO == wParam)
  {
   //画视频图像
   if (m_bHaveVideo)
   {
    CTVAutoLock lockBufVideo(&m_lockBufVideo);
    if (m_bufVideo.m_pBuf)
    {
     CDrawVideoGDI::DrawVideo(m_hWnd, IDC_STATIC_VIDEO, m_iVideoWidth, m_iVideoHeight, 24, m_bufVideo.m_pBuf, m_bufVideo.m_iActualDataLen);
     m_bHaveVideo = false;
    }
   }
  }
  else if ( TIMER_ID_PROCESS_MSG == wParam )
  {
   CTVAutoLock lockQueueStr(&m_lockQueueStr);
   while (m_queueStr.size() > 0)
   {
    this->m_listboxInsertStr.Insert( 0, m_queueStr.front().c_str() );
    m_queueStr.pop();
   }
  }
  else if ( TIMER_ID_CONNECT_FMS == wParam )
  {
     if (initCrtmp()==NULL)
     {
     wchar_t strData[1024] = {0};
     GetDlgItemText(IDC_EDIT_FMS_ADDR, strData, 1024);
     USES_CONVERSION;
     char *svrPath = W2A( strData );
      initCrtmp()->RegistListen(this);
      initCrtmp()->Rtmp_Connect(svrPath); 
     }

  }
  else if ( TIMER_ID_UPDATA_INFO == wParam )
  {
   if (m_bNeedUpdataInfoShow)
   {
    this->SetDlgItemText(IDC_STATIC_BITRATE_INFO, CFormatWString(L"AudioBitrate: %d, AudioCount: %d/r/nVideoBitrate: %d, VideoCount: %d",
     m_iAudioAvgBitrate, m_iCountPerSecAudio, m_iVideoAvgBitrate, m_iCountPerSecVideo) );
    m_bNeedUpdataInfoShow = false;
   }
  }

  return 0;
 }

 LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
 {
  //m_bHaveVideo = true;
  bHandled = FALSE;
  return 0;
 }

 void InsertStringToListbox(const wchar_t* pstr)
 {
  CTVAutoLock lockQueueStr(&m_lockQueueStr);
  m_queueStr.push( wstring(pstr) );
 }

 //更新参数
 void UpdataPara()
 {
  USES_CONVERSION;

  ATL::CString strDevice;
  if ( CB_ERR != m_comboxVideoDev.GetCurSel() )
  {
   m_comboxVideoDev.GetWindowText(strDevice);
   m_strVideoDevName = strDevice;
  }
  if ( CB_ERR != m_comboxAudioDev.GetCurSel() )
  {
   m_comboxAudioDev.GetWindowText(strDevice);
   m_strAudioDevName = strDevice;
  }

  UINT uWidth = this->GetDlgItemInt(IDC_EDIT_VIDEO_WIDTH);
  UINT uHeight = this->GetDlgItemInt(IDC_EDIT_VIDEO_HEIGHT);
  SetBitmapInfo(m_videoFormat, uWidth, uHeight, 24);

  UINT uSamplePerSec = this->GetDlgItemInt(IDC_EDIT_AUDIO_SAMPLERATE);
  SetWaveFormat(m_audioFormat, uSamplePerSec);

  m_dwVideoEncoderBitRate = this->GetDlgItemInt(IDC_EDIT_VIDEO_BITRATE);
  m_dwAudioEncoderBitRate = this->GetDlgItemInt(IDC_EDIT_AUDIO_BITRATE);
  m_uFramePerSec = this->GetDlgItemInt(IDC_EDIT_VIDEO_FPS);

  m_bMute = this->IsDlgButtonChecked(IDC_CHECK_MUTE) > 0;
  m_dVolum = double( m_trackBarVolum.GetPos() );

  wchar_t strAddr[1024] = {0};
  GetDlgItemText(IDC_EDIT_FMS_ADDR, strAddr, 1024);
  m_strFmsAddr = W2A( strAddr );
 }

 

public:
 void Start()
 {
  if (m_bStart)
  {
   return;
  }

 

  //
  //虚拟视频数据发送启动
  //
  if (m_videoSourceServer)
  {
   m_videoSourceServer->Start();
  }


  //
  //flash数据发送启动
  //
  {
   CTVAutoLock lockFlash(&m_lockFlash);
   wchar_t strData[1024] = {0};
   GetDlgItemText(IDC_EDIT_FMS_ADDR, strData, 1024);
   USES_CONVERSION;
   char *svrPath = W2A( strData );
   /******(2010-12-12)******************************************************************/
   /*
    更换了2个函数的位置
   */
   /******(2010-12-12)******************************************************************/

   initCrtmp()->RegistListen(this);
   initCrtmp()->Rtmp_Connect(svrPath); 
//    m_rtmpConInfo = RtmpSDK_CreateConnInfo();
//    if (m_rtmpConInfo)
//    {
//     ConnectFms();
//    }
   
   
  }


  //
  //时间
  //
  m_rtLastVideoSampleTime = 0;
  m_rtLastAudioSampleTime = 0;

  m_bFirstSample = true;


  //
  //启动捕获
  //
  wchar_t* pVideoEnc = L"ADVideo Encoder";
  wchar_t* pAudioEnc = L"ADAudio Encoder";

  char* pMediaTypeData = NULL;
  DWORD dwMediaTypeDataLen = 0;
  assert(NULL == m_pStreamCap);
  m_pStreamCap = CreateStreamCap(pMediaTypeData, dwMediaTypeDataLen, 0, this,
   m_audioFormat, m_videoFormat, m_uFramePerSec,
   const_cast<wchar_t*>(m_strAudioDevName.c_str()), const_cast<wchar_t*>(m_strVideoDevName.c_str()), //L"Kkyoo Video Source", //
   pVideoEnc, m_dwVideoEncoderBitRate,
   pAudioEnc, m_dwAudioEncoderBitRate, TRUE, m_dVolum, m_bMute, 0, 0);
  if (m_pStreamCap)
  {
   m_pStreamCap->Start();
  }

  m_bStart = true;
 }

 void Stop()
 {
  if (!m_bStart)
  {
   return;
  }

  if (m_pStreamCap)
  {
   m_pStreamCap->Stop();
   m_pStreamCap->Release();
   m_pStreamCap = NULL;
  }

  if (m_videoSourceServer)
  {
   m_videoSourceServer->Stop();
  }

  {
   CTVAutoLock lockFlash(&m_lockFlash);
   initCrtmp()->UnRegistListen(this);
   initCrtmp()->Rtmp_ReleaseConn();
   
//    if (m_rtmpConInfo)
//    {
//     RtmpSDK_ReleaseConnInfo(m_rtmpConInfo);
//     m_rtmpConInfo = NULL;
//     InsertStringToListbox( L"fms 断开连接!" );
//    }
    this->KillTimer(TIMER_ID_CONNECT_FMS);
  }

  m_bStart = false;
 }

//  void ConnectFms()
//  {
//   if ( 1 == RtmpSDK_Connect(m_rtmpConInfo, m_strFmsAddr.c_str()) )
//   {
//    InsertStringToListbox( L"fms连接成功!" );
//   }
//   else
//   {
//    InsertStringToListbox( L"fms连接失败!" );
//   }
//
//   if ( 1 == RtmpSDK_StreamControl(m_rtmpConInfo,StreamLIVE) )
//   {
//    InsertStringToListbox( L"fms StreamLIVE成功!" );
//   }
//   else
//   {
//    InsertStringToListbox( L"fms StreamLIVE失败!" );
//   }
//  }

 


public:
 //
 //IStreamCapNotfiy
 //
 virtual void OnStreamCapStatus(int iID, STREAMCAPSTATUS_LEVEL level, STREAMCAPSTATUS status, HRESULT errCode, WCHAR* szStatusString)
 {
  InsertStringToListbox( CFormatWString(L"StreamCap %s", szStatusString) );
 }
 virtual void OnStreamCapStart(int iID, int iFramesPerSec, int iWidth, int iHeight)
 {
  {
   InsertStringToListbox( CFormatWString(L"StreamCap 开始--帧率%d, 宽%d, 高%d", iFramesPerSec, iWidth, iHeight) );
  }
 }
 virtual void OnStreamCapStop(int iID){}
 virtual void OnStreamCapUncompressedAudioData(int iID, IMediaSample *pSample, void* pBuf, int iLen, WAVEFORMATEX* pWft){}
 virtual void OnStreamCapUncompressedVideoData(int iID, IMediaSample *pSample, void* pBuf, int iLen, int iWidth, int iHeight)
 {
  if (m_videoSourceServer)
  {
   BITMAPINFO format;
   SetBitmapInfo(format, iWidth, iHeight, 24);
   m_videoSourceServer->SetVideoFormat(format);
   m_videoSourceServer->SetVideoData(pBuf, iLen);
  }

  {
   CTVAutoLock lockBufVideo(&m_lockBufVideo);
   m_bufVideo.CheckBufSize( iLen );
   if (m_bufVideo.m_pBuf)
   {
    memcpy(m_bufVideo.m_pBuf, pBuf, iLen);
    m_bufVideo.m_iActualDataLen = iLen;
    m_iVideoWidth = iWidth;
    m_iVideoHeight = iHeight;
    m_bHaveVideo = true;
   }
  }
 }
 virtual void OnCompressedData(int iID, char* pData, unsigned int nSize)
 {
  WORD wStreamNum = 0;
  bool bDiscontinuty = false;
  bool bPreroll = false;
  bool bSyncPoint = false;
  REFERENCE_TIME cnsSampleTime = 0;
  REFERENCE_TIME cnsSampleDuration = 0;
  int iSubSeq = 0;      //当前流的包序
  unsigned int nMediaSize = 0;
  unsigned char* pMediaData = NULL;

  //
  //解包包头
  //
  bool bReadSuc = CStreamDataUnpackerUnpress::ReadPakcet(wStreamNum, bDiscontinuty, bPreroll, bSyncPoint, cnsSampleTime, cnsSampleDuration, 
   iSubSeq, nMediaSize, pMediaData, (char*)pData, (int)nSize);
  
  if (bReadSuc)
  {
   CTVAutoLock lockFlash(&m_lockFlash);
//    if (m_rtmpConInfo)
//    {
    if (m_bFirstSample)
    {
     m_rtLastVideoSampleTime = cnsSampleTime;
     m_rtLastAudioSampleTime = cnsSampleTime;
     m_bFirstSample = false;
    }


    if (AUDIO_STREAM_NUM == wStreamNum && nMediaSize > 0)
    {
     initCrtmp()->Rtmp_SendStream((char*)pMediaData, nMediaSize, AUDIO_DATA, 0);
    }

    if (VIDEO_STREAM_NUM == wStreamNum && nMediaSize > 0)
    {
     //
     //计算时间差
     //
     DWORD dwTimeStamp = 0;
     __int64 timeStamp = (cnsSampleTime - m_rtLastVideoSampleTime) / 10000;
     if (timeStamp < 0)
     {
      timeStamp = 10;
     }
     dwTimeStamp = DWORD(timeStamp);
     m_rtLastVideoSampleTime = cnsSampleTime;

     initCrtmp()->Rtmp_SendStream((char*)pMediaData, nMediaSize, VIDEO_DATA, dwTimeStamp);
    }
  // }
  }
 }
 virtual void OnStreamCapAudioStatistics(int iAudioAvgBitrate, int iCountPerSec)
 {
  m_iAudioAvgBitrate = iAudioAvgBitrate;
  m_iCountPerSecAudio = iCountPerSec;
  m_bNeedUpdataInfoShow = true;
 }
 virtual void OnStreamCapVideoStatistics(int iVideoAvgBitrate, int iCountPerSec)
 {
  m_iVideoAvgBitrate = iVideoAvgBitrate;
  m_iCountPerSecVideo = iCountPerSec;
  m_bNeedUpdataInfoShow = true;
 }
 virtual void OnStreamCapStatistics(int iAvgBitrate, int iCountPerSec){}
};

 

如上所示的一个实例

在初始化的时候LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)里面设置this->SetTimer(TIMER_ID_CONNECT_FMS, TIME_CONNECT_FMS, NULL);

以连接rtmp连接服务器为例,在这里设置了消息,在OnTimer里面有对应的消息映射,对相应的消息进行不同的消息处理,我们这里的这个消息是

else if ( TIMER_ID_CONNECT_FMS == wParam )
  {
     if (initCrtmp()==NULL)
     {
     wchar_t strData[1024] = {0};
     GetDlgItemText(IDC_EDIT_FMS_ADDR, strData, 1024);
     USES_CONVERSION;
     char *svrPath = W2A( strData );
      initCrtmp()->RegistListen(this);
      initCrtmp()->Rtmp_Connect(svrPath); 
     }

  }

在OnTimer中每隔1000毫秒的话执行一次

在这里的意思是假如连接断开的话重新连接服务器

最后在停止Stop或者void CloseDialog(int nVal)中将 this->KillTimer(TIMER_ID_CONNECT_FMS);kill这条消息。