当前位置: 代码迷 >> VC/MFC >> 如何在MFC对话框 text control控件中根据自定义坐标绘制ROI矩形框
  详细解决方案

如何在MFC对话框 text control控件中根据自定义坐标绘制ROI矩形框

热度:130   发布时间:2016-05-02 03:49:05.0
怎么在MFC对话框 text control控件中根据自定义坐标绘制ROI矩形框

界面说明:见上图,左边是一个text control的控件用来显示视频,通过右边的ROI设置中自定义输入感兴趣区域的坐标。
预期目标:最后通过点击按钮“保存设置”,在坐标的text control控件中显示一个矩形框,矩形框在最顶层,不会被其他控件或者图片覆盖掉,矩形框位置相对控件固定。


void CImgCaptureDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
GetDlgItem(IDC_X)->GetWindowText(StartPoint_X);
GetDlgItem(IDC_Y)->GetWindowText(StartPoint_Y);
GetDlgItem(IDC_WIDTH)->GetWindowText(ROI_Width);
GetDlgItem(IDC_HEIGHT)->GetWindowText(ROI_Height);

x = _ttoi(StartPoint_X);
y = _ttoi(StartPoint_Y);
w = _ttoi(ROI_Width);
h = _ttoi(ROI_Height);


//picture control中直观显示ROI区域
       CWnd *m_pWndCap = GetDlgItem(IDC_STATICVIDEO);     //IDC_STATICVIDEO为text control控件的ID

        CRect rc;
        m_pWndCap->GetWindowRect(&rc);
        ScreenToClient(&rc);

        //绝对坐标,坐标就是相对于视频控件的坐标了,要画多大可以自己修改

        int x1 = rc.left+x;
        int y1 = rc.top+y;
        int x2 = x1+w;
        int y2 = y1+h;

       //调用矩形框绘制函数
        DrawRectangle(m_hWnd, x1, y1, x2, y2);    
}



void DrawRectangle(HWND m_HWnd, int x1, int y1, int x2, int y2)
{

TRACE("x1,y1,x2,y2%d,%d,%d,%d",x1,y1,x2,y2);

HDC hdc = ::GetDC(m_HWnd);
PAINTSTRUCT ps;
::BeginPaint( m_HWnd, &ps );

HPEN hPen;
hPen=CreatePen(PS_SOLID,3,RGB(255,255,0)); //创建画笔
SelectObject(hdc,hPen);                                        
SelectObject(hdc,(HBRUSH)GetStockObject(NULL_BRUSH));  //不填充
//画Rect
Rectangle(hdc, x1, y1, x2, y2);

DeleteObject(hPen);

::EndPaint( m_HWnd, &ps );
::ReleaseDC( m_HWnd, hdc );
}


程序没问题,我看到网上说绘制代码要放在OnPaint()函数中,试过了,也不能显示矩形框,求大神帮助!!!
------解决思路----------------------
ScreenToClient(&rc); 这里改成
m_pWndCap->ScreenToClient(&rc);


其实你完全可以直接拿客户区就是了,没必要拿窗口区域再去转换m_pWndCap->GetClientRect(&rc)也可以
------解决思路----------------------
我是直接在OnPaint里绘制的

------解决思路----------------------
dc 不对
PAINTSTRUCT Structure
The PAINTSTRUCT structure has the following form:

typedef struct tagPAINTSTRUCT {
   HDC  hdc;
   BOOL fErase;
   RECT rcPaint;
   BOOL fRestore;
   BOOL fIncUpdate;
   BYTE rgbReserved[16];
} PAINTSTRUCT;

hdc=BeginPaint(hWnd,&ps);

------解决思路----------------------
这里还可能有一个问题: DrawRectangle(m_hWnd, x1, y1, x2, y2); 这里传入的句柄应该是你static控件的句柄,应为你是在static上绘制的,而不应该传入对话框的句柄
------解决思路----------------------
引用:
Quote: 引用:

这里还可能有一个问题: DrawRectangle(m_hWnd, x1, y1, x2, y2); 这里传入的句柄应该是你static控件的句柄,应为你是在static上绘制的,而不应该传入对话框的句柄


对啊,我也是在考虑这个问题,画矩形框的句柄是对话框,但是不知道控件的句柄是什么?新手求助~

控件句柄这样拿:
HWND hWnd = m_pWndCap->GetSafeHdc();或者
HWND hWnd = m_pWndCap->m_hDC;

------解决思路----------------------
明明是一把枪,非得拿来做烧火棍,实在不明白什么逻辑
text是专题用来显示文本的,非得用来显示位图?
------解决思路----------------------
引用:
Quote: 引用:

Quote: 引用:

Quote: 引用:

这里还可能有一个问题: DrawRectangle(m_hWnd, x1, y1, x2, y2); 这里传入的句柄应该是你static控件的句柄,应为你是在static上绘制的,而不应该传入对话框的句柄


对啊,我也是在考虑这个问题,画矩形框的句柄是对话框,但是不知道控件的句柄是什么?新手求助~

控件句柄这样拿:
HWND hWnd = m_pWndCap->GetSafeHdc();或者
HWND hWnd = m_pWndCap->m_hDC;


HWND hWnd=m_pWndCap->GetSafeHwnd();    //是不是这样?GetSafeHdc()好像不正确。
另外:

               CWnd *m_pWndCap = GetDlgItem(IDC_STATICVIDEO);// IDC_为绘制矩形框控件的ID

HWND hWnd=m_pWndCap->GetSafeHwnd();
if(hWnd == NULL)
{
MessageBox("没有获取到句柄!");
return;
}

    CRect rc;
    m_pWndCap->GetWindowRect(&rc);
    m_pWndCap->ScreenToClient(&rc);

   //绝对坐标,坐标就是相对于视频控件的坐标了,要画多大可以自己修改
   
   int x1 = rc.left+x;
   int y1 = rc.top+y;
   int x2 = x1+w;
   int y2 = y1+h;

   //调用矩形框绘制函数
   DrawRectangle(hWnd, x1, y1, x2, y2);


上面的代码放在OnPaint函数中哪里有问题?怎么还是没有矩形框显示,真是要哭瞎了。

GetSafeHdc()怎么会不对呢!
------解决思路----------------------
BeginPaint
The BeginPaint function prepares the specified window for painting and fills a PAINTSTRUCT structure with information about the painting. 

HDC BeginPaint(
  HWND hwnd,  // handle to window
  LPPAINTSTRUCT lpPaint
              // pointer to structure for paint information
);
注意Paint中只能用 PaintDC , 不能用 HDC hdc = ::GetDC(m_HWnd);
  相关解决方案