// AddressView.cpp : implementation of the CAddressView class
//
#include "stdafx.h"
#include "Address.h"
#include "AddressDoc.h"
#include "CntrItem.h"
#include "AddressView.h"
#include "PersonPropSheet.h"
#include "hyperlink.h"
#include "tapi.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAddressView
IMPLEMENT_DYNCREATE(CAddressView, CFormView)
BEGIN_MESSAGE_MAP(CAddressView, CFormView)
//{{AFX_MSG_MAP(CAddressView)
ON_WM_DESTROY()
ON_WM_SIZE()
ON_NOTIFY(LVN_GETDISPINFO, IDC_ADDRESSLIST, OnGetdispinfoAddresslist)
ON_NOTIFY(LVN_ITEMCHANGED, IDC_ADDRESSLIST, OnItemchangedAddresslist)
ON_COMMAND(ID_DELETE, OnDelete)
ON_COMMAND(ID_HEADERFORMAT, OnHeaderformat)
ON_COMMAND(ID_CUSTOMIZEHEADER, OnCustomizeheader)
ON_COMMAND(ID_AUTOPREVIEW, OnAutopreview)
ON_UPDATE_COMMAND_UI(ID_AUTOPREVIEW, OnUpdateAutopreview)
ON_COMMAND(ID_PROPERTIES, OnProperties)
ON_COMMAND(ID_DIAL, OnDial)
ON_COMMAND(ID_DIALHOME, OnDialhome)
ON_COMMAND(ID_DIALBUSINESS, OnDialbusiness)
ON_COMMAND(ID_EMAIL, OnEmail)
ON_UPDATE_COMMAND_UI(ID_DIALBUSINESS, OnUpdateDialbusiness)
ON_UPDATE_COMMAND_UI(ID_DIALHOME, OnUpdateDialhome)
ON_UPDATE_COMMAND_UI(ID_EMAIL, OnUpdateEmail)
ON_UPDATE_COMMAND_UI(ID_PROPERTIES, OnUpdateProperties)
ON_UPDATE_COMMAND_UI(ID_DELETE, OnUpdateDelete)
ON_UPDATE_COMMAND_UI(ID_DIAL, OnUpdateDial)
//}}AFX_MSG_MAP
ON_MESSAGE(WM_LISTEX_NOTIFY, OnListExNotify)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CAddressView construction/destruction
CAddressView::CAddressView()
: CFormView(CAddressView::IDD)
{
//{{AFX_DATA_INIT(CAddressView)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// TODO: add construction code here
ftTimes.CreatePointFont(90, "Times New Roman");
}
CAddressView::~CAddressView()
{
}
void CAddressView::DoDataExchange(CDataExchange* pDX)
{
CFormView::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAddressView)
DDX_Control(pDX, IDC_ADDRESSLIST, wndList);
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BOOL CAddressView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CFormView::PreCreateWindow(cs);
}
int _DEFCOLS[] =
{
0,ADDR_FIRST_NAME,ADDR_LAST_NAME,ADDR_MIDDLE_NAME,ADDR_NAME,
ADDR_NICK_NAME,ADDR_EMAIL,ADDR_HOME_STREET,ADDR_HOME_CITY,
ADDR_HOME_POSTAL_CODE,ADDR_HOME_STATE,ADDR_HOME_COUNTRY,
ADDR_HOME_PHONE, ADDR_HOME_FAX, ADDR_CAR_PHONE,ADDR_PERSONAL_WEB_PAGE,
ADDR_BUSINESS_STREET,ADDR_BUSINESS_CITY,ADDR_BUSINESS_POSTAL_CODE,
ADDR_BUSINESS_STATE,ADDR_BUSINESS_COUNTRY,ADDR_BUSINESS_WEB_PAGE,
ADDR_BUSINESS_PHONE,ADDR_BUSINESS_FAX,ADDR_PAGER,ADDR_COMPANY,
ADDR_JOB_TITLE, ADDR_DEPARTMENT, ADDR_OFFICE_LOCATION
};
void CAddressView::OnInitialUpdate()
{
static bool bIsFirst = true;
CFormView::OnInitialUpdate();
// Setup the CGfxListCtrl control
if (bIsFirst) {
bIsFirst = false;
wndList.m_pAddressDoc = GetDocument();
CGfxColumnManager * pManager = wndList.CreateColumnManager();
pManager->DefineColumn(0, "", NULL, LVCFMT_LEFT, 20, fhNoSortArrow|fhNoResizeColumn);
pManager->DefineColumn(1, "First Name", NULL, LVCFMT_LEFT, 120, fhSortAble);
pManager->DefineColumn(2, "Last Name", NULL, LVCFMT_LEFT, 120, fhSortAble);
pManager->DefineColumn(3, "Middle Name", NULL, LVCFMT_LEFT,220, fhSortAble);
pManager->DefineColumn(4, "Name", NULL, LVCFMT_LEFT, 120, fhSortAble);
pManager->DefineColumn(5, "Nickname",NULL, LVCFMT_LEFT, 120, fhSortAble);
pManager->DefineColumn(6, "E-mail Address", NULL, LVCFMT_LEFT, 120, fhSortAble);
pManager->DefineColumn(7, "Home Street", NULL, LVCFMT_LEFT, 220, fhSortAble);
pManager->DefineColumn(8, "Home City", NULL, LVCFMT_LEFT, 120, fhSortAble);
pManager->DefineColumn(9, "Home Postal Code",NULL, LVCFMT_LEFT, 120, fhSortAble);
pManager->DefineColumn(10,"Home State", NULL, LVCFMT_LEFT, 120, fhSortAble);
pManager->DefineColumn(11,"Home Country", NULL, LVCFMT_LEFT, 220, fhSortAble);
pManager->DefineColumn(12,"Home Phone", NULL, LVCFMT_LEFT, 120, fhSortAble);
pManager->DefineColumn(13,"Home Fax", NULL, LVCFMT_LEFT, 120, fhSortAble);
pManager->DefineColumn(14,"Cellular", NULL, LVCFMT_LEFT, 120, fhNumeric|fhSortAble);
pManager->DefineColumn(15,"Personal Web Page", NULL, LVCFMT_LEFT, 220, fhSortAble);
pManager->DefineColumn(16,"Business Street", NULL, LVCFMT_LEFT, 120, fhSortAble);
pManager->DefineColumn(17,"Business City", NULL, LVCFMT_LEFT, 120, fhSortAble);
pManager->DefineColumn(18,"Business Postal Code", NULL, LVCFMT_LEFT, 120, fhNumeric|fhSortAble);
pManager->DefineColumn(19,"Business State", NULL, LVCFMT_LEFT, 220, fhSortAble);
pManager->DefineColumn(20,"Business Country", NULL, LVCFMT_LEFT, 120, fhSortAble);
pManager->DefineColumn(21,"Business Web Page", NULL, LVCFMT_LEFT, 120, fhSortAble);
pManager->DefineColumn(22,"Business Phone", NULL, LVCFMT_LEFT, 120, fhNumeric|fhSortAble);
pManager->DefineColumn(23,"Business Fax", NULL, LVCFMT_LEFT, 220, fhSortAble);
pManager->DefineColumn(24,"Pager", NULL, LVCFMT_LEFT, 120, fhSortAble);
pManager->DefineColumn(25,"Company", NULL, LVCFMT_LEFT, 120, fhSortAble);
pManager->DefineColumn(26,"Job Title", NULL, LVCFMT_LEFT, 120, fhSortAble);
pManager->DefineColumn(27,"Department", NULL, LVCFMT_LEFT, 120, fhSortAble);
pManager->DefineColumn(28,"Office Location", NULL, LVCFMT_LEFT, 220, fhSortAble);
pManager->DefineDefaultColumns(sizeof(_DEFCOLS)/sizeof(int), _DEFCOLS);
pManager->ReadFromProfile("AddressList");
wndList.OnInit();
wndList.ModifyFlag(0,fHighRowSelect|fVertGrid|fHorizGrid|fAutoSort,0);
SetWindowPos(0,0,0,0,0,SWP_FRAMECHANGED);
wndList.SetupColumnData();
wndList.SetItemCount(100);
wndList.SetItemHeight(17);
wndList.SetExInfoCallback((long (CWnd::*)(LXHDREX *))GetExInfoCallback);
}
}
void CAddressView::OnDestroy()
{
// If we are in category view, we need to switch back to normal view before saving the state (or column 0 will have incorrect size)
if (wndList.GetCategoryManager()) wndList.EnableCategoryView(false);
CGfxColumnManager * pManager = wndList.GetColumnManager();
// We have to call RetrieveColumnData before WriteToProfile
pManager->RetrieveColumnData(&wndList);
pManager->WriteToProfile("AddressList");
// We need to do the save operations before the calling to OnDestroy()
// Deactivate the item on destruction; this is important
// when a splitter view is being used.
CFormView::OnDestroy();
}
void CAddressView::OnSize(UINT nType, int cx, int cy)
{
CFormView::OnSize(nType, cx, cy);
if (wndList.GetSafeHwnd()) wndList.SetWindowPos(0,2,2,cx-4,cy-4,SWP_NOZORDER);
SetScrollSizes(MM_TEXT, CSize(cx,cy));
}
/////////////////////////////////////////////////////////////////////////////
// CAddressView diagnostics
#ifdef _DEBUG
void CAddressView::AssertValid() const
{
CFormView::AssertValid();
}
void CAddressView::Dump(CDumpContext& dc) const
{
CFormView::Dump(dc);
}
CAddressDoc* CAddressView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CAddressDoc)));
return (CAddressDoc*)m_pDocument;
}
#endif //_DEBUG
LRESULT CAddressView::OnListExNotify(WPARAM , LPARAM lParam)
{
TRACE0("OnListExNotify\n");
LXHDREX * pLx = (LXHDREX *) lParam;
ASSERT(pLx);
switch(pLx->iNotifyCode)
{
case NTEX_ITEMINFO:
switch (pLx->iSubItem) {
case ADDR_EMAIL:
case ADDR_PERSONAL_WEB_PAGE:
case ADDR_BUSINESS_WEB_PAGE:
//pLx->dwFlag |= LXHDREX::exUnderline; // Uncommend if you like URL's underlined
pLx->dwFlag |= LXHDREX::exTextColor;
pLx->crText = RGB(0,0,255);
break;
}
return 1;
break;
case NTEX_SETTEXT:
wndList.SetItemText(pLx->iItem, pLx->iSubItem, pLx->csText);
return 1;
};
return 0L;
}
long CAddressView::GetExInfoCallback(LXHDREX * pLx)
{
ASSERT(pLx);
switch(pLx->iNotifyCode)
{
case NTEX_ITEMINFO:
switch (pLx->iSubItem) {
case ADDR_EMAIL:
case ADDR_PERSONAL_WEB_PAGE:
case ADDR_BUSINESS_WEB_PAGE:
//pLx->dwFlag |= LXHDREX::exUnderline;
pLx->dwFlag |= LXHDREX::exTextColor;
pLx->crText = RGB(0,0,255);
break;
case ADDR_HOME_PHONE:
case ADDR_BUSINESS_PHONE:
pLx->dwFlag |= LXHDREX::exBold;
pLx->dwFlag |= LXHDREX::exTextColor;
pLx->crText = RGB(0,150,150);
break;
default:
pLx->hfText = (HFONT) ftTimes.GetSafeHandle();
pLx->dwFlag |= LXHDREX::exHFont;
};
return 1;
break;
case NTEX_SETTEXT:
return 1;
case NTEX_AUTOPREVIEW:
{
LXHDREX_DIV * pLxEx = (LXHDREX_DIV *) pLx;
// Display the notes associated with the person
COLORREF ocr = pLxEx->pDC->SetTextColor(RGB(0,0,255));
pLxEx->pDC->DrawText(GetDocument()->m_PersonArray[pLx->dwItemData - 1].m_strNotes , pLxEx->rcItem, DT_END_ELLIPSIS|DT_WORDBREAK);
pLxEx->pDC->SetTextColor(ocr);
return 1;
}
};
return 0L;
}
void CAddressView::GetTextCallback(int iIndex, int iSubItem, long lCode, CString &cs)
{
int rc = wndList.GetColumnIndex(iSubItem);
CPerson person;
int iTruncIndex;
cs = "";
if (GetDocument()->m_PersonArray.GetSize() == 0 ||
GetDocument()->m_PersonArray.GetSize() < (iIndex + 1)) {
return;
}
// Get the correct record from the array to be displayed
person=GetDocument()->m_PersonArray[lCode - 1 ];
// Based on the column display the required information
switch (rc) {
case 0: cs.Format("%d", iIndex + 1 ); break;
case ADDR_FIRST_NAME: cs = person.m_strFirstName; break;
case ADDR_LAST_NAME: cs = person.m_strLastName; break;
case ADDR_MIDDLE_NAME:cs = person.m_strMiddleName; break;
case ADDR_NAME: cs = person.m_strName; break;
case ADDR_NICK_NAME: cs = person.m_strNickName; break;
case ADDR_EMAIL: cs = person.m_strEMail; break;
case ADDR_HOME_STREET:
iTruncIndex = person.m_strHomeStreet.Find('\r');
cs = person.m_strHomeStreet;
if (iTruncIndex != -1) {
cs=person.m_strHomeStreet.Left(iTruncIndex);
}
break;
case ADDR_HOME_CITY: cs = person.m_strHomeCity; break;
case ADDR_HOME_POSTAL_CODE: cs = person.m_strHomePostalCode; break;
case ADDR_HOME_STATE: cs = person.m_strHomeState; break;
case ADDR_HOME_COUNTRY: cs = person.m_strHomeCountry; break;
case ADDR_HOME_PHONE: cs = person.m_strHomePhone; break;
case ADDR_HOME_FAX: cs = person.m_strHomeFax; break;
case ADDR_CAR_PHONE: cs = person.m_strCarPhone; break;
case ADDR_PERSONAL_WEB_PAGE: cs = person.m_strPersonalWebPage; break;
case ADDR_BUSINESS_STREET:
iTruncIndex = person.m_strBusinessStreet.Find('\r');
cs = person.m_strBusinessStreet;
if (iTruncIndex != -1) {
cs=person.m_strBusinessStreet.Left(iTruncIndex);
}
break;
case ADDR_BUSINESS_CITY: cs = person.m_strBusinessCity; break;
case ADDR_BUSINESS_POSTAL_CODE:cs = person.m_strBusinessPostalCode; break;
case ADDR_BUSINESS_STATE: cs = person.m_strBusinessState; break;
case ADDR_BUSINESS_COUNTRY: cs = person.m_strBusinessCountry; break;
case ADDR_BUSINESS_WEB_PAGE: cs = person.m_strBusinessWebPage; break;
case ADDR_BUSINESS_PHONE: cs = person.m_strBusinessPhone; break;
case ADDR_BUSINESS_FAX: cs = person.m_strBusinessFax; break;
case ADDR_PAGER: cs = person.m_strPager; break;
case ADDR_COMPANY: cs = person.m_strCompany; break;
case ADDR_JOB_TITLE: cs = person.m_strJobTitle; break;
case ADDR_DEPARTMENT: cs = person.m_strDepartment; break;
case ADDR_OFFICE_LOCATION: cs = person.m_strOfficeLocation; break;
case ADDR_NOTES: cs = person.m_strNotes; break;
default: cs.Format("%d, %d", lCode, rc);
}
}
/////////////////////////////////////////////////////////////////////////////
// CAddressView message handlers
void CAddressView::OnGetdispinfoAddresslist(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
*pResult = 0;
long index = pDispInfo->item.iItem;
long subItem = pDispInfo->item.iSubItem;
long objCode = pDispInfo->item.lParam;
if(pDispInfo->item.mask & LVIF_TEXT)
{
CString cs;
GetTextCallback(index, subItem, objCode, cs);
lstrcpyn(pDispInfo->item.pszText, cs, pDispInfo->item.cchTextMax);
*pResult = 1;
}
if(pDispInfo->item.mask & LVIF_IMAGE) pDispInfo->item.iImage = 0;//set image to first in list
}
void CAddressView::OnItemchangedAddresslist(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
*pResult = 0;
}
void CAddressView::OnUpdate(CView* , LPARAM , CObject* )
{
if ((GetDocument()->m_PersonArray.GetSize() - wndList.GetItemCount()) < 0) {
wndList.DeleteAllItems();
wndList.InsertItemEx(0,0);
}
for (int i = wndList.GetItemCount()+1; i <= GetDocument()->m_PersonArray.GetSize() ; i++ ) {
wndList.InsertItemEx(i,i);
}
wndList.Invalidate();
}
// Delete a Person record
void CAddressView::OnDelete()
{
int i = wndList.GetNextItem(-1, LVNI_SELECTED);
DWORD dwRow;
CString strMessage;
if (i < 0) return;
dwRow= wndList.GetItemData(i) - 1;
strMessage.Format("Confirm delete of %s", (LPCTSTR) GetDocument()->m_PersonArray[dwRow].m_strName);
if (AfxMessageBox(strMessage, MB_YESNO|MB_ICONQUESTION| MB_DEFBUTTON2) == IDYES) {
wndList.DeleteAllItems();
GetDocument()->m_PersonArray.RemoveAt(dwRow);
GetDocument()->SetModifiedFlag();
for (int i = 1 ; i <= GetDocument()->m_PersonArray.GetSize() ; i++ ) {
wndList.InsertItemEx(i,i);
}
wndList.Invalidate();
}
}
void CAddressView::OnHeaderformat()
{
wndList.OnGfxFormatheader();
}
void CAddressView::OnCustomizeheader()
{
wndList.OnGfxCustomizehead();
}
void CAddressView::OnAutopreview()
{
if (wndList.GetAutoPreviewHeight() <= 0) wndList.SetAutoPreviewHeight(30);
else wndList.SetAutoPreviewHeight(0);
}
void CAddressView::OnUpdateAutopreview(CCmdUI* pCmdUI)
{
if (wndList.GetAutoPreviewHeight() <= 0) {
pCmdUI->SetCheck(0);
} else {
pCmdUI->SetCheck(1);
}
pCmdUI->Enable(wndList.GetCategoryManager() == NULL);
}
void CAddressView::OnProperties()
{
wndList.DisplayProperties();
}
void CAddressView::OnDial()
{
int i = wndList.GetNextItem(-1, LVNI_SELECTED);
DWORD dwRow;
if (i < 0) return;
dwRow= wndList.GetItemData(i) - 1;
if (GetDocument()->m_PersonArray[dwRow].m_strHomePhone.IsEmpty())
OnDialbusiness();
else
OnDialhome();
}
void CAddressView::OnDialhome()
{
int i = wndList.GetNextItem(-1, LVNI_SELECTED);
CString strNumber;
CString strName;
DWORD dwRow;
if (i < 0) return;
dwRow= wndList.GetItemData(i) - 1;
strNumber = GetDocument()->m_PersonArray[dwRow].m_strHomePhone;
if (strNumber.IsEmpty())
return;
strName = GetDocument()->m_PersonArray[dwRow].m_strName;
if (tapiRequestMakeCall(strNumber,"Address",strName, "Home Number")!=0) {
AfxMessageBox("Unable to dial the number");
}
}
void CAddressView::OnDialbusiness()
{
int i = wndList.GetNextItem(-1, LVNI_SELECTED);
CString strNumber;
CString strName;
DWORD dwRow;
if (i < 0) return;
dwRow= wndList.GetItemData(i) - 1;
strNumber = GetDocument()->m_PersonArray[dwRow].m_strBusinessPhone;
if (strNumber.IsEmpty())
return;
strName = GetDocument()->m_PersonArray[dwRow].m_strName;
if (tapiRequestMakeCall(strNumber,"Address",strName, "Business Number")!=0) {
AfxMessageBox("Unable to dial the number");
}
}
// Send an e-mail
void CAddressView::OnEmail()
{
int i = wndList.GetNextItem(-1, LVNI_SELECTED);
CString strEMail;
CString strURL;
DWORD dwRow;
if (i < 0) return;
dwRow= wndList.GetItemData(i) - 1;
strEMail = GetDocument()->m_PersonArray[dwRow].m_strEMail;
if (strEMail.IsEmpty())
return;
strURL.Format("mailto:%s",(LPCTSTR) strEMail);
CHyperLink::GotoURL(strURL, SW_SHOWNORMAL);
}
void CAddressView::OnUpdateDialbusiness(CCmdUI* pCmdUI)
{
CString strNumber;
int i = wndList.GetNextItem(-1, LVNI_SELECTED);
if ( i<0) {
pCmdUI->Enable(FALSE);
return;
}
DWORD dwRow;
dwRow= wndList.GetItemData(i) - 1;
strNumber = GetDocument()->m_PersonArray[dwRow].m_strBusinessPhone;
if (strNumber.IsEmpty()) {
pCmdUI->Enable(FALSE);
return;
}
pCmdUI->Enable(TRUE);
}
void CAddressView::OnUpdateDialhome(CCmdUI* pCmdUI)
{
CString strNumber;
int i = wndList.GetNextItem(-1, LVNI_SELECTED);
if ( i<0) {
pCmdUI->Enable(FALSE);
return;
}
DWORD dwRow;
dwRow= wndList.GetItemData(i) - 1;
strNumber = GetDocument()->m_PersonArray[dwRow].m_strHomePhone;
if (strNumber.IsEmpty()) {
pCmdUI->Enable(FALSE);
return;
}
pCmdUI->Enable(TRUE);
}
void CAddressView::OnUpdateEmail(CCmdUI* pCmdUI)
{
int i = wndList.GetNextItem(-1, LVNI_SELECTED);
if ( i<0) {
pCmdUI->Enable(FALSE);
return;
}
DWORD dwRow;
dwRow= wndList.GetItemData(i) - 1;
if (GetDocument()->m_PersonArray[dwRow].m_strEMail.IsEmpty()) {
pCmdUI->Enable(FALSE);
return;
}
pCmdUI->Enable(TRUE);
}
void CAddressView::OnUpdateProperties(CCmdUI* pCmdUI)
{
int i = wndList.GetNextItem(-1, LVNI_SELECTED);
if ( i<0) {
pCmdUI->Enable(FALSE);
return;
}
pCmdUI->Enable(TRUE);
}
void CAddressView::OnUpdateDelete(CCmdUI* pCmdUI)
{
int i = wndList.GetNextItem(-1, LVNI_SELECTED);
if ( i<0) {
pCmdUI->Enable(FALSE);
return;
}
pCmdUI->Enable(TRUE);
}
void CAddressView::OnUpdateDial(CCmdUI* pCmdUI)
{
int i = wndList.GetNextItem(-1, LVNI_SELECTED);
if ( i<0) {
pCmdUI->Enable(FALSE);
return;
}
DWORD dwRow;
dwRow= wndList.GetItemData(i) - 1;
if (GetDocument()->m_PersonArray[dwRow].m_strHomePhone.IsEmpty()
&& GetDocument()->m_PersonArray[dwRow].m_strBusinessPhone.IsEmpty()) {
pCmdUI->Enable(FALSE);
return;
}
pCmdUI->Enable(TRUE);
}