www.pudn.com > agsm2-1.2_src.zip > ScSmsPage.cpp
// ScSmsPage.cpp : implementation file
//
#include "stdafx.h"
#include "agsm2.h"
#include "ScSmsPage.h"
#include "agsm2Dlg.h"
#include "Helper.h"
#include "SMSDialog.h"
#include "ref/csv.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CScSmsPage property page
IMPLEMENT_DYNCREATE(CScSmsPage, CScPropertyPage)
CScSmsPage::CScSmsPage() : CScPropertyPage(CScSmsPage::IDD)
{
//{{AFX_DATA_INIT(CScSmsPage)
//}}AFX_DATA_INIT
}
CScSmsPage::~CScSmsPage()
{
}
void CScSmsPage::DoDataExchange(CDataExchange* pDX)
{
CScPropertyPage::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CScSmsPage)
DDX_Control(pDX, IDC_LIST_SMS, m_SmsListCtrl);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CScSmsPage, CScPropertyPage)
//{{AFX_MSG_MAP(CScSmsPage)
ON_WM_CONTEXTMENU()
ON_NOTIFY(NM_DBLCLK, IDC_LIST_SMS, OnDblclkListSms)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CScSmsPage message handlers
BOOL CScSmsPage::OnApply()
{
// TODO: Add your specialized code here and/or call the base class
SC_OPERATION curOp = ((CAgsm2Dlg *)(AfxGetApp()->m_pMainWnd))->m_CurOperation;
TRACE(_T("CScSmsPage::OnApply %d\n"),curOp);
switch(curOp)
{
case SC_READ:
break;
case SC_WRITE:
break;
case SC_IMPORT:
break;
case SC_EXPORT:
break;
case SC_PRINT:
break;
default:
break;
}
return CScPropertyPage::OnApply();
}
BOOL CScSmsPage::OnInitDialog()
{
CScPropertyPage::OnInitDialog();
// TODO: Add extra initialization here
m_SmsListCtrl.SetExtendedStyle(LVS_EX_FULLROWSELECT|
LVS_EX_GRIDLINES|
LVS_EX_HEADERDRAGDROP);
CString pos((LPCSTR)IDS_STRING_POS);
CString from((LPCSTR)IDS_STRING_FROM);
CString content((LPCSTR)IDS_STRING_CONTENT);
CString date((LPCSTR)IDS_STRING_DATE);
CString state((LPCSTR)IDS_STRING_STATE);
m_SmsListCtrl.InsertColumn(0,pos,LVCFMT_LEFT,40);
m_SmsListCtrl.InsertColumn(1,from,LVCFMT_LEFT,80);
m_SmsListCtrl.InsertColumn(2,content,LVCFMT_LEFT,200);
m_SmsListCtrl.InsertColumn(3,date,LVCFMT_LEFT,100);
m_SmsListCtrl.InsertColumn(4,state,LVCFMT_LEFT,80);
char buf[8];
for(int i=1; i<20; i++)
{
sprintf(buf,"%d",i);
m_SmsListCtrl.AddItem(i-1,0,buf);
}
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CScSmsPage::OnContextMenu(CWnd* pWnd, CPoint point)
{
// TODO: Add your message handler code here
TRACE("OnContextMenu\n");
CMenu menu;
VERIFY(menu.LoadMenu(IDR_POPUP_MENU));
CMenu* pPopup = menu.GetSubMenu(0);
ASSERT(pPopup != NULL);
if(m_SmsListCtrl.GetSelectedCount() == 0)
{
pPopup->EnableMenuItem(ID_MENUITEM_EDIT,MF_GRAYED);
pPopup->EnableMenuItem(ID_MENUITEM_CUT,MF_GRAYED);
pPopup->EnableMenuItem(ID_MENUITEM_COPY,MF_GRAYED);
pPopup->EnableMenuItem(ID_MENUITEM_DELETE,MF_GRAYED);
}else{
POSITION pos = m_SmsListCtrl.GetFirstSelectedItemPosition();
TRACE("HotItem %d\n",pos);
if(pos)
{
if( m_SmsListCtrl.GetItemText((int)pos-1,1).IsEmpty() ||
m_SmsListCtrl.GetItemText((int)pos-1,2).IsEmpty() )
{
pPopup->EnableMenuItem(ID_MENUITEM_CUT,MF_GRAYED);
pPopup->EnableMenuItem(ID_MENUITEM_COPY,MF_GRAYED);
pPopup->EnableMenuItem(ID_MENUITEM_DELETE,MF_GRAYED);
}
}
}
if(CanPaste() == FALSE)
{
pPopup->EnableMenuItem(ID_MENUITEM_PASTE,MF_GRAYED);
}
pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,
point.x, point.y, AfxGetMainWnd());
}
CScListCtrl* CScSmsPage::GetListCtrl()
{
return &m_SmsListCtrl;
}
void CScSmsPage::ReadRecord(int n)
{
CPcScCtrl &ScReader = ((CAgsm2Dlg *)(AfxGetApp()->m_pMainWnd))->m_SCReader;
int from = 0, to = 0, i;
try{
BeginWaitCursor();
SelectCurFile();
CProgressCtrl &ReadProgress = ((CAgsm2Dlg *)(AfxGetApp()->m_pMainWnd))->m_RWProgress;
if(n == -1)//read all records
{
ReadProgress.SetRange(0,(SHORT)m_NumOfRecs);
ReadProgress.ShowWindow(SW_SHOW);
m_SmsListCtrl.DeleteAllItems();
from =1; to = m_NumOfRecs;
for(i =from; i<= to; i++)
{
ReadRecordN(i,TRUE);
ReadProgress.SetPos(i);
}
//Beep(1000,50);
ReadProgress.ShowWindow(SW_HIDE);
}else if(n == -2){
int nSelected = m_SmsListCtrl.GetSelectedCount();
int nItem = -1;
ReadProgress.SetRange(0,(SHORT)nSelected);
ReadProgress.ShowWindow(SW_SHOW);
for (i=1; i<=nSelected; i++)
{
nItem = m_SmsListCtrl.GetNextItem(nItem, LVNI_SELECTED);
ASSERT(nItem != -1);
ReadRecordN(nItem+1,FALSE);
ReadProgress.SetPos(i);
}
ReadProgress.ShowWindow(SW_HIDE);
}else{
ReadRecordN(n,FALSE);
}
EndWaitCursor();
}
catch(LONG e)
{
if((e & 0xfffff000) == 0x6000 || (e & 0xfffff000) == 0x9000)
AfxMessageBox(ScReader.FormatErrMsg(e));
else
Helper::ShowLastError(e);
}
}
void CScSmsPage::SelectCurFile()
{
RESAPDU resApdu;
resApdu.data = m_pResData;
resApdu.len = sizeof(m_pResData);
CPcScCtrl &ScReader = ((CAgsm2Dlg *)(AfxGetApp()->m_pMainWnd))->m_SCReader;
try{
ScReader.m_bGetRes = FALSE;
ScReader.Select(0x3f00,resApdu);
resApdu.len = sizeof(m_pResData);
ScReader.Select(0x7f10,resApdu);
ScReader.m_bGetRes = TRUE;
resApdu.len = sizeof(m_pResData);
ScReader.Select(0x6f3c,resApdu);
m_FileSize = (m_pResData[2]<<8)|m_pResData[3];
m_RecordLen = m_pResData[14];
m_NumOfRecs = m_FileSize/m_RecordLen;
}catch (LONG)
{
throw;
}
}
void CScSmsPage::ReadRecordN(int n, BOOL newRecord)
{
try{
int nItem = n - 1;
CPcScCtrl &ScReader = ((CAgsm2Dlg *)(AfxGetApp()->m_pMainWnd))->m_SCReader;
LPBYTE pRecData = (LPBYTE)malloc(m_RecordLen+2);
RESAPDU resApdu;
resApdu.data = pRecData;
resApdu.len = m_RecordLen+2;
ScReader.ReadRecord((UCHAR)n,RRM_Absolute,resApdu);
//todo
// int len = m_RecordLen+2;
// LPSTR pStr = Helper::BinToHex(pRecData,len);
CString cstrNum;
cstrNum.Format("%d",n);
if(newRecord)
m_SmsListCtrl.AddItem(nItem,0,cstrNum);
// free(pStr);
m_SmsListCtrl.AddItem(nItem,4,Helper::UCharToSmsStatus(pRecData[0]));
//SMS and the PDU format http://www.dreamfabric.com/sms/
int smsc_len = pRecData[1];
if(smsc_len < 12)//have meaning data.
{
UCHAR mr = 0;
UCHAR vp = 7;//
UCHAR pdu = *(pRecData + 2 + smsc_len);
if((pdu & 0x03) == 1)//SMS-SUBMIT (MS ==> SMSC)
{
mr = 1;
if((pdu & 0x18) == 0)
vp = 0;
else if((pdu & 0x18) == 0x10)
vp = 1;
}
LPBYTE oa_a = pRecData+2+smsc_len + mr + 2;
int oa_len;
CString oa_phonenum;
if(*oa_a == 0xd0)//for Alphanumeric address type
{
oa_len = pRecData[2+smsc_len+mr+1] / 2;
oa_phonenum = Helper::Gsm11Enc7bitToCStr(oa_a+1,oa_len);
oa_len += 1;
}else{
oa_len = (pRecData[2+smsc_len+mr+1]+1)/2 + 1;
oa_phonenum = Helper::PhoneNumToAscii(
oa_a,
oa_len);
}
m_SmsListCtrl.AddItem(nItem,1,oa_phonenum);
LPBYTE udl_a = oa_a + oa_len + 2 + vp;
int udl = *udl_a;
UCHAR encoding = *(oa_a+oa_len+1);
CString cstr;
if((encoding&0xe8) == 0x08){//UCS2
cstr = Helper::Gsm11UCS2ToCStr(udl_a+1, udl);
}else if((encoding&0xec) == 0x00 || (encoding&0xf4) == 0xf0){//7bit default alphabet
cstr = Helper::Gsm11Enc7bitToCStr(udl_a+1,udl);
}
else if((encoding&0xec) == 0x40 || (encoding&0xf4) == 0xf4){//append a space as 8 bit ascii
*(udl_a + udl + 1) = 0;
cstr = (LPCSTR)(udl_a+1);
}else{
CString str((LPCSTR)IDS_STRING153);
cstr = str;
}
m_SmsListCtrl.AddItem(nItem,2,cstr);
if(vp == 7)
{
CString cstr_date = Helper::Gsm11SCTStoCStr(udl_a-7,7);
m_SmsListCtrl.AddItem(nItem,3,cstr_date);
}
}
void *ItemData = (void *)((SCLIST_ITEMDATA *)m_SmsListCtrl.GetItemData(nItem))->ItemData;
if(ItemData)
free(ItemData);
((SCLIST_ITEMDATA *)m_SmsListCtrl.GetItemData(nItem))->ItemData = (DWORD)pRecData;
((SCLIST_ITEMDATA *)m_SmsListCtrl.GetItemData(nItem))->dirty = FALSE;
m_SmsListCtrl.Update(nItem);
}catch(LONG){
throw;
}
}
void CScSmsPage::WriteRecordN(int n,BOOL newRecord)
{
try{
int nItem = n-1;
CPcScCtrl &ScReader = ((CAgsm2Dlg *)(AfxGetApp()->m_pMainWnd))->m_SCReader;
LPBYTE pRecData = (LPBYTE)((SCLIST_ITEMDATA *)m_SmsListCtrl.GetItemData(nItem))->ItemData;
if(!pRecData)
{
pRecData = (LPBYTE)malloc(m_RecordLen);
memset(pRecData,0xff,m_RecordLen);
}
TRACE("=============Write to card %d================\n",n);
BOOL bRet = Helper::ComposeSms(pRecData,m_RecordLen,
m_SmsListCtrl.GetItemText(nItem,4),//Status
m_SmsListCtrl.GetItemText(nItem,1),//Da/Oa
m_SmsListCtrl.GetItemText(nItem,2),//Content
m_SmsListCtrl.GetItemText(nItem,3)///Date
);
for(int i=0; i<(int)m_RecordLen; i++)
{
TRACE("%02x ",pRecData[i]);
if((i%16) == 0)
TRACE("\n");
}
TRACE("\n");
if(bRet)
ScReader.UpdateRecord(n,RRM_Absolute,pRecData,(UCHAR)m_RecordLen);
((SCLIST_ITEMDATA *)m_SmsListCtrl.GetItemData(nItem))->dirty = FALSE;
((SCLIST_ITEMDATA *)m_SmsListCtrl.GetItemData(nItem))->ItemData = (DWORD)pRecData;
}catch(LONG)
{
throw;
}
}
void CScSmsPage::EditRecord()
{
POSITION pos = m_SmsListCtrl.GetFirstSelectedItemPosition();
TRACE("HotItem %d\n",pos);
if(pos)
{
CSMSDialog dlg;
int nItem = (int)pos-1;
dlg.m_smsOwner = m_SmsListCtrl.GetItemText(nItem,1);
dlg.m_smsRichEditContent = m_SmsListCtrl.GetItemText(nItem,2);
dlg.m_smsStatusStr = m_SmsListCtrl.GetItemText(nItem,4);
dlg.DoModal();
m_SmsListCtrl.AddItem(nItem,1,dlg.m_smsOwner);
m_SmsListCtrl.AddItem(nItem,2,dlg.m_smsRichEditContent);
m_SmsListCtrl.AddItem(nItem,4,dlg.m_smsStatusStr);
}
}
void CScSmsPage::OnDblclkListSms(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
EditRecord();
*pResult = 0;
}
void CScSmsPage::WriteRecord(int n)
{
TRACE("Write Record\n");
int iRet;
if(n == -1)
iRet = AfxMessageBox(IDS_STRING128,MB_YESNO);
else
iRet = AfxMessageBox(IDS_STRING129,MB_YESNO);
if(iRet == IDNO)
return;
CPcScCtrl &ScReader = ((CAgsm2Dlg *)(AfxGetApp()->m_pMainWnd))->m_SCReader;
try{
BeginWaitCursor();
SelectCurFile();
CProgressCtrl &ReadProgress = ((CAgsm2Dlg *)(AfxGetApp()->m_pMainWnd))->m_RWProgress;
int itemCount = m_SmsListCtrl.GetItemCount();
int from = 0, to = 0, i;
if(n == -1)//write all records
{
ReadProgress.SetRange(0,(SHORT)m_NumOfRecs);
ReadProgress.ShowWindow(SW_SHOW);
from = 1; to = m_NumOfRecs;
for(i=from; i <= to && i<=itemCount; i++)
{
WriteRecordN(i,FALSE);
ReadProgress.SetPos(i);
}
//Beep(1000,50);
ReadProgress.ShowWindow(SW_HIDE);
}else if( n == -2){//selected
int nSelected = m_SmsListCtrl.GetSelectedCount();
int nItem = -1;
ReadProgress.SetRange(0,(SHORT)nSelected);
ReadProgress.ShowWindow(SW_SHOW);
for (i=1; i<=nSelected; i++)
{
nItem = m_SmsListCtrl.GetNextItem(nItem, LVNI_SELECTED);
ASSERT(nItem != -1);
WriteRecordN(nItem+1,FALSE);
ReadProgress.SetPos(i);
}
ReadProgress.ShowWindow(SW_HIDE);
}else{//individual
WriteRecordN(n,FALSE);
}
EndWaitCursor();
}catch(LONG e)
{
if((e & 0xfffff000) == 0x6000 || (e & 0xfffff000) == 0x9000)
AfxMessageBox(ScReader.FormatErrMsg(e));
else
Helper::ShowLastError(e);
}
}
BOOL CScSmsPage::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
HACCEL hAccelTable = ((CAgsm2Dlg *)(AfxGetApp()->m_pMainWnd))->m_hAccelTable;
TranslateAccelerator(GetSafeHwnd(), hAccelTable, pMsg);
return CScPropertyPage::PreTranslateMessage(pMsg);
}
BOOL CScSmsPage::CanPaste()
{
if ( !OpenClipboard() )
{
AfxMessageBox( "Cannot open the Clipboard" );
return FALSE;
}
/* get text from the clipboard */
HANDLE hClipData;
LPVOID lpClipData;
if (!(hClipData = GetClipboardData(CF_TEXT))) {
//AfxMessageBox( "Cannot get Clipboard data" );
CloseClipboard();
return FALSE;
}
if (!(lpClipData = GlobalLock(hClipData))) {
AfxMessageBox( "Out of Memory" );
CloseClipboard();
return FALSE;
}
int len = strlen((char *)lpClipData)+1;
char *buf = (char *)malloc(len);
memcpy(buf,lpClipData,len);
unsigned char *buf_cols = (unsigned char *)malloc(len*2);
char *cols[10];
int sep = ',';
int flags = CSV_TRIM | CSV_QUOTES;
int column = 10;
csv_row_parse_str((const unsigned char *)buf,
len,buf_cols,2*len,
(unsigned char **)&cols,column,sep,flags);
BOOL bRet = RowCanPaste(cols);
free(buf);
free(buf_cols);
GlobalUnlock(hClipData);
CloseClipboard();
return bRet;
}
void CScSmsPage::Paste()
{
if ( !OpenClipboard() )
{
AfxMessageBox( "Cannot open the Clipboard" );
return;
}
/* get text from the clipboard */
HANDLE hClipData;
LPVOID lpClipData;
if (!(hClipData = GetClipboardData(CF_TEXT))) {
AfxMessageBox( "Cannot get Clipboard data" );
CloseClipboard();
return;
}
if (!(lpClipData = GlobalLock(hClipData))) {
AfxMessageBox( "Out of Memory" );
CloseClipboard();
return;
}
int len = strlen((char *)lpClipData)+1;
unsigned char *buf = (unsigned char *)malloc(len);
unsigned char *buf_cols = (unsigned char *)malloc(len*2);
char *cols[10];
memcpy(buf,lpClipData,len);
UINT nSelectedCount = m_SmsListCtrl.GetSelectedCount();
POSITION pos = m_SmsListCtrl.GetFirstSelectedItemPosition();
UINT nPasted = 0;
int sep = ',';
int flags = CSV_TRIM | CSV_QUOTES;
int column = 10;
int consume_len = 0;
while(consume_len < len)
{
consume_len += csv_row_parse_str((const unsigned char *)buf+consume_len,
len,buf_cols,2*len,
(unsigned char **)&cols,column,sep,flags);
if(!RowCanPaste(cols))
continue;
CString haveRead((LPCSTR)IDS_STRING_READ);
if(nSelectedCount == 0)
{
int i = m_SmsListCtrl.GetItemCount();
char buf1[8];
sprintf(buf1,"%d",i);
m_SmsListCtrl.AddItem(i,0,buf1);
m_SmsListCtrl.AddItem(i,1,cols[1]);
m_SmsListCtrl.AddItem(i,2,cols[2]);
m_SmsListCtrl.AddItem(i,3,cols[3]);
m_SmsListCtrl.AddItem(i,4,cols[4] ? cols[4] : haveRead);
}else{
if(nPasted < nSelectedCount)
{
//AddItem((int)(pos+nPasted-1),0,buf1);
m_SmsListCtrl.AddItem((int)(pos+nPasted-1),1,cols[1]);
m_SmsListCtrl.AddItem((int)(pos+nPasted-1),2,cols[2]);
m_SmsListCtrl.AddItem((int)(pos+nPasted-1),3,cols[3]);
m_SmsListCtrl.AddItem((int)(pos+nPasted-1),4,cols[4] ? cols[4] : haveRead);
nPasted++;
}
}
}
free(buf_cols);
free(buf);
GlobalUnlock(hClipData);
CloseClipboard();
}
BOOL CScSmsPage::RowCanPaste(char *cols[])
{
int ret = 0;
char buf[512];
if(cols[0] && cols[1])
{
ret = sscanf(cols[0],"%3[0-9]",buf);
if(ret == 1)
ret = sscanf(cols[1],"%20[+0-9*#]",buf);
}
if(cols[4])
{
UCHAR rValue;
CString str(cols[4]);
if(!Helper::SmsStatusToUChar(str,rValue))
ret = 0;
}
return ret == 1;
}