📄 histogramdlg.cpp
字号:
// HistogramDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "photoshow.h"
#include "HistogramDlg.h"
#include "MainFrm.h"
#include "photoshowDoc.h"
#include "photoshowView.h"
// CHistogramDlg 对话框
IMPLEMENT_DYNAMIC(CHistogramDlg, CDialog)
CHistogramDlg::CHistogramDlg(CWnd* pParent /*=NULL*/)
: CDialog(CHistogramDlg::IDD, pParent)
, m_nLimitLow(0)
, m_nLimitUp(255)
, m_nGray(0)
, m_dPer(0)
{
memset(m_lCounts, 0, sizeof(long) * 256);
m_nIsDraging = DT_NULL;
}
CHistogramDlg::~CHistogramDlg()
{
}
void CHistogramDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_HISTOGRAM, m_stiHistogram);
DDX_Text(pDX, IDC_LIMIT_LOWER, m_nLimitLow);
DDX_Text(pDX, IDC_LIMIT_UP, m_nLimitUp);
DDX_Text(pDX, IDC_STATIC_GRAY, m_nGray);
DDX_Text(pDX, IDC_STATIC_PER, m_dPer);
}
BEGIN_MESSAGE_MAP(CHistogramDlg, CDialog)
ON_EN_CHANGE(IDC_LIMIT_LOWER, &CHistogramDlg::OnEnChangeLimitLower)
ON_EN_CHANGE(IDC_LIMIT_UP, &CHistogramDlg::OnEnChangeLimitUp)
ON_WM_PAINT()
ON_WM_MOUSEMOVE()
ON_WM_SETCURSOR()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_BN_CLICKED(IDCANCEL, &CHistogramDlg::OnBnClickedCancel)
END_MESSAGE_MAP()
// CHistogramDlg 消息处理程序
void CHistogramDlg::OnEnChangeLimitLower()
{
UpdateData(TRUE);
// 限定取值范围
if (m_nLimitLow < 0)
m_nLimitLow = 0;
else if (m_nLimitLow > 255)
m_nLimitLow = 255;
// 如果下限比上限大,则互换
if (m_nLimitLow > m_nLimitUp)
{
int nTemp = m_nLimitLow;
m_nLimitLow = m_nLimitUp;
m_nLimitUp = nTemp;
}
Refresh();
UpdateData(FALSE);
}
void CHistogramDlg::OnEnChangeLimitUp()
{
UpdateData(TRUE);
// 限定取值范围
if (m_nLimitUp < 0)
m_nLimitUp = 0;
else if (m_nLimitUp > 255)
m_nLimitUp = 255;
if (m_nLimitLow > m_nLimitUp)
{
int nTemp = m_nLimitLow;
m_nLimitLow = m_nLimitUp;
m_nLimitUp = nTemp;
}
Refresh();
UpdateData(FALSE);
}
void CHistogramDlg::OnPaint()
{
CPaintDC dc(this); // device context for painting
Refresh();
}
void CHistogramDlg::OnMouseMove(UINT nFlags, CPoint point)
{
CRect rect;
m_stiHistogram.GetWindowRect(rect);
if((nFlags&MK_LBUTTON)&&m_nIsDraging){
int offset=point.x-m_psMove.x;
if(m_nIsDraging==DT_UP){
if((offset+m_nLimitUp)<=255){
if((offset+m_nLimitUp)>=m_nLimitLow)
m_nLimitUp+=offset;
else
m_nLimitUp=m_nLimitLow;
}
else
m_nLimitUp=255;
}
else{
if((offset+m_nLimitLow)>=0){
if((offset+m_nLimitLow)<=m_nLimitUp)
m_nLimitLow+=offset;
else
m_nLimitLow=m_nLimitUp;
}
else
m_nLimitLow=0;
}
UpdateData(FALSE);
Refresh();
m_psMove=point;
}
else
m_nIsDraging=DT_NULL;
ClientToScreen(&point);
int x=point.x-rect.left-10;
if(abs(x-m_nLimitUp)>3&&abs(x-m_nLimitLow)>3)
m_nIsDraging=DT_NULL;
if(rect.PtInRect(point)){
if(x>m_nLimitLow && x<=m_nLimitUp){
m_nGray=x;
m_dPer=float(m_lCounts[x])/m_nPixelCount*100;
}
UpdateData(FALSE);
}
}
BOOL CHistogramDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
CRect rect;
CPoint point;
GetCursorPos(&point);
m_stiHistogram.GetWindowRect(rect);
if (rect.PtInRect(point))
{
int x = point.x - rect.left - 10;
if (abs(x - m_nLimitUp) <= 3 || abs(x - m_nLimitLow) <= 3)
{
SetCursor(::LoadCursor(NULL, IDC_SIZEWE));
return TRUE;
}
}
return CDialog::OnSetCursor(pWnd, nHitTest, message);
}
void CHistogramDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
CRect rect;
CPoint oldPoint=point;
m_stiHistogram.GetWindowRect(rect);
ClientToScreen(&point);
int x=point.x-rect.left-10;
if(abs(x-m_nLimitUp)<=3){
m_psMove=oldPoint;
m_nIsDraging=DT_UP;
}
else if(abs(x-m_nLimitLow)<=3){
m_psMove=oldPoint;
m_nIsDraging=DT_LOW;
}
}
void CHistogramDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
m_nIsDraging=DT_NULL;
}
BOOL CHistogramDlg::OnInitDialog()
{
CDialog::OnInitDialog();
CMainFrame* pMain=(CMainFrame*)AfxGetMainWnd();
CphotoshowView* pView=(CphotoshowView*)pMain->GetActiveView();
for(UINT i=0;i<pView->m_nPicWidth*pView->m_nPicHeight;i++){
int value=pView->m_pImageTempBuffer[i*4];
m_lCounts[value]++;
}
m_nPixelCount=pView->m_nPicWidth*pView->m_nPicHeight;
return TRUE;
}
void CHistogramDlg::Refresh(void)
{
CDC* pDC=m_stiHistogram.GetDC();
CRect rect;
CDC memDC;
CBitmap MemBitmap;
m_stiHistogram.GetClientRect(rect);
memDC.CreateCompatibleDC(NULL);
MemBitmap.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());
memDC.SelectObject(MemBitmap);
memDC.FillSolidRect(0,0,rect.Width(),rect.Height(),RGB(255,255,255));
Graphics graph(memDC.GetSafeHdc());
graph.FillRectangles(&SolidBrush(Color::White),
&Rect(0,0,rect.Width(),rect.Height()),
1);
graph.DrawLine(&Pen(Color::Black),10,10,10,280);
graph.DrawLine(&Pen(Color::Black),10,10,5,15);
graph.DrawLine(&Pen(Color::Black),10,10,15,15);
graph.DrawLine(&Pen(Color::Black),10,280,290,280);
graph.DrawLine(&Pen(Color::Black),290,280,285,285);
graph.DrawLine(&Pen(Color::Black),290,280,285,275);
CString strNum;
Font font(L"宋体",10);
strNum=L"0";
graph.DrawString(strNum,-1,&font,
PointF(8,290),&SolidBrush(Color::Black));
for(int i=0;i<256;i+=5){
if(i%50==0)
graph.DrawLine(&Pen(Color::Black),10+i,280,10+i,286);
else if(i%10==0)
graph.DrawLine(&Pen(Color::Black),10+i,280,10+i,283);
}
strNum=L"50";
graph.DrawString(strNum,-1,&font,
PointF(53,290),&SolidBrush(Color::Black));
strNum=L"100";
graph.DrawString(strNum,-1,&font,
PointF(100,290),&SolidBrush(Color::Black));
strNum=L"150";
graph.DrawString(strNum,-1,&font,
PointF(150,290),&SolidBrush(Color::Black));
strNum=L"200";
graph.DrawString(strNum,-1,&font,
PointF(200,290),&SolidBrush(Color::Black));
Pen pen(Color::Blue);
pen.SetDashStyle(DashStyleDash);
graph.DrawLine(&pen,10+m_nLimitLow,280,10+m_nLimitLow,10);
graph.DrawLine(&pen,10+m_nLimitUp,280,10+m_nLimitUp,10);
long lMax=0;
REAL dHeight=0.0;
for(int i=m_nLimitLow;i<=m_nLimitUp;i++)
lMax=max(lMax,m_lCounts[i]);
strNum.Format(L"%d",lMax);
graph.DrawString(strNum,-1,&font,
PointF(10,25),&SolidBrush(Color::Black));
for (int i=m_nLimitLow;i<= m_nLimitUp;i++){
dHeight=(REAL)(m_lCounts[i])/lMax*250;
graph.DrawLine(&Pen(Color::Gray),i+10.0f,280.0f,i+10.0f,280-dHeight);
}
pDC->BitBlt(0,0,rect.Width(),rect.Height(),&memDC,0,0,SRCCOPY);
m_stiHistogram.ReleaseDC(pDC);
}
void CHistogramDlg::OnBnClickedCancel()
{
// TODO: 在此添加控件通知处理程序代码
OnCancel();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -