You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1203 lines
29 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "StdAfx.h"
#include "GlobalFunction.h"
#include "PropertiesWnd.h"
#include "BitOperation.h"
#include "GlobalDrawMgr.h"
#include<math.h>
#include "MsgBox.h"
#include "AllThreadMgr.h"
#include "WorkTime.h"
#include "FileMgr.h"
#include "WorkCmdInvoker.h"
#include "CStringFuc.h"
#if 1
UINT RedrawViewByThread(LPVOID pParam)
{
m_pView->RefreshView();
return 0;
}
UINT NewMsgThread(LPVOID pParam)
{
CMsgBox *pMsgBox = (CMsgBox *)pParam;
pMsgBox->ShowSetMsg();
return 0;
}
//获取当前视类指针
CLaiPuLaserView *GetCurViewPtr()
{
CMainFrame *pFrame = (CMainFrame*)AfxGetApp()->GetMainWnd();
CChildFrame *pChild = (CChildFrame*)pFrame->GetActiveFrame();
CLaiPuLaserView *pView = (CLaiPuLaserView*)pChild->GetActiveView();
return pView;
}
//获取当前文件指针
CLaiPuLaserDoc *GetCurDocPtr()
{
CLaiPuLaserView *pView = GetCurViewPtr();
CLaiPuLaserDoc *pDoc = pView->GetDocument();
return pDoc;
}
CMainFrame* GetFrame()
{
CMainFrame* pFrame = (CMainFrame*)AfxGetApp()->GetMainWnd();
return pFrame;
}
//通过新线程的方式刷新view
void RedrawViewByThread()
{
AfxBeginThread(RedrawViewByThread,NULL);
}
#endif
#if 1//矩形范围相关函数
//点是否在矩形中
bool IsPointInRect(Dbxy point,DbRect rect)
{
if(point.x>= rect.L && point.x<=rect.R && point.y<= rect.T && point.y>=rect.B)
return true;
else
return false;
}
//两个矩形是否相交
bool IsTwoRectIntersect(DbRect &rect1,DbRect &rect2)
{
if((((rect2.L>=rect1.L)&&(rect2.L<=rect1.R)) || ((rect2.R>=rect1.L)&&(rect2.R<=rect1.R))) &&
(((rect2.T>=rect1.B)&&(rect2.T<=rect1.T)) || ((rect2.B>=rect1.B)&&(rect2.B<=rect1.T))))
return true;
else
return false;
}
//判断点形成的直线是否可能和rect 相交
//Radius 是直线的一半长度mm
bool IsLineAndRectIntersect(Dbxy pt,DbRect rect,double Ang,double Radius)
{
//计算直线的端点
Dbxy StartPt(Radius*(-1),pt.y);
Dbxy EndPt(Radius,pt.y);
StartPt = RotatoPt(StartPt,Ang,pt);
EndPt = RotatoPt(EndPt,Ang,pt);
return IsLineInRect(StartPt,EndPt,rect);
}
//判断线段是否在矩形中
bool IsLineInRect(Dbxy point1,Dbxy point2,DbRect rect)
{
if(IsTwoLineIntersect(point1,point2,Dbxy(rect.R,rect.T),Dbxy(rect.L,rect.B)))
return true;
if(IsTwoLineIntersect(point1,point2,Dbxy(rect.L,rect.T),Dbxy(rect.R,rect.B)))
return true;
if(IsPointInRect(point1,rect) || IsPointInRect(point2,rect))
return true;
return false;
}
void AdjustRange(double &min,double &max,double val)
{
if(min>max)//第一个点
{
min = max = val;
}
else
{
if(min > val)
{
min = val;
}
if(max < val)
{
max = val;
}
}
}
//获取数据点的边界范围
DbRect GetDbPointVecRect(vector<Dbxy> &vec)
{
DbRect rect;
vector<Dbxy>::iterator iter = vec.begin();
vector<Dbxy>::iterator iter_end = vec.end();
for(;iter!=iter_end;iter++)
{
AdjustRectByPoint(rect,(*iter));
}
return rect;
}
DbRect GetDbPointVecRect(vector<vector<Dbxy>> &vec)
{
DbRect rect;
vector<vector<Dbxy>>::iterator iter = vec.begin();
vector<vector<Dbxy>>::iterator iter_end = vec.end();
for(;iter!=iter_end;iter++)
{
vector<Dbxy>::iterator iter1 = (*iter).begin();
vector<Dbxy>::iterator iter1_end = (*iter).end();
for(;iter1!=iter1_end;iter1++)
{
AdjustRectByPoint(rect,(*iter1));
}
}
return rect;
}
//根据一个点来扩大矩形范围
void AdjustRectByPoint(DbRect &rect,Dbxy pt)
{
AdjustRange(rect.L,rect.R,pt.x);
AdjustRange(rect.B,rect.T,pt.y);
}
//根据一个矩形来扩大矩形范围
void AdjustRectByRect(DbRect &rect1,DbRect rect2)
{
Dbxy pt1(rect2.L,rect2.T);
Dbxy pt2(rect2.R,rect2.B);
AdjustRectByPoint(rect1,pt1);
AdjustRectByPoint(rect1,pt2);
}
#endif
#if 1//判断两条线段是否相交
#define EPS 1e-8
#define ZERO(x) (((x)>0?(x):-(x))<EPS) //判断double 是否为0
//计算交叉乘积(P1-P0)x(P2-P0)
double xmult(Dbxy p1,Dbxy p2,Dbxy p0)
{
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
//判点是否在线段上,包括端点
int dot_online_in(Dbxy p,Dbxy l1,Dbxy l2)
{
return ZERO(xmult(p,l1,l2))&&(l1.x-p.x)*(l2.x-p.x)<EPS&&(l1.y-p.y)*(l2.y-p.y)<EPS;
}
//判两点在线段同侧,点在线段上返回0
int same_side(Dbxy p1,Dbxy p2,Dbxy l1,Dbxy l2)
{
return xmult(l1,p1,l2)*xmult(l1,p2,l2)>EPS;
}
//判两直线平行
int Parallel(Dbxy u1,Dbxy u2,Dbxy v1,Dbxy v2)
{
return ZERO((u1.x-u2.x)*(v1.y-v2.y)-(v1.x-v2.x)*(u1.y-u2.y));
}
//判三点共线
int dots_inline(Dbxy p1,Dbxy p2,Dbxy p3)
{
return ZERO(xmult(p1,p2,p3));
}
//两条线段是否相交
int IsTwoLineIntersect(Dbxy u1,Dbxy u2,Dbxy v1,Dbxy v2)
{
if (!dots_inline(u1,u2,v1)||!dots_inline(u1,u2,v2))
return !same_side(u1,u2,v1,v2)&&!same_side(v1,v2,u1,u2);
return dot_online_in(u1,v1,v2)||dot_online_in(u2,v1,v2)||dot_online_in(v1,u1,u2)||dot_online_in(v2,u1,u2);
}
//计算两条线段的交点
Dbxy CalIntersection(Dbxy u1,Dbxy u2,Dbxy v1,Dbxy v2)
{
Dbxy ret=u1;
double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))/((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));
ret.x+=(u2.x-u1.x)*t;
ret.y+=(u2.y-u1.y)*t;
return ret;
}
void IntersectionOfRectAndLineExt(bool &flg,Dbxy &pt1,Dbxy &pt2,Dbxy u1,Dbxy u2,Dbxy v1,Dbxy v2)
{
if(IsTwoLineIntersect(u1,u2,v1,v2))
{
//如果相交求出交点
Dbxy pt = CalIntersection(u1,u2,v1,v2);
if(flg)
{
pt1 = pt;
}
else
{
pt2 = pt;
}
flg =!flg;
}
}
//计算矩形和线段的交点
Dbxy IntersectionOfRectAndLine(Dbxy LinePt1,Dbxy LinePt2,DbRect rect)
{
bool flg = false;//用来区分保存到点1 还是点2
Dbxy pt1,pt2;
//先求出线段和rect 两条边的交点
{
Dbxy TmpPt1(rect.L,rect.T);
Dbxy TmpPt2(rect.L,rect.B);
IntersectionOfRectAndLineExt(flg,pt1,pt2,LinePt1,LinePt2,TmpPt1,TmpPt2);
}
{
Dbxy TmpPt1(rect.L,rect.B);
Dbxy TmpPt2(rect.R,rect.B);
IntersectionOfRectAndLineExt(flg,pt1,pt2,LinePt1,LinePt2,TmpPt1,TmpPt2);
}
{
Dbxy TmpPt1(rect.R,rect.B);
Dbxy TmpPt2(rect.R,rect.T);
IntersectionOfRectAndLineExt(flg,pt1,pt2,LinePt1,LinePt2,TmpPt1,TmpPt2);
}
{
Dbxy TmpPt1(rect.R,rect.T);
Dbxy TmpPt2(rect.L,rect.T);
IntersectionOfRectAndLineExt(flg,pt1,pt2,LinePt1,LinePt2,TmpPt1,TmpPt2);
}
//返回两个点的中间点
return CenterPtOfTwoPoint(pt1,pt2);
}
//计算两个点的中间的点
Dbxy CenterPtOfTwoPoint(Dbxy Pt1,Dbxy Pt2)
{
Dbxy ret;
ret.x = (Pt1.x+Pt2.x)/2;
ret.y = (Pt1.y+Pt2.y)/2;
return ret;
}
#endif
#if 1//计算函数
//反正切角转换为360 角
double AngleTo360(double Angle)
{
double _360Angle;
_360Angle = - Angle*180/PI;
//校正为正值
if(_360Angle < 0)
{
_360Angle += 360;
}
if(_360Angle > 180)
{
_360Angle -= 360;
}
return _360Angle;
}
//360 角转换为弧度(360°角=2π弧度)
double _360ToAngle(double _360Angle)
{
double Angle;
Angle = (_360Angle*PI)/180;
return Angle;
}
//计算反正切角度StartPt: 旋转起始点EndPt: 旋转结束点CenterPt: 旋转中心点
double CalAngle(Dbxy CenterPt,Dbxy StartPt,Dbxy EndPt)
{
double x2 = CenterPt.x;
double y2 = CenterPt.y;
double x1 = StartPt.x;
double y1 = StartPt.y;
double x3 = EndPt.x;
double y3 = EndPt.y;
double flRlt,flAtanA,flAtanB;
//从中心点竖方向开始旋转
if(x1==x2)
{
if(y1>y2)
{
flAtanA=PI/2;
}else if(y1<y2)
{
flAtanA=-PI/2;
}else
{
flAtanA=0;
}
flAtanB = 0;
}
//旋转到中心点竖方向
else if(x3==x2)
{
if(y3>y2)
{
flAtanB=PI/2;
}else if(y3<y2)
{
flAtanB=-PI/2;
}else
{
flAtanB=0;
}
flAtanA=0;
}
else
{
//反正切函数atan 可以将斜率转换为角度
flAtanA=atan((y1-y2)/(x1-x2));
flAtanB=atan((y3-y2)/(x3-x2));
if(y1-y2>0&&x1-x2<0){
flAtanA+=PI;
}
if(y1-y2<=0&&x1-x2<0){
flAtanA+=PI;
}
if(y3-y2>0&&x3-x2<0){
flAtanB+=PI;
}
if(y3-y2<=0&&x3-x2<0){
flAtanB+=PI;
}
}
flRlt=flAtanB-flAtanA;
return flRlt*(-1);
}
//通过两个点计算360 度角
double Cal360AngleByTwoPt(Dbxy pt1,Dbxy pt2)
{
Dbxy StartPt;
StartPt.x = CalDistance(pt1,pt2);
StartPt.y = pt1.y;
//先计算反正切角
double angle = CalAngle(pt1,StartPt,pt2);
return AngleTo360(angle);
}
//旋转一个点,返回旋转后的点
//Angle 是弧度角CenterPt 是旋转中心点
Dbxy RotatoPt(Dbxy pt,double Angle,Dbxy CenterPt)
{
Dbxy ret;
//旋转-----------------------------------------------
ret.x = ((pt.x-CenterPt.x)*cos(Angle)-(pt.y-CenterPt.y)*sin(Angle))+CenterPt.x;
ret.y = ((pt.y-CenterPt.y)*cos(Angle)+(pt.x-CenterPt.x)*sin(Angle))+CenterPt.y;
return ret;
}
//根据第一个点,线段的长度,角度计算出线段第二个点
//angle 是弧度角
Dbxy GetPoint2(Dbxy point1,double length,double angle)
{
Dbxy point2;
point2.x = point1.x+length*cos(angle);
point2.y = point1.y+length*sin(angle);
return point2;
}
#endif
#if 1
//判断两个double 是否相等
bool IsTwoDbEqual(double a,double b)
{
if((abs(a-b))<=COORD_EPS)
return true;
else
return false;
}
bool IsTwoDbEqual(double a,double b,double eps)
{
if((abs(a-b))<=eps)
return true;
else
return false;
}
bool IsTwoPtEqual(Dbxy pt1,Dbxy pt2,double eps)
{
return IsTwoDbEqual(pt1.x,pt2.x,eps) && IsTwoDbEqual(pt1.y,pt2.y,eps);
}
bool IsDbEqualZero(double num)
{
if(num<0)
{
num *= -1;
}
if(num <= COORD_EPS)
return true;
else
return false;
}
bool IsDbxyZero(Dbxy pt)
{
return IsDbEqualZero(pt.x) && IsDbEqualZero(pt.y);
}
void SwapTwoPt(Dbxy &pt1,Dbxy &pt2)
{
Dbxy pt = pt1;
pt1 = pt2;
pt2 = pt;
}
//计算两点之间的距离(勾股定律:Z^2 = X^2 + Y^2)
//返回值肯定是大于0 的
double CalDistance(Dbxy pt1,Dbxy pt2)
{
double flRlt;
flRlt=(pt1.x-pt2.x)*(pt1.x-pt2.x)+(pt1.y-pt2.y)*(pt1.y-pt2.y);
flRlt=sqrt(flRlt);
return flRlt;
}
//计算num 有几位
int GetNumDigit(int num)
{
int cnt = 0;
while(num)
{
num /=10;
cnt++;
}
if(cnt==0)//最少一位
cnt = 1;
return cnt;
}
#endif
#if 1
bool CheckStringIsNum(CString str)
{
CString strSet1 = "qwertyuiopasdfghjklzxcvbnm";
CString strSet2 = "QWERTYUIOPASDFGHJKLZXCVBNM";
CString strSet3 = "!@#$%^&*()_+=[]\\{}|;':\",/<>?";
CString strSet = strSet1+strSet2+strSet3;
if(str.FindOneOf(strSet)==-1)
{
return true;
}
return false;
}
//从str 中提取两个值(例如123.456,789.123)
//提取到Val1 返回1,同时提取到Val1,Val2 返回2
//一个没提取到返回0
int GetTwoNum(CString str,double &Val1,double &Val2)
{
int CommaPos = 0;
//检查是否有逗号
CommaPos = str.Find(',',0);
if(CommaPos!=-1)
{
CString str1(str,CommaPos);
str.Delete(0,CommaPos+1);
CString str2(str);
if(CheckStringIsNum(str1)&&CheckStringIsNum(str2))
{
Val1 = atof(str1);
Val2 = atof(str2);
return 2;
}
}
else
{
if(CheckStringIsNum(str))
{
Val1 = atof(str);
return 1;
}
}
return 0;
}
#endif
#if 1//排序点容器
//通过x 排序
bool CompareDbxyByX(Dbxy pt1,Dbxy pt2)
{
return pt1.x>pt2.x;
}
bool CompareDbxyByY(Dbxy pt1,Dbxy pt2)
{
return pt1.y>pt2.y;
}
#endif
#if 1
//判断shift 是否按下
bool IsShiftKeyDown()
{
if((GetAsyncKeyState(VK_SHIFT)&0x8000)&&(GetAsyncKeyState(VK_CONTROL)&0x8000))
return true;
else
return false;
}
//模拟鼠标左键点击(CoordX,CoordY屏幕坐标)
void MouseLeftBtnClick(int CoordX,int CoordY,bool bDbClick)
{
SetCursorPos(CoordX,CoordY);//鼠标移动到位置
mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,NULL);//鼠标down事件
mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,NULL);//鼠标up事件
if(bDbClick)//双击
{
mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,NULL);//鼠标down事件
mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,NULL);//鼠标up事件
}
}
//获取list 当前选择的行号
int GetCurListIdx(CListCtrl &list)
{
POSITION pos = list.GetFirstSelectedItemPosition();
if(pos == NULL)
{
return -1;
}
else
{
while (pos)
{
int nItem = list.GetNextSelectedItem(pos);
return nItem;
}
}
return -1;
}
#endif
#if 1
int Byte2Int(BYTE x)
{
BYTE c = 0x80;
int a = (IsBitOn(x,7))?c:0;
x = SetBitOff(x,7);
return x+a;
}
//保留double 小数点后面n 位
double RetainDecimalPlaces(double val,int n)
{
for(int i=0;i<n;i++)
{
val *= 10;
}
int t = (int)val;
val = (double)t;
for(int i=0;i<n;i++)
{
val /= 10;
}
return val;
}
//获取0~ rang 的一个随机值
int GetRandVal(int rang)
{
int ret = rand()%rang;
return ret;
}
//n 转换为16 进制字符(n>=0 && n<=15)
char Int2HexChar(int n)
{
char c = '0';
if(n>=0 && n<= 9)
c = '0' + n;
else if(n>=10 && n<= 15)
c = 'A' + n - 10;
return c;
}
//16进制的char 转换为十进制数
int HexChar2Int(char c)
{
int val = 0;
if(c>='0' && c<='9')
val = (c - '0');
else if(c>='A' && c<='F')
val = (c - 'A') + 10;
else if(c>='a' && c<='f')
val = (c - 'a') + 10;
return val;
}
//四字节的16 进制转换为十进制数(比如0707 ---->17991179---->4473)
double _4DigitHex2Double(char *buf,int len)
{
double Sum = 0;
for(int k=0;k<len;k++)
{
double m = len-k-1;
double val = HexChar2Int(buf[k]);
Sum += val*pow(16,m);
}
return Sum;
}
//两个字节的asc 字符转换为int (例如"0F" --->15)
int TwoCharHexStringToInt(CString str)
{
int Val = 0;
if(str.GetLength()>=2)
{
char *buf = CStringToLPCSTR(str);
Val = _2CharToHex(buf[0],buf[1]);
}
return Val;
}
//13 88--->5000 20 08--->8200
int HexByte2Int(int Byte1,int Byte2)
{
int Byte4 = Byte1%16;
int Byte3 = (Byte1-Byte4)/16;
int Byte6 = Byte2%16;
int Byte5 = (Byte2-Byte6)/16;
int val =0;
val = (Byte3)*16*16*16+(Byte4)*16*16+(Byte5)*16+(Byte6);
return val;
}
//10C3E4(十六进制)--->1098724(十进制)
//Byte3 低位Byte2 中位Byte1 高位
double _3HexByteToDouble(unsigned int ByteH,unsigned int ByteM,unsigned int ByteL)
{
unsigned int Byte4 = ByteH%16;
unsigned int Byte3 = (ByteH-Byte4)/16;
unsigned int Byte6 = ByteM%16;
unsigned int Byte5 = (ByteM-Byte6)/16;
unsigned int Byte7 = ByteL%16;
unsigned int Byte8 = (ByteL-Byte7)/16;
double val =0;
val = (Byte3)*16*16*16*16*16+(Byte4)*16*16*16*16+(Byte5)*16*16*16+(Byte6)*16*16+(Byte8)*16 + (Byte7);
return val;
}
double _4HexByteToDouble(unsigned int HexByte1,unsigned int HexByte2,unsigned int HexByte3,unsigned int HexByte4)
{
unsigned int Byte7 = HexByte1%16;
unsigned int Byte8 = (HexByte1-Byte7)/16;
unsigned int Byte5 = HexByte2%16;
unsigned int Byte6 = (HexByte2-Byte5)/16;
unsigned int Byte3 = HexByte3%16;
unsigned int Byte4 = (HexByte3-Byte3)/16;
unsigned int Byte1 = HexByte4%16;
unsigned int Byte2 = (HexByte4-Byte1)/16;
double val =0;
val += (Byte1);
val += (Byte2)*16;
val += (Byte3)*16*16;
val += (Byte4)*16*16*16;
val += (Byte5)*16*16*16*16;
val += (Byte6)*16*16*16*16*16;
val += (Byte7)*16*16*16*16*16*16;
val += (Byte8)*16*16*16*16*16*16*16;
return val;
}
//两个字符转换为16 进制数
//比如charA = 'B' ,charB = 'F' 转换为 0xBF (十进制191)
int _2CharToHex(char charA,char charB)
{
int a = HexChar2Int(charA);
int b = HexChar2Int(charB);
return a*16 + b;
}
/*整型数转换为2 字节16 进制数
比如5000的16 进制为0x1388 ,转换结果
buf[0] = 0x13
buf[1] = 0x88
*/
void IntTo2ByteHex(int n,char *buf)
{
char TmpBuf[128];
memset(TmpBuf,0,128);
//5000->"1388"
itoa(n,TmpBuf,16);
int len = strlen(TmpBuf);
char CharBuf4[4];
memset(CharBuf4,0,4);
int idx = 3;
while(len>0 && idx>=0)
{
CharBuf4[idx] = TmpBuf[len-1];//保存在TmpBuf 的后面几位
len--;
idx--;
}
buf[0] = _2CharToHex(CharBuf4[0],CharBuf4[1]);//0x13
buf[1] = _2CharToHex(CharBuf4[2],CharBuf4[3]);//0x88
}
//5000->"1388" 整型转换为四字节的16进制asc 字符串
CString IntTo4ByteHexStr(int n)
{
CString ValStr = "0000";
char *CharBuf = CStringToLPCSTR(ValStr);
char TmpBuf[128];
memset(TmpBuf,0,128);
//int --> char (16进制)
itoa(n,TmpBuf,16);//调用标准库来计算
int len = strlen(TmpBuf);
int idx = 3;
while(len>0 && idx>=0)
{
CharBuf[idx] = TmpBuf[len-1];//保存在TmpBuf 的后面几位
len--;
idx--;
}
//转换成大写字符
ValStr.MakeUpper();
return ValStr;
}
//500000->"07 A1 20" 整型转换为六字节的16进制asc 字符串
CString IntTo6ByteHexStr(int n)
{
CString ValStr = "000000";
char *CharBuf = CStringToLPCSTR(ValStr);
char TmpBuf[128];
memset(TmpBuf,0,128);
//int --> char (16进制)
itoa(n,TmpBuf,16);//调用标准库来计算
int len = strlen(TmpBuf);
int idx = 5;
while(len>0 && idx>=0)
{
CharBuf[idx] = TmpBuf[len-1];//保存在TmpBuf 的后面几位
len--;
idx--;
}
//转换成大写字符
ValStr.MakeUpper();
return ValStr;
}
CString IntTo8ByteHexStr(int n)
{
CString ValStr = "00000000";
char *CharBuf = CStringToLPCSTR(ValStr);
char TmpBuf[128];
memset(TmpBuf,0,128);
//int --> char (16进制)
itoa(n,TmpBuf,16);//调用标准库来计算
int len = strlen(TmpBuf);
int idx = 7;
while(len>0 && idx>=0)
{
CharBuf[idx] = TmpBuf[len-1];//保存在TmpBuf 的后面几位
len--;
idx--;
}
//转换成大写字符
ValStr.MakeUpper();
return ValStr;
}
//ByteLow 低8位,ByteHigh 高8位
int TwoByte2Int(BYTE ByteLow,BYTE ByteHigh)
{
int val = 0;
//ByteLow 低8位
for(int k=0;k<8;k++)
{
if(IsBitOn(ByteLow,k))
SetIntBitOn(val,k);
}
//ByteHigh 高8位
for(int k=0;k<8;k++)
{
if(IsBitOn(ByteHigh,k))
SetIntBitOn(val,k+8);
}
return val;
}
//获取int 的0~7 位或者8~15位
BYTE Int2Byte(int Val,bool bByteLow)
{
BYTE Byte = 0;
int Start=(bByteLow)?0:8;
for(int k=0;k<8;k++)
{
if((Val>>(k+Start))&1)
{
Byte= Byte |(1<<k);
}
}
return Byte;
}
#endif
#if 1
//等待一个线程结束
void WaitForThreadExit(CWinThread* pThread)
{
if(pThread == NULL)
return;
DWORD dRet=-2;
MSG msg;
while (1)
{
dRet=MsgWaitForMultipleObjects(1,&pThread->m_hThread,FALSE,INFINITE,QS_ALLINPUT);
if (dRet == WAIT_OBJECT_0)//等待的线程结束
{
break;
}
else if (dRet == WAIT_OBJECT_0+1)//有消息到达,转发
{
while (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else//错误
{
break;
}
}
}
//检查bool 变量b 为期望值,返回检查结果是否通过
bool CheckBool(bool b,CString msg)
{
if(!b)
{
CMsgBox MsgBox;
MsgBox.Show(msg);
return false;
}
return true;
}
//检查n 的范围[Start,end]
bool CheckRange(int n,int Start,int end)
{
return n>=Start && n<=end;
}
bool CheckRangeDb(double n,double Start,double end)
{
return n>=Start && n<=end;
}
bool CheckParRangeDb(CString ParName,double n,double Start,double end)
{
if(!CheckRangeDb(n,Start,end))
{
CString s1,s2;
s1 += "[";
s1 += ParName;
s1 += "]范围:";
s2.Format("[%.3f]~[%.3f]",Start,end);
s1 += s2;
CMsgBox MsgBox;
MsgBox.Show(s1);
return false;
}
return true;
}
//通过参数CirclePar 创建圆数据到Vec
void CreatCircleData(CCirclePar CirclePar,vector<Dbxy> &Vec)
{
Dbxy CenterPt = CirclePar.CenterPt;
double Radius = CirclePar.Radius;
int DEdgeCnt = CirclePar.DEdgeCnt;
bool bMerge = CirclePar.bMerge;
double StartAng = CirclePar.StartAng;
double EndAng = CirclePar.EndAng;
if(DEdgeCnt == 0)
{
DEdgeCnt = gDraw->GetCirclePtCnt(Radius);
}
//半径------------------------------------
double EachAngle = 360/DEdgeCnt;
bool Flg = true;//第一个点的标志
double CurrAngle =StartAng;
Dbxy pt;
Dbxy FirstPt;
bool bLastPt = false;
vector<Dbxy> VecTmp;
while(CurrAngle<(EndAng+0.001))
{
//角度转换为弧度
double radian = CurrAngle*PI/180;
if(IsDbEqualZero(Radius))//半径为0 则为点
{
pt = CenterPt;
}
else
{
pt.x = CenterPt.x + Radius*cos(radian);
pt.y = CenterPt.y + Radius*sin(radian);
}
if(Flg)
{
Flg = false;
FirstPt = pt;
VecTmp.push_back(pt);
}
else
{
VecTmp.push_back(pt);
}
if(bLastPt)
break;
CurrAngle += EachAngle;
if(CurrAngle>EndAng)//最后一个点特殊计算
{
CurrAngle = EndAng;
bLastPt = true;
}
}
//最后一条线段
if(bMerge)
{
VecTmp.push_back(FirstPt);
}
if(CirclePar.bReverse)
{
vector<Dbxy>::iterator iter = VecTmp.begin();
vector<Dbxy>::iterator iter_end = VecTmp.end();
reverse(iter,iter_end);
}
vector<Dbxy>::iterator iter = VecTmp.begin();
vector<Dbxy>::iterator iter_end = VecTmp.end();
for(;iter!=iter_end;iter++)
{
Dbxy pt = *iter;
pt.Cx = CenterPt.x;//设置圆弧信息
pt.Cy = CenterPt.y;
pt.bArc = true;
pt.bDir = CirclePar.bReverse;//圆弧的方向(区分顺时针和逆时针)
Vec.push_back(pt);
}
}
//计算圆弧的方向
bool GetArcDir(vector<Dbxy> &PtVec,Dbxy CenterPt)
{
int size = PtVec.size();
if(size>3)
{
Dbxy pt1 = PtVec[0];
Dbxy pt2 = PtVec[size/2];
Dbxy pt3 = PtVec[size-1];
if(((pt2.x-pt1.x)*(pt3.y-pt2.y)-(pt2.y-pt1.y)*(pt3.x-pt2.x))<0)
return true;
else
return false;
}
return true;
}
//微秒级延时us为微秒
void ExactDelay(unsigned int us)
{
if(us>0)
{
LARGE_INTEGER ClockFre;
QueryPerformanceFrequency(&ClockFre);
LARGE_INTEGER start, end;
LONGLONG count = (us*ClockFre.QuadPart)/(1000*1000);
QueryPerformanceCounter(&start);
count = count + start.QuadPart ;
do
{
QueryPerformanceCounter(&end);
}while(end.QuadPart<count);
}
}
//通过三个点计算圆心
CCirclePar CalCircleByThreePt(Dbxy Pt1,Dbxy Pt2,Dbxy Pt3)
{
Dbxy Midpt1,Midpt2;
Midpt1.x = (Pt2.x+Pt1.x)/2;
Midpt1.y = (Pt2.y+Pt1.y)/2;
Midpt2.x = (Pt3.x+Pt1.x)/2;
Midpt2.y = (Pt3.y+Pt1.y)/2;
double K1 = -(Pt2.x-Pt1.x)/(Pt2.y-Pt1.y);
double K2 = -(Pt3.x-Pt1.x)/(Pt3.y-Pt1.y);
CCirclePar CD;
CD.CenterPt.x = (Midpt2.y - Midpt1.y -K2*Midpt2.x + K1*Midpt1.x)/(K1-K2);
CD.CenterPt.y = Midpt1.y + K1*(Midpt2.y - Midpt1.y - K2*Midpt2.x + K2*Midpt1.x)/(K1-K2);
CD.Radius = sqrtf((CD.CenterPt.x-Pt1.x)*(CD.CenterPt.x-Pt1.x)+(CD.CenterPt.y-Pt1.y)*(CD.CenterPt.y-Pt1.y));
return CD;
}
//判断显示内容是否变化
bool IsDlgItemStrChange(int ID,CString Str,vector<CDlgItemStr> &DlgItemStrVec)
{
int size = DlgItemStrVec.size();
for(int k=0;k<size;k++)
{
CDlgItemStr &ItemStr = DlgItemStrVec[k];
if(ItemStr.m_ID == ID)
{
bool ret = (Str != ItemStr.m_Str);
if(ret)//记录变化
{
ItemStr.m_Str = Str;
}
return ret;
}
}
//没找到新建一个
CDlgItemStr ItemStr;
ItemStr.m_ID = ID;
ItemStr.m_Str = Str;
DlgItemStrVec.push_back(ItemStr);
return true;
}
//查询WndName 窗口是否打开
bool IsWndExist(CString WndName)
{
HWND hWnd;
hWnd = (HWND)::FindWindow(NULL,WndName);
return !(hWnd == NULL);
}
//给名字为WndName 的窗口发送消息WndMsg
bool SendMsgToWnd(CString &WndName,CString &WndMsg)
{
HWND hWnd;
hWnd = (HWND)::FindWindow(NULL,WndName);
if(hWnd == NULL)
return false;
COPYDATASTRUCT cpd;
cpd.dwData = 0;
cpd.cbData = WndMsg.GetLength()+1;//加1 防止乱码
cpd.lpData = (void*)(CStringToLPCSTR(WndMsg));
SendMessage(hWnd,WM_COPYDATA,0, (LPARAM)&cpd);
return true;
}
//发送消息给Dlg 用来显示当前的cmd 到list
void SendComLogToWnd(bool bSend,CString WndName,CString Msg)
{
CString WndMsg = gWorkTime.GetCurTime(":");
if(bSend)
WndMsg += " Send->";
else
WndMsg += " Rev->";
WndMsg += Msg;
SendMsgToWnd(WndName,WndMsg);
}
#endif
#if 1
//ms 转换为us
int Ms2Us(int ms)
{
return ms*1000;
}
int MM2UM(double mm)
{
return mm*1000;
}
double UM2MM(int um)
{
return um/1000;
}
double D_UM2MM(double um)
{
return um/1000;
}
#endif
//在新线程中显示消息
void ShowMsgInNewThread(CString s)
{
if(gMsgBox.IsbShowing())
return;
gMsgBox.SetMsg(s);
AfxBeginThread(NewMsgThread,&gMsgBox);
}
//使用windows 图片查看器打开图片
BOOL PictureWindows(const CString &strPicFile)
{
CString sPicturePara= "shimgvw.dll ImageView_Fullscreen "+ strPicFile ;
ShellExecute(NULL, NULL, "rundll32.exe",
sPicturePara,"C:\\WINDOWS\\system32", SW_SHOW);
return TRUE;
}
void InitYearComb(CString FilePath,CComboBox &ComboBox)
{
ComboBox.ResetContent();//清空
CWorkTime WorkTime;
vector<CString> YearPathVec;
//获取当前所有年的路径
CFileMgr FileMgr;
FileMgr.GetChildFileOrDirName(true,FilePath,YearPathVec,"");
CString ThisYear = WorkTime.GetCurYear();
int size = YearPathVec.size();
if(size<1)//无数据
{
ComboBox.InsertString(0,ThisYear);
ComboBox.SetCurSel(0);
return;
}
int SelIdx = 0;
for(int k=0;k<size;k++)
{
CString Year = FileMgr.GetFileNameFromPath(YearPathVec[k],true);
if(IsStringDigit(Year))
{
ComboBox.InsertString(k,Year);
if(Year == ThisYear)
SelIdx = k;
}
}
ComboBox.SetCurSel(SelIdx);
}
void InitMonthComb(CComboBox &ComboBox)
{
CWorkTime WorkTime;
CString Month = WorkTime.GetCurMonth();
int DefualtIdx = 0;
ComboBox.InsertString(0,SEL_ALL_STR);
for(int i=1;i<=12;i++)
{
CString s;
if(i<10)
s.Format("0%ld",i);
else
s.Format("%ld",i);
ComboBox.InsertString(i,s);
if(Month == s)
DefualtIdx = i;
}
//设置默认选择项
ComboBox.SetCurSel(DefualtIdx);
}
//将list 控件重置
void ResetListCtrl(CListCtrl &List)
{
List.DeleteAllItems();
int nColumnCount = List.GetHeaderCtrl()->GetItemCount();
// Delete all of the columns.
for (int i=0; i < nColumnCount; i++)
{
List.DeleteColumn(0);
}
}
//等待指定的时间ms(用来避免长时间的Sleep延时)
bool WaitDelayTime(int DelayTime)
{
int TotalDelay = DelayTime;//总共等待的时间ms
int CheckDelay = 300;//每次循环延时
int CurDelay = 0;//当前的总延时
while(1)
{
if(gStopAllWrokCmd)
{
return false;
}
Sleep(CheckDelay);
CurDelay += CheckDelay;
if(CurDelay>TotalDelay)//时间到了
break;
}
return true;
}
//MFC 的CString 转换为C++ string
//不要使用CString 的GetBuffer 函数,有内存泄漏的风险
char* CStringToLPCSTR(CString s)
{
return (char*)(LPCTSTR)s;
}
/*
//DirPath = E:\\LaipuLaserData\\ParaModifyRecord\\
//-->E:\\LaipuLaserData\\ParaModifyRecord\\2022\\01\\19\\
*/
//创建当前时间的目录
CString CreatDataTimePath(CString DirPath)
{
CString Path = DirPath;
CFileMgr FileMgr;
CWorkTime WorkTime;
Path += WorkTime.GetCurYear();
Path += "\\"+WorkTime.GetCurMonth();
Path += "\\"+WorkTime.GetCurDay();
Path += "\\";
if(!FileMgr.IsDirectoryExists(Path))
{
FileMgr.CreatDir(Path);
}
return Path;
}