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; 
}