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

📄 tryshotdlg.cpp

📁 手掌采集程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// tryshotDlg.cpp : implementation file
//

#include "stdafx.h"
#include "tryshot.h"
#include "tryshotDlg.h"
#include "D:\Program Files\DXSDK\Samples\C++\DirectShow\common\dshowutil.cpp"
//#include "D:\Program Files\DXSDK_90\Samples\C++\DirectShow\common\dshowutil.cpp"


#include "PersonalInfoDlg.h"



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




// Constants
#define WM_CAPTURE_BITMAP   WM_APP + 1

/*
 * Dib文件头标志(字符串"BM",写DIB时用到该常数)
 */
#define DIB_HEADER_MARKER   ((WORD) ('M' << 8) | 'B')




// Global data
BOOL g_bOneShot=FALSE;
HWND g_hwnd=0;



// Structures
typedef struct _callbackinfo 
{
    double dblSampleTime;
    long lBufferSize;
    BYTE *pBuffer;
    BITMAPINFOHEADER bih;

} CALLBACKINFO;

CALLBACKINFO cb={0};



// Note: this object is a SEMI-COM object, and can only be created statically.
// We use this little semi-com object to handle the sample-grab-callback,
// since the callback must provide a COM interface. We could have had an interface
// where you provided a function-call callback, but that's really messy, so we
// did it this way. You can put anything you want into this C++ object, even
// a pointer to a CDialog. Be aware of multi-thread issues though.
//
class CSampleGrabberCB : public ISampleGrabberCB 
{
public:
    // these will get set by the main thread below. We need to
    // know this in order to write out the bmp
    long lWidth;
    long lHeight;
    CTryshotDlg * pOwner;
    TCHAR m_szCapDir[MAX_PATH]; // the directory we want to capture to
    TCHAR m_szSnappedName[MAX_PATH];
    BOOL bFileWritten;

    CSampleGrabberCB( )
    {
        pOwner = NULL;
        ZeroMemory(m_szCapDir, sizeof(m_szCapDir));
        ZeroMemory(m_szSnappedName, sizeof(m_szSnappedName));
        bFileWritten = FALSE;
    }   

    // fake out any COM ref counting
    //
    STDMETHODIMP_(ULONG) AddRef() { return 2; }
    STDMETHODIMP_(ULONG) Release() { return 1; }

    // fake out any COM QI'ing
    //
    STDMETHODIMP QueryInterface(REFIID riid, void ** ppv)
    {
        if( riid == IID_ISampleGrabberCB || riid == IID_IUnknown ) 
        {
            *ppv = (void *) static_cast<ISampleGrabberCB*> ( this );
            return NOERROR;
        }    
        return E_NOINTERFACE;
    }

    // we don't implement this interface for this example
    //
    STDMETHODIMP SampleCB( double SampleTime, IMediaSample * pSample )
    {
        return 0;
    }

    // The sample grabber is calling us back on its deliver thread.
    // This is NOT the main app thread!
    //
    //           !!!!! WARNING WARNING WARNING !!!!!
    //
    // On Windows 9x systems, you are not allowed to call most of the 
    // Windows API functions in this callback.  Why not?  Because the
    // video renderer might hold the global Win16 lock so that the video
    // surface can be locked while you copy its data.  This is not an
    // issue on Windows 2000, but is a limitation on Win95,98,98SE, and ME.
    // Calling a 16-bit legacy function could lock the system, because 
    // it would wait forever for the Win16 lock, which would be forever
    // held by the video renderer.
    //
    // As a workaround, copy the bitmap data during the callback,
    // post a message to our app, and write the data later.
    //
    STDMETHODIMP BufferCB( double dblSampleTime, BYTE * pBuffer, long lBufferSize )
    {
        // this flag will get set to true in order to take a picture
        //
        if( !g_bOneShot )
            return 0;
        if (!pBuffer)
            return E_POINTER;
		//-----当取得一个Sample后,进行动目标检测,暂时屏蔽掉后几帧的检测-------
		g_bOneShot=FALSE;//检测结束再检测下一帧
        if( cb.lBufferSize < lBufferSize )
        {
            delete [] cb.pBuffer;
            cb.pBuffer = NULL;
            cb.lBufferSize = 0;
        }
        cb.dblSampleTime = dblSampleTime;
        if (!cb.pBuffer)
        {
            cb.pBuffer = new BYTE[lBufferSize];
            cb.lBufferSize = lBufferSize;
        }
        if( !cb.pBuffer )
        {
            cb.lBufferSize = 0;
            return E_OUTOFMEMORY;
        }
        memcpy(cb.pBuffer, pBuffer, lBufferSize);
        PostMessage(g_hwnd, WM_CAPTURE_BITMAP, 0, 0L);
        return 0;
    }

    // This function will be called whenever a captured still needs to be
    // displayed in the preview window.  It is called initially within
    // CopyBitmap() to display the captured still, but it is also called
    // whenever the main dialog needs to repaint and when we transition
    // from video capture mode back into still capture mode.
    //


    // This is the implementation function that writes the captured video
    // data onto a bitmap on the user's disk.
    //



    void PlaySnapSound(void)
    {
        TCHAR szSound[MAX_PATH];
        const TCHAR szFileToPlay[] = { TEXT("\\media\\click.wav\0") };
        int nSpaceAllowed = MAX_PATH - NUMELMS(szFileToPlay);
        int nSpaceUsed=0;
        
        nSpaceUsed = GetWindowsDirectory(szSound, nSpaceAllowed);
        if (nSpaceUsed && nSpaceUsed <= nSpaceAllowed)
        {
            _tcscat( szSound, szFileToPlay );
            sndPlaySound(szSound, SND_ASYNC);
        }           
    }

	BOOL IsHandMoving( double dblSampleTime, BYTE * pBuffer, long lBufferSize, BYTE * pBback)
	{
		double kLevel=7050240;//640*480*3=921600_20%有色度变化255的15%||30%认为有动目标28200960
        //        18432000      14100480    7050240
		BOOL bflg=FALSE;
		double dtemp=0;
		for (int nIndex=0;nIndex<lBufferSize;nIndex++)//-----比较当前照片pBuffer和背景照片pBback上是否有运动目标,且目标足够大------
		{
			dtemp=dtemp+(double)abs((double)*(pBuffer+nIndex)-(double)*(pBback+nIndex));//_______存在符合条件的动目标就返回TRUE________
		}
		if (dtemp>kLevel)
		{
			bflg=TRUE;//超过门限,表明有动目标
		}
		return bflg;
	}
};


//////////////////////////////////////////////////////////////////
//
// This semi-COM object will receive sample callbacks for us
//
//////////////////////////////////////////////////////////////////

CSampleGrabberCB mCB;



/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTryshotDlg dialog



CTryshotDlg::CTryshotDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CTryshotDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CTryshotDlg)
	m_CaptureNumb = 3;
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	mFilterGraph=NULL;
	m_naccumul=0;
	lWidth=640;
	lHeight=480;
	m_pBmem=new BYTE[lWidth*lHeight*3*m_CaptureNumb];//RGB
	m_pBback=new BYTE[lWidth*lHeight*3];//存放背景照片
	m_pTemp=new BYTE[lWidth*lHeight*3];//存放临时照片

	pnCtrlVal=new BYTE[8];
	pnCtrlVal[0]=0;
	pnCtrlVal[1]=8;
	pnCtrlVal[2]=4;
	pnCtrlVal[3]=12;
	pnCtrlVal[4]=2;
	pnCtrlVal[5]=10;
	pnCtrlVal[6]=6;
	pnCtrlVal[7]=14;
	//闪光等控制选择
	
	
	b_havesettingPersonalInformation=FALSE;
	b_TestLightFlag=FALSE;
}

void CTryshotDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CTryshotDlg)
	DDX_Control(pDX, IDC_VW4, m_V4);
	DDX_Control(pDX, IDC_VW3, m_V3);
	DDX_Control(pDX, IDC_VW2, m_V2);
	DDX_Control(pDX, IDC_VW1, m_V1);
	DDX_Control(pDX,IDC_VW0,mVideoWindow);
	DDX_Text(pDX, IDC_PHOTO_NUMB, m_CaptureNumb);
	DDV_MinMaxInt(pDX, m_CaptureNumb, 1, 4);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CTryshotDlg, CDialog)
	//{{AFX_MSG_MAP(CTryshotDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_SETPHOTONUMB, OnSetphotonumb)
	ON_BN_CLICKED(IDC_EMEND, OnEmend)
	ON_BN_CLICKED(IDC_LOAD_PIC, OnLoadPic)
	ON_BN_CLICKED(IDC_BUTTON_INPUTNAME, OnButtonInputname)
	ON_BN_CLICKED(IDC_BUTTON_TESTLIGHT, OnButtonTestlight)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTryshotDlg message handlers

BOOL CTryshotDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	CreateGraph();
	mVideoWindow.ModifyStyle(0,WS_CLIPCHILDREN);
	m_V1.ModifyStyle(0,WS_CLIPCHILDREN);
	m_V2.ModifyStyle(0,WS_CLIPCHILDREN);
	m_V3.ModifyStyle(0,WS_CLIPCHILDREN);
	m_V4.ModifyStyle(0,WS_CLIPCHILDREN);
	//--------设定按钮的状态---------
	GetDlgItem(IDOK)->EnableWindow(FALSE);
	GetDlgItem(IDC_PHOTO_NUMB)->EnableWindow(FALSE);
	GetDlgItem(IDC_SETPHOTONUMB)->EnableWindow(FALSE);
	GetDlgItem(IDC_EMEND)->EnableWindow(FALSE);
	g_hwnd=GetSafeHwnd();
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CTryshotDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CTryshotDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
		refreshsubwnd();
	}

⌨️ 快捷键说明

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