1)在OnInitDialog()里启动了2个OnTimer:
SetTimer(1,500,NULL);//开启音频播放
SetTimer(5,1000,NULL);//重绘状态图
2)CActiveMovie3相关部分如下:
switch(nIDEvent)
{
case 1://处理音频
  double CurPos;
  CurPos=m_ActiveMovie.GetCurrentPosition(); //获得播放位置
  if(CurPos==0&&!list.empty()&&audio_lock==false)
  {
    audio_lock=true;//上锁
    //m_ActiveMovie.SetAutoStart(1);//设置自动播放
    items_value[0]=list.front();
    m_ActiveMovie.SetFileName(list.front());//设置文件
    m_ActiveMovie.SetAutoStart(1);//设置自动播放
    //m_ActiveMovie.Run(); 
    list.pop();//list是方路径字符串的队列
    audio_lock=false;//解锁
    }
break;
3)SetDestFullAudio(i);//设置播放队列
void CBPJZhukongDlg::SetDestFullAudio(int lattic)
{
  switch(lattic)
  {
  case 1:
    list.push(audi_0);//audi_0是一个文件路径
    list.push(audi_1);
    list.push(lattic_full_audio);
    break;
    ......
    }
}
4)SetTimer(6,100,NULL);//用于启动队列进栈,其中相关内容如下:
for(i=1;i<=MAX_LATTIC;i++)//扫描格口情况
{
  if(port[i]==1)//如果格口满
  {
//SetDestFullAudio(i);//设置播放队列
  lattic_status[i]=2;//设置当前格口状态为满
  }
}
5)通过4)里面的内容给队列进栈,然后2) 放音频,为什么有时候会跳掉1,2个音频直接播最后一个;时候从当中的音频开始播,不播第一个;偶尔一两次会正常播放呢?是OnTimer的刷新时间太短了吗?该怎么该?还有m_ActiveMovie.Run()要不要?貌似不写也能播声音
6)SetTimer(5,1000,NULL)相关部分如下:
case 5://重绘状态图
  switch(start_stop_status)
  {
  case 0://主机停止
    ShowBmp(red_bmp,IDC_RUNSTATUS);
    break;
  case 1://主机启动
    ShowBmp(green_bmp,IDC_RUNSTATUS);
    break;
  default:
    break;
  }
  for(i=1;i<=MAX_LATTIC;i++)//扫描格口状态
    ShowLatticStatus(i);
break;
7)ShowLatticStatus定义如下:
ShowLatticStatus(int lattic)
{
  switch(lattic)
  {
  case 1:
    switch(lattic_status[lattic])
    {
    case 1://正常状态
      ShowBmp(green_bmp,IDC_LATTIC01STATUS);
     break;
    case 2://格口已满
    ShowBmp(yellow_bmp,IDC_LATTIC01STATUS);
     break;
    case 3://格口已锁
    ShowBmp(red_bmp,IDC_LATTIC01STATUS);
    break;
   default:
    break;
    }
  break;
  ......
}
8)ShowBmp用于显示位图,nID为Picture型控件的ID
void CBPJZhukongDlg::ShowBmp(CString path,int nID)
{
  //将关键图显示出来
  hwnd = GetDlgItem(nID);
  hDesDC = hwnd->GetDC()->m_hDC;
  hSrcDC = CreateCompatibleDC(hDesDC);
  hBitmap=(HBITMAP)LoadImage(AfxGetInstanceHandle(),path,IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION);
  GetObject(hBitmap, sizeof BITMAP, &bm);
  SelectObject(hSrcDC, hBitmap);
  hwnd->GetClientRect(&rect);
  ::SetStretchBltMode(hDesDC,COLORONCOLOR);       
  ::StretchBlt(hDesDC, rect.left, rect.top, rect.right, rect.bottom, hSrcDC, 0, 0, bm.bmWidth, bm.bmHeight,+SRCCOPY);
}
说明:部分变量定义如下,是类域:
//以下变量为显示状态图片时所需变量
BITMAP bm;
RECT rect;
CWnd * hwnd;
HDC hDesDC;
HDC hSrcDC;
HBITMAP hBitmap;
9)为什么程序运行久了内存会出错导致程序崩溃(就是问我要不要发送错误报告的那种)?如果我OnTimer刷新设长点,只是晚点崩溃,但早晚还要崩溃。什么原因产生这个问题的呢?要怎么才能避免呢?会不会是什么资源没释放导致的呢?补充:队列定义如下:
#include   <queue>
using namespace std; 
typedef   queue<char*>   CHARQUEUE;
CHARQUEUE list;

解决方案 »

  1.   

    估计是有些费时io操作造成定时器重入,进一步导致对队列 list 的操作不同步而崩溃的,注意队列的保护和定时不同步时的处理
      

  2.   

    但为什么不是马上崩溃,而是要过短时间呢?因为定时器太多了吗?如果我每过段时间把这些定时器关掉,再果断时间再开定时器,会不会减少定时器启动的数量,从而避免长时间运行后的崩溃?又或者我给每个定时间加锁(类似多线程同步锁那样)对这些崩溃有没有效果呢?还有声音的播放的问题是不是也因为同时出栈吗?可我已经加锁了呀!难道说锁要直接加在第一层的switch上?
      

  3.   

    主要是用定时器以及在定时器里处理 m_ActiveMovie,建议你先用 Button 试试
      

  4.   

    用Button是可以的,我试过。但我一定要放定时器里。例外,我调试发现,是这段出了问题导致程序崩溃的:
    hwnd = GetDlgItem(nID);
    hDesDC = hwnd->GetDC()->m_hDC;//就是到这句出了问题,貌似内存泄露
    hSrcDC = CreateCompatibleDC(hDesDC);
    要怎么办呢?增加异常处理吗?怎么加啊?