给公司一个产品做的配套小功能。放出一点自认为有一点技术含量的代码。

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);//这一步很重要
StretchDIBits(hdcMem,0,0,bmpDet.bmWidth,bmpDet.bmHeight,
0,0,bmpDet.bmWidth,bmpDet.bmHeight,lpSrcBits,lpBitmapInfo,DIB_RGB_COLORS,SRCCOPY);
RotateAnyAngle(hdcMem,bmpDet.bmWidth,bmpDet.bmHeight,angle);
}

void CDetector::RotateAnyAngle(HDC hdcSrc, int SrcWidth, int SrcHeight, double angle)
{
double x1, x2, x3;
double y1, y2, y3;
double maxWidth, maxHeight, minWidth, minHeight;
double srcX, srcY;
double sinA, cosA;
double DstWidth;
double DstHeight;
HDC hdcDst;//旋转后的内存设备环境
HBITMAP newBitmap;
sinA = sin(angle);
cosA = cos(angle);
x1 = -SrcHeight*sinA;
y1 = SrcHeight*cosA;
x2 = SrcWidth*cosA-SrcHeight*sinA;
y2 = SrcHeight*cosA+SrcWidth*sinA;
x3 = SrcWidth*cosA;
y3 = SrcWidth*sinA;
minWidth = x3>(x1>x2?x2:x1)?(x1>x2?x2:x1):x3;
minWidth=minWidth>0?0:minWidth;
minHeight=y3>(y1>y2?y2:y1)?(y1>y2?y2:y1):y3;
minHeight=minHeight>0?0:minHeight;
maxWidth=x3>(x1>x2?x1:x2)?x3:(x1>x2?x1:x2);
maxWidth=maxWidth>0?maxWidth:0;
maxHeight=y3>(y1>y2?y1:y2)?y3:(y1>y2?y1:y2);
maxHeight=maxHeight>0?maxHeight:0;
DstWidth=maxWidth-minWidth;
DstHeight=maxHeight-minHeight;
hdcDst=CreateCompatibleDC(hdcSrc);
newBitmap=CreateCompatibleBitmap(hdcSrc,(int)DstWidth,(int)DstHeight);
SelectObject(hdcDst,newBitmap);
for(int I=0;I<DstHeight;I++)
{
for(int J=0;J<DstWidth;J++)
{
srcX=(J+minWidth)*cosA+(I+minHeight)*sinA;
srcY=(I+minHeight)*cosA-(J+minWidth)*sinA;
if((srcX>=0)&&(srcX<=SrcWidth)&&(srcY>=0)&&(srcY<=SrcHeight))
{
BitBlt(hdcDst,J,I,1,1,hdcSrc,(int)srcX,(int)srcY,SRCCOPY);
}
}
}
}



2、对话框类

// DragPictureDlg.h : header file
//

#if !defined(AFX_DRAGPICTUREDLG_H__6AE96BD5_759E_483B_813C_591D1EB226BA__INCLUDED_)
#define AFX_DRAGPICTUREDLG_H__6AE96BD5_759E_483B_813C_591D1EB226BA__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "Detector.h"
#include "DBOper.h"


/
// CDragPictureDlg dialog

class CDragPictureDlg : public CDialog
{
public:
unsigned int idSelected;
CDBOper db;
//建立链表需要的临时指针
CDetector* pDetTmp;
//表示链表第一个元素的指针
CDetector* pDetFirst;
//表示链表最后一个元素的指针
CDetector* pDetLast;
//表示点选的探头的指针
CDetector* pDetToDel;
//探头数组
CDetector *pDet[MAX_DETECTOR_NUM];
int cxClient;
int cyClient;
int nXSrc;
int nYSrc;
POINT ptEnd;
POINT ptBeg;
BOOL bMoved;
BOOL bDraging;
int cxSource;
int cySource;
BITMAP bmpMap;
HDC hdcClient;
HDC hdcMem;
HBITMAP hbmp;
RECT rectClient;
// Construction
public:
int iAccumeDelta;
int iDeltaPerLine;
RECT rectToolbar;
bool bHasDetOnMap;
void OnImportBmp(TCHAR *szBmpName);
void DrawDetector(UINT id, int x, int y);
CString strFilePath;
unsigned int nDetectorNums;
BOOL bDrawing;
CDragPictureDlg(CWnd* pParent = NULL); // standard constructor

// Dialog Data
//{{AFX_DATA(CDragPictureDlg)
enum { IDD = IDD_DRAGPICTURE_DIALOG };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA

// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDragPictureDlg)
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL

// Implementation
protected:
HICON m_hIcon;

// Generated message map functions
//{{AFX_MSG(CDragPictureDlg)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnMenuOpenBmp();
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnTimer(UINT nIDEvent);
afx_msg void OnDestroy();
afx_msg void OnDrawDetector();
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnToolCursor();
afx_msg void OnUpdateToolCursor(CCmdUI* pCmdUI);
afx_msg void OnToolDetector3();
afx_msg void OnToolDelete();
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnMenuCursor();
afx_msg void OnMenuDelete();
afx_msg void OnMenuDetector3();
afx_msg void OnMenuAlarm();
afx_msg void OnMenuImportdetector();
afx_msg void OnMenuAlarmcancel();
afx_msg void OnMenuRotate();
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
CToolBar mToolBar;
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_DRAGPICTUREDLG_H__6AE96BD5_759E_483B_813C_591D1EB226BA__INCLUDED_)


// DragPictureDlg.cpp : implementation file
//

#include "stdafx.h"
#include "DragPicture.h"
#include "DragPictureDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

const UINT IDTimerDraging = 1;
TCHAR szDefaultPathName[256] = TEXT("C:\\");

/
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
CAboutDlg();

// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA

// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL

// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CDragPictureDlg dialog

CDragPictureDlg::CDragPictureDlg(CWnd* pParent /*=NULL*/)
: CDialog(CDragPictureDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CDragPictureDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

bDraging = FALSE;
bMoved = FALSE;
bDrawing = FALSE;
nXSrc = 0;
nYSrc = 0;
nDetectorNums = 0;
memset(pDet, 0, sizeof(pDet));
idSelected = 0;
pDetTmp = NULL;
pDetFirst = new CDetector();
pDetLast = NULL;
pDetToDel = NULL;
bHasDetOnMap = false;
iAccumeDelta = 0;
}

void CDragPictureDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDragPictureDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CDragPictureDlg, CDialog)
//{{AFX_MSG_MAP(CDragPictureDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_COMMAND(IDM_IMPORT_BMP, OnMenuOpenBmp)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_TIMER()
ON_WM_DESTROY()
ON_COMMAND(IDM_DRAW, OnDrawDetector)
ON_WM_KEYDOWN()
ON_COMMAND(IDT_CURSOR, OnToolCursor)
ON_UPDATE_COMMAND_UI(IDT_CURSOR, OnUpdateToolCursor)
ON_COMMAND(IDT_DETECTOR3, OnToolDetector3)
ON_COMMAND(IDT_DELETE, OnToolDelete)
ON_WM_SIZE()
ON_COMMAND(IDM_CURSOR, OnMenuCursor)
ON_COMMAND(IDM_DELETE, OnMenuDelete)
ON_COMMAND(IDM_DETECTOR3, OnMenuDetector3)
ON_COMMAND(IDM_ALARM, OnMenuAlarm)
ON_COMMAND(IDM_IMPORTDETECTOR, OnMenuImportdetector)
ON_COMMAND(IDM_ALARMCANCEL, OnMenuAlarmcancel)
ON_COMMAND(IDM_ROTATE, OnMenuRotate)
ON_WM_CREATE()
ON_WM_MOUSEWHEEL()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CDragPictureDlg message handlers

BOOL CDragPictureDlg::OnInitDialog()
{
CDialog::OnInitDialog();

// Add "About..." menu item to system menu.

// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}

// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here

//CMenu *pMenu = GetMenu();


//TCHAR szBmpName[] = TEXT("D:\\DragPicture\\HouseLayoutDrawing.bmp");
//TCHAR szBmpName[] = TEXT("D:\\DragPicture\\pic.bmp");
TCHAR szBmpName[] = TEXT("D:\\DragPicture\\HongJiZiYunL6.bmp");
OnImportBmp(szBmpName) ;
db.SelectDetectorAndDraw(strFilePath);

return TRUE; // return TRUE unless you set the focus to a control
}

void CDragPictureDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}

// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.

void CDragPictureDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting

SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;

// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
::BitBlt(hdcClient, 0, 0, cxClient, cyClient,
//hdcMem, 0, 0, SRCCOPY);
hdcMem, nXSrc, nYSrc, SRCCOPY);
}
}

// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CDragPictureDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CDragPictureDlg::OnMenuOpenBmp()
{
CString strFilter = TEXT("位图文件(*.bmp)|*.bmp||");
CFileDialog dlg(TRUE, NULL, NULL, NULL, strFilter, this);
dlg.m_ofn.lpstrInitialDir = szDefaultPathName;
if(IDOK == dlg.DoModal())
{
CString strPathName = dlg.GetPathName();
CString strFileName = dlg.GetFileName();
CString strPath = strFilePath.Left(strFilePath.GetLength() - strFileName.GetLength());
lstrcpy(szDefaultPathName, strPath.GetBuffer(strPath.GetLength()));

OnImportBmp(strPathName.GetBuffer(strPathName.GetLength()));
}
}

void CDragPictureDlg::OnImportBmp(TCHAR *szBmpName)
{
// TODO: Add your command handler code here


strFilePath.Format("%s", szBmpName);
HINSTANCE hInst = (HINSTANCE)::GetWindowLong(m_hWnd, GWL_HINSTANCE);


FILE *fp;
BITMAPFILEHEADER bmpFileHeader;
BITMAPINFOHEADER bmpInfoHeader;
unsigned int uiRead;

fp = fopen(szBmpName, "rb");
if((fp = fopen(szBmpName, "rb")) == NULL)
{
MessageBox(TEXT("read file err"));
return ;
}
uiRead = fread(&bmpFileHeader, 1, sizeof(bmpFileHeader), fp);
if( uiRead != sizeof(bmpFileHeader))
{
MessageBox(TEXT("read file header err"));
return ;
}
if(bmpFileHeader.bfType != 0x4d42)
{
MessageBox(TEXT("not a bmp file"));
return ;
}
if((fread(&bmpInfoHeader, 1, sizeof(bmpInfoHeader), fp)) != sizeof(bmpInfoHeader))
{
MessageBox(TEXT("read info header err"));
return ;
}
if(bmpInfoHeader.biBitCount != 24)
{
MessageBox(TEXT("not a 24 bits bitmap"));
return ;
}
fclose(fp);
cxSource = bmpInfoHeader.biWidth;
cySource = bmpInfoHeader.biHeight;

hdcClient = ::GetDC(m_hWnd);
hdcMem = ::CreateCompatibleDC(hdcClient);
hbmp = (HBITMAP)::LoadImage(hInst, szBmpName, IMAGE_BITMAP, cxSource, cySource, LR_LOADFROMFILE);
::GetObject(hbmp, sizeof(BITMAP), &bmpMap);
::SelectObject(hdcMem, hbmp);
::GetClientRect(m_hWnd, &rectClient);

cxClient = rectClient.right - rectClient.left;
cyClient = rectClient.bottom - rectClient.top;// - (rectToolbar.bottom - rectToolbar.top);

::BitBlt(hdcClient, 0, 0, cxClient, cyClient,
hdcMem, nXSrc, nYSrc, SRCCOPY);
}

void CDragPictureDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default

CDialog::OnLButtonDown(nFlags, point);
//绘制探头
if(bDrawing == TRUE)
{
if(++nDetectorNums == MAX_DETECTOR_NUM)
return;
POINT ptNow;
::GetCursorPos(&ptNow);
::ScreenToClient(m_hWnd, &ptNow);
ptNow.x += nXSrc;
ptNow.y += nYSrc;

DrawDetector(nDetectorNums, ptNow.x, ptNow.y);
db.Add(nDetectorNums, ptNow.x, ptNow.y, strFilePath);

}
//拖动地图
else
{
/*
idSelected = 0;
for(unsigned int i = 1; i <= nDetectorNums; i++)
{
if((pDet[i]) &&
::PtInRect(&(pDet[i]->rect), point))
{
idSelected = i;
break;
}
}
*/

if(bHasDetOnMap)
{
for(pDetToDel = pDetFirst; pDetToDel != pDetLast; )
{
if(pDetToDel
&& ::PtInRect(&(pDetToDel->rect), point))
break;

pDetToDel = pDetToDel->pNextDetector;
}
TRACE("Det To Del id %d\n", pDetToDel->id);
}

bDraging = TRUE;
ptBeg = point;
}
}

void CDragPictureDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default

CDialog::OnLButtonUp(nFlags, point);
if(bMoved == TRUE)
{
bDraging = FALSE;
bMoved = FALSE;
KillTimer(IDTimerDraging);
}
bMoved = FALSE;
bDraging = FALSE;
}

void CDragPictureDlg::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default

CDialog::OnMouseMove(nFlags, point);
if(bDraging == TRUE)
{
bDraging = FALSE;
bMoved = TRUE;

//::SetFocus(m_hWnd);
SetTimer(IDTimerDraging, 1, NULL);
}
}

void CDragPictureDlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
switch(nIDEvent)
{
case IDTimerDraging:
{
POINT ptNow;
GetCursorPos(&ptNow);
ScreenToClient(&ptNow);

if(!PtInRect(&rectClient, ptNow) || (cxSource <= cxClient))
{
bDraging = FALSE;

KillTimer(IDTimerDraging);
break;
}

if(ptBeg.x != ptNow.x || ptBeg.y != ptEnd.y)
{
int cxMove, cyMove;

cxMove = ptBeg.x - ptNow.x;
cyMove = ptBeg.y - ptNow.y;
nXSrc += cxMove;
nYSrc += cyMove;

if(nXSrc < 0)
nXSrc = 0;
if(nYSrc < 0)
nYSrc = 0;

if(nXSrc > cxSource - cxClient)
nXSrc = cxSource - cxClient;
if(nYSrc > cySource - cyClient)
nYSrc = cySource - cyClient;

::BitBlt(hdcClient, 0, 0, cxClient, cyClient,
hdcMem, nXSrc, nYSrc, SRCCOPY);

ptBeg = ptNow;
}

}
break;
}
CDialog::OnTimer(nIDEvent);
}

void CDragPictureDlg::OnDestroy()
{
CDialog::OnDestroy();

// TODO: Add your message handler code here
::ReleaseDC(m_hWnd, hdcClient);
::ReleaseDC(m_hWnd, hdcMem);
::DeleteObject(hbmp);
}

void CDragPictureDlg::OnDrawDetector()
{
// TODO: Add your command handler code here

}

void CDragPictureDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call default
/*switch(nChar)
{
case VK_ESCAPE:
SetClassLong(m_hWnd, GCL_HCURSOR,
(LONG)::LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW)));
return;
break;
}*/
CDialog::OnKeyDown(nChar, nRepCnt, nFlags);
}

BOOL CDragPictureDlg::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
if(pMsg->message == WM_KEYDOWN)
{
if(pMsg->wParam == VK_ESCAPE)
{
OnToolCursor();
return TRUE;
}
}

return CDialog::PreTranslateMessage(pMsg);
}

void CDragPictureDlg::OnToolCursor()
{
// TODO: Add your command handler code here
SetClassLong(m_hWnd, GCL_HCURSOR,
(LONG)::LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW)));
POINT pt;
::GetCursorPos(&pt);
pt.x += 1; pt.y += 1;
::SetCursorPos(pt.x, pt.y);
bDrawing = FALSE;

}

void CDragPictureDlg::OnUpdateToolCursor(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
int i = 0;
}

void CDragPictureDlg::OnToolDetector3()
{
// TODO: Add your command handler code here
pDet[0] = new CDetector();
pDet[0]->BeginDrawing(m_hWnd);
bDrawing = TRUE;
}

void CDragPictureDlg::OnToolDelete()
{
if(nDetectorNums == 0)
return;

/*
for(size_t i = nDetectorNums; i >= 1; i--)
{
if(pDet[i]->id == nDetectorNums)
{
pDet[i]->UnDrawDetector();
nDetectorNums--;
OnToolCursor() ;
RECT rect;
::SetRect(&rect, pDet[i]->ptDest.x - nXSrc, pDet[i]->ptDest.y - nYSrc,
pDet[i]->ptDest.x + pDet[i]->DetWidth - nXSrc,
pDet[i]->ptDest.y + pDet[i]->DetHeight - nYSrc);

InvalidateRect(&rect, TRUE);
db.Delete(i);
break;
}
}
*/
//pDetToDel
pDetToDel->UnDrawDetector();
OnToolCursor();
RECT rect;
int i = pDetToDel->id;
::SetRect(&rect, pDetToDel->ptDest.x - nXSrc, pDetToDel->ptDest.y - nYSrc,
pDetToDel->ptDest.x + pDetToDel->DetWidth - nXSrc,
pDetToDel->ptDest.y + pDetToDel->DetHeight - nYSrc);

InvalidateRect(&rect, TRUE);
db.Delete(pDetToDel->id);

CDetector *pDetMem = new CDetector;
for(pDetMem = pDetFirst; pDetMem != pDetLast; )
{
if(pDetToDel == pDetLast)
{
if(pDetMem->pNextDetector == pDetLast)
{
pDetToDel = pDetLast = pDetMem;
break;
}
}
else if(pDetMem->pNextDetector == pDetToDel)
{
pDetMem->pNextDetector = pDetToDel->pNextDetector;
pDetToDel = pDetLast;
break;
}

pDetMem = pDetMem->pNextDetector;
}
}

void CDragPictureDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);

// TODO: Add your message handler code here
cxClient = cx;
cyClient = cy;// - (rectToolbar.bottom - rectToolbar.top);

if(nXSrc < 0)
nXSrc = 0;
if(nYSrc < 0)
nYSrc = 0;

if(nXSrc > abs(cxSource - cxClient))
nXSrc = abs(cxSource - cxClient);
if(nYSrc > abs(cySource - cyClient))
nYSrc = abs(cySource - cyClient);

if(nType == SIZE_MAXIMIZED && cxSource < cxClient && cySource < cyClient)
{
nXSrc = 0;
nYSrc = 0;
}
}

void CDragPictureDlg::OnMenuCursor()
{
// TODO: Add your command handler code here
OnToolCursor();
}

void CDragPictureDlg::OnMenuDelete()
{
// TODO: Add your command handler code here
OnToolDelete();
}

void CDragPictureDlg::OnMenuDetector3()
{
// TODO: Add your command handler code here
OnToolDetector3();
}

void CDragPictureDlg::OnMenuAlarm()
{
// TODO: Add your command handler code here

//CreateThread(0, 0, ThreadAlarm, this, 0, 0);
//for(unsigned int i = 1; i < nDetectorNums - 1; i+=2)
pDet[1]->Alarm();
}

void CDragPictureDlg::DrawDetector(UINT id, int x, int y)
{
if(pDet[id])
{
pDet[id]->Release();
pDet[id] = NULL;
}

pDet[id] = new CDetector();
pDet[id]->id = id;
pDet[id]->DrawDetector(hdcMem, x, y);
//Invalidate();
::BitBlt(hdcClient, 0, 0, cxClient, cyClient,
hdcMem, nXSrc, nYSrc, SRCCOPY);

if(pDetTmp != NULL)
pDetTmp->pNextDetector = pDet[id];
else
pDetFirst->pNextDetector = pDet[id];

pDetTmp = pDet[id];
pDetLast = pDet[id];
pDetToDel = pDet[id];

bHasDetOnMap = true;
}

void CDragPictureDlg::OnMenuImportdetector()
{
// TODO: Add your command handler code here
db.SelectDetectorAndDraw(strFilePath);
}

//DEL DWORD WINAPI CDragPictureDlg::ThreadAlarm(LPVOID lp)
//DEL {
//DEL int i = 1;
//DEL int time = 5;
//DEL CDragPictureDlg *pdlg = (CDragPictureDlg *)lp;
//DEL RECT rect;
//DEL ::SetRect(&rect, pdlg->pDet[i]->ptDest.x - pdlg->nXSrc, pdlg->pDet[i]->ptDest.y - pdlg->nYSrc,
//DEL pdlg->pDet[i]->ptDest.x + pdlg->pDet[i]->DetWidth - pdlg->nXSrc,
//DEL pdlg->pDet[i]->ptDest.y + pdlg->pDet[i]->DetHeight - pdlg->nYSrc);
//DEL while(time-- > 0)
//DEL {
//DEL pdlg->pDet[i]->UnDrawDetector();
//DEL pdlg->InvalidateRect(&rect, TRUE);
//DEL Sleep(500);
//DEL pdlg->pDet[i]->Alarm();
//DEL pdlg->InvalidateRect(&rect, TRUE);
//DEL //pdlg->DrawDetector(i, pdlg->pDet[i]->ptDest.x, pdlg->pDet[i]->ptDest.y);
//DEL Sleep(500);
//DEL }
//DEL //AfxMessageBox("Alarm over");
//DEL
//DEL
//DEL return 0;
//DEL }

void CDragPictureDlg::OnMenuAlarmcancel()
{
// TODO: Add your command handler code here
pDet[1]->AlarmStop();
}

void CDragPictureDlg::OnMenuRotate()
{
// TODO: Add your command handler code here
//pDet[nDetectorNums]->UnDrawDetector();
//Invalidate();
//pDet[nDetectorNums]->Rotate();
//DrawDetector(nDetectorNums, pDet[nDetectorNums]->ptDest.x, pDet[nDetectorNums]->ptDest.y);
}

int CDragPictureDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDialog::OnCreate(lpCreateStruct) == -1)
return -1;

// TODO: Add your specialized creation code here
/*
if(!mToolBar.CreateEx(this, TBSTYLE_FLAT,
WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS,
CRect(4, 4, 0, 0)) || !mToolBar.LoadToolBar(IDR_TOOLBAR1))
{
TRACE0(TEXT("create tool bar failed\n"));
return FALSE;
}
mToolBar.GetItemRect(0, &rectToolbar);
mToolBar.SetButtonStyle(0,TBBS_CHECKBOX);
mToolBar.SetButtonStyle(1,TBBS_CHECKBOX);
mToolBar.SetButtonStyle(2,TBBS_CHECKBOX);
//CFrameWnd::DockControlBar(&mToolBar, AFX_IDW_DOCKBAR_LEFT);
mToolBar.ShowWindow(TRUE);
RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0);
*/
return 0;
}

BOOL CDragPictureDlg::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
// TODO: Add your message handler code here and/or call default
static bool brun = false;
if(!brun)
{
unsigned long ulScrollLines;
::SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &ulScrollLines, 0);
if(ulScrollLines != 0)
iDeltaPerLine = WHEEL_DELTA / ulScrollLines;
else
iDeltaPerLine = 0;
brun =true;
}

if(iDeltaPerLine == 0)
return FALSE;

iAccumeDelta += zDelta;//(short)HIWORD(wParam); // 120 ro -120

//while(iAccumeDelta >= iDeltaPerLine)
{
//cxSource += cxSource * 0.1;
//cySource += cySource * 0.1;
HDC hdc = ::CreateCompatibleDC(hdcMem);
::StretchBlt(hdc, 0, 0, cxSource * 2, cxSource * 2,
hdcMem, 0, 0, cxSource, cySource, MERGECOPY);
::BitBlt(hdcMem, 0, 0, cxClient, cyClient,
hdc, 0, 0, MERGECOPY);
Invalidate();
//break;
}

while(iAccumeDelta <= iDeltaPerLine)
{
break;
}

return CDialog::OnMouseWheel(nFlags, zDelta, pt);
}


3、数据库操作类

// DBOper.h: interface for the CDBOper class.
//
//

#if !defined(AFX_DBOPER_H__AEBC8D6F_012E_4AF1_961A_3A45EFF94784__INCLUDED_)
#define AFX_DBOPER_H__AEBC8D6F_012E_4AF1_961A_3A45EFF94784__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "ado2.h"

class CDBOper
{
public:
CADODatabase * pDatebase;
CADORecordset * pDataGridRecord;
public:
void SelectDetectorAndDraw(CString strFilePath);
void Delete(UINT id);
void Add(UINT id, int xPos, int yPos, CString strFilePath);

CDBOper();
virtual ~CDBOper();
protected:
void ConnDB(void);

};

#endif // !defined(AFX_DBOPER_H__AEBC8D6F_012E_4AF1_961A_3A45EFF94784__INCLUDED_)


// DBOper.cpp: implementation of the CDBOper class.
//
//

#include "stdafx.h"
#include "DragPicture.h"
#include "DBOper.h"
#include "DragPictureDlg.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//
// Construction/Destruction
//

CDBOper::CDBOper()
{
pDatebase = new CADODatabase;
pDataGridRecord = new CADORecordset(pDatebase);
ConnDB();
}

CDBOper::~CDBOper()
{

}

void CDBOper::ConnDB()
{
//连接数据库
CString strConn = "";
strConn = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source= Detector.mdb;Jet OLEDB:Database Password= ";

if(!pDatebase->Open(strConn))
{
AfxMessageBox("数据库连接失败!");
}
}

void CDBOper::Add(UINT id, int xPos, int yPos, CString strFilePath)
{
CString str;
str.Format("Insert into Detectorpos(ID, X, Y, BmpFilePath)values(%d, %d, %d, '%s')", id, xPos, yPos, strFilePath);
pDatebase->Execute(str);
}

void CDBOper::Delete(UINT id)
{
CString str;
str.Format("Delete from Detectorpos where ID=%d", id);
pDatebase->Execute(str);
}

void CDBOper::SelectDetectorAndDraw(CString strFilePath)
{
CString str;
int count = 0;
str.Format("select * from Detectorpos where BmpFilePath='%s'", strFilePath);
pDataGridRecord->Open(pDatebase->m_pConnection,str);
count = pDataGridRecord->GetRecordCount();
if(count != 0)
{
int id, x, y;
CString strFilePath;
CDragPictureDlg *pdlg = (CDragPictureDlg *)AfxGetApp()->m_pMainWnd;
pdlg->nDetectorNums = count;
for(int i = 0; i < count; i++)
{
pDataGridRecord->GetFieldValue("ID", id);
pDataGridRecord->GetFieldValue("X", x);
pDataGridRecord->GetFieldValue("Y", y);
pDataGridRecord->GetFieldValue("BmpFilePath", strFilePath);

pdlg->DrawDetector(id, x, y);

pDataGridRecord->MoveNext();
}
}
pDataGridRecord->Close();
}


设计的很拙劣,但毕竟是我这个出道半年的小菜鸟自己完成的作品,高手愿意喷一喷就喷一喷吧。。☺