📄 mainfrm.cpp
字号:
/*!
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(LONG lCount)
{
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_wndView.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);
}
}
}
}
}
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.
*/
void CMainFrame::OnGrabStop()
{
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" )
}
/*!
Called if the #GrabThreadProc receives a #NotifyQuit message. This means that the command queue is
empty now and everything can be cleaned up.
*/
afx_msg LRESULT CMainFrame::OnGrabStopped(WPARAM wParam, LPARAM lParam)
{
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
// Cancel pending I/O requests.
// This is optional since closing the driver will cancel pending requests automatically
m_Bcam.Cancel();
// Release bandwidth, isoch channels and isoch transfer contexts
// This is optional since closing the driver will trigger this automatically.
// Warning! Calling FreeResources is not allowed, if there are still pending I/O requests,
// so call Cancel() first
m_Bcam.FreeResources();
// 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_wndStatusBar.SetPaneText(ID_FPS_PANE, "");
}
CATCH_MSGBOX( "CMainFrame::OnGrabStopped" )
return 0;
}
/*!
Called if an error occurred in the #GrabThreadProc. Shows an error message box.
*/
afx_msg LRESULT CMainFrame::OnError(WPARAM wParam, LPARAM lParam)
{
// 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
*/
void CMainFrame::OnSysCommand(UINT nID, LPARAM lParam)
{
if(nID == 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
}
}
CFrameWnd::OnSysCommand(nID, lParam);
}
void CMainFrame::OnFileNew()
{
if((bool)m_wndView.m_ptrBitmap)
m_wndView.ReleaseBitmap();
}
void CMainFrame::OnFileOpen()
{
CFileDialog dlg(TRUE, _T("bmp"), NULL, 0, _T("Bitmap Files (*.bmp)|*.bmp|All Files (*.*)|*.*||"), this);
if(dlg.DoModal() == IDOK)
{
try
{
CDibPtr ptrBitmap;
ptrBitmap.LoadBMP(dlg.GetPathName());
m_wndView.SetBitmap(ptrBitmap);
}
CATCH_MSGBOX( "CMainFrame::OnFileOpen" )
}
}
void CMainFrame::OnFileSave()
{
if(!m_wndView.m_ptrBitmap)
return;
CFileDialog dlg(FALSE, _T("bmp"), _T("Temp.bmp"), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("Bitmap Files (*.bmp)|*.bmp|All Files (*.*)|*.*||"), this);
if(dlg.DoModal() == IDOK)
{
try
{
m_wndView.m_ptrBitmap->StoreBMP(dlg.GetPathName());
}
CATCH_MSGBOX( "CMainFrame::OnFileSave" )
}
}
void CMainFrame::OnAppExit()
{
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);
}
void CMainFrame::OnEditCopy()
{
try
{
if(!m_LiveGrabbing && (bool)m_wndView.m_ptrBitmap)
{
m_wndView.m_ptrBitmap->CopyToClipboard();
}
}
CATCH_MSGBOX( "CMainFrame::OnEditCopy" )
}
void CMainFrame::OnUpdateFileSave(CCmdUI* pCmdUI)
{
pCmdUI->Enable( !m_LiveGrabbing && (bool)m_wndView.m_ptrBitmap);
}
void CMainFrame::OnUpdateFileNew(CCmdUI* pCmdUI)
{
pCmdUI->Enable( !m_LiveGrabbing );
}
void CMainFrame::OnUpdateFileOpen(CCmdUI* pCmdUI)
{
pCmdUI->Enable( !m_LiveGrabbing );
}
void CMainFrame::OnUpdateGrabLive(CCmdUI* pCmdUI)
{
pCmdUI->Enable( !m_LiveGrabbing );
}
//------------------------------------------------------------------------------
// void CMainFrame::OnUpdateGrabStop(CCmdUI* pCmdUI)
// Author:
// Date: 29.08.2002
//------------------------------------------------------------------------------
/**
* <type function description here>
*
* \param pCmdUI
*/
//------------------------------------------------------------------------------
void CMainFrame::OnUpdateGrabStop(CCmdUI* pCmdUI)
{
pCmdUI->Enable( m_LiveGrabbing );
}
//------------------------------------------------------------------------------
// void CMainFrame::OnUpdateEditCopy(CCmdUI* pCmdUI)
// Author:
// Date: 29.08.2002
//------------------------------------------------------------------------------
/**
* <type function description here>
*
* \param pCmdUI
*/
//------------------------------------------------------------------------------
void CMainFrame::OnUpdateEditCopy(CCmdUI* pCmdUI)
{
pCmdUI->Enable( !m_LiveGrabbing && (bool)m_wndView.m_ptrBitmap);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -