//---------------------------------------------------------------------------
#include <vcl>
#ifndef ComportH
#define ComportH
#include <windows.h>
//---------------------------------------------------------------------------
class CommPort
{
public:
CommPort();
~CommPort();
bool OpenComm(const char* pPort, int nBaudRate, int nParity, int nByteSize, int nStopBits) ; //打开串口
bool CloseComm();//关闭串口
int ReadComm(void* pData, int nLength); //读取
void WriteComm(void* pData, int nLength); //写串口
int ReadDataWaiting( void );
String GetCommPort(String szPortName );
bool PurgeCommPort(DWORD dwFlags);
bool IsOpened( void ){ return( m_bOpened ); }
protected:
HANDLE hcomm;
OVERLAPPED m_OverlappedRead, m_OverlappedWrite;
bool m_bOpened;
};
#endif
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#include <process.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TMain *Main;
#define NUM_THREADS 2
unsigned __stdcall RunThreadA(void *params);
unsigned __stdcall RunThreadB(void *params);
HANDLE printMutex = CreateMutex(NULL, FALSE, NULL);
//---------------------------------------------------------------------------
__fastcall TMain::TMain(TComponent* Owner)
: TForm(Owner)
{
Init();
GetAllComName();
// Port = new CommPort();
}
//---------------------------------------------------------------------------
__fastcall TMain::~TMain()
{
Main == NULL;
}
//---------------------------------------------------------------------------
void TMain::Init()
{
Port = NULL;
memset(cCenterNumber, 0, 32);
Timer->Interval = 1000;
Timer->Enabled = false;
WaitTimer->Interval = 1000;
WaitTimer->Enabled = false;
LabTime->Caption = "";
m_strCurCom = "";
m_strCommBuffer = "";
ComOpend = false;
TestEnd = false;
bCallTest = false;
bBtnEndClick = false;
bCloseClick = false;
SendSuc = 0;
SendFail = 0;
CallSuc = 0;
CallFail = 0;
Time = 0;
WaitTime = 0;
SendCounter = 0;
CallCounter = 0;
ButtonState(false);
}
//---------------------------------------------------------------------------
void TMain::GetAllComName()
{
auto_ptr<TStringList > pComDevNameList(new TStringList());
auto_ptr<TStringList > pComNameList(new TStringList());
//ylp.得到COM口就进行登记并读取COM设备名列表
auto_ptr<TRegistry > Reg(new TRegistry);
Reg->RootKey = HKEY_LOCAL_MACHINE;
Reg->OpenKey("HARDWARE//DEVICEMAP//SERIALCOMM",true);
Reg->GetValueNames(pComDevNameList.get());
//读取COM口的名字数据
for(int i = 0; i < pComDevNameList->Count; i++)
{
String ComName = Reg->ReadString(pComDevNameList->Strings[i]);
if(ComName.Length() == 0)
{
ShowMessage("Found one comname is NULL!");
continue;
}
if(ComName.Length() >= COM_NAME_LEN-1)
{
ShowMessage("Com name length is beyond the program scope, please contact with ZTE. Com name is: "+ComName);
continue;
}
//ylp.把COM口读取到的名字加入到COM名列表中
pComNameList->Add(ComName);
}
pComNameList->Sort();
ComboBoxCom->Clear();
ComboBoxCom->Items->Add("");
for(int i=0; i<pComNameList->Count; i++)
{
String ComName = pComNameList->Strings[i];
// m_vComName.push_back(ComName);
ComboBoxCom->Items->Add(ComName);
}
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
bool TMain::ApplySMSParam()
{
TSMSPlan InitStrc;
SMSPLAN = InitStrc;
if(EdtSendNumber->Text.IsEmpty() == true || EdtSendNumber->Text == NULL)
{
String strText = "SendNumber is empty.";
MessageBox(0, strText.c_str(), "WARNING", MB_ICONWARNING);
if (EdtSendNumber->CanFocus() == true)
{
EdtSendNumber->SetFocus();
EdtSendNumber->SelectAll();
}
return false;
}
if(EdtSendCount->Text.IsEmpty() == true || EdtSendCount->Text == NULL)
{
String strText = "SendCount is empty.";
MessageBox(0, strText.c_str(), "WARNING", MB_ICONWARNING);
if (EdtSendCount->CanFocus() == true)
{
EdtSendCount->SetFocus();
EdtSendCount->SelectAll();
}
return false;
}
if(ComboBoxCenterNo->Text.IsEmpty() == true || ComboBoxCenterNo->Text == NULL)
{
String strText = "CenterNumber is empty.";
MessageBox(0, strText.c_str(), "WARNING", MB_ICONWARNING);
if (ComboBoxCenterNo->CanFocus() == true)
{
ComboBoxCenterNo->SetFocus();
ComboBoxCenterNo->SelectAll();
}
return false;
}
memcpy(SMSPLAN.m_SendNumber, EdtSendNumber->Text.c_str(), EdtSendNumber->Text.Length());
SMSPLAN.m_SendCount = StrToInt(EdtSendCount->Text);
memcpy(SMSPLAN.m_Content, Memo1->Text.c_str(), Memo1->Text.Length());
String strCenterNumber = "+86" + String(ComboBoxCenterNo->Text);
memcpy(cCenterNumber, strCenterNumber.c_str(), strCenterNumber.Length());
return true;
}
//---------------------------------------------------------------------------
bool TMain::ApplyCallParam()
{
TCallPlan InitStrc;
CALLPLAN = InitStrc;
if(EditCallNumber->Text.IsEmpty() == true || EditCallNumber->Text == NULL)
{
String strText = "CallNumber is empty.";
MessageBox(0, strText.c_str(), "WARNING", MB_ICONWARNING);
if (EditCallNumber->CanFocus() == true)
{
EditCallNumber->SetFocus();
EditCallNumber->SelectAll();
}
return false;
}
if(EditCallCount->Text.IsEmpty() == true || EditCallCount->Text == NULL)
{
String strText = "CallCount is empty.";
MessageBox(0, strText.c_str(), "WARNING", MB_ICONWARNING);
if (EditCallCount->CanFocus() == true)
{
EditCallCount->SetFocus();
EditCallCount->SelectAll();
}
return false;
}
if(EditCallTime->Text.IsEmpty() == true || EditCallTime->Text == NULL)
{
String strText = "CallTime is empty.";
MessageBox(0, strText.c_str(), "WARNING", MB_ICONWARNING);
if (EditCallTime->CanFocus() == true)
{
EditCallTime->SetFocus();
EditCallTime->SelectAll();
}
return false;
}
memcpy(CALLPLAN.m_CallNumber, EditCallNumber->Text.c_str(), EditCallNumber->Text.Length());
CALLPLAN.m_CallCount = StrToInt(EditCallCount->Text);
CALLPLAN.m_CallTime = StrToInt(EditCallTime->Text);
return true;
}
//---------------------------------------------------------------------------
bool TMain::GetCurCom()
{
if(ComboBoxCom->Text.IsEmpty() == true || ComboBoxCom->Text == NULL)
{
String strText = "Moden_Com is empty.";
MessageBox(0, strText.c_str(), "WARNING", MB_ICONWARNING);
if (ComboBoxCom->CanFocus() == true)
{
ComboBoxCom->SetFocus();
ComboBoxCom->SelectAll();
}
return false;
}
m_strCurCom = ComboBoxCom->Text;
m_strCurCom = "////.//" + m_strCurCom;
return true;
}
//---------------------------------------------------------------------------
bool TMain::OpenCom()
{
if(ComOpend == true)
return false;
Port = new CommPort();
if(Port == NULL)
{
ShowMessage("Port is null.");
return false;
}
if(Port->OpenComm(m_strCurCom.c_str(), 115200, 0, 8, 1) == false)
{
String strText = "Fail to open " + m_strCurCom + ".";
MessageBox(0, strText.c_str(), "STOP", MB_ICONSTOP);
return false;
}
ComOpend = true;
return true;
}
//---------------------------------------------------------------------------
void TMain::CloseCom()
{
if(Port != NULL && ComOpend == true)
{
Port->CloseComm();
ComOpend = false;
delete Port;
Port = NULL;
}
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
void __fastcall TMain::EdtSendNumberKeyPress(TObject *Sender, char &Key)
{
if (Key<0x30 || Key>0x39)
{
if (Key == 8)//backspace/
return;
Key = 0;
MessageBeep(0xFFFFFFFF);
}
}
//---------------------------------------------------------------------------
void __fastcall TMain::EditCallNumberKeyPress(TObject *Sender, char &Key)
{
if (Key<0x30 || Key>0x39)
{
if (Key == 8)//backspace/
return;
Key = 0;
MessageBeep(0xFFFFFFFF);
}
}
//---------------------------------------------------------------------------
void __fastcall TMain::EdtSendCountKeyPress(TObject *Sender, char &Key)
{
if (Key<0x30 || Key>0x39)
{
if (Key == 8)//backspace/
return;
Key = 0;
MessageBeep(0xFFFFFFFF);
}
}
//---------------------------------------------------------------------------
void __fastcall TMain::EditCallCountKeyPress(TObject *Sender, char &Key)
{
if (Key<0x30 || Key>0x39)
{
if (Key == 8)//backspace/
return;
Key = 0;
MessageBeep(0xFFFFFFFF);
}
}
//---------------------------------------------------------------------------
void __fastcall TMain::ComboBoxCenterNoKeyPress(TObject *Sender, char &Key)
{
if (Key<0x30 || Key>0x39)
{
if (Key == 8)//backspace/
return;
Key = 0;
MessageBeep(0xFFFFFFFF);
}
}
//---------------------------------------------------------------------------
void __fastcall TMain::EditCallTimeKeyPress(TObject *Sender, char &Key)
{
if (Key<0x30 || Key>0x39)
{
if (Key == 8)//backspace/
return;
Key = 0;
MessageBeep(0xFFFFFFFF);
}
}
//---------------------------------------------------------------------------
bool TMain::TestModenCom()
{
if(ComOpend == false)
return false;
// Port->WriteComm(AT_CMD_STRING, 4); // 测试GSM-MODEM的存在性
String strCmd = "AT/r";
void *Cmd = (void*)(strCmd.c_str());
Port->WriteComm(Cmd, strCmd.Length());
if(ResponseOk(NULL) == false)
{
EndTest();
if(bBtnEndClick == false)
{
String Com = ComboBoxCom->Text;
String strText = "/" " + Com + " /" has no response. Please insure that /" " +
Com + " /" is a moden com connected accurately,/n and not being used by others!";
MessageBox(0, strText.c_str(), "STOP", MB_ICONSTOP);
}
return false;
}
else
return true;
}
//---------------------------------------------------------------------------
bool TMain::ResponseOk(String Key)
{
if(Key.IsEmpty() || Key == "" || Key == NULL)
//Key = "OK'/r/n";
Key = "OK";
bool re = false;
m_strCommBuffer = "";
WaitTime = 0;
WaitTimer->Enabled = true;
char buf[AT_RES_MAX_LEN];
memset(buf, 0, AT_RES_MAX_LEN);
DWORD dwRet = 0;
while (1)
{
Application->ProcessMessages();
Sleep(1000);
Application->ProcessMessages();
if(Port == NULL)
{
re = false;
break;
}
dwRet = Port->ReadComm(buf, AT_RES_MAX_LEN);
if(WaitTime > WAITTIME)
{
re = false;
break;
}
if (dwRet > 0)
{
m_strCommBuffer += buf;
//判断指令执行是否正确//如果di里面包含了"OK'/r/n" 说明指令执行正确
if (m_strCommBuffer.Pos(Key) != 0)
{
re = true;
break;
}
else
{
re = false;
break;
}
}
/* else
{
re = false;
break;
} */
}
WaitTimer->Enabled = false;
return re;
}
//-------------------------------------------------------------------------------
void TMain::ResetParams()
{
TestEnd = false;
ComOpend = false;
bCallTest = false;
bBtnEndClick = false;
SendSuc = 0;
SendFail = 0;
CallSuc = 0;
CallFail = 0;
Time = 0;
WaitTime = 0;
SendCounter = 0;
CallCounter = 0;
LabTime->Caption = "";
LabTime->Update();
Timer->Enabled = false;
ButtonState(false);
UpdateResult();
}
//-------------------------------------------------------------------------------
void TMain::UpdateResult()
{
EditSendSuc->Text = IntToStr(SendSuc);
EditSendSuc->Update();
EditSendFail->Text = IntToStr(SendFail);
EditSendFail->Update();
UINT SendTotal = SendSuc + SendFail;
if(SendTotal == 0)
EditSendSucRate->Text = "-- %";
else
EditSendSucRate->Text = IntToStr(SendSuc*100 /SendTotal) + " %";
EditSendSucRate->Update();
EditCallSuc->Text = IntToStr(CallSuc);
EditCallSuc->Update();
EditCallFial->Text = IntToStr(CallFail);
EditCallFial->Update();
UINT CallTotal = CallSuc + CallFail;
if(CallTotal == 0)
EditCallSucRate->Text = "-- %";
else
EditCallSucRate->Text = IntToStr(CallSuc*100/CallTotal) + " %";
EditCallSucRate->Update();
}
//-------------------------------------------------------------------------------
void TMain::VoiceCall(char *CallNumber)
{
// ButtonState(true);
ControlTimer(true);
if(TestModenCom() == false)
return;
String strCmd = "ATD" + String(CallNumber) + ";/r";
void *Cmd = (void*)(strCmd.c_str());
Port->WriteComm(Cmd, strCmd.Length()); // 得到肯定回答,继续输出PDU串
CallCounter++;
if(ResponseOk(NULL) == true)
{
CallSuc++;
//UpdateResult();
}
else
{
CallFail++;
UpdateResult();
NextCall();
}
}
//-------------------------------------------------------------------------------
bool TMain::EndCall()
{
if(ComOpend == false)
return false;
ControlTimer(false);
String strCmd = "AT+CHUP;/r";
void *Cmd = (void*)(strCmd.c_str());
Port->WriteComm(Cmd, strCmd.Length());
if(true ==ResponseOk(NULL))
return true;
else
return false;
}
//-------------------------------------------------------------------------------
void TMain::ButtonState(bool Testing)
{
if(Testing)
{
BtnStartSend->Enabled = false;
//BtnStartCall->Enabled = true;
GroupBox1->Enabled = false;
GroupBox2->Enabled = false;
Panel3->Enabled = false;
if(bCallTest == true)
{
BtnEndCall->Enabled = true;
BtnEndSend->Enabled = false;
}
else
{
BtnEndCall->Enabled = false;
BtnEndSend->Enabled = true;
}
}
else
{
BtnStartSend->Enabled = true;
BtnEndSend->Enabled = false;
BtnStartCall->Enabled = true;
BtnEndCall->Enabled = false;
GroupBox1->Enabled = true;
GroupBox2->Enabled = true;
Panel3->Enabled = true;
WaitTimer->Enabled = false;
ControlTimer(false);
CloseCom();
}
}
//-------------------------------------------------------------------------------
void TMain::SendSMS(char *SendNumber, char *MsgContent)
{
// ButtonState(true);
ControlTimer(true);
String strSendNumber = String(SendNumber); //发送的目的手机号码
String SmsContent = String(MsgContent); //发送消息内容
SM_PARAM DUANXIN;
memset(DUANXIN.SCA, 0, sizeof(DUANXIN.SCA));
memcpy(DUANXIN.SCA, cCenterNumber, strlen(cCenterNumber)); //短消息中心号码"8613800290500"
DUANXIN.TP_PID = 0; //用户信息协议标志
DUANXIN.TP_DCS = 0; //用户信息编码方式
strcpy(DUANXIN.TP_UD, SmsContent.c_str()); //用户信息
strcpy(DUANXIN.TPA, strSendNumber.c_str()); //目标手机号码
int nLength = strlen(DUANXIN.TP_UD); // 用户信息字符串的长度
WCHAR *puinicode = new WCHAR[2048];
try
{
GB2312ToUnicode(DUANXIN.TP_UD, puinicode);
//断断需要什么编码7bit or 8bit or Ucs2
if (ChargeUnicodeOfAscll(puinicode, nLength))
{
DUANXIN.TP_DCS = 8;//若为8则是用ucs2
}
}
__finally
{
delete[]puinicode;
}
if (GsmInit() == true)//初始化状态,测试当前at命令
{
if (GsmSendMsg(&DUANXIN) == false) //发送消息失败
{
SendFail++;
}
else//发送成功
{
SendSuc++;
}
SendCounter++;
UpdateResult();
NextSend();
}
else
{
BtnEndSendClick(NULL);
}
}
//-------------------------------------------------------------------------------
bool TMain::GsmInit()
{
char ans[AT_RES_MAX_LEN]; // 应答串
char cmd[AT_CMD_MAX_LEN];
if(TestModenCom() == false)
return false;
strcpy(cmd, "AT+CMGF=");
strcat(cmd, "0/r/n");
Port->WriteComm(cmd, strlen(cmd));
if(ResponseOk(NULL) == false)
{
String strText = "Switch to the PDU mode, err.";
MessageBox(0, strText.c_str(), "WARNING", MB_ICONWARNING);
return false;
}
else
return true;
}
//-------------------------------------------------------------------------------
bool TMain::GsmSendMsg(const SM_PARAM *pSrc)
{
int nPduLength; // PDU串长度
unsigned char nSmscLength; // SMSC串长度
int nLength = 0; // 串口收到的数据长度
char cmd[16] = ""; // 命令串
char pdu[512] = ""; // PDU串
char ans[1024] = ""; // 应答串
nPduLength = gsmEncodePdu(pSrc, pdu); // 根据PDU参数,编码PDU串
strcat(pdu, "/x01a"); // 以Ctrl-Z结束
gsmString2Bytes(pdu, &nSmscLength, 2); // 取PDU串中的SMSC信息长度
nSmscLength++; // 加上长度字节本身
// 命令中的长度,不包括SMSC信息长度,以数据字节计
sprintf(cmd, "at+cmgs=%d/r/n", nPduLength / 2 - nSmscLength); // 生成命令
Port->WriteComm(cmd, strlen(cmd));
// 先输出命令串
if(ResponseOk("/r/n> ") == true) // 根据能否找到"/r/n> "决定成功与否 ,找到,成功。
{
//Port->WriteComm(&pdu, strlen(pdu));
Port->WriteComm(&pdu/*[18]*/, strlen(pdu)); // 得到肯定回答,继续输出PDU串
char buf[AT_RES_MAX_LEN];
DWORD dwNow = ::GetTickCount();
DWORD dwNowend = dwNow;
while ((dwNowend - dwNow) / 1000 < 10)
{
Application->ProcessMessages();
//延迟10秒如果还没有读取到发送短消反馈成功信息就放弃
nLength = Port->ReadComm(ans, 1024); // 读应答数据
Application->ProcessMessages();
// 根据能否找到"+CMS ERROR"决定成功与否
if (nLength > 0 && (strstr(ans, AT_RES_OK_END) != NULL))
{
return true;
}
dwNowend = ::GetTickCount();
}
}
return false;
}
//---------------------------------------------------------------------------------
void TMain::NextSend()
{
ControlTimer(false);
if(SendCounter < SMSPLAN.m_SendCount && TestEnd == false)
SendSMS(SMSPLAN.m_SendNumber, SMSPLAN.m_Content);
else
{
ButtonState(false);
}
}
//-------------------------------------------------------------------------------
void TMain::NextCall()
{
EndCall();
if(CallCounter < CALLPLAN.m_CallCount && TestEnd == false)
VoiceCall(CALLPLAN.m_CallNumber);
else
{
ButtonState(false);
}
}
//-------------------------------------------------------------------------------
void __fastcall TMain::TimerTimer(TObject *Sender)
{
Time++;
if(bCallTest)
{
LabTime->Caption = "Calling... " + IntToStr(Time);
LabTime->Update();
if(Time >= 4)
{
UpdateResult();
}
if(Time == CALLPLAN.m_CallTime+1)
{
NextCall();
}
}
else
{
LabTime->Caption = "Sending... " + IntToStr(Time);
LabTime->Update();
}
}
//---------------------------------------------------------------------------
void TMain::ControlTimer(bool Start)
{
if(Start)
{
Timer->Interval = 1000;
Timer->Enabled = true;
}
else
{
Time = 0;
LabTime->Caption = "";
LabTime->Update();
Timer->Enabled = false;
}
}
//---------------------------------------------------------------------------
void __fastcall TMain::BtnStartCallClick(TObject *Sender)
{
ResetParams();
bCallTest = true;
if(ApplyCallParam() == false)
return;
if(GetCurCom()== false)
return;
if(OpenCom() == false)
return;
VoiceCall(CALLPLAN.m_CallNumber);
}
//---------------------------------------------------------------------------
void __fastcall TMain::BtnEndCallClick(TObject *Sender)
{
if(bCallTest == false)
{
return;
}
bBtnEndClick = true;
EndTest();
}
//---------------------------------------------------------------------------
void __fastcall TMain::WaitTimerTimer(TObject *Sender)
{
WaitTime++;
}
//---------------------------------------------------------------------------
void __fastcall TMain::BtnRefreshClick(TObject *Sender)
{
GetAllComName();
}
//---------------------------------------------------------------------------
void __fastcall TMain::FormClose(TObject *Sender, TCloseAction &Action)
{
if(TestEnd == false)
{
if(bCallTest)
BtnEndCallClick(NULL);
else
BtnEndSendClick(NULL);
}
Action = caFree;
}
//---------------------------------------------------------------------------
void __fastcall TMain::BtnStartSendClick(TObject *Sender)
{
ResetParams();
bCallTest = false;
if(ApplySMSParam() == false)
return;
if(GetCurCom()== false)
return;
if(OpenCom() == false)
return;
SendSMS(SMSPLAN.m_SendNumber, SMSPLAN.m_Content);
}
//---------------------------------------------------------------------------
void __fastcall TMain::BtnEndSendClick(TObject *Sender)
{
if(bCallTest == true)
{
return;
}
bBtnEndClick = true;
EndTest();
}
//---------------------------------------------------------------------------
void TMain::EndTest()
{
if(bCallTest == true)
{
EndCall();
}
TestEnd = true;
ControlTimer(false);
ButtonState(false);
}
//---------------------------------------------------------------------------
void __fastcall TMain::EdtSendCountChange(TObject *Sender)
{
if(EdtSendCount->Text.ToInt() < 1)
{
EdtSendCount->Text = "1";
}
}
//---------------------------------------------------------------------------
void __fastcall TMain::EditCallCountChange(TObject *Sender)
{
if(EditCallCount->Text.ToInt() < 1)
{
EditCallCount->Text = "1";
}
}
//---------------------------------------------------------------------------
void __fastcall TMain::EditCallTimeChange(TObject *Sender)
{
if(EditCallTime->Text.ToInt() < 5)
{
EditCallTime->Text = "5";
}
}
//---------------------------------------------------------------------------
void __fastcall TMain::FormCloseQuery(TObject *Sender, bool &CanClose)
{
if(bCloseClick == true)
{
CanClose = false;
return;
}
this->Enabled = false;
bCloseClick = true;
String strText = "Are you sure to exit software?";
int x = MessageBox(0, strText.c_str(), "Exit", MB_YESNO/*MB_YESNOCANCEL*/);
if(x == 6)
{
CanClose = true;
}
else if(x == 7)
{
CanClose = false;
// this->WindowState = wsMinimized;
}
/* else if(x == 2)
{
CanClose = false;
} */
bCloseClick = false;
this->Enabled = true;
}
//---------------------------------------------------------------------------
void __fastcall TMain::testClick(TObject *Sender)
{
if(GetCurCom()== false)
return;
if(OpenCom() == false)
return;
if(ApplyCallParam() == false)
return;
if(ApplySMSParam() == false)
return;
HANDLE threads[NUM_THREADS];
unsigned aID;
threads[0] = (HANDLE)_beginthreadex(
NULL, 0, RunThreadA, this, 0, &aID);
unsigned bID;
threads[1] = (HANDLE)_beginthreadex(
NULL, 0, RunThreadB, this, 0, &bID);
WaitForMultipleObjects(2, threads, TRUE, INFINITE);
CloseHandle(threads[0]);
CloseHandle(threads[1]);
CloseHandle(printMutex);
}
unsigned __stdcall RunThreadA(void *params)
{
WaitForSingleObject(printMutex, INFINITE);
TMain *p=(TMain*)params;
p->VoiceCall(p->CALLPLAN.m_CallNumber);
ReleaseMutex(printMutex);
}
unsigned __stdcall RunThreadB(void *params)
{
WaitForSingleObject(printMutex, INFINITE);
TMain *p=(TMain*)params;
p->SendSMS(p->SMSPLAN.m_SendNumber, p->SMSPLAN.m_Content);
ReleaseMutex(printMutex);
}
//---------------------------------------------------------------------------

被折叠的 条评论
为什么被折叠?



