界面说明:见上图,左边是一个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上绘制的,而不应该传入对话框的句柄
------解决思路----------------------
控件句柄这样拿:
HWND hWnd = m_pWndCap->GetSafeHdc();或者
HWND hWnd = m_pWndCap->m_hDC;
------解决思路----------------------
明明是一把枪,非得拿来做烧火棍,实在不明白什么逻辑
text是专题用来显示文本的,非得用来显示位图?
------解决思路----------------------
这里还可能有一个问题: 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);