Aide - Recherche - Membres - Calendrier
Version complète : developement d'une conduite
Les Forums de PalmAttitude.org > GENERAL PalmOS > Développement sous PalmOS
nsadon
Bonjour a tous,
je souhaiterai developé une conduite avec BorlandC++X me permettant de mettre copier/mettre a jours mes bases de mon palm a partir d'une base interbase.
J'ai les grnade ligne de developement, mais je ne trouve pas d'exemple simple, ou bien rien qui ne soit expliqué en detail et surtout depuis le debut car je ne peut pas utiliser des editeurs qui donne un debut de code generique pour une conduite.
J'espere avoir été assez clair dans ma demande et que vous pourrez m'aider merci
Patrice
Le CDK est fourni avec un paquet d'exemple, pourtant !!!
nsadon
oui mais les exemples du cdk utilisent visual c++ et son generateur de code pour avoir un conduit de base.
moi ce que ke souhaite c'ets utiliser borland c++ X qui ne possede pas encore d'outil visuel et donc de creer la conduite from scratch.
Patrice
Euh... Non. Tu as bien un wizard pour VC++ mais tu as aussi des exemples de sources tout ce qu'il y a de plus normaux (je n'ai d'ailleurs jamais utilisé de wizard pour faire mes conduites, je pars du sample GenCN et je change ce que j'ai à changer.

Ce qui est clair, c'est que tu as besoin des .h et des librairies du CDK. Je ne sais pas si le format des lib VC++ est compatible avec ton environnement Borland (à une époque il ne l'était pas) car si ce n'est pas le cas, il va falloir que tu reconstruises ces librairies (soit en convertissant celles du SDK, soit en repartant des DLLs).
nsadon
dans le code generique qu'on nous donne je ne comprend pas tout, que permet t'il de faire a la base, ou doit je rejouter mon code poiur mettre a jour ma base de donnée,.....
Plein de questions, que Patrice pourra peut etre m'aider a resoudre.
Pourrai tu stp m'expliquer ce que le code generique produit lorsqe l'on ne lui rajoute rien, puis me dire ensuite ou integrer mon code de modification de base.
merci d'avance
Patrice
On va faire autrement... Voilà MA conduite "générique", plus simple et commentée anim_wink.gif

CODE
#include "stdafx.h"  // Include API standards



#include "syncmgr.h"

#include "condapi.h"

#include "basemon.h"

#include "condmgre.h"

#include "hslog.h"



#include "mycond.h"     // Déclarations (pas grand chose)

#include "pdcmn.h"

#include "cmnres.h"

#include "mycondDlg.h"  // Dialogue de configuration de la conduite



HINSTANCE myInst=0;



class CMyCondDll : public CWinApp

{

public:

    virtual BOOL InitInstance(); // Initialization

    virtual int ExitInstance();  // Termination

};


Rien d'extraordinaire dans les déclarations, n'est-ce pas ?

CODE
/////////////////////////////////////////////////////////////////////////////

//

//       Function:            InitInstance()

//

//       Description:  basic initialisation when DLL is loaded

//

//       Parameters:  none

//

//       Returns:     Success (non-zero) or Failure (zero)

//

/////////////////////////////////////////////////////////////////////////////

//       REVISION HISTORY:

//

//  10/27/97  jayita    initial version

//

/////////////////////////////////////////////////////////////////////////////

BOOL CMyCondDll::InitInstance()

{

    // DLL initialization

    myInst = AfxGetInstanceHandle();

    // add any extension DLLs into CDynLinkLibrary chain



    return TRUE;

}


Il s'agit simplement d'une initialisation standard de DLL

CODE
/////////////////////////////////////////////////////////////////////////////

//

//       Function:            ExitInstance()

//

//       Description:  DLL clean up before exit

//

//       Parameters:  none

//

//       Returns:     Error code

//

/////////////////////////////////////////////////////////////////////////////

//       REVISION HISTORY:

//

//  10/27/97  jayita    initial version

//

/////////////////////////////////////////////////////////////////////////////

int CMyCondDll::ExitInstance()

{

    // DLL clean up, if required

    return CWinApp::ExitInstance();

}


Et la fonction de fin d'instance...

CODE
/////////////////////////////////////////////////////////////////////////////

// The one and only CMaCondDll object



CMyCondDll myCondDll;


Et l'instanciation... Donc tout ce qui est ci-dessus n'est qu'un squelette standard de DLL, que tu peux remplacer par tout autre code standard (la version en C est tout aussi utilisable).

CODE
/////////////////////////////////////////////////////////////////////////////

//    OpenConduit

/////////////////////////////////////////////////////////////////////////////

//

//    Function:  OpenConduit()

//

//    Description:    This is the main function which gets called by the hotsync

//        application.  The conduit acts upon the sync properties

//        passed by the HotSync application.  In this particular

//        example only, copying hand-held to pc and vise versa are

//        implemented.  All other properties defaults to the same

//        handler as eHHtoPC.

//

//    Parameters:  PROGRESSFN  -    pFn, Pointer to a callback function

//          used to report progress.

//        CSyncProperties& -    rProps, reference to sync properties

//

//    Returns:    !0 if error

//

/////////////////////////////////////////////////////////////////////////////

ExportFunc long OpenConduit(PROGRESSFN pFn, CSyncProperties& rProps)

{

    long retval = 0;

    char data[4096];

    char retdat[64];

    CCallModuleParams params;



    CONDHANDLE    conduitHandle = (CONDHANDLE)0;



    // Check if anything to do

    if (rProps.m_SyncType == eDoNothing)

    {

 sprintf(data, "%s - Conduite réglée sur "Ne rien faire"", STR_MY_CONDUIT);

 LogAddEntry(data, slSyncFinished, TRUE);

 return (retval);

    }



    // Register this conduit with SyncMgrDLL for communication to HH

    if (retval = SyncRegisterConduit(conduitHandle))

    {

 return (retval);

    }



    // Do the real work HERE



    // End of processing

    sprintf(data, "%s", STR_MY_CONDUIT);

    LogAddEntry(data, slSyncFinished, TRUE);



    // End of job: unregister with SyncMgrDLL

    SyncUnRegisterConduit(conduitHandle);



    return (retval);

}


Et c'est là l'essentiel : c'est cette fonction qui est appelée lorsque la conduite est exécutée... A toi de remplir avec ton traitement...

Note que le modifier ExportFunc est spécifique à VC++ mais qu'il revient à exporter la fonction (tout bêtement)...

CODE
/////////////////////////////////////////////////////////////////////////////

//

/////////////////////////////////////////////////////////////////////////////

//

//  Function:  GetConduitName()

//

//  Description:    Extern "C" entry point into this conduit which returns

//        the name to be used when display messages regarding

//        this conduit.

//

//  Parameters:    pszName - buffer in which to place the name

//        nLen - maximum number of bytes of buffer

//

//  Returns:  -1 indicates erros

//

/////////////////////////////////////////////////////////////////////////////

ExportFunc long GetConduitName(char* pszName,WORD nLen)

{

    AFX_MANAGE_STATE(AfxGetStaticModuleState());

    long retval = 0;



    memset(pszName, 0, nLen);

    strncpy(pszName, STR_MY_CONDUIT, nLen-1);



    return retval;

}


Utilisé pour afficher le nom de la conduite dans la liste de hotsync...

CODE
/////////////////////////////////////////////////////////////////////////////

//

/////////////////////////////////////////////////////////////////////////////

//

//    Function:  GetConduitVersion()

//

//    Description:    Extern "C" entry point into this conduit which returns

//        the conduits version

//

//    Parameters:  none

//

//    Returns:  DWORD indicating major and minor version number

//      HIWORD - reserved

//      HIBYTE(LOWORD) - major number

//      LOBYTE(LOWORD) - minor number

//

/////////////////////////////////////////////////////////////////////////////



ExportFunc DWORD GetConduitVersion()

{

    AFX_MANAGE_STATE(AfxGetStaticModuleState());

    return MY_CONDUIT_VERSION;

}


Pour ta gestion de version

CODE
/////////////////////////////////////////////////////////////////////////////

//

/////////////////////////////////////////////////////////////////////////////

//

//  Method:  GetConduitInfo

//

//  Description:    This function provides a way for a Conduit to provide info

//                  to the caller.

//                  In this version of the call, MFC Version, Conduit Name, and

//                  Default sync action are the types of information this call

//                  will return.

//

//  Parameters:    ConduitInfoEnum infoType - enum specifying what info is being

//                          requested.

//                  void *pInArgs - This parameter may be null, except for the Conduit

//                          name enum, this value will be a ConduitRequestInfoType structure.

//                  This following to parameters vary depending upon the info being requested.

//                  For enum eConduitName

//                  void *pOut - will be a pointer to a character buffer

//                  DWORD *pdwOutSize - will be a pointer to a DWORD specifying the size of the character buffer.

//

//                  For enum eMfcVersion

//                  void *pOut - will be a pointer to a DWORD

//                  DWORD *pdwOutSize - will be a pointer to a DWORD specifying the size of pOut.

//

//                  For enum eDefaultAction

//                  void *pOut - will be a pointer to a eSyncType variable

//                  DWORD *pdwOutSize - will be a pointer to a DWORD specifying the size of pOut.

//

//  Returns:  0  - Success.

//        !0      - error code.

//

/////////////////////////////////////////////////////////////////////////////

//  REVISION HISTORY:

//  01/23/98    KRM Created

//

/////////////////////////////////////////////////////////////////////////////

ExportFunc long GetConduitInfo(ConduitInfoEnum infoType, void *pInArgs, void *pOut, DWORD *pdwOutSize)

{

   if (!pOut)

    {

       return CONDERR_INVALID_PTR;

    }

   if (!pdwOutSize)

    {

       return CONDERR_INVALID_OUTSIZE_PTR;

    }



   switch (infoType)

    {

       case eConduitName:

 memset((TCHAR *) pOut, 0, *pdwOutSize);

 strncpy((TCHAR *) pOut, STR_MY_CONDUIT, (*pdwOutSize)-1);

       break;



       case eDefaultAction:

       if (*pdwOutSize != sizeof(eSyncTypes))

 {

           return CONDERR_INVALID_BUFFER_SIZE;

 }

       (*(eSyncTypes*)pOut) = eFast;

       break;



       case eMfcVersion:

       if (*pdwOutSize != sizeof(DWORD))

 {

           return CONDERR_INVALID_BUFFER_SIZE;

 }

       (*(DWORD*)pOut) = MFC_VERSION_50;

       break;



       default:

       return CONDERR_UNSUPPORTED_CONDUITINFO_ENUM;

   }

   return 0;

}


Très important : c'est là où tu "déclares" ta conduite au programme hotsync : son nom (oui, encore, il y a plusieurs versions et l'action par défaut : synchroniser / Palm remplace PC / ...)

CODE
/////////////////////////////////////////////////////////////////////////////

//

/////////////////////////////////////////////////////////////////////////////

//

//       Function:     ConfigureConduit

//

//       Description:  Extern "C" entry point into this conduit which returns

//                     should display the UI necessary to configure this

//        conduit.

//

//       Parameters:   none

//

//       Returns:      0 - success, !0 - failure

//

/////////////////////////////////////////////////////////////////////////////

//       REVISION HISTORY:

//  05Oct96  cja  created

/////////////////////////////////////////////////////////////////////////////

ExportFunc long ConfigureConduit(CSyncPreference& pref)

{

    long                nRtn = -1;

    char                szName[81];

    CMCConfigureDlg     actDlg;



    pref.m_SyncPref = eNoPreference;



    GetConduitName(szName,80);

    actDlg.m_csGroupText = szName;



    switch (pref.m_SyncType)

    {

 case eFast:

 case eSlow:

 actDlg.m_nActionIndex = 0;

 break;

/*  case ePCtoHH:

 actDlg.m_nActionIndex = 1;

 break;

 case eHHtoPC:

 actDlg.m_nActionIndex = 2;

 break;*/

 case eDoNothing:

 default:

 actDlg.m_nActionIndex = 1;

 break;

    }



    if (actDlg.DoModal() == IDOK)

    {



 switch (actDlg.m_nActionIndex)

 {

     case 0:

     pref.m_SyncType = eFast;

     break;

     case 1:

/*      pref.m_SyncType = ePCtoHH;

     break;

     case 2:

     pref.m_SyncType = eHHtoPC;

     break;

     case 3:*/

     default:

     pref.m_SyncType = eDoNothing;

     break;

 }



 pref.m_SyncPref = (actDlg.m_bMakeDefault) ? ePermanentPreference : eTemporaryPreference;



 nRtn = 0;

    }



    return nRtn;

}


La fonction qui est appelée lorsque tu demandes à configurer la conduite depuis le programme hotsync. En général, tu affiches le dialogue de choix entre synchronise / Palm remplace PC / ... Les exemples de dialogue dans le CDK sont assez simples, il me semble...

CODE
/////////////////////////////////////////////////////////////////////////////

//

/////////////////////////////////////////////////////////////////////////////

//

//  Method:  CfgConduit

//

//  Description:    This is the second instance of ConfigureConduit. This function

//                  is provided with more info from the caller.

//                  This version of the function only supports the eConfig1 enum.

//

//  Parameters:    ConduitCfgEnum cfgType - enum specifying the version of the

//                      CfgConduit Call.

//                  void *pArgs - In the eConfig1 call, this is a pointer to aCfgConduitInfoType

//                      structure. This structure provides extra info to the conduit.

//                  DWORD *pdwArgsSize - This is a pointer to a DWORD specifying the size of pArgs.

//

//  Returns:  0  - Success.

//        !0      - error code.

//

/////////////////////////////////////////////////////////////////////////////

//  REVISION HISTORY:

//  01/23/98    KRM Created

//

/////////////////////////////////////////////////////////////////////////////

ExportFunc long CfgConduit(ConduitCfgEnum cfgType, void * pArgs, DWORD * pdwArgsSize)

{

    AFX_MANAGE_STATE(AfxGetStaticModuleState());



    long nRtn = -1;

    TCHAR szName[256];

   DWORD dwNamesize;

    CMCConfigureDlg actDlg;

   ConduitRequestInfoType infoStruct;

   CfgConduitInfoType * pCfgInfo;



   dwNamesize = sizeof(szName);



   if (cfgType != eConfig1)

    {

 return CONDERR_UNSUPPORTED_CFGCONDUIT_ENUM;

    }



   if (!pArgs)

    {

       return CONDERR_INVALID_INARGS_PTR;

    }

   if (!pdwArgsSize)

    {

       return CONDERR_INVALID_ARGSSIZE_PTR;

    }

   if (*pdwArgsSize != SZ_CFGCONDUITINFO)

    {

       return CONDERR_INVALID_ARGSSIZE;

    }



   pCfgInfo = (CfgConduitInfoType *)pArgs;

   if (pCfgInfo->dwVersion != CFGCONDUITINFO_VERSION_1)

    {

       return CONDERR_UNSUPPORTED_STRUCT_VERSION;

    }



   infoStruct.dwVersion   = CONDUITREQUESTINFO_VERSION_1;

   infoStruct.dwSize      = SZ_CONDUITREQUESTINFO;

   infoStruct.dwCreatorId = pCfgInfo -> dwCreatorId;

   infoStruct.dwUserId    = pCfgInfo -> dwUserId;

   strcpy(infoStruct.szUser, pCfgInfo -> szUser);

   nRtn = GetConduitInfo(eConduitName, (void *) &infoStruct, (void *) szName, &dwNamesize);

   if (nRtn)

    {

       return nRtn;

    }



   actDlg.m_csGroupText = szName;



   switch (pCfgInfo->syncTemporary)

    {

       case eFast:

       case eSlow:

       actDlg.m_nActionIndex = 0;

       break;

/*        case ePCtoHH:

       actDlg.m_nActionIndex = 1;

       break;

       case eHHtoPC:

       actDlg.m_nActionIndex = 2;

       break;*/

       case eDoNothing:

       default:

       actDlg.m_nActionIndex = 1;

       break;

   }



   nRtn = -1;

   if (actDlg.DoModal() == IDOK)

    {



       switch (actDlg.m_nActionIndex)

 {

           case 0:

           pCfgInfo->syncNew = eFast;

           break;

           case 1:

/*            pCfgInfo->syncNew = ePCtoHH;

           break;

           case 2:

           pCfgInfo->syncNew = eHHtoPC;

           break;

           case 3:*/

           default:

           pCfgInfo->syncNew = eDoNothing;

           break;

       }



       pCfgInfo->syncPref = (actDlg.m_bMakeDefault) ? ePermanentPreference : eTemporaryPreference;



       nRtn = 0;

   }



   return nRtn;

}


La même ( rolleyes.gif ) mais pour une version plus ancienne de hotsync...
nsadon
ok merci Patrice c'est un peu plus clair maintenant dans mon esprit.
Par contre une autre petite question, le but de mon conduit c'est de creer une base de donnée sur mon palm a partir d'une base Interbase.
D'où ma question, comment faire la difference pour lui indiquer que j'ouvre ma base sur le pc ou sur le palm, les fonctions relative aux traitements des bases de données sont elles les memes pour le palm et Interbase?
Puisqu'en faite il faut que j'ouvre ma base Interbase, creer celle du palm si elle n'existe pas deja et copier chaque records dans l'autre base.
J'espere etre assez clair car c'est pas tres clair pour moi deja.
encore uen fois merci de ton aide icon_biggrin.gif
Patrice
icon_question.gif Je pense que je ne comprend pas la question :!: Une base Interbase et une base PALM n'ont strictement rien à voir (déjà la première est une base de données au sens SGBD et l'autre n'est qu'un fichier dans un filesystem un peu particulier)...
Donc à moins que tu ne parles d'une version Palm d'Interbase (auquel cas je ne pourrai pas t'aider car je ne connais absolument pas), je ne vois pas...
nsadon
nan ce que je me demandais c'est quelles fonctions je dois utiliser pour ouvrir mes deux bases, celle d'interbase et celle du palm, j'utilise les memes fonction que d'habitudes ou bien il y en a des specifiques au cdk
Patrice
Pour Interbase, je n'en sais fichtre rien mais tu dois avoir un SDK. Et pour le Palm, il faut utiliser les fonctions du CDK...
nsadon
oki merci
jvais m'y mettre je te tiendra iau cournat de mon avancé.
nsadon
Bonjour,

Dans mon conduit, apres l'ouverture de ma base de donnée de mon palm je n'arrive pas a ecrire dedans, pour faire cela j'utilise SyncWriteRec();
mais je ne comprend pas trop le CRawRecordInfo que cette fonction prend en parametre plus precisement ce qu'est le HSByte.

CODE
CRawRecordInfo rrinfo_m;

rrInfo.m_pBytes  = ma structure; //ca ne passe pas et j'aimerai savoir ce qui              faut que je mette pour pouvoir lui filer ma structure


Si quelqu'un pouvait m'eclaircir sur ce point j'apprecierai.
merci
Ceci est une version "bas débit" de notre forum. Pour voir la version complète avec plus d'information, la mise en page et les images, veuillez cliquer ici.
Invision Power Board © 2001-2008 Invision Power Services, Inc.