常用MFC控件基础使用
本文总结常用MFC控件使用方法,具体使用方法网上一箩筐,这里不在赘述,仅供查询常用函数,文章持续更新,阅读者不可依葫芦画瓢,还应举一反三
1.Edit Control
文本输入控件,功能是显示或设置参数,主要涉及参数类型的转换,设置显示值等
,此外还可以设置相关事件函数,如销毁焦点或值变化时执行不同的函数
CString Val;
int num=10;
GetDlgItemText(IDC,Val);//获取控件IDC值并将值传给Val
SetDlgItemText(IDC,Val);//将Val值写给控件
GetDlgItem(IDC)->SetWindowTextW(Val);//显示Val在IDC控件上
GetDlgItem(IDC)->GetWindowTextW(Val);//获取控件IDC值并将值传给Val
m_Edit.SetWindowTextW(Val);//显示Val在IDC控件上
m_Edit.GetWindowTextW(Val);//获取控件成员m_Edit中的值并将值传给Val
num=_ttoi(Val);//将值Val转换为int类型赋给num,亦有_ttof,_wtoi等指令
Val.Format(_T("%d"),num);//将值num格式化输出给Val
2.Button控件
和Edit控件一样,Button控件也可以根据场景设置响应函数,如按下、双击等,亦可以添加成员变量CButton,通过成员或者IDC设置控件状态如是否可点击:
CButton m_Btn;//事先设置了IDC_BTN的控件变量
GetDlgItem(IDC_BTN)->EnableWindow(FALSE);//控件变灰,不可点击
m_Btn.EnableWindow(TRUE);//控件变亮,可点击
3.Check控件
Check为复选框控件,是一种在二选一时分路执行程序的控件
int state = m_check.GetCheck();//判断是否勾选,并将状态传给state
m_check.SetCheck(0);//0未勾选,1为勾选,并且一般在参数是布尔变量时用0或FALSE表示非,1与TRUE表示真
m_check.SetCheck(TRUE);//真,表示勾选
if (BST_CHECKED == IsDlgButtonChecked(IDC_CHECK))
//判断Check控件是否处于BST_CHECKED状态,并根据情况执行不同code
{
//Your Code
}
else
{
//Your Code
}
4.Combo Box
下拉框控件,通过该控件可以在多个参数中快速选择所需参数,可判断参数索引值或框文本内容实现不同的code功能。组合框(ComboBox)的本质是文本框(TextBox)和列表框(ListBox)的组合。
组合框的属性方法和事件与文本框和列表框的大多数用法一致。
m_Combo.AddString(_T("1"));//自动从末行添加字符串,m_Combo为控件变量
m_Combo.InsertString(1,_T("2"));//在索引1位置显示字符2
m_Combo.DeleteString(n)//删除第n行
m_Combo.ResetContent();//可以删除列表框中所有行。
m_Combo.GetCount();//得到当前列表框中行的数量。
m_Combo.GetLBText(n,str);//获取n行内容并赋值给str
m_COmbo.FindString(n,str);//从第n行开始查找str内容,若查找到则返回所在位置
m_Combo.SetCurSel(n);//设置第n行内容为显示的内容。
int Sel=m_Combo.GetCurSel();//获取当前显示行所在索引值
5.Tree 控件
CTreeCtrl m_Tree;//控件变量
HTREEITEM Root_Sub[10];//十个一级树
HTREEITEM Root_Sub_sub[10];//十个二级树
Root_Sub[0] = m_ServerTree.InsertItem(L"这是第一个一级树", 1, 0, TVI_ROOT);//添加一个一级树
Root_Sub[1] = m_ServerTree.InsertItem(L"这是第二个一级树", 1, 0, TVI_ROOT);//添加一个一级树
Root_Sub_sub[0] = m_ServerTree.InsertItem(L"这是一级树Root_Sub[0]的第一个二级树", 1, 0, Root_Sub[0]);
Root_Sub_sub[1] = m_ServerTree.InsertItem(L"这是一级树Root_Sub[0]的第二个二级树", 1, 0, Root_Sub[0]);/
///后续以此类推不再赘述
5.快捷键设置
定义一个成员变量
HACCEL m_hAccel;
OnInitDialog()方法里进行初始化:
m_hAccel = LoadAccelerators(AfxGetResourceHandle(),
MAKEINTRESOURCE(IDR_ACCELERATOR1));
类向导增加消息函数PreTranslateMessage
BOOL CXXXDlg::PreTranslateMessage(MSG* pMsg)
{
if (WM_KEYFIRST <= pMsg->message && pMsg->message <= WM_KEYLAST)
{
HACCEL hAccel = m_hAccel;
if (hAccel && ::TranslateAccelerator(m_hWnd, hAccel, pMsg))
return TRUE;
}
return CDialog::PreTranslateMessage(pMsg);
}
6 显示缓冲区位图
1.在Dlg.h中加入
CRect rcRect;
HDC m_hDC;
byte* m_pRawBuffer;
BITMAPINFO* m_pBitmapInfo;
2.在初始化代码加入
GetDlgItem(IDC_STATIC_IMGSTREAM)->GetWindowRect(rcRect);
ScreenToClient(rcRect);
m_hDC = GetDC()->GetSafeHdc();
3.添加显示函数(以宽度为基准保持显示比例不变,需要创建位图信息)
//显示
void CXXXDlg::ShowImg()
{
double rcrate = (double)m_nDataHeight/(double)m_nDataWidth;
SetStretchBltMode(m_hDC, COLORONCOLOR);
StretchDIBits(m_hDC,
rcRect.left,
rcRect.top,
rcRect.Width(),
rcrate* rcRect.Width(),
0,
0,
m_nDataWidth,
m_nDataHeight,
m_pRawBuffer,//byte*
m_pBitmapInfo,//BITMAPINFO*
DIB_RGB_COLORS,
SRCCOPY
);
}
7 窗口自适应大小
1.XXDlg.h文件中加入
//控件Rect表
CList<CRect, CRect&> m_listRect;
2.初始化代码中加入
/// /-----------------控件大小自适应---------------------//
CRect rect;
GetWindowRect(&rect);
m_listRect.AddTail(rect);//对话框的区域
CWnd* pWnd = GetWindow(GW_CHILD);//获取子窗体
while (pWnd)
{
pWnd->GetWindowRect(rect);//子窗体的区域
m_listRect.AddTail(rect); //CList<CRect,CRect> m_listRect成员变量
pWnd = pWnd->GetNextWindow();//取下一个子窗体
}
3.添加消息函数WM_SIZE
void CXXXDlg::OnSize(UINT nType, int cx, int cy)
{
CDialogEx::OnSize(nType, cx, cy);
if (m_listRect.GetCount() > 0)
{
CRect dlgNow;
GetWindowRect(&dlgNow);
POSITION pos = m_listRect.GetHeadPosition();//第一个保存的是对话框的Rect
CRect dlgSaved;
dlgSaved = m_listRect.GetNext(pos);
ScreenToClient(dlgNow);
float x = dlgNow.Width() * 1.0 / dlgSaved.Width();//根据当前和之前保存的对话框的宽高求比例
float y = dlgNow.Height() * 1.0 / dlgSaved.Height();
ClientToScreen(dlgNow);
CRect childSaved;
CWnd* pWnd = GetWindow(GW_CHILD);
while (pWnd)
{
childSaved = m_listRect.GetNext(pos);//依次获取子窗体的Rect
childSaved.left = dlgNow.left + (childSaved.left - dlgSaved.left) * x;//根据比例调整控件上下左右距离对话框的距离
childSaved.right = dlgNow.right + (childSaved.right - dlgSaved.right) * x;
childSaved.top = dlgNow.top + (childSaved.top - dlgSaved.top) * y;
childSaved.bottom = dlgNow.bottom + (childSaved.bottom - dlgSaved.bottom) * y;
ScreenToClient(childSaved);
pWnd->MoveWindow(childSaved);
pWnd = pWnd->GetNextWindow();
}
/-------------更新图像显示区域位置----------------
GetDlgItem(IDC_STATIC_IMGSTREAM)->GetWindowRect(rcRect);
ScreenToClient(rcRect);
m_hDC = GetDC()->GetSafeHdc();
/-------------更新图像显示区域位置----------------
}
}
4.添加GetMinMaxInfo消息控制窗口最大最小值
void CXXXDlg::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
/*窗口最小值*/
if (lpMMI->ptMinTrackSize.x <= 400)
lpMMI->ptMinTrackSize.x = 400;
if (lpMMI->ptMinTrackSize.y <= 500)
lpMMI->ptMinTrackSize.y = 500;
/*窗口最大值*/
if (lpMMI->ptMaxTrackSize.x >= 1920)
lpMMI->ptMaxTrackSize.x = 1920;
if (lpMMI->ptMaxTrackSize.y >= 1080)
lpMMI->ptMaxTrackSize.y = 1080;
CDialogEx::OnGetMinMaxInfo(lpMMI);
}
8 线程快速使用
在CThreadDemoDlg.h下申明定义:
CWinThread* pThread= NULL;//线程指针
HANDLE m_hThread= NULL;//线程句柄
CRITICAL_SECTION m_ThreadLock;//线程锁
static UINT ThreadFunction(LPVOID ptr);//声明线程函数
在初始化代码OnInitDialog()中添加
创建事件并初始化关键帧
m_hThread= CreateEvent(NULL, TRUE, FALSE, NULL);
InitializeCriticalSection(&m_ThreadLock);
if (pThread== NULL)
{
pThread= AfxBeginThread(ThreadFunction, this);// 创建线程, 线程函数是静态成员函数或全局函数
}
在需要进入线程处理数据的地方添加:
EnterCriticalSection(&m_ThreadLock);//线程锁,进入临界区
//在这个线程尚未执行LeaveCriticalSection之前,其它线程碰到EnterCritialSection语句的话就会处于等待状态,以此保护共享资源的作用。
//Data Change在此处进行数据交换,交换数据后进入线程对数据做进一步处理
LeaveCriticalSection(&m_ThreadLock);//离开临界区
SetEvent(m_hThread);
线程函数:
UINT ThreadDemoDlg::ThreadFunction(LPVOID ptr)
{
ThreadDemoDlg* pDemo= (ThreadDemoDlg*)ptr;
while (1)
{
if (WaitForSingleObject(pDemo->m_hThread, INFINITE) == WAIT_OBJECT_0)
{
ResetEvent(pDemo->m_hThread);//重置事件
EnterCriticalSection(&pDemo->m_ThreadLock);//进入关键帧
//GetLocalTime(&Systm); //do your code
LeaveCriticalSection(&pDemo->m_ThreadLock);//离开关键帧
}
}
return 0;
}
DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds );
//hHandle 指明一个内核对象的句柄
//dwMilliseconds 等待时间(毫秒)
- 参数一:该函数需要传递一个内核对象句柄,该句柄标识一个内核对象,
- 若该内核对象处于未通知状态,则该函数导致线程进入阻塞状态;
- 若该内核对象处于已通知状态,则该函数立即返回
WAIT_OBJECT_0
。
- 参数二:
- 1–INFINITE:指明要无限期等待下去,
- 2–0:函数测试同步对象的状态并立即返回。
- 3–指定毫秒 若等待超时,该函数返回
WAIT_TIMEOUT
。 若该函数失败,返回WAIT_FAILED
。
示例:
DWORD dword = WaitForSingleObject(hProcess, 5000); //等待一个进程结束
switch (dword)
{
case WAIT_OBJECT_0: // hProcess所代表的进程在5秒内结束do...
break;
case WAIT_TIMEOUT: // 等待时间超过5秒,do...
break;
case WAIT_FAILED: // 函数调用失败,比如传递了一个无效的句柄do...
break;
}
9 界面右键悬浮菜单
void CXXXDlg::OnContextMenu(CWnd* /*pWnd*/, CPoint point)
{
// TODO: 在此处添加消息处理程序代码
RECT rectPic;
CMenu menu;
GetDlgItem(IDC_LIST_INFO)->GetWindowRect(&rectPic);
if (PtInRect(&rectPic, point))
{
menu.LoadMenu(IDR_MENU_INFO);
CMenu* pContextMenu = menu.GetSubMenu(0);//获取第一位子菜单
pContextMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this);
}
}
10 控件矩形框重定位(移动控件和调整大小)
void CXXXDlg::MoveRectCtrl(int nID,CPoint first,CPoint next )
{
CRect Rect;
GetDlgItem(nID)->GetWindowRect(Rect);
ScreenToClient(Rect);
Rect.SetRect(first, next);
GetDlgItem(nID)->MoveWindow(Rect, TRUE);
}
11 MFC从文件读取位图作为背景
注意必须位图文件!
BOOL CXXXDlg::OnEraseBkgnd(CDC* pDC)
{
//设定背景图像
HBITMAP hBmp;
CBitmap c_bmp;
BITMAP bmp;
CRect rect;
CDC dcCompatible;
GetClientRect(&rect);
hBmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), _T("bkgnd.bmp"), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
c_bmp.DeleteObject();
c_bmp.Attach(hBmp);
c_bmp.GetBitmap(&bmp);
dcCompatible.CreateCompatibleDC(pDC);
dcCompatible.SelectObject(c_bmp);
//pDC->BitBlt(0,0,rect.Width(),rect.Height(),&dcCompatible,0,0,SRCCOPY);
pDC->StretchBlt(0, 0, rect.Width(), rect.Height(), &dcCompatible, 0, 0,
bmp.bmWidth, bmp.bmHeight, SRCCOPY);
return true;//这一句不能少
//return CDialogEx::OnEraseBkgnd(pDC);
}
12 屏蔽enter & esc防止程序退出
BOOL CDemoDlg::PreTranslateMessage(MSG *pMsg)
{
if(pMsg->message == WM_KEYDOWN)
{
switch(pMsg->wParam)
{
case VK_RETURN://屏蔽回车
// OnKeyDown(VK_SPACE, LOWORD(pMsg ->lParam), HIWORD(pMsg->lParam));
return TRUE;
case VK_ESCAPE://屏蔽Esc
return TRUE;
}
}
return CDialog::PreTranslateMessage(pMsg);
}