opencv開發之MFC的.SetWindowTextA() + OnTimer(UINT_PTR nIDEvent) +cvNamedWindow 在MFC上顯示
前述:本人做的是OpenCV的人臉識別專案,利用MFC做的使用者圖形介面,針對專案過程中遇到的問題和解決方法,在此予以分享、記錄。
編譯環境:Windows 10 pro + Visual Studio 2013 +OpenCV2.4.9
一、BUG之 .SetWindowTextA
問題描述:
void CFACEDlg::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此新增訊息處理程式程式碼和/或呼叫預設值
TEXT_NAME.SetWindowTextA(face.people[face.predictedLabel].name);
CDialogEx ::OnTimer(nIDEvent);
}
想要在Static Text 控制元件(控制元件ID:IDC_NAME,變數名:TEXT_NAME)上實時顯示識別出的人臉對應的人員姓名,然而在使用TEXT_NAME.SetWindowTextA(/此處為使用者人員名稱變數/)顯示文字時,編譯器提示:沒有SetWindowTextA()這個函式(->原話其實不是這樣的,不過大概就是這個意思)!
1).首先在專案屬性裡做以下修改
修改 字符集 為 多位元組字符集
2)由於本人使用的是VS2013,其對MFC的支援缺少 MFC MBCS Library 官方下載地址
二、BUG之 OnTimer(UINT_PTR nIDEvent)使用
1)針對Static Text 控制元件,新增OnTimer()函式。步驟如下:
然後就會出現以下程式碼:
void CFACEDlg::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此新增訊息處理程式程式碼和/或呼叫預設值
CDialogEx::OnTimer(nIDEvent);
}`
2)若想使OnTimer()函式正常使用,需要在下面這個函式裡新增SetTimer()函式,如下所示:
// CFACEDlg 訊息處理程式
BOOL CFACEDlg::OnInitDialog()
{
//編譯器自動生成的程式碼不再贅述
// TODO: 在此新增額外的初始化程式碼
SetTimer(1, 10, NULL);//此處設定,對應於OnTimer()
return TRUE; // 除非將焦點設定到控制元件,否則返回 TRUE
}
3)然後,OnTimer()內的程式碼行就會根據SetTimer(1, 10, NULL)自動重新整理定時執行。
三、BUG之 OpenCV cvNamedWindow視窗在MFC的Picture Control 控制元件顯示
在Picture Control 上嵌入cvNamedWindow視窗只需5行程式碼,需要注意的是:所有要顯示的圖片或視訊視窗,都要嚴格對應於OnInitDialog()中的cvNamedWindow視窗名稱。
具體程式碼如下:
BOOL CFACEDlg::OnInitDialog()
{
//編譯器自動生成的程式碼不再贅述
// TODO: 在此新增額外的初始化程式碼
cvNamedWindow("result", WINDOW_AUTOSIZE);
HWND hWnd = (HWND)cvGetWindowHandle("result");
HWND hParent = ::GetParent(hWnd);
::SetParent(hWnd, GetDlgItem(IDC_M_ImgShow)->m_hWnd);
::ShowWindow(hParent, SW_HIDE);
return TRUE; // 除非將焦點設定到控制元件,否則返回 TRUE
}
其中,IDC_M_ImgShow對應於MFC 裡Picture Control 控制元件的 ID,上述程式碼片中的5行程式碼中,只有cvNamedWindow(“result”, WINDOW_AUTOSIZE)中的”result”和::SetParent(hWnd, GetDlgItem(IDC_M_ImgShow)->m_hWnd)中的IDC_M_ImgShow需要根據自己的程式碼做適當更改即可使用。注意,在其他的.c檔案程式碼中要cvShowImage()時,其視窗名稱都要跟OnInitDialog()中宣告的cvNamedWindow視窗對應,這樣才可以將影象或視訊顯示在MFC Picture Control 控制元件上。