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 + -
显示快捷键?