如何解决在优化校准中计算图像的正确位置,并正确绘制背景在MFC对话框上
我有这个对话框:
这是对话框的RC:
IDD_DIALOG_SPECIAL_EVENT_VIDEOCONF DIALOGEX 0,541,233
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
EXSTYLE WS_EX_APPWINDOW
CAPTION "Special Event — Videoconference"
FONT 8,"MS Shell Dlg",0x1
BEGIN
GROUPBOX "Details",IDC_STATIC,7,301,201
LTEXT "Path to image to display:",15,22,80,8
CONTROL "",IDC_BROWSE_SPECIAL_EVENT_VIDEOCONF_PATH_IMAGE,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x880,14,32,288,14
LTEXT "50%",13,49,16,IDC_SLIDER_SPECIAL_EVENT_VIDEOCONF_IMAGE_WIDTH,"msctls_trackbar32",TBS_AUTOTICKS | TBS_BOTH | WS_TABSTOP,8,58,294,15
LTEXT "Width of image:",77,52,8
LTEXT "%",IDC_STATIC_SPECIAL_EVENT_VIDEOCONF_IMAGE_WIDTH,70,19,8
LTEXT "Text to display before the image:",97,108,8
EDITTEXT IDC_EDIT_SPECIAL_EVENT_VIDEOCONF_TEXT_BEFORE_IMAGE,109,37,ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL
LTEXT "Text to display after the image:",152,102,8
EDITTEXT IDC_EDIT_SPECIAL_EVENT_VIDEOCONF_TEXT_AFTER_IMAGE,163,ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL
DEFPUSHBUTTON "OK",IDOK,198,212,50,14
PUSHBUTTON "Cancel",IDCANCEL,252,14
LTEXT "100%",287,48,20,8
GROUPBOX "Image Preview",314,224,201
CONTROL "",IDC_STATIC_IMAGE_PREVIEW,"Static",SS_OWNERDRAW,321,18,210,181
END
上面带有 Picture Control 。我已将其设置为所有者抽奖。当用户浏览文件时,对话框会将图像加载到CImage
中:
void CSpecialEventVideoconferenceInfoDlg::OnEnChangeBrowseSpecialEventVideoconfPathImage()
{
CString strImagePath;
GetDlgItemText(IDC_BROWSE_SPECIAL_EVENT_VIDEOCONF_PATH_IMAGE,strImagePath);
m_imgPreview.Load(strImagePath);
}
而且,渲染过程如下:
void CSpecialEventVideoconferenceInfoDlg::OnDrawItem(int nIDCtl,LPDRAWITEMSTRUCT lpDrawItemStruct)
{
if (nIDCtl == IDC_STATIC_IMAGE_PREVIEW && !m_imgPreview.IsNull())
{
SetStretchBltMode(lpDrawItemStruct->hDC,HALFTONE);
CRect dest(lpDrawItemStruct->rcItem);
float nRatioImage = m_imgPreview.GetWidth() / (float)m_imgPreview.GetHeight();
float nRatioDest = dest.Width() / (float)dest.Height();
CRect rectDraw = dest;
if (nRatioImage > nRatioDest)
rectDraw.SetRect(0,rectDraw.right,rectDraw.right / nRatioImage);
else if (nRatioImage < nRatioDest)
rectDraw.SetRect(0,rectDraw.bottom * nRatioImage,rectDraw.bottom);
m_imgPreview.Draw(lpDrawItemStruct->hDC,rectDraw);
}
}
这里有两个我目前无法解决的问题:
- 该图像未在容器的中央绘制:
- 如果我决定使用其他图像,则图片控件无法正确擦除背景:
更新
如果我这样调整代码:
void CSpecialEventVideoconferenceInfoDlg::OnDrawItem(int nIDCtl,HALFTONE);
FillRect(lpDrawItemStruct->hDC,&lpDrawItemStruct->rcItem,(HBRUSH)GetStockObject(WHITE_BRUSH));
CRect dest(lpDrawItemStruct->rcItem);
float nRatioImage = m_imgPreview.GetWidth() / (float)m_imgPreview.GetHeight();
float nRatioDest = dest.Width() / (float)dest.Height();
CRect rectDraw = dest;
if (nRatioImage > nRatioDest)
rectDraw.SetRect(0,rectDraw);
}
}
...它解决了第二个问题。它使用FillRect
。因此,只需更改代码以集中图片即可解决。
解决方法
这是我的解决方案:
void CSpecialEventVideoconferenceInfoDlg::OnDrawItem(int nIDCtl,LPDRAWITEMSTRUCT lpDrawItemStruct)
{
if (nIDCtl == IDC_STATIC_IMAGE_PREVIEW && !m_imgPreview.IsNull())
{
SetStretchBltMode(lpDrawItemStruct->hDC,HALFTONE);
FillRect(lpDrawItemStruct->hDC,&lpDrawItemStruct->rcItem,(HBRUSH)GetStockObject(WHITE_BRUSH));
CRect dest(lpDrawItemStruct->rcItem);
float nRatioImage = m_imgPreview.GetWidth() / (float)m_imgPreview.GetHeight();
float nRatioDest = dest.Width() / (float)dest.Height();
CRect rectDraw = dest;
if (nRatioImage > nRatioCanvas)
rectDraw.SetRect(0,rectDraw.right,(int)(rectDraw.right / nRatioImage));
else if (nRatioImage < nRatioCanvas)
rectDraw.SetRect(0,(int)(rectDraw.bottom * nRatioImage),rectDraw.bottom);
rectDraw.DeflateRect(5,5);
CSize ptOffset = dest.CenterPoint() - rectDraw.CenterPoint();
rectDraw.OffsetRect(ptOffset);
FrameRect(lpDrawItemStruct->hDC,(HBRUSH)GetStockObject(BLACK_BRUSH));
m_imgPreview.Draw(lpDrawItemStruct->hDC,rectDraw);
}
}
- 我使用
FillRect
擦除背景。 - 我使用
CenterPoint
和OffsetRect
来制定新的中心。 - 我使用
FrameRect
在图片周围添加漂亮的矩形。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。