⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mainmod.cpp

📁 Activesync Mobile 的同步软件开发例子
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*++
--*/
STDMETHODIMP_(int) CStore::CompareItem
(
    HREPLITEM hItem1,  // Points to the handle of first object. This handle is guaranteed to be created by IReplStore::FindFirstObject or IReplStore::FindNextObject
    HREPLITEM hItem2   // Points to the handle of second object. This handle is guaranteed to be created by IReplStore::FindFirstObject or IReplStore::FindNextObject
)
{
    CItem   *pItem1 = (CItem *)hItem1;
    CItem   *pItem2 = (CItem *)hItem2;

    if ( pItem1->m_uid == pItem2->m_uid )
        return 0;

    if ( pItem1->m_uid < pItem2->m_uid )
        return -1;

    return 1;
}

/*++
--*/
STDMETHODIMP_(BOOL) CStore::IsItemChanged
(
    HREPLFLD    hFolder,    // Handle of a folder
    HREPLITEM   hItem,      // Handle of an object
    HREPLITEM   hItemComp   // Handle of the object used for comparison, could be NULL
)
{
    CFolder *pFolder = (CFolder *)hFolder;
    CItem   *pItem = (CItem *)hItem;
    CItem   *pItemComp = (CItem *)hItemComp;
    BOOL    fChanged = FALSE;

    if ( pItemComp )
        fChanged = CompareFileTime( &pItem->m_ftModified, &pItemComp->m_ftModified );
    else
    {
        PSTOCK      pStock;

        // read the modification time stamp from the object into ft
        Lock();
        pStock = FindStock( pItem->m_uid );
        fChanged = pStock && CompareFileTime( &pItem->m_ftModified, &pStock->ftLastModified );
        Unlock();
    }

    return fChanged;
}

/*++
--*/
STDMETHODIMP_(BOOL) CStore::IsItemReplicated
(
    HREPLFLD    hFolder,    // Handle of a folder
    HREPLITEM   hItem       // Handle of an object
)
{
    CFolder *pFolder = (CFolder *)hFolder;
    CItem   *pItem = (CItem *)hItem;
    PSTOCK  pStock;
    char    cSym;

    // hItem can be passed NULL.
    if ( pItem == NULL )
        return TRUE;

    // check if pItem should be replicated using information stored both in pFolder & pItem
    Lock();
    pStock = FindStock( pItem->m_uid );
    if ( pStock )
        cSym = pStock->szSym[0]; 
    Unlock();

    if ( !pStock ) return FALSE;

    switch ( v_uSyncOpt )
    {
    case SO_ALL:    return TRUE;
    case SO_AM:     return cSym >= 'A' && cSym <= 'M';
    case SO_NZ:     return cSym >= 'N' && cSym <= 'Z';
    }

    return FALSE;
}

/*++
--*/
STDMETHODIMP_(void) CStore::UpdateItem
(
    HREPLFLD    hFolder,    // Handle of a folder
    HREPLITEM   hItemDst,   // Handle of the destination object
    HREPLITEM   hItemSrc    // Handle to the source object, could be NULL.
)
{
    CFolder *pFolder = (CFolder *)hFolder;
    CItem   *pItemDst = (CItem *)hItemDst;
    CItem   *pItemSrc = (CItem *)hItemSrc;

    if ( pItemSrc )
    {
        pItemDst->m_ftModified = pItemSrc->m_ftModified;
    }
    else 
    {
        // Update the time stamp stored in the given handle
        Lock();
        PSTOCK pStock = FindStock( pItemDst->m_uid );
        if ( pStock )
            pItemDst->m_ftModified = pStock->ftLastModified;
        Unlock();
    }
}

//
//  ==================== UI related routines =====================
//

/*++
--*/
STDMETHODIMP CStore::GetConflictInfo( PCONFINFO pConfInfo )
{
    // make sure we have the right version of OBJUIDATA
    if ( pConfInfo->cbStruct != sizeof( CONFINFO ) )
        return E_INVALIDARG;

    lstrcpy( pConfInfo->szLocalName, "Stock" );
    lstrcpy( pConfInfo->szRemoteName, "Stock" );

    CItem   *pLocalItem = (CItem *)pConfInfo->hLocalItem;
    CItem   *pRemoteItem = (CItem *)pConfInfo->hRemoteItem;
    PSTOCK  pLocalStock, pRemoteStock;

    Lock();

    pLocalStock = FindStock( pLocalItem->m_uid );
    pRemoteStock = FindStock( pRemoteItem->m_uid );
    if ( pLocalStock && pRemoteStock )
    {
        // resolve the conflict automatically if two stocks are considered identical
        if ( !lstrcmpi( pLocalStock->szCompany, pRemoteStock->szCompany ) && 
             !lstrcmpi( pLocalStock->szSym, pRemoteStock->szSym ) && 
             !lstrcmpi( pLocalStock->szLastPrice, pRemoteStock->szLastPrice ) && 
             !lstrcmpi( pLocalStock->szPurDate, pRemoteStock->szPurDate ) && 
             !lstrcmpi( pLocalStock->szPurPrice, pRemoteStock->szPurPrice ) )
        {
            Unlock();
            return RERR_IGNORE;
        }
    }

    if ( pLocalStock )
        wsprintf( pConfInfo->szLocalDesc, "%s\r\nPrice: %s\r\nPur. Price: %s", 
                  pLocalStock->szCompany, pLocalStock->szLastPrice,
                  pLocalStock->szPurPrice, pLocalStock->szCompany );
   
    if ( pRemoteStock )
        wsprintf( pConfInfo->szRemoteDesc, "%s\r\nPrice: %s\r\nPur. Price: %s", 
                  pRemoteStock->szCompany, pRemoteStock->szLastPrice,
                  pRemoteStock->szPurPrice, pRemoteStock->szCompany );

    Unlock();
    return NOERROR;
}


STDMETHODIMP CStore::DoOptionsDialog(HWND hwndParent, LPCSTR lpszObjType, IReplNotify * pntfy)
{
    HRESULT     hr = NOERROR;

    v_pStore = this;
    lstrcpy( v_szStockFile, m_szStockFile );

    lstrcpy( v_szDBVol, "" );


    //
    //  Note: Unable to call QueryDevice since the SSP may not have been enabled.
    //
    if ( DialogBox( v_hInst, TEXT( "SyncOptDlg" ), hwndParent, (DLGPROC)dlgSyncOpt ) == IDOK )
    {
        hr = NOERROR;
    }
    else
    {
        hr = RERR_CANCEL;
    }

    return hr;
}


BOOL CALLBACK dlgSyncOpt( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
    switch( uMsg )
    {
    case WM_INITDIALOG:
        if ( v_uSyncOpt == SO_AM )
            CheckDlgButton( hDlg, IDC_SYNC_AM, TRUE );
        else if ( v_uSyncOpt == SO_NZ )
            CheckDlgButton( hDlg, IDC_SYNC_NZ, TRUE );
        else
            CheckDlgButton( hDlg, IDC_SYNC_ALL, TRUE );

        SetDlgItemText( hDlg, IDC_DB_VOL, v_szDBVol );
        SetDlgItemText( hDlg, IDC_FILE, v_pStore->m_szStockFile );
        return TRUE;

    case WM_COMMAND:
        switch( LOWORD( wParam ) )
        {
        case IDOK:
            if ( IsDlgButtonChecked( hDlg, IDC_SYNC_AM ) )
                v_uSyncOpt = SO_AM;
            else if ( IsDlgButtonChecked( hDlg, IDC_SYNC_NZ ) )
                v_uSyncOpt = SO_NZ;
            else
                v_uSyncOpt = SO_ALL;

            GetDlgItemText( hDlg, IDC_FILE, v_szStockFile, sizeof( v_szStockFile ) );

            EndDialog( hDlg, IDOK ); 
            break;

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

/*++
--*/
STDMETHODIMP CStore::ActivateDialog
( 
    UINT            uDlg,           // Which dialog should be actiavted
    HWND            hwndParent,     // Handle of the window that should be used as parent for the dialog
    HREPLFLD        hFolder,        // Points to a valid STD for the folder
    IEnumReplItem   *penum          // Points to a enumerator of object STD for objects stored in the folder
)
{
    HRESULT     hr;
    SDREQUEST   sd;
    WCHAR       wszDBVol[ MAX_PATH ];

    if ( uDlg != OPTIONS_DIALOG )
        return E_NOTIMPL;

    v_pStore = this;
    lstrcpy( v_szStockFile, m_szStockFile );

    // call device to get the database volume name, the QueryDevice will return error if no device is connected
    memset( wszDBVol, 0, sizeof( wszDBVol ) );
    memset( &sd, 0, sizeof( sd ) );
    lstrcpy( sd.szObjType, SZ_STOCKPOR );
    sd.fSet     = FALSE;                // we are reading data from device
    sd.uCode    = 1;                    // we can have up to 8 different code
    sd.lpbData  = (LPBYTE)wszDBVol;    // we are passing a buffer to the call, 
                                        // we can also pass NULL, in which case, 
                                        // we must free the buffer using GlobalFree after we are done
    sd.cbData   = sizeof( wszDBVol );

    hr = m_pNotify->QueryDevice( QDC_SYNC_DATA, (LPVOID *)&sd );
    if ( hr == RERR_NO_DEVICE )
        lstrcpy( v_szDBVol, "<Device is not connected>" );
    else if ( FAILED( hr ) )
        lstrcpy( v_szDBVol, "<Erroring reading data from device>" );
    else if ( wszDBVol[0] == 0 )
        lstrcpy( v_szDBVol, "System Volume" );
    else
    {
        // need to convert Unicode
        WideCharToMultiByte( CP_ACP, 0, wszDBVol, -1, v_szDBVol, sizeof( v_szDBVol ) - 1, NULL, NULL );
    }

    if ( DialogBox( v_hInst, TEXT( "SyncOptDlg" ), hwndParent, (DLGPROC)dlgSyncOpt ) == IDOK )
    {
        // see if the stock file is changed, and if the new file is valid
        if ( lstrcmpi( v_szStockFile, m_szStockFile ) && GetFileAttributes( v_szStockFile ) != (DWORD)-1 )
        {
            // save the new file into registry
            HKEY    hKey;

            // get the correct registry key for stock sync options
            if ( SUCCEEDED( m_pNotify->QueryDevice( ( m_uFlags & ISF_SELECTED_DEVICE )? QDC_SEL_DEVICE_KEY : QDC_CON_DEVICE_KEY, (LPVOID *)&hKey ) ) )
            {
                // read the hKey for the stock portfolio file to sync
                RegSetValueEx( hKey, "Stock File", NULL, REG_SZ, (const LPBYTE)v_szStockFile, lstrlen( v_szStockFile ) + 1 );
                RegSetValueEx( hKey, "Sync Option", NULL, REG_DWORD, (const LPBYTE)&v_uSyncOpt, sizeof( v_uSyncOpt ) );

                RegCloseKey( hKey );

                // ask ActiveSync service manager to unload service providers so the new option can be applied
                return RERR_UNLOAD;
            }
        }

        return NOERROR;
    }

    return RERR_CANCEL;
}

/*++
--*/
STDMETHODIMP CStore::GetObjTypeUIData
( 
    HREPLFLD    hFolder,        // Input, points to a STD of a folder that stores the object 
    POBJUIDATA  pData           // Output, points to a OBJUIDATA structure.
)
{
    // make sure we have the right version of OBJUIDATA
    if ( pData->cbStruct != sizeof( OBJUIDATA ) )
        return E_INVALIDARG;

    pData->hIconLarge = (HICON)LoadImage( v_hInst, MAKEINTRESOURCE( IDI_ICON ), IMAGE_ICON, 32, 32, 0 );
    pData->hIconSmall = (HICON)LoadImage( v_hInst, MAKEINTRESOURCE( IDI_ICON ), IMAGE_ICON, 16, 16, 0 );

    lstrcpy( pData->szName, "Stock Portfolio Data" );
    lstrcpy( pData->szTypeText, "Database" );
    lstrcpy( pData->szPlTypeText, "Databases" );

    lstrcpy( pData->szSyncText, m_szStockFile );

    return E_NOTIMPL;
}


LPSTR MakeMapObjName( LPSTR lpszFile )
{
static char v_szMapObjName[ MAX_PATH ];
    UINT    ix;
    LPSTR   lpsz;
    
    for ( ix = 0, lpsz = lpszFile; *lpsz; ix++, lpsz++ )
    {
        if ( *lpsz >= 'a' && *lpsz <= 'z' )
            v_szMapObjName[ix] = *lpsz - 'a' + 'A';
        else if ( *lpsz >= 'A' && *lpsz <= 'Z' )
            v_szMapObjName[ix] = *lpsz;
        else
            v_szMapObjName[ix] = 'A';
    }
    v_szMapObjName[ix] = 0;
    return v_szMapObjName;
}

/*++
HRESULT CStore::Open
    Open the file named by m_szStockFile
--*/
HRESULT CStore::Open( BOOL fCreateNew )
{
    // is it open already?
    if ( m_hFile != INVALID_HANDLE_VALUE )
        return NOERROR;

    BOOL    fNewFile = ( GetFileAttributes( m_szStockFile ) == (DWORD)-1 );
    HRESULT hr = fNewFile && !fCreateNew? E_FAIL : NOERROR;

    if ( FAILED( hr ) ) goto Exit;   

    // need to create this file if it doesn't exist
    if ( fNewFile )
        m_hFile = CreateFile( m_szStockFile, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 
                              NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
    else
        m_hFile = CreateFile( m_szStockFile, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 
                              NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );

    if ( m_hFile == INVALID_HANDLE_VALUE )
    {
        hr = E_FAIL;
        goto Exit;
    }

    m_hMapObj = CreateFileMapping( m_hFile, NULL, PAGE_READWRITE, 0, sizeof( PORTFILE ), MakeMapObjName( m_szStockFile ) );
    if ( m_hMapObj == NULL )
    {
        hr = E_FAIL;
        goto Exit;
    }

    // Get a pointer to the file-mapped shared memory:
    m_pStocks = (PPORTFILE)MapViewOfFile( m_hMapObj, FILE_MAP_WRITE, 0, 0, 0 );
    if ( m_pStocks == NULL ) 
    {
        hr = E_FAIL;
        goto Exit;
    }

    // Get the Mutex
    if ( !m_hMutex )
        m_hMutex = CreateMutex( NULL, FALSE, SZ_MUTEX );

    if ( !m_hMutex )
    {
        hr = E_FAIL;
        goto Exit;
    }
    
    if ( fNewFile )
    {
        Lock();
        ClearStruct( *m_pStocks );
        m_pStocks->uVer1        = PORTFILE_VERSION;
        m_pStocks->uVer2        = PORTFILE_VERSION;
        m_pStocks->uidCurrStock = 1;
        FlushViewOfFile( 0, sizeof( PORTFILE ) );
        Unlock();
    }
    else
    {
        Lock();
        if ( m_pStocks->uVer1 != PORTFILE_VERSION || m_pStocks->uVer2 != PORTFILE_VERSION )
        {
            hr = E_UNEXPECTED;
            Unlock();
            goto Exit;
        }
        Unlock();
    }

Exit:
    return hr;
}


/*++
HRESULT CStore::Close
    Close the file named by m_szStockFile
--*/
HRESULT CStore::Close( void )
{
    if ( m_hMutex )
    {
        CloseHandle( m_hMutex );
        m_hMutex = NULL;
    }

    if ( m_pStocks )
    {
        UnmapViewOfFile( m_pStocks );
        m_pStocks = NULL;
    }
    
    if ( m_hMapObj )
    {
        CloseHandle( m_hMapObj );
        m_hMapObj = NULL;
    }
    
    if ( m_hFile != INVALID_HANDLE_VALUE )
    {
        CloseHandle( m_hFile );
        m_hFile = INVALID_HANDLE_VALUE;
    }

    return NOERROR;
}

/*++
PSTOCK CStore::FindStock
    Find a stock using the stock ID, return NULL if not found.
    m_pStocks must be protected by the mutex before calling this routine and
    before finish using the pointer it returns
--*/
PSTOCK CStore::FindStock( UINT uidStock, PUINT puix )
{
    UINT    ix;
    for ( ix = 0; ix < m_pStocks->cStocks; ix++  )
        if ( m_pStocks->rgStocks[ix].uidStock == uidStock )
            break;

    if ( puix )
        *puix = ix < m_pStocks->cStocks? ix : (UINT)-1;

    return ix < m_pStocks->cStocks? m_pStocks->rgStocks + ix: NULL;
}


/*++
--*/
PITEM CStore::MakeNewItem( UINT uidStock )
{
    PITEM   pItem = new CItem;
    PSTOCK  pStock;
    if ( pItem )
    {
        pItem->m_uid = uidStock;

        // set the time stamp if we can
        Lock();
        pStock = FindStock( uidStock );
        if ( pStock )
            pItem->m_ftModified = pStock->ftLastModified;
        Unlock();
    }
    return pItem;
}

//
// Function called when the SSP is enabled in the ActiveSync options dialog
//
HRESULT WINAPI OnSSPEnable(HWND hwnd)
{
    MessageBox(hwnd, "StockPor- OnEnable", "StockPor", MB_OK);

    return S_OK;
}


//
// Function called when the SSP is disabled in the ActiveSync options dialog
//
HRESULT WINAPI OnSSPDisable(HWND hwnd)
{
    MessageBox(hwnd, "StockPor- OnDisable", "StockPor", MB_OK);

    return S_OK;
}

⌨️ 快捷键说明

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