给公司一个产品做的配套小功能。放出一点自认为有一点技术含量的代码。
1、探头类
class CDetector
{
//Attributs:
public:
RECT rect;
LPBITMAPINFO lpBitmapInfo;
LPVOID lpSrcBits;
HDC hdcDest;
HDC hdcMem;
HBITMAP hbmpDet;
//探头编号
UINT id;
//探头的端点集合,最大支持128端点图形
POINT ptArray[128];
//投入使用的端点数(1~128)
unsigned short cbPoints;
//用于填充探头区域的图形
BITMAP bmpDet;
POINT ptDest;
int DetWidth;
int DetHeight;
//Operators:
public:
//报警
void Alarm();
void UnDrawDetector(void);
void DrawDetector(HDC hdcDest, int xDest, int yDest);
void BeginDrawing(HWND hwndMainWnd);
protected:
HDC hdcOld;
void RotateAnyAngle(HDC hdcSrc, int SrcWidth, int SrcHeight, double angle);
HBITMAP hbmpOld;
BITMAP bmpOld;
public:
CDetector * pNextDetector;
void Rotate(void);
void AlarmStop(void);
static DWORD WINAPI ThreadAlarm(LPVOID lp);
HBITMAP hbmpAlarm;
void Release(void);
CDetector();
virtual ~CDetector();
private:
BOOL bAlarming;
void Init(void);
};
// Detector.cpp: implementation of the CDetector class.
//
//
#include "stdafx.h"
#include "DragPicture.h"
#include "Detector.h"
#include "DragPictureDlg.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//UINT CDetector::id = 0;
//
// Construction/Destruction
//
CDetector::CDetector()
{
bAlarming = FALSE;
Init();
}
CDetector::~CDetector()
{
if(hdcMem)
::DeleteDC(hdcMem);
//if(hdcDest)
//::DeleteDC(hdcDest);
if(hdcOld)
::DeleteDC(hdcOld);
if(hbmpDet)
::DeleteObject(hbmpDet);
if(hbmpOld)
::DeleteObject(hbmpOld);
}
void CDetector::Alarm()
{
bAlarming = TRUE;
HANDLE h = CreateThread(0, 0, ThreadAlarm, this, CREATE_SUSPENDED, 0);
SetThreadPriority(h, THREAD_PRIORITY_ABOVE_NORMAL);
ResumeThread(h);
}
void CDetector::Init()
{
POINT ptTmp[] = {
5, 0, 20, 0,
20, 4, 24, 4,
24, 11, 20, 11,
20, 20, 24, 20,
24, 27, 20, 27,
20, 36, 24, 36,
24, 43, 24, 36,
24, 43, 20, 43,
20, 47, 5, 47};
cbPoints = sizeof(ptTmp) / sizeof(POINT);
CopyMemory(ptArray, ptTmp, cbPoints);
hbmpDet = ::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BMP_DETECTOR3));
hbmpAlarm = ::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BMP_DETECTOR3_ALARM));
::GetObject(hbmpDet, sizeof(BITMAP), &bmpDet);
DetHeight = bmpDet.bmHeight;
DetWidth = bmpDet.bmWidth;
LPCTSTR lpszFileName=".//res//bmp_dete.bmp"; //文件路径
CFile file; //用于读取BMP文件
BITMAPFILEHEADER bfhHeader; //bmp文件头
BITMAPINFOHEADER bmiHeader; //bmp格式头
//bmp格式具体信息
int bmpWidth=0; //图片宽度
int bmpHeight = 0; //图片高度
if(!file.Open(lpszFileName,CFile::modeRead))
return ; //打开文件
file.Read(&bfhHeader,sizeof(BITMAPFILEHEADER)); //读取文件头
if(bfhHeader.bfType!=((WORD) ('M'<<8)|'B')) //判断是否是"BM"
return ;
if(bfhHeader.bfSize!=file.GetLength())
return ;
if (file.Read((LPSTR)&bmiHeader, sizeof(bmiHeader)) != sizeof(bmiHeader))
return ;
bmpHeight = bmiHeader.biHeight;//得到高度和宽度
bmpWidth = bmiHeader.biWidth;
file.SeekToBegin();
file.Read(&bfhHeader,sizeof(BITMAPFILEHEADER));
UINT uBmpInfoLen=(UINT) bfhHeader.bfOffBits-sizeof(BITMAPFILEHEADER);
lpBitmapInfo=(LPBITMAPINFO) new BYTE[uBmpInfoLen];
file.Read((LPVOID) lpBitmapInfo,uBmpInfoLen);
if((* (LPDWORD)(lpBitmapInfo))!=sizeof(BITMAPINFOHEADER))
return ;
DWORD dwBitlen=bfhHeader.bfSize - bfhHeader.bfOffBits;
lpSrcBits=new BYTE[dwBitlen]; //将数据读入lpSrcBits数组
file.ReadHuge(lpSrcBits,dwBitlen);
file.Close();
}
void CDetector::BeginDrawing(HWND hwndMainWnd)
{
HCURSOR hCursor = ::LoadCursor(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDC_CURSOR1));
//::SetCursor(hCursor);
::SetClassLong(hwndMainWnd, GCL_HCURSOR,
(LONG)::LoadCursor(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDC_CURSOR1)));
}
void CDetector::DrawDetector(HDC hdcDest, int xDest, int yDest)
{
this->hdcDest = hdcDest;
ptDest.x = xDest;
ptDest.y = yDest;
rect.left = xDest;
rect.top = yDest;
rect.right = xDest + bmpDet.bmWidth;
rect.bottom = yDest + bmpDet.bmHeight;
//保存要覆盖区域的HBITMAP
hbmpOld = ::CreateCompatibleBitmap(this->hdcDest, bmpDet.bmWidth, bmpDet.bmHeight);
hdcOld = ::CreateCompatibleDC(this->hdcDest);
::SelectObject(hdcOld, hbmpOld);
::BitBlt(hdcOld, 0, 0, bmpDet.bmWidth, bmpDet.bmHeight,
this->hdcDest, ptDest.x, ptDest.y, SRCCOPY);
//绘制探头
hdcMem = ::CreateCompatibleDC(this->hdcDest);
::SelectObject(hdcMem, hbmpDet);
::BitBlt(this->hdcDest, ptDest.x, ptDest.y, bmpDet.bmWidth, bmpDet.bmHeight,
hdcMem, 0, 0, SRCAND);
}
void CDetector::UnDrawDetector()
{
//将被覆盖区域的HBITMAP选进记忆设备描述表hdcMem
::BitBlt(this->hdcDest, ptDest.x, ptDest.y, bmpDet.bmWidth, bmpDet.bmHeight,
hdcOld, 0, 0, SRCCOPY);
}
void CDetector::Release()
{
/*
if(hdcMem)
::DeleteDC(hdcMem);
if(hdcDest)
::DeleteDC(hdcDest);
if(hdcOld)
::DeleteDC(hdcOld);
if(hbmpDet)
::DeleteObject(hbmpDet);
if(hbmpOld)
::DeleteObject(hbmpOld);
*/
}
DWORD WINAPI CDetector::ThreadAlarm(LPVOID lp)
{
CDetector *pDet = (CDetector *)lp;
CDragPictureDlg *pdlg = (CDragPictureDlg *)AfxGetApp()->m_pMainWnd;
RECT rect;
::SetRect(&rect, pDet->ptDest.x - pdlg->nXSrc, pDet->ptDest.y - pdlg->nYSrc,
pDet->ptDest.x + pDet->DetWidth - pdlg->nXSrc,
pDet->ptDest.y + pDet->DetHeight - pdlg->nYSrc);
while(pDet->bAlarming)
{
pDet->UnDrawDetector();
::SelectObject(pDet->hdcMem, pDet->hbmpAlarm);
::BitBlt(pDet->hdcDest, pDet->ptDest.x, pDet->ptDest.y, pDet->bmpDet.bmWidth, pDet->bmpDet.bmHeight,
pDet->hdcMem, 0, 0, SRCAND);
pdlg->InvalidateRect(&rect, TRUE);
Sleep(600);
pDet->UnDrawDetector();
::SelectObject(pDet->hdcMem, pDet->hbmpDet);
::BitBlt(pDet->hdcDest, pDet->ptDest.x, pDet->ptDest.y, pDet->bmpDet.bmWidth, pDet->bmpDet.bmHeight,
pDet->hdcMem, 0, 0, SRCAND);
pdlg->InvalidateRect(&rect, TRUE);
Sleep(600);
}
return 0;
}
void CDetector::AlarmStop()
{
bAlarming = FALSE;
}
void CDetector::Rotate()
{
//double angle = (90.0/180.0)*3.14159;
//RotateAnyAngle(hdcMem, bmpDet.bmWidth, bmpDet.bmHeight, angle);
double angle = (90.0/180.0)*3.14159;//旋转45Degree,可为任意角度
BitBlt(hdcMem,0,0,bmpDet.bmWidth, bmpDet.bmHeight, hdcDest,0,0,SRCCOPY);//这一步很重要