📄 cdrawf.cpp
字号:
#include "stdafx.h"
#include "CDrawF.h"
#include "error.h"
#include <math.h>
BEGIN_MESSAGE_MAP(CDrawFace, CFrameWnd)
//{{AFX_MSG_MAP(CDrawFace)
ON_WM_PAINT()
ON_WM_VSCROLL()
ON_WM_CREATE()
ON_WM_SIZE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
CDrawFace::CDrawFace()
{
pFaceDB = NULL;
pFaceMat = NULL;
pEigenVal = NULL;
bMat = FALSE;
}
int CDrawFace::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
/*Set the vertical scroll range*/
GEOMPARAMS gp;
RECT rect;
GetGeomParams(&gp);
nMaxVPos = gp.yNum + ((gp.lastNum > 0) ? 1:0);
GetClientRect(&rect);
if (nMaxVPos - (float)rect.bottom/(float)Getylen() + 2 > 1)
SetScrollRange(SB_VERT, 1, nMaxVPos - (float)rect.bottom/(float)Getylen() + 2);
else
SetScrollRange(SB_VERT, 1, 1);
nVPos = 1;
/*Create the font*/
LPSTR pszFace = "MS Sans Serif";
HDC hdc = ::GetDC(GetSafeHwnd());
MapModePrevious = SetMapMode(hdc, MM_TWIPS);
hfont = CreateFont(-12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "MS Sans Serif");
SetMapMode(hdc, MapModePrevious);
::ReleaseDC(GetSafeHwnd(), hdc);
return 0;
}
void CDrawFace::OnSize(UINT nType, int cx, int cy)
{
CFrameWnd::OnSize(nType, cx, cy);
/*Reset the vertical scroll range*/
GEOMPARAMS gp;
GetGeomParams(&gp);
nMaxVPos = gp.yNum + ((gp.lastNum > 0) ? 1:0);
if (nMaxVPos - (float)cy/(float)Getylen() + 2 > 1)
SetScrollRange(SB_VERT, 1, nMaxVPos - (float)cy/(float)Getylen() + 2);
else
SetScrollRange(SB_VERT, 1, 1);
int nLinePage;
nLinePage = floor((float)cy / (float)Getylen());
if (nVPos > nMaxVPos - nLinePage + 2)
nVPos = nMaxVPos - nLinePage + 2;
if (nVPos < 1)
nVPos = 1;
SetScrollPos(SB_VERT, nVPos);
}
void CDrawFace::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
RECT rect;
int nLinePage, nPrevVPos;
GetClientRect(&rect);
nLinePage = floor((float)(rect.bottom - rect.top) / (float)Getylen());
nPrevVPos = nVPos;
switch (nSBCode)
{
case SB_LINEDOWN:
nVPos++;
break;
case SB_LINEUP:
nVPos--;
break;
case SB_PAGEDOWN:
nVPos += nLinePage;
break;
case SB_PAGEUP:
nVPos -= nLinePage;
break;
case SB_THUMBPOSITION:
case SB_THUMBTRACK:
nVPos = nPos;
break;
}
if (nVPos < 1)
nVPos = 1;
if (nVPos > nMaxVPos - nLinePage + 2)
nVPos = nMaxVPos - nLinePage + 2;
SetScrollPos(SB_VERT, nVPos);
ScrollWindow(0, -(nVPos - nPrevVPos)*Getylen());
CFrameWnd::OnVScroll(nSBCode, nPos, pScrollBar);
}
/*************************************************************************************************
* Draws the area that must be redrawn. This fct is called by windows
*************************************************************************************************/
void CDrawFace::OnPaint()
{
CPaintDC dc(this); // device context for painting
typeface *pData = NULL;
long x, y, xlen, ylen, nFace, nNumFace;
COLORREF color;
CORNER c;
RECT DrawRect, FaceRect, TextRect;
RECT area;
char name[64];
unsigned int val;
float shift = 0.0;
float scale = 1.0;
CFace *pFace = NULL;
GetUpdateRect(&area, TRUE); /*Put in area the rectangle that must be redrawn*/
if (IsRectEmpty(&area))
GetClientRect(&area);
GetGeomParams(&gp);
if (bMat == TRUE)
{
nNumFace = pFaceMat->GetCol();
}
else
{
nNumFace = pFaceDB->GetNumFace();
}
/*Select the font*/
hfontOld = (HFONT)::SelectObject(dc.m_hDC, (HGDIOBJ)hfont);
for (nFace = (nVPos-1)*gp.xNum+1; nFace <= nNumFace; nFace++)
{
if (bMat == TRUE)
{
pFaceMat->Expand(nFace, &scale, &shift, 0, 255);
pFaceMat->Lock();
pEigenVal->Lock();
sprintf(name, "%.3f", pEigenVal->GetAt(nFace));
pEigenVal->Unlock();
xlen = (long)sqrt((double)pFaceMat->GetLi());
ylen = xlen;
}
else
{
pFaceDB->Expand(nFace, &scale, &shift, 0, 255);
pFace = pFaceDB->GetFace(nFace);
strcpy(name, pFace->GetName());
xlen = pFace->Getxlen();
ylen = pFace->Getylen();
pFace->Lock();
}
GetCornerFace(&c, nFace);
c.y -= (nVPos-1)*Getylen();
SetRect(&FaceRect, c.x, c.y, c.x + xlen, c.y + ylen);
if (IntersectRect(&DrawRect, &area, &FaceRect))
/*Assigns to DrawRect the rectangle that must be drawn*/
{ /*The face has to be drawn because it is inside the drawing area*/
for (y = DrawRect.top - FaceRect.top + 1L; y <= DrawRect.bottom - FaceRect.top; y++)
{
for (x = DrawRect.left - FaceRect.left + 1L; x <= DrawRect.right - FaceRect.left; x++)
{
if (bMat == TRUE)
{
val = (unsigned int)(shift + scale*pFaceMat->GetAt(xlen*y+x+1L, nFace));
}
else
{
val = (unsigned int)(shift + scale*pFace->GetAt(x, y));
}
/*the value of a single pixel is set in this loop, the grey level range is from 0 to 255*/
color = RGB((unsigned int)val, (unsigned int)val, (unsigned int)val);
dc.SetPixel(x + c.x, y + c.y, color);
/*Set the pixel's value*/
}
}
/* Draw the face's name at the bottom of it */
GetCornerName(&c, nFace);
c.y -= (nVPos-1)*Getylen();
SetRect(&TextRect, c.x, c.y, xlen, YTEXT);
dc.DrawText(name, strlen(name), &TextRect, DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE);
}
if (bMat == TRUE)
{
pFaceMat->Unlock();
}
else
{
pFace->Unlock();
}
}
SelectObject(dc.m_hDC, hfontOld); /*deselect the font*/
}
/*************************************************************************************************
* Puts in the CORNER struct c (basically a point) the point where the face whose number is nFace
* must be drawn in the face database drawing area.
*************************************************************************************************/
void CDrawFace::GetCornerFace(CORNER *c, long nFace)
{
int nx, ny;
nFace--;
nx = fmod(nFace, gp.xNum);
ny = floor(nFace / gp.xNum);
c->x = nx*Getxlen();
c->y = ny*Getylen();
}
/*************************************************************************************************
* Puts in the CORNER struct c (basically a point) the point where the face's name whose number is
* nFace must be drawn in the face database drawing area.
*************************************************************************************************/
void CDrawFace::GetCornerName(CORNER *c, long nFace)
{
long lval;
GetCornerFace(c, nFace);
if (bMat == TRUE)
{
lval = (long)sqrt((double)pFaceMat->GetLi());
}
else
lval = pFaceDB->Getylen();
c->y += lval + YFACETEXT;
}
/*************************************************************************************************
* Returns the width of a face as it is displayed in the face database drawing area (including the
* space around it).
*************************************************************************************************/
int CDrawFace::Getxlen()
{
long lval;
if (bMat == TRUE)
{
lval = (long)sqrt((double)pFaceMat->GetLi());
}
else
lval = pFaceDB->Getxlen();
return XSPACE + lval;
}
/*************************************************************************************************
* Returns the length of a face as it is displayed in the face database drawing area (including the
* space around it, the space for the face's name and for the little area between the face and its
* name).
*************************************************************************************************/
int CDrawFace::Getylen()
{
long lval;
if (bMat == TRUE)
{
lval = (long)sqrt((double)pFaceMat->GetLi());
}
else
lval = pFaceDB->Getylen();
return YSPACE + lval + YFACETEXT + YTEXT;
}
/*************************************************************************************************
* Puts in a struct GEOMPARAMS the number of faces displayed in the two directions and the number
* of faces which are displayed on the last line.
*************************************************************************************************/
void CDrawFace::GetGeomParams(GEOMPARAMS *gp)
{
long lval;
RECT rect;
if (bMat == TRUE)
{
lval = pFaceMat->GetCol();
}
else
lval = pFaceDB->GetNumFace();
GetClientRect(&rect);
gp->xNum = floor((float)rect.right/(float)Getxlen());
gp->yNum = floor((float)lval/(float)gp->xNum);
gp->lastNum = lval - gp->xNum*gp->yNum;
}
/*****************************************************************************
* SetFaceDB initialise the face database data (pFaceDB).
******************************************************************************/
void CDrawFace::SetFaceDB(CFaceDB *pFaceDBt)
{
pFaceDB = pFaceDBt;
bMat = FALSE;
}
/*****************************************************************************
* SetFaceDB initialise the face matrix (pFaceMat).
******************************************************************************/
void CDrawFace::SetFaceDB(CMatrix *pFaceMatt, CDiag *pEigenValt)
{
pFaceMat = pFaceMatt;
pEigenVal = pEigenValt;
bMat = TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -