⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mainframe.cpp

📁 BCAM 1394 Driver
💻 CPP
📖 第 1 页 / 共 2 页
字号:
            }
            
            // Store the image to the stream
            hr = AVIStreamWrite(hVideoStream,       // stream pointer
              RunningIndex,                           // time of this frame
              1,                              // number to write
              pDst, // pointer to data
              This->m_ptrBitmaps[BufferIndex]->GetTotalPixelBytes(),// size of this frame
              AVIIF_KEYFRAME,                  // flags....
              NULL,
              NULL);
            ++RunningIndex;
            
            if (hr != AVIERR_OK) 
              throw BcamException(hr, "CMainFrame::GrabThreadProc");
            
            if(STORE_TEXT_STREAM)
            {
              SYSTEMTIME SystemTime;
              GetLocalTime(&SystemTime);
              CString Buffer;
              Buffer.Format("%02d.%02d.%04d  %02d:%02d:%02d.%04d",
                SystemTime.wDay, SystemTime.wMonth, SystemTime.wYear,
                SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond, SystemTime.wMilliseconds);
              
              // Store some tect comments to the image
              hr = AVIStreamWrite(hTextStream,
                RunningIndex,
                1,
                (void*)(LPCSTR)Buffer,
                Buffer.GetLength() + 1,
                RunningIndex % (DELTA_FRAMES_PER_KEY_FRAME + 1) == 0 ? AVIIF_KEYFRAME : 0,
                NULL,
                NULL);
              if (hr != AVIERR_OK)
                throw BcamException(hr, "CMainFrame::GrabThreadProc");
            }
          }
          else if(RunningIndex == MAX_NUM_FRAMES)
          {
            ::MessageBox(This->m_hWnd, "Capture stopped after MAX_NUM_FRAMES", "StoreAVI", MB_ICONINFORMATION + MB_OK);
            
            // Make sure this messagebox is shown only once
            ++RunningIndex;
            
            // Press the stop button
            This->PostMessage(WM_COMMAND, ID_GRAB_STOP, NULL ); 
          }
          
          // Notfy the GDI thread that the buffer with the BufferIndex has been grabbed
          This->PostMessage(WM_GRAB_FINISHED, *(WPARAM*)&BufferIndex, *(LPARAM*)&ElapsedTime ); 
        }
        break;
        
        // This means the queue is empty now ==> suicide
      case NotifyQuit:
        // Tell the GdiThread to clean up
        This->PostMessage(WM_GRAB_STOPPED, 0, 0 ); 
        
        // Finish thread
        goto Cleanup;
        
        // Don't care about other function codes like AsyncSetGain etc.
      default:
        ErrorCode = 1;
        break;
      }
                }
        }
        catch (BcamException&  e )
        {
          // Forward error to GdiThread for display
          BcamException* pE = new BcamException(e);
          This->PostMessage(WM_ERROR, (unsigned int)pE, 0); 
          return e.Error();
        }
        catch (...)
        {
          // Forward error to GdiThread for display
          BcamException* pE = new BcamException(DISP_E_EXCEPTION, "CMainFrame::GrabThreadProc");
          This->PostMessage(WM_ERROR, (unsigned int)pE, 0); 
          return DISP_E_EXCEPTION;
        }
        
        
Cleanup:
        
        if (hVideoStream)
          AVIStreamClose(hVideoStream);
        
        if (hTextStream )
          AVIStreamClose(hTextStream );
        
        if (hAviFile)
          AVIFileClose(hAviFile);
        
        // Close operating support for AVI files
        AVIFileExit();
        CoUninitialize();
        
        return 0;
}

/*!
Called if the #GrabThreadProc receives a finished grab command. The wParam includes the buffer's index.
Enqueues the buffer's index to the #m_BufferQueue. The BufferQueue will be emplied by #OnIdle.
*/
LRESULT CMainFrame::OnGrabFinished(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
  try
  {
    // store the index of the grabbed buffer in the buffer queue
    m_BufferQueue.push(*(unsigned int*)&wParam);
    
    // Update framerate statistics
    float ElapsedTime = *((float*)&lParam);
    if(ElapsedTime > FLT_EPSILON || ElapsedTime < -FLT_EPSILON)
      m_Fps.Add(1.0 / ElapsedTime);
    
    // Show framerate
    CString Buffer;
    Buffer.Format("%3.1f fps", m_Fps.Avg());
    m_StatusBar.SetPaneText(ID_FPS_PANE, Buffer);
    
    // Show framecounter
    Buffer.Format("%lu", m_FrameCounter);
    m_StatusBar.SetPaneText(ID_FRAME_COUNTER_PANE, Buffer);
    // increase framecounter
    m_FrameCounter++;
    
  }
  CATCH_MSGBOX( "CMainFrame::OnGrabFinished" )            
    
    return 0;
}

/*!
Called each time all messages in the message queue of the GUI thread are processed and
no more messages are waiting.
- If the #m_BufferQueue contains buffer indices these are removes. For each buffer 
a new grab command is enqueued. When the grab commands are finished they turn up in 
the #GrabThreadProc. The most recent buffer is put to m_view for display.
- Updates the user interface's enable stati.
*/
BOOL CMainFrame::OnIdle()
{
  try
  {
    // If the grab is to be stopped, don't enqueue buffers any more
    if(m_LiveGrabbing)
    {
      
      // For all buffer which might have been pushed to the queue by OnGrabFinished
      while(0 < m_BufferQueue.size())
      {
        // Get the buffer's index from the queue
        unsigned int BufferIndex = m_BufferQueue.front();
        m_BufferQueue.pop();
        
        // If more than one buffer is in the queue display only the most recent
        if(0 < m_BufferQueue.size() )
        { 
          // Enqueue a new Grab command 
          m_Bcam.GrabImageAsync(
            (char*)m_ptrBitmaps[BufferIndex]->GetPixels(), 
            m_ptrBitmaps[BufferIndex]->GetTotalPixelBytes(), 
            (void*)BufferIndex,
            USE_ONESHOT);  
        }
        else 
        {
          // If the image is monochrome the most recent buffer is hold
          // by BitmapView; if the image is Bayer the SetBitmap function
          // will do a RGB copy so the buffer can be enqueued again
          // immediately
          if(!m_IsBayerImage)
          {
            // Enqueue the buffer currently being displayed
            if(m_DisplayedBufferIndex != -1)
            {
              // Enqueue a new Grab command 
              m_Bcam.GrabImageAsync(
                (char*)m_ptrBitmaps[m_DisplayedBufferIndex]->GetPixels(), 
                m_ptrBitmaps[m_DisplayedBufferIndex]->GetTotalPixelBytes(), 
                (void*)BufferIndex,
                USE_ONESHOT);  
            }
            
            // Remeber which buffer is now displayed
            m_DisplayedBufferIndex = BufferIndex;
          }
          
          // Update View
          m_view.SetBitmap(m_ptrBitmaps[BufferIndex], m_IsBayerImage);
          
          // see comment above
          if(m_IsBayerImage)
          {
            // Enqueue a new Grab command 
            m_Bcam.GrabImageAsync(
              (char*)m_ptrBitmaps[BufferIndex]->GetPixels(), 
              m_ptrBitmaps[BufferIndex]->GetTotalPixelBytes(), 
              (void*)BufferIndex,
              USE_ONESHOT);  
          }
          
        }
      }
    }
    
    // Update the user interface
    UpdateUI();
  }
  CATCH_MSGBOX( "CMainFrame::OnIdle" ) 
    
    return FALSE;
}

/*!
Called if the user wants the live grab to stop. Enqueues a #NotifyQuit message to the grab
queue. Sets the #m_LiveGrabbing flag to false to prevent new grab commands from being enqueued.
When all commands currently being in the queue are finished the NotifyQuit message will turn up 
in the #GrabThreadProc.
*/
LRESULT CMainFrame::OnGrabStop(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
  try
  {
    // This will prevent new images from being enqueued
    m_LiveGrabbing = false;
    
    // Enqueue a "clean-up" message which will show up after all images being currently
    // in the queue have been received
    m_Bcam.Notify(NotifyQuit, NULL);
  }
  CATCH_MSGBOX( "CMainFrame::OnGrabStop" )        
    
    return 0;
}

/*!
Called if the #GrabThreadProc receives a #NotifyQuit message. This means that the command queue is
empty now and everything can be cleaned up.
*/
LRESULT CMainFrame::OnGrabStopped(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
  try
  {
    // Clean up queue
    while(0 < m_BufferQueue.size())
      m_BufferQueue.pop();
    
    // forget about the displayed buffer
    m_DisplayedBufferIndex = -1;
    
    // switch off camera (in case we're using ContinuousShot)
    if(!USE_ONESHOT)
      m_Bcam.ContinuousShot = false;
    
    // shutdown thread
    m_GrabThread.Release();  // this waits for the thread to die
    
    // Release bandwidth, isoch channels and isoch transfer contexts 
    // This is optional since closing the driver will trigger this automatically
    m_Bcam.Close();
    
    // Close driver 
    m_Bcam.Close();
    
    // We could take away the Bitmap from the view
    //but since it's reference counted we leavi ti there for display
    //m_view.SetBitmap(NULL);
    
    // Delete bitmaps
    for(int i=0; i<NUM_BUFFERS; ++i)
      m_ptrBitmaps[i].Release();
    
    // Reset frame rate display
    m_Fps.Reset();
    m_StatusBar.SetPaneText(ID_FPS_PANE, "");
    
  }
  CATCH_MSGBOX( "CMainFrame::OnGrabStopped" )     
    
    return 0;
}


/*!
Called if an error occurred in the #GrabThreadProc. Shows an error message box.
*/
LRESULT CMainFrame::OnError(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
  // Show the error message coming from another thread
  BcamException* pE = (BcamException*)wParam;
  CString Buffer, B;
  Buffer += (B.Format("Exception 0x%X occurred\n", pE->Error() ), B);
  Buffer += (B.Format("Message = %s\n", pE->Description() ), B);
  Buffer += (B.Format("Context = %s\n", pE->Context()), B);
  MessageBox(Buffer, _T("CMainFrame::OnError"), MB_OK | MB_ICONEXCLAMATION);
  
  delete pE;
  
  return 0;
}


/*!
Makes sure the application terminates cleanly if closed via the system menu
*/
LRESULT CMainFrame::OnSysCommand(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
{
  if(wParam == SC_CLOSE)
  {
    if(m_LiveGrabbing)
    {
      
      // Enqueue a "clean-up" message which will show up after all images being currently
      // in the queue have been received
      m_Bcam.Notify(NotifyQuit, NULL);
      
      // Wait until the GrabThread died
      ::WaitForSingleObject((HANDLE)m_GrabThread,INFINITE);
      
      // The rest will clean up itselfe via the destructors
    }
    
  }
  
  bHandled = false;
  
  return 0;
}

LRESULT CMainFrame::OnFileNew(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
  if((bool)m_view.m_ptrBitmap)
    m_view.ReleaseBitmap();
  
  return 0;
}


LRESULT CMainFrame::OnFileOpen(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
  CFileDialog dlg(TRUE, _T("bmp"), NULL, 0, _T("Bitmap Files (*.bmp)\0*.bmp\0All Files (*.*)\0*.*\0"), m_hWnd);
  if(dlg.DoModal() == IDOK)
  {
    try
    {
      CDibPtr ptrBitmap;
      ptrBitmap.LoadBMP(dlg.m_szFileName);
      m_view.SetBitmap(ptrBitmap);
    }
    CATCH_MSGBOX( "CMainFrame::OnFileOpen" )        
  }
  
  return 0;
}

LRESULT CMainFrame::OnFileSave(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
  if(!m_view.m_ptrBitmap)
    return 0;
  
  CFileDialog dlg(FALSE, _T("bmp"), _T("Temp.bmp"), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("Bitmap Files (*.bmp)\0*.bmp\0All Files (*.*)\0*.*\0"), m_hWnd);
  if(dlg.DoModal() == IDOK)
  {
    try
    {
      m_view.m_ptrBitmap->StoreBMP(dlg.m_szFileName);
    }
    CATCH_MSGBOX( "CMainFrame::OnFileSave" )        
  }
  
  return 0;
}

LRESULT CMainFrame::OnFileExit(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
  try
  {
    if(m_LiveGrabbing)
    {
      
      // Enqueue a "clean-up" message which will show up after all images being currently
      // in the queue have been received
      m_Bcam.Notify(NotifyQuit, NULL);
      
      // Wait until the GrabThread died
      ::WaitForSingleObject((HANDLE)m_GrabThread,INFINITE);
      
      // The rest will clean up itselfe via the destructors
    }
  }
  CATCH_MSGBOX( "CMainFrame::OnFileExit" )
    
    PostMessage(WM_CLOSE);
  
  return 0;
}

LRESULT CMainFrame::OnEditCopy(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
  try
  {
    if(!m_LiveGrabbing && (bool)m_view.m_ptrBitmap)
    {
      m_view.m_ptrBitmap->CopyToClipboard();
    }
  }
  CATCH_MSGBOX( "CMainFrame::OnEditCopy" )
    
    return 0;
}

void CMainFrame::UpdateUI()
{
  // update UI elements
  UIEnable(ID_FILE_NEW, !m_LiveGrabbing);
  UIEnable(ID_FILE_OPEN, !m_LiveGrabbing);
  UIEnable(ID_FILE_SAVE, !m_LiveGrabbing && (bool)m_view.m_ptrBitmap);
  UIEnable(ID_GRAB_LIVE, !m_LiveGrabbing);
  UIEnable(ID_GRAB_STOP, m_LiveGrabbing);
  UIEnable(ID_EDIT_COPY, !m_LiveGrabbing && (bool)m_view.m_ptrBitmap);
  
  // These functions are not yet implemented so they have to be disabled always
  UIEnable(ID_FILE_PRINT, false);
  UIEnable(ID_FILE_PRINT_PREVIEW, false);
  UIEnable(ID_FILE_PRINT_SETUP, false);
  
  UIUpdateToolBar();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -