1、工具栏形式的,
注意图片大小要与代码中设置的宽高一致,按钮宽高大于图片宽高。
核心代码
if (!m_ToolBar)
{
if (!m_ToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_SIZE_FIXED | CBRS_LEFT | CBRS_TOOLTIPS))
{
TRACE("Failed to create toolbar!\n");
return;
}
CBitmap cBmp[2];
m_imagelist.Create(30, 30, ILC_COLOR24 | ILC_MASK,3, 1);
m_imagelist.SetBkColor(::GetSysColor(COLOR_BTNFACE));
cBmp[0].LoadBitmap(IDB_BITMAP2);
m_imagelist.Add(&cBmp[0], RGB(255, 255, 255));
cBmp[1].LoadBitmap(IDB_BITMAP3);
m_imagelist.Add(&cBmp[1], RGB(255, 255, 255));
m_ToolBar.GetToolBarCtrl().SetImageList(&m_imagelist);//设置图像
//m_ToolBar.CreateEx(this);//创建工具栏控件
//m_ToolBar.SetSizes(CSize(70, 60), CSize(28, 40));
UINT array[10] = { IDB_BITMAP2,IDB_BITMAP2 + 1 };
//m_ToolBar.SetSizes(CSize(70, 60), CSize(28, 40));
//UINT array[10] = { 1000,1001 };
m_ToolBar.SetButtons(array, 2);
m_ToolBar.SetSizes(CSize(40, 40), CSize(30, 30));//图片大小要与实际图片大小一致
m_ToolBar.EnableToolTips(TRUE);
/*m_ToolBar.SetButtonText(0, _T("选定马赛克"));
m_ToolBar.SetButtonText(1, _T("取消马赛克"));
*/
//m_ToolBar.EnableDocking(CBRS_ALIGN_ANY);
//CReBar m_Rebar;
//m_Rebar.Create(this);//创建窗口(控件)
//m_Rebar.AddBar(&m_ToolBar);//添加m_Toolbar为子窗口
//m_Rebar.RedrawWindow();//重画窗口
//REBARBANDINFO info;
//info.cbSize = sizeof(info);
//info.fMask = RBBIM_BACKGROUND;
//m_ToolBar.ModifyStyle(0, TBSTYLE_TRANSPARENT);//设置工具栏背景色透明
//info.hbmBack = LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP4));//加载位图
//m_Rebar.GetReBarCtrl().SetBandInfo(0, &info);
RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0);
}
/*EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_ToolBar);*/
int i_LDCoordicateX = 0;
int i_LDCoordicateY = 0;
if ((80 + x) > m_iWidth)
i_LDCoordicateX = x - 80;
else
i_LDCoordicateX = x + 80;
if ((40 + y) > m_iHeight)
i_LDCoordicateY = y - 40;
else
i_LDCoordicateY = 40 + y;
if (x > i_LDCoordicateX)
{
int itemp = x;
x = i_LDCoordicateX;
i_LDCoordicateX = itemp;
}
if (y > i_LDCoordicateY)
{
int itemp = y;
y = i_LDCoordicateY;
i_LDCoordicateY = itemp;
}
CRect rect(x, y, i_LDCoordicateX, i_LDCoordicateY);
m_ToolBar.MoveWindow(rect);//移动工具栏在父窗口的位置
m_ToolBar.ShowWindow(TRUE);
2、菜单栏形式的
核心代码
void CShowMosaicDlg::ShowCMenuBar(int x, int y)
{
menu1.CreatePopupMenu(); //动态创建弹出式菜单对象
menu1.AppendMenu(MF_STRING, ID_TEST1, L" 马赛克");
menu1.AppendMenu(MF_STRING, ID_TEST2, L" 取消马赛克");
CPoint pt;
pt.x = m_iStartX;
pt.y = m_iStartY;
GetCursorPos(&pt);
menu1.TrackPopupMenu(TPM_LEFTALIGN | TPM_BOTTOMALIGN, pt.x, pt.y, this);
menu1.DestroyMenu();
}
3、但是最后的效果图都不是这样的,需要时菜单样式但是每次按钮显示在框选框框的正下方。暂未解决。
其他代码
void CShowMosaicDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CRect rect;
this->GetWindowRect(&rect);//获取MFC图像显示区域
m_iStartX = point.x;
m_iStartY = point.y;
Point p(point.x, point.y);//opencv鼠标坐标(相对界面)
ScreenToClient(rect);//转化为对话框上的相对位置
Rect r(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);//OPenCV窗口显示区域
if (r.contains(p)) //鼠标放在图片窗口上
{
m_startRect = TRUE; //鼠标左键单击,设置可以开始绘制矩形框
m_endRect = false;
m_startPoint = point; //记录开始点
m_OldPoint = point; //设置老点也为开始点
}
Invalidate();
CDialogEx::OnLButtonDown(nFlags, point);
}
void CShowMosaicDlg::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CRect rect;
this->GetWindowRect(&rect);//获取MFC图像显示区域
ScreenToClient(rect);//转化为对话框上的相对位置
Point p(point.x, point.y);//opencv鼠标坐标(相对界面)
Rect r(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);//opencv窗口显示区域
if (r.contains(p) && (true == m_startRect)) //鼠标放在图片窗口上
{
HCURSOR hCur = LoadCursor(NULL, IDC_CROSS);
::SetCursor(hCur);
CClientDC dc(this); //获取设备句柄
//SetRop2 Specifies the new drawing mode.(MSDN)
//R2_NOT Pixel is the inverse of the screen color.(MSDN)
//即:该函数用来定义绘制的颜色,而该参数则将颜色设置为原屏幕颜色的反色
//这样,如果连续绘制两次的话,就可以恢复原来屏幕的颜色了(如下)
//但是,这里的连续两次绘制却不是在一次消息响应中完成的
//而是在第一次拖动响应的绘制可以显示(也就是看到的),第二次拖动绘制实现擦出(也就看不到了)
dc.SetROP2(R2_NOT); //此为关键!!!
dc.SelectStockObject(NULL_BRUSH); //不使用画刷
//if (TRUE == m_startRect) //根据是否有单击判断是否可以画矩形
{
m_endRect = true;
dc.Rectangle(CRect(m_startPoint, m_OldPoint));
dc.Rectangle(CRect(m_startPoint, point));
m_OldPoint = point;
}
}
CDialogEx::OnMouseMove(nFlags, point);
}
void CShowMosaicDlg::OnButtoncancle()
{
// TODO: 在此添加命令处理程序代码
MessageBox(TEXT("取消"), TEXT("取消"), MB_YESNO);
Invalidate();
//m_ToolBar.ShowWindow(false);
}
void CShowMosaicDlg::OnButtondo()
{
// TODO: 在此添加命令处理程序代码
MessageBox(TEXT("操作"), TEXT("操作"), MB_YESNO);
Invalidate();
//m_ToolBar.ShowWindow(false);
}
void CShowMosaicDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CRect rect;
this->GetWindowRect(&rect);//获取MFC图像显示区域
ScreenToClient(rect);//转化为对话框上的相对位置
Point p(point.x, point.y);//opencv鼠标坐标(相对界面)
Rect r(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);//opencv窗口显示区域
if (r.contains(p) && m_endRect) //鼠标放在图片窗口上
{
int current_x = point.x;
int current_y = point.y;
int tx = (current_x - before_x);
int ty = (current_y - before_y);
//CClientDC dc(this);//选定当前画图环境
//COLORREF colorrrefRGB = RGB(250, 0, 0);
//CPen pen(PS_SOLID, 1, colorrrefRGB);//做一支红色粗细为1的笔
//dc.SelectObject(&pen);//将pen放到dc上
//dc.Rectangle(before_x, before_y, tx, ty);//画一个矩形
//一个底下出现弹框 选择是否马赛克
if (current_x < m_startPoint.x)
{
current_x = m_startPoint.x;
}
if (current_y < m_startPoint.y)
{
current_y = m_startPoint.y;
}
ShowCMenuBar(current_x, current_y);
//OnShowToolBar(current_x, current_y);
}
m_startRect = false;
m_endRect = false;
CDialogEx::OnLButtonUp(nFlags, point);
}
借鉴博客
https://www.cnblogs.com/lujin49/p/4962256.html MFC菜单栏
https://blog.csdn.net/wangshubo1989/article/details/49309547 TrackPopupMenu样式
代码链接地址
代码链接地址