📄 histogramwnd.cpp
字号:
// HistogramWnd.cpp : implementation file
//
#include "stdafx.h"
#include "Segment.h"
#include "HistogramWnd.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CHistogramWnd
//-----------------------------------------------------------------
//
// CHistogramWnd constructor
//
//-----------------------------------------------------------------
CHistogramWnd::CHistogramWnd()
{
m_bMovingSlider = FALSE;
}
//-----------------------------------------------------------------
//
// CHistogramWnd destructor
//
//-----------------------------------------------------------------
CHistogramWnd::~CHistogramWnd()
{
}
BEGIN_MESSAGE_MAP(CHistogramWnd, CWnd)
//{{AFX_MSG_MAP(CHistogramWnd)
ON_WM_PAINT()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_SETCURSOR()
ON_WM_CHAR()
ON_WM_KILLFOCUS()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CHistogramWnd message handlers
//-----------------------------------------------------------------
//
// CHistogramWnd::OnPaint - paint the histogram and thresholding tool
//
//-----------------------------------------------------------------
void CHistogramWnd::OnPaint()
{
CPaintDC dc(this); // device context for painting
CBrush brBackground(GetSysColor(COLOR_BTNFACE));
CRect crClient;
GetClientRect(&crClient);
dc.FillRect(&crClient,&brBackground);
if (m_vHistogram.size()) {
// Find the maximum height in the histogram.
int nMax = INT_MIN;
for (int i = 0; i < m_vHistogram.size(); i++) {
if (m_vHistogram[i] > nMax) {
nMax = m_vHistogram[i];
}
}
int nHeight = crClient.Height();
dc.MoveTo(0,nHeight - MulDiv(m_vHistogram[0],nHeight,nMax));
for (i = 1; i < m_vHistogram.size(); i++) {
dc.LineTo(ConvertChannelToX(i),nHeight - MulDiv(m_vHistogram[i],nHeight,nMax));
}
int nXBound = ConvertChannelToX(m_nBound);
dc.MoveTo(nXBound,crClient.top);
dc.LineTo(nXBound,crClient.bottom);
CRect crSlider;
GetSliderRect(crSlider);
dc.Draw3dRect(&crSlider,GetSysColor(COLOR_3DHIGHLIGHT),GetSysColor(COLOR_3DSHADOW));
crSlider.InflateRect(-GetSystemMetrics(SM_CXEDGE),-GetSystemMetrics(SM_CYEDGE));
CBrush brBtnFace(GetSysColor(COLOR_3DFACE));
dc.FillRect(&crSlider,&brBtnFace);
}
}
//-----------------------------------------------------------------
//
// CHistogramWnd::ConvertXToChannel - Convert client coordinate
// to histogram channel #.
//
//-----------------------------------------------------------------
int CHistogramWnd::ConvertXToChannel(int nX)
{
CRect cr;
GetClientRect(&cr);
if (cr.Width() == 0) return 0;
return MulDiv(nX,m_vHistogram.size(),cr.Width());
}
//-----------------------------------------------------------------
//
// CHistogramWnd::ConvertChannelToX - Convert histogram channel # to
// client coordinate.
//
//-----------------------------------------------------------------
int CHistogramWnd::ConvertChannelToX(int nChannel)
{
CRect cr;
GetClientRect(&cr);
const int nChannels = m_vHistogram.size();
if (nChannels == 0) return 0;
return MulDiv(nChannel,cr.Width(),nChannels);
}
//-----------------------------------------------------------------
//
// CHistogramWnd::GetSliderRect - Return the coordinates of the
// slider rectangle (the user grabs this
// to drag the thresholding tool).
//
//-----------------------------------------------------------------
void CHistogramWnd::GetSliderRect(CRect & cr)
{
int nSliderX = ConvertChannelToX(m_nBound);
CRect crClient;
GetClientRect(&crClient);
cr.top = cr.bottom = (crClient.top + crClient.bottom) / 2;
cr.left = cr.right = nSliderX;
cr.InflateRect(3,3);
}
//-----------------------------------------------------------------
//
// CHistogramWnd::OnLButtonDown - If the cursor is within the slider
// rectangle, we initiate a drag of the
// thresholding tool.
//
//-----------------------------------------------------------------
void CHistogramWnd::OnLButtonDown(UINT nFlags, CPoint point)
{
CRect crSlider;
GetSliderRect(crSlider);
if (crSlider.PtInRect(point)) {
// Capture the mouse.
SetCapture();
m_bMovingSlider = TRUE;
CRect crClient;
GetClientRect(&crClient);
ClientToScreen(&crClient);
if (! ClipCursor(&crClient)) {
ReleaseCapture();
m_bMovingSlider = FALSE;
}
}
CWnd::OnLButtonDown(nFlags, point);
}
//-----------------------------------------------------------------
//
// CHistogramWnd::OnLButtonUp - End the thresholding tool drag
//
//-----------------------------------------------------------------
void CHistogramWnd::OnLButtonUp(UINT nFlags, CPoint point)
{
if (m_bMovingSlider) {
// release the mouse capture
ClipCursor(NULL);
ReleaseCapture();
m_bMovingSlider = FALSE;
}
CWnd::OnLButtonUp(nFlags, point);
}
//-----------------------------------------------------------------
//
// CHistogramWnd::OnMouseMove - Move the thresholding tool and
// adjust the threshold if we're dragging.
//
//-----------------------------------------------------------------
void CHistogramWnd::OnMouseMove(UINT nFlags, CPoint point)
{
if (m_bMovingSlider) {
// First, invalidate the old slider.
CRect crOldSlider;
GetSliderRect(crOldSlider);
CRect crClient;
GetClientRect(&crClient);
crOldSlider.top = crClient.top;
crOldSlider.bottom = crClient.bottom;
// Move to the new position.
m_nBound = ConvertXToChannel(point.x);
CRect crNewSlider;
GetSliderRect(crNewSlider);
crNewSlider.top = crClient.top;
crNewSlider.bottom = crClient.bottom;
InvalidateRect(&crOldSlider);
InvalidateRect(&crNewSlider);
}
CWnd::OnMouseMove(nFlags, point);
}
//-----------------------------------------------------------------
//
// CHistogramWnd::OnSetCursor - Special cursor if we're in the slider rect.
//
//-----------------------------------------------------------------
BOOL CHistogramWnd::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if (nHitTest == HTCLIENT) {
CRect crSlider;
GetSliderRect(crSlider);
CPoint pt;
if (GetCursorPos(&pt)) {
ScreenToClient(&pt);
if (crSlider.PtInRect(pt) || m_bMovingSlider) {
SetCursor(LoadCursor(NULL,IDC_SIZEWE));
return TRUE;
}
}
SetCursor(LoadCursor(NULL,IDC_ARROW));
return TRUE;
}
return CWnd::OnSetCursor(pWnd, nHitTest, message);
}
//-----------------------------------------------------------------
//
// CHistogramWnd::OnChar - Cancel the drag on escape.
//
//-----------------------------------------------------------------
void CHistogramWnd::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (nChar == VK_ESCAPE && m_bMovingSlider) {
ReleaseCapture();
ClipCursor(NULL);
m_bMovingSlider = FALSE;
return;
}
CWnd::OnChar(nChar, nRepCnt, nFlags);
}
//-----------------------------------------------------------------
//
// CHistogramWnd::OnKillFocus - Cancel the drag if the window loses focus.
//
//-----------------------------------------------------------------
void CHistogramWnd::OnKillFocus(CWnd* pNewWnd)
{
if (m_bMovingSlider) {
ReleaseCapture();
ClipCursor(NULL);
m_bMovingSlider = FALSE;
}
CWnd::OnKillFocus(pNewWnd);
// TODO: Add your message handler code here
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -