📄 wfmgraph.h
字号:
// WfmGraph.h: interface for the CWfmGraph class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_WFMGRAPH_H__AE6E88E5_9113_42AF_9F99_6B47C53DD109__INCLUDED_)
#define AFX_WFMGRAPH_H__AE6E88E5_9113_42AF_9F99_6B47C53DD109__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
//#include "WfmGraphImpl.h"
#include "AfxTempl.h"
#include "AFXMT.H"
/* 1.
处理波形窗事件, 采用对象策略(Strategy)模式,
被显示窗口继承使用。
*/
typedef struct _tagCursorMeasInfo
{
double xAxis; //X轴数据
double yAxis; //Y轴信息
}CursorMeasInfo;
/* 3.
模板类的形式实现波形显示, 结合模板类Adapter模式。
采用对象模式。
*/
#define PI 3.1415
#define MAXCHANNELNUM 64
template <class BASETYPE>
class CWfmGraph : public BASETYPE
{
//friend class CEventListner;
public:
typedef enum
{
adNormal = 0, //CNiGraph::TrackPlotAreaEvents, 正常
adZoom = 6, //CNiGraph::TrackZoomRectXY, 缩放方式
adPanXY = 3, //CNiGraph::TrackPanPlotAreaXY 平移方式
adCursor = 2 //CNiGraph::TrackDragCursor//光标方式
}WfmAdjMode;
public:
CWfmGraph():m_Minimum(0.0),m_Maximum(0.0),m_nMaxChnls(MAXCHANNELNUM)
{this->InitRes();}
virtual ~CWfmGraph(){this->DestroyRes();}
//1.产生曲线
void PaintWfm(int arrWfmSize[]/*每通道波形数*/, double *arrWfmData[]/*波形数据*/,
short nChnls/*通道数*/);
void PlotXY(int nDevice, int nChnl, double dbXValue, double dbYValue);
void PlotY(double *dbValue[], ULONG arrWfmSize[], int nCount/*数目*/);
void ChartXY(int nDevice, int nChnl, double dbXValue, double dbYValue); //ChartXY
void ChartY(double dbValue);
void ChartY(int nChnls, double dbValue[]);
void ChartY(double *dbValue[], int arrWfmSize[], int Device[], int Chnl[], int nCount/*数目*/);
void SavePic(CRect rc, CString &szPicNm);
//2.改变属性
int GetCapcity(){return MAXCHANNELNUM;}
//设定通道曲线的颜色
void SetMaxChnls(short nMaxChnls, CStringArray &arrChnlNms, CDWordArray &arrClrChnls);
void ChangeChnlClr(int nDevice, int nChnl, COLORREF clr);
void SetRange(double Minimum=0.0, double Maximum=600);
void SetYRange(int nAxisInd, double dMin=-0.01, double dMax=0.01); //设定Y轴范围
//3.实现增加/删除光标的功能
virtual void ApplyCursors(BOOL bEnable);
void SetAutoScale(int nDevice, int nChnl, BOOL bAutoScale); //自动坐标系
void SetAutoScale(); //自动坐标系
void SetWfmVis(int nDevice, int nChnl, BOOL bVis); //通道波形的可视性
void SetWfmAdjMode(WfmAdjMode adjMode); //通道调整方式
protected:
void ClearGraph();
double m_Minimum;
double m_Maximum;
short m_nMaxChnls;
CArray* pArrColors;
// CEventListner *m_pEvtListner; //波形窗事件通知
private:
void InitPlots(CStringArray *pArrChnlNms, CDWordArray *pArrClrChnls);
void InitRes(); //预定义颜色和变量
void DestroyRes();
BOOL SaveBmp(HBITMAP hBitmap, CString FileName);
CNiColor m_arrColors[MAXCHANNELNUM]; //颜色
static CNiReal64Vector m_ppWfmVectors[MAXCHANNELNUM];//
CCriticalSection m_critSect;
};
typedef CWfmGraph<CNiGraph> CCalWfmGraph;
/************************************************************************/
/* */
/************************************************************************/
template <class BASETYPE>
CNiReal64Vector CWfmGraph <BASETYPE>::m_ppWfmVectors[MAXCHANNELNUM];
template <class BASETYPE>
void CWfmGraph <BASETYPE>::SetMaxChnls(short nMaxChnls, CStringArray &arrChnlNms, CDWordArray &arrClrChnls)
{
m_nMaxChnls = nMaxChnls;
ASSERT(m_nMaxChnls <= MAXCHANNELNUM);
//
this->InitPlots(&arrChnlNms, &arrClrChnls);
}
template <class BASETYPE>
void CWfmGraph <BASETYPE>::SetAutoScale(int nDevice, int nChnl, BOOL bAutoScale)
{
char szFmt[36];
::sprintf(szFmt, "Dev%d-Ch%d", nDevice, nChnl);
if (this->GetPlots().GetCount()>0)
this->GetPlots().Item(szFmt).SetAutoScale(bAutoScale?true:false);
}
template <class BASETYPE>
BOOL CWfmGraph <BASETYPE>::SaveBmp(HBITMAP hBitmap, CString FileName)
{
//设备描述表
HDC hDC;
//当前分辨率下每象素所占字节数
int iBits;
//位图中每象素所占字节数
WORD wBitCount;
//定义调色板大小, 位图中像素字节大小 ,位图文件大小 , 写入文件字节数
DWORD dwPaletteSize=0, dwBmBitsSize=0, dwDIBSize=0, dwWritten=0;
//位图属性结构
BITMAP Bitmap;
//位图文件头结构
BITMAPFILEHEADER bmfHdr;
//位图信息头结构
BITMAPINFOHEADER bi;
//指向位图信息头结构
LPBITMAPINFOHEADER lpbi;
//定义文件,分配内存句柄,调色板句柄
HANDLE fh, hDib, hPal,hOldPal=NULL;
//计算位图文件每个像素所占字节数
hDC = CreateDC("DISPLAY", NULL, NULL, NULL);
iBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
DeleteDC(hDC);
if (iBits <= 1) wBitCount = 1;
else if (iBits <= 4) wBitCount = 4;
else if (iBits <= 8) wBitCount = 8;
else wBitCount = 24;
GetObject(hBitmap, sizeof(Bitmap), (LPSTR)&Bitmap);
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = Bitmap.bmWidth;
bi.biHeight = Bitmap.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = wBitCount;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrImportant = 0;
bi.biClrUsed = 0;
dwBmBitsSize = ((Bitmap.bmWidth * wBitCount + 31) / 32) * 4 * Bitmap.bmHeight;
//为位图内容分配内存
hDib = GlobalAlloc(GHND,dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER));
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
*lpbi = bi;
// 处理调色板
hPal = GetStockObject(DEFAULT_PALETTE);
if (hPal)
{
hDC = ::GetDC(NULL);
hOldPal = ::SelectPalette(hDC, (HPALETTE)hPal, FALSE);
RealizePalette(hDC);
}
// 获取该调色板下新的像素值
::GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight, (LPSTR)lpbi + sizeof(BITMAPINFOHEADER)
+dwPaletteSize, (BITMAPINFO *)lpbi, DIB_RGB_COLORS);
//恢复调色板
if (hOldPal)
{
::SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);
RealizePalette(hDC);
::ReleaseDC(NULL, hDC);
}
//创建位图文件
fh = CreateFile(FileName, GENERIC_WRITE,0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (fh == INVALID_HANDLE_VALUE) return FALSE;
// 设置位图文件头
bmfHdr.bfType = 0x4D42; // "BM"
dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize;
bmfHdr.bfSize = dwDIBSize;
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize;
// 写入位图文件头
::WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
// 写入位图文件其余内容
::WriteFile(fh, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL);
//清除
::GlobalUnlock(hDib);
::GlobalFree(hDib);
::CloseHandle(fh);
return TRUE;
}
template <class BASETYPE>
void CWfmGraph <BASETYPE>::SavePic(CRect rc, CString &szPicNm)
{
SIZE sz;
HWND hwnd = this->GetSafeHwnd();/*::GetDesktopWindow();*/
HDC hDC = ::GetDC(hwnd);
rc.NormalizeRect();
sz.cx=rc.right-rc.left;
sz.cy=rc.bottom-rc.top;
HBITMAP hbmp = ::CreateCompatibleBitmap(hDC, sz. cx,sz.cy);
HDC hmemdc = ::CreateCompatibleDC(hDC);
HGDIOBJ holdbmp = ::SelectObject(hmemdc, hbmp); //关键在此!!
::BitBlt(hmemdc/*Dest*/, 0, 0, sz.cx, sz.cx, hDC/*source*/, rc.left, rc.top, SRCCOPY);
::SelectObject(hmemdc, holdbmp);
::DeleteObject(hmemdc);
::ReleaseDC(hwnd, hDC);
//////////////////////////////////////////////////////////////////////////
//设备描述表
int iBits;
//当前显示分辨率下每个像素所占字节数
WORD wBitCount;
//位图中每个像素所占字节数
DWORD dwPaletteSize=0, dwBmBitsSize, dwDIBSize, dwWritten;
//定义调色板大小, 位图中像素字节大小 ,位图文件大小 , 写入文件字节数
BITMAP Bitmap;
BITMAPFILEHEADER bmfHdr;
//位图属性结构
BITMAPINFOHEADER bi;
//位图文件头结构
LPBITMAPINFOHEADER lpbi;
//位图信息头结构
HANDLE fh, hDib, hPal,hOldPal=NULL;
//指向位图信息头结构,定义文件,分配内存句柄,调色板句柄
//计算位图文件每个像素所占字节数
//hDC = CreateDC("DISPLAY", NULL, NULL, NULL);
iBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
//DeleteDC(hDC);
if (iBits <= 1)
wBitCount = 1;
else if (iBits <= 4)
wBitCount = 4;
else if (iBits <= 8)
wBitCount = 8;
else if (iBits <= 24)
wBitCount = 24;
else
wBitCount = 32;//原来没有,应有
//计算调色板大小
if (wBitCount <= 8)
dwPaletteSize = (1 << wBitCount) *sizeof(RGBQUAD);
//设置位图信息头结构
GetObject(hbmp, sizeof(BITMAP), (LPSTR)&Bitmap);
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = Bitmap.bmWidth;
bi.biHeight = Bitmap.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = wBitCount;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -