pcdmsyncfldr.cpp

来自「《Windows CE 权威指南》(作者:(美)CHRIS MUENCH」· C++ 代码 · 共 481 行

CPP
481
字号
//
//	File:
//	=====
//	PCDMSyncFldr.cpp: Implementation file
//
//	Description:
//	============
//	Class represents a folder object. Derives from
//	CBaseFolder class. The store object keeps a reference
//	to an instance of this class. To add a new folder to the store
//	derive your class from CBaseFolder and add it to the store's 
//	list of folder ptrs.
//

#include "stdafx.h"
#include <cesync.h>
#include "PCDMSyncStore.h"
#include "PCDMSyncObjHand.h"
#include "BaseFolder.h"

#include "PCDMSyncFldr.h"

CPCDMSyncFolder::CPCDMSyncFolder(CPCDMSyncStore *pStore): CBaseFolder(pStore)
{
}

CPCDMSyncFolder::~CPCDMSyncFolder()
{
}

HRESULT CPCDMSyncFolder::Initialize(IUnknown **ppObjHandler)
{
	//
	//	TODO: Add any folder initialization code here.
	//	We create our object handler and set the ppObjHandler ptr.
	//	This object will get deleted automatically when ActiveSync manager 
	//	releases it.
	//
//<BOOK_ADDON Chapter 9.3.2.1> ***************************************************
OutputDebugString(TEXT("In Initialize...\n\r"));
	_variant_t	vaEmpty;
	_bstr_t		bsEmpty = L"";


	HRESULT hr=m_Conn1.CreateInstance( __uuidof( Connection ) ); 
	if (FAILED(hr)) return hr;
	m_Conn1->ConnectionString = L"Provider=MSDASQL.1;Persist Security Info=False;Data Source=DeluxeCD"; 
	hr=m_Conn1->Open( bsEmpty, bsEmpty, bsEmpty, -1 );
	if (FAILED(hr)) return hr;
	hr=m_Rs1.CreateInstance( __uuidof( Recordset ) );
	if (FAILED(hr))	return hr;		
OutputDebugString(TEXT("I:Out..\n\r"));
//<BOOK_ADDON Chapter 9.3.2.1> ***************************************************

	*ppObjHandler = NULL;

	CPCDMSyncObjHandler *pObj = new CPCDMSyncObjHandler(this);
	if(pObj == NULL)
		return E_OUTOFMEMORY;

	hr = pObj->QueryInterface(IID_IUnknown, reinterpret_cast<void**>(ppObjHandler));
	pObj->Release();
	return hr;
}

HRESULT CPCDMSyncFolder::IsFolderChanged(BOOL *pfChanged)
{
	//
	//	TODO: If we are set for pollng, then add code here 
	//	to check your folder for any items have changed since
	//	the last time this function was called. set *pfChanged
	//	to TRUE if the folder got changed.
	//	If we are set for real-time we will be notifying ActiveSync
	//	manager of changes using the m_pStore->m_pNotify ptr. We only
	//	need to return TRUE	here the very first time this function is
	//	called all other calls should return FALSE(the folder does not
	//	need to be checked for changes).
	//

	*pfChanged = TRUE;
	return S_OK;
}

HRESULT CPCDMSyncFolder::FindFirstItem(HREPLITEM *phItem, BOOL *pfExist)
{
    *phItem  = NULL;
    *pfExist = FALSE;

	//
    //	We need to get info about our file and set the new CReplItem's members.
	//	If our file has been deleted, we simply return success.
	//

//<BOOK_ADDON Chapter 9.3.2.1> ***************************************************
OutputDebugString(TEXT("In FindFirstItem...\n\r"));
	_bstr_t		bsSel(L"SELECT * FROM Titles");
	m_Rs1->PutRefActiveConnection( m_Conn1 );
	m_Rs1->Open(bsSel,vtMissing,adOpenKeyset,adLockBatchOptimistic,-1);
	BuildItem(phItem,pfExist);
OutputDebugString(TEXT("FFI:Out..\n\r"));
//</BOOK_ADDON Chapter 9.3.2.1> ***************************************************
	return S_OK;
}

//<BOOK_ADDON Chapter 9.3.2.1> **************************************************
int PCDMCDsIDs[]= { 0,1,2,4,5,3,-1,-1,-1,-1,-1,-1 };

HRESULT CPCDMSyncFolder::BuildItemStrNCrc(_RecordsetPtr RS,_bstr_t *str, FILETIME *ft)
{
int	i,max;
VARIANT		value;
VariantInit(&value);
LPCSTR tP;
_bstr_t		bsSel(L"");
WCHAR tStr[1000];

OutputDebugString(TEXT("In BuildItemStrNCRC...\n\r   "));
	max=RS->Fields->GetCount();
	for (i=0;i<max;i++)	
	{
		if (PCDMCDsIDs[i]>=0)
		{
			bsSel+=L"&";
			VariantClear(&value);
			VariantCopy(&value,&RS->Fields->Item[(long)PCDMCDsIDs[i]]->Value);
			if (PCDMCDsIDs[i]==0) 
				ft->dwHighDateTime=value.lVal;
			VariantChangeType(&value,&value,0,VT_BSTR);
			if (lstrlenW(value.bstrVal)!=0)
				wsprintfW(tStr,L"Fld%d=%s",i,value.bstrVal);
			else
				wsprintfW(tStr,L"Fld%d=n.a.",i);
			bsSel+=tStr;
		}
	}
	ft->dwLowDateTime=0;
	tP=(LPCSTR)bsSel;
	for (i=0;i<lstrlen(bsSel);i++) 
		ft->dwLowDateTime+=(int)*tP++;
	wsprintfW(tStr,L"&Fld6=%d",ft->dwLowDateTime);
	bsSel+=tStr;
	bsSel+=L";";
	max=lstrlen(bsSel);

	if (str!=NULL)
		str->Assign(bsSel);
OutputDebugString(bsSel);
OutputDebugString(TEXT("\n\rBISNC:Out\n\r"));
	return S_OK;
}

HRESULT CPCDMSyncFolder::BuildItem(HREPLITEM *phItem, BOOL *pfExist)
{
	if  (!m_Rs1->EOF)
	{
		FILETIME crc={0,0};
		_bstr_t		bsSel;

		BuildItemStrNCrc(m_Rs1,&bsSel,&crc);

		CReplItem *pItem = new CReplItem(bsSel);
		if(pItem == NULL)
			return E_OUTOFMEMORY;

		pItem->SetModified(crc);	
		*phItem = reinterpret_cast<HREPLITEM>(pItem);
		*pfExist = TRUE;

	}

	return S_OK;
}
//</BOOK_ADDON Chapter 9.3.2.1> ***************************************************

HRESULT CPCDMSyncFolder::FindNextItem(HREPLITEM *phItem, BOOL *pfExist)
{
	//
	//	TODO: Find the Next item in your folder, create a new CReplItem object
	//	set its members & return it thru hItem ptr. You can free any additional
	//	memory allocated in this call when FindItemClose() is called. If there
	//	are no more items in the folder, set *pfExist to FALSE.
	//
		*pfExist = FALSE;
//<BOOK_ADDON Chapter 9.3.2.1> ***************************************************
OutputDebugString(TEXT("In FindNextItem...\n\r"));
		m_Rs1->MoveNext();
		BuildItem(phItem,pfExist);
OutputDebugString(TEXT("FNI:Out..\n\r"));
//</BOOK_ADDON Chapter 9.3.2.1> ***************************************************
	return S_OK;
}

HRESULT CPCDMSyncFolder::FindItemClose()
{
	//
	//	TODO: Sync manager calls this function after enumerating
	//	all the items in your folder(thru calls to FindFirstItem() 
	//	& FindNextItem()). Add clean up code here - you will have
	//	to free any memory that was allocated.
	//
//<BOOK_ADDON Chapter 9.3.2.1> ***************************************************
OutputDebugString(TEXT("In FindItemClose...\n\r"));
	m_Rs1->Close();
OutputDebugString(TEXT("FIC:Out..\n\r"));
//</BOOK_ADDON Chapter 9.3.2.1> ***************************************************
	return S_OK;
}

HRESULT CPCDMSyncFolder::IsValidObject(HREPLITEM hObject, UINT uFlags)
{
    CReplItem *pReplItem = reinterpret_cast<CReplItem *>(hObject);
    if(pReplItem == NULL)
        return RERR_CORRUPT;
	//
	//	We check to see if our sample sync file actually exists.
	//	If not, we send back RERR_OBJECT_DELETED
	//

//<BOOK_ADDON Chapter 9.3.2.1> ***************************************************
OutputDebugString(TEXT("In IsValidObject...\n\r"));
	_bstr_t		bsSel(L"SELECT * FROM Titles where TitleID=");
	_RecordsetPtr   tRs; 
	HRESULT hr;
	TCHAR id[20];
	hr=tRs.CreateInstance( __uuidof( Recordset ) );
	if (FAILED(hr))	return hr;		
	FILETIME& ftOld=pReplItem->GetModified();
	wsprintf(id,TEXT("%d"),ftOld.dwHighDateTime);
	bsSel+=id;
	tRs->PutRefActiveConnection( m_Conn1 );
	tRs->Open(bsSel,vtMissing,adOpenKeyset,adLockBatchOptimistic,-1);
	if (tRs->EOF)
		hr=RERR_OBJECT_DELETED;
	else
		hr=S_OK;
	tRs->Close();
OutputDebugString(TEXT("IVO:Out..\n\r"));
	return hr;
//</BOOK_ADDON Chapter 9.3.2.1> ***************************************************
}

BOOL CPCDMSyncFolder::IsItemChanged(HREPLITEM hItem)
{
	//
	//	We need to check the modified time of the "real" file
	//	with the one in our handle, to see if the item has
	//	changed since the last time we synced.
	//
    CReplItem *pReplItem = reinterpret_cast<CReplItem *>(hItem);
	FILETIME& ftOld = pReplItem->GetModified();


//<BOOK_ADDON Chapter 9.3.2.1> ***************************************************
OutputDebugString(TEXT("In IsItemChanged...\n\r"));
	_bstr_t		bsSel(L"SELECT * FROM Titles where TitleID=");
	_RecordsetPtr   tRs; 
	HRESULT hr;
	FILETIME ftNew={0,0};
	TCHAR id[20];
TCHAR tStr[200];
	wsprintf(id,TEXT("%d"),ftOld.dwHighDateTime);
	bsSel+=id;
	hr=tRs.CreateInstance( __uuidof( Recordset ) );
	if (FAILED(hr))	return hr;		
	tRs->PutRefActiveConnection( m_Conn1 );
	tRs->Open(bsSel,vtMissing,adOpenKeyset,adLockBatchOptimistic,-1);
	if (tRs->EOF)
		hr=FALSE;
	else
	{
		BuildItemStrNCrc(tRs,NULL,&ftNew);
wsprintf(tStr,TEXT("Old:<%d>,<%d> New:<%d>,<%d>\n\r"),ftOld.dwHighDateTime,ftOld.dwLowDateTime,ftNew.dwHighDateTime,ftNew.dwLowDateTime);
OutputDebugString(tStr);
		hr=::CompareFileTime(&ftOld, &ftNew);
	}
	tRs->Close();

OutputDebugString(TEXT("IIC:Out..\n\r"));
	return hr;
//</BOOK_ADDON Chapter 9.3.2.1> ***************************************************
}

BOOL CPCDMSyncFolder::IsItemReplicated(HREPLITEM hItem)
{
	//
	//	TODO: If this item needs to be filtered out(not
	//	to be sycned to device) due	to a setting in the
	//	provider then return FALSE. If you return TRUE 
	//	here, this item will be synced to the device.
	//
	return TRUE;
}

HRESULT CPCDMSyncFolder::RemoveDuplicates()
{
	//
	//	TODO: When the combine option option is selected
	//	during sync, this folder may have some duplicate
	//	items created in the process. Loop thru the items
	//	in the folder and remove any duplicates that may
	//	exist.
	//
	return S_OK;
}

HRESULT CPCDMSyncFolder::UpdateItem(HREPLITEM hItem)
{
	//
	//	Find the file item and update our CReplItem's modified
	//	time to be the same.
	//
    CReplItem *pReplItem = reinterpret_cast<CReplItem *>(hItem);

//<BOOK_ADDON Chapter 9.3.2.1> ****************************************************
OutputDebugString(TEXT("In UpdateItem...\n\r"));
	FILETIME& ftOld = pReplItem->GetModified();
	_bstr_t		bsSel(L"SELECT * FROM Titles where TitleID=");
	_RecordsetPtr   tRs; 
	HRESULT hr;
	FILETIME ftNew;
	TCHAR id[20];
	wsprintf(id,TEXT("%d"),ftOld.dwHighDateTime);
	bsSel+=id;
	hr=tRs.CreateInstance( __uuidof( Recordset ) );
	if (FAILED(hr))	return hr;		
	tRs->PutRefActiveConnection( m_Conn1 );
	tRs->Open(bsSel,vtMissing,adOpenKeyset,adLockBatchOptimistic,-1);
	if (tRs->EOF)
		hr=FALSE;
	else
	{
		BuildItemStrNCrc(tRs,NULL,&ftNew);
		pReplItem->SetModified(ftNew);
	}
	tRs->Close();

OutputDebugString(TEXT("UI:Out..\n\r"));
//</BOOK_ADDON Chapter 9.3.2.1> ***************************************************
	return S_OK;
}

HRESULT CPCDMSyncFolder::DeleteItem(HREPLITEM hItem)
{
	//	
	//	TODO: Called when an item on the device has been
	//	deleted. Find the item in your folder & delete it.
	//
    CReplItem *pReplItem = reinterpret_cast<CReplItem *>(hItem);
//<BOOK_ADDON Chapter 9.3.2.1> ***************************************************
OutputDebugString(TEXT("In DeleteItem...\n\r"));
	_bstr_t		bsSel(L"delete from Titles where TitleID=");
	_variant_t	vaEmpty;
	TCHAR id[20];
	FILETIME& ftOld=pReplItem->GetModified();
	wsprintf(id,TEXT("%d"),ftOld.dwHighDateTime); bsSel+=id;
OutputDebugString(bsSel);
OutputDebugString(TEXT("\n\r"));
	HRESULT hr=m_Conn1->Execute(bsSel,&vaEmpty,0);
	bsSel=L"delete from Tracks where TitleID=";
	bsSel+=id;
OutputDebugString(bsSel);
OutputDebugString(TEXT("\n\r"));
	hr=m_Conn1->Execute(bsSel,&vaEmpty,0);
OutputDebugString(TEXT("DI:Out..\n\r"));
//</BOOK_ADDON Chapter 9.3.2.1> ***************************************************

	return S_OK;
}

HRESULT CPCDMSyncFolder::GetObjTypeUIData(POBJUIDATA pData)
{
	//
	//	TODO: Return UI specific information about this folder to
	//	ActiveSync manager. Modify code below to change text, icon
	//	displayed in the ActiveSync UI.
	//
    pData->hIconLarge = reinterpret_cast<HICON>(::LoadImage(_Module.m_hInst, MAKEINTRESOURCE(IDI_PCDMSYNC_ICON), IMAGE_ICON, 32, 32, 0));
    pData->hIconSmall = reinterpret_cast<HICON>(::LoadImage(_Module.m_hInst, MAKEINTRESOURCE(IDI_PCDMSYNC_ICON), IMAGE_ICON, 16, 16, 0));

    ::_tcscpy(pData->szName,	   GetName());
    ::_tcscpy(pData->szTypeText,   GetTypeText());
    ::_tcscpy(pData->szPlTypeText, GetPlTypeText());
    ::_tcscpy(pData->szSyncText,   GetSyncFileName());

	return S_OK;
}	

HRESULT CPCDMSyncFolder::ActivateDialog(UINT uDlg, HWND hwndParent, IEnumReplItem *pEnum)
{
	//
	//	TODO: Activate the settings dialog and return
	//	user's action that caused the dialog to be
	//	dismissed - OK/CANCEL.
	//
    if(uDlg == OPTIONS_DIALOG)
	{
		if(::DialogBox(_Module.m_hInst, MAKEINTRESOURCE(IDD_PCDMSYNC_SETTINGS), hwndParent, (DLGPROC)SettingsDlgProc) == IDOK)
			return S_OK;
		else
			return RERR_CANCEL;
	}
	else
	{
		return E_NOTIMPL;
	}
}

HRESULT CPCDMSyncFolder::GetConflictInfo(PCONFINFO pConfInfo)
{
	//
	//	TODO: ActiveSync manager calls this function when a conflict
	//	is detected between the desktop & device stores. Analyze the
	//	information about the conflicting items	and return RERR_IGNORE
	//	if this conflict should be ignored else return S_OK.
	//
	return RERR_IGNORE;
}

BOOL CALLBACK CPCDMSyncFolder::SettingsDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	//
	//	TODO: Add code here to handle dialog messages.
	//	Store the new settings when the dialog is OK'ed.
	//
    switch(uMsg)
    {
    case WM_INITDIALOG:
        return TRUE;
    case WM_COMMAND:
        switch(LOWORD(wParam))
        {
        case IDOK:
            ::EndDialog(hWnd, IDOK); 
            break;

        case IDCANCEL:      
            ::EndDialog(hWnd, IDCANCEL); 
            break;
        };
        break;
    }
    return FALSE;
}

const LPTSTR CPCDMSyncFolder::GetName()
{
	//
	//	This string will be used by the ActiveSync UI.
	//	to display the name this folder.
	//
	return _T("PCDMSync");
}

const LPTSTR CPCDMSyncFolder::GetPlTypeText()
{
	//
	//	This string will be used by the ActiveSync UI.
	//	to denote items in this folder.
	//
	return _T("PCDM CD Items");
}

const LPTSTR CPCDMSyncFolder::GetTypeText()
{
	//
	//	This string will be used by the ActiveSync UI.
	//	to denote an item in this folder.
	//
	return _T("PCDM CD Item");
}

const LPTSTR CPCDMSyncFolder::GetSyncFileName()
{
	//
	//	Text file that will be synced
	//
//<BOOK_ADDON Chapter 9.3.2.1> ***************************************************
	return _T("Synchronizing the PCDM-DB...");
//</BOOK_ADDON Chapter 9.3.2.1> ***************************************************
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?