Récupération d’informations sur le 4D Server par les librairies 4D Open : Projets Windows, CFM, Mach-O (1/2)

Aziz ELGHOMARI

- Titre : Récupération d’informations sur le 4D Server par les librairies 4D Open : Projets Windows, CFM, Mach-O (1/2)

- Auteur : Aziz ELGHOMARI

- Parution : 1 août 2004

- Licence : Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.

Sommaire

- I. Introduction ♪

- II. Les API de 4e Dimension

- III. Explication et construction d'applications « Carbon »

- « Carbon » et Mac OS X

- Construction d'application et Windows (projet « Mach-O », projet « CFM », projet « Windows »)

- Projet CFM

- Projet Mach-0

- Projet Windows

- IV. Explication de points d'entrées de l'API 4D Open utilisés dans le Code « C »

- Phase d'initialisation et sélection du 4D Server

- Affichage d'informations sur le 4D Server

- Affichage d'informations sur la structure de la base de données

- Affichage d'informations sur les process

- V. Mode d'emploi de la note technique

- Pour les formats « Windows » et « CFM »

- Pour le format « Mach-O »

- VI. Conclusion

- VII. Annexes : Les Codes Sources utilisés en Language « C »

- Code Source Windows

- Code Source Macintosh

- VIII. Bases exemples

I - Introduction ♪

Cette note technique va vous permettre de créer un client léger grâce aux librairies « 4D Open ». L'exécutable récupérera des informations sur le 4D Server, sur les process exécutés ainsi que sur la structure de la base de données (tables, champs, etc..). Trois projets sont fournis avec la note technique : projet « Mach-O », projet « CFM », projet « Windows ».

Ces différents projets sont fournis pour 4D 2003 et 4D 2004.

Une suite à cette note technique sera prochainement publiée, qui traitera de l'accès aux sélections (création, déplacement…) et aux données (ajout, suppression, modification).

II - Les API de 4e Dimension

Une API (Application Programming Interface) est une librairie au sens Pascal ou C du terme, permettant de lier une application à une autre, en accédant à certains points d'entrée et en transmettant des données dans un sens ou dans l'autre.

Pour cela, l'application cible doit posséder un ou plusieurs points d'entrée, acceptant un type spécifique d'information. Il existe une liste des points d'entrée permettant de communiquer avec une base exploitée avec 4D Serveur.

Les API de 4e Dimension permettent de communiquer avec 4D Serveur, avec des fonctions divisées en quatre grandes classes :

- Contrôle des accès : gestion des mots de passe et des groupes ;

- Accès à la structure : description de la structure de la base de données. Les données sont organisées en tables, en champs, dont on peut récupérer la liste et les attributs ;

- Accès aux sélections : il est possible de créer des sélections de fiches par des recherches, de se déplacer dans ces sélections, de créer des sélections temporaires, etc. ;

- Accès aux données : on peut ajouter, détruire, modifier des enregistrements, en restant cohérent avec un système multiutilisateur.

Dans cette note technique, nous traiterons de la partie concernant l'accès à la structure d'une base tournant sur 4D Server. L'accès aux sélections et aux données fera l'objet d'une deuxième note.

III - Explication et construction d'applications « Carbon »

Dans cette note technique, nous allons travailler sur différents projets utilisés :

Pour la partie Macintosh, nous avons un seul projet qui contient le projet « CFM » et le projet « Mach-O ».

Pour la partie Windows, nous avons le projet Windows

« Carbon » et Mac OS X

« Carbon » est l'ensemble des interfaces de programmation « C » pour Mac OS X.

A l'origine Carbon a été conçu pour apporter une migration en douceur aux développeurs chargés de migrer leur code Mac OS 9.

« Cocoa » : l'interface orientée objet pour écrire des applications Mac OS X en « C » ou en « Java ».

« Classic » : un environnement de compatibilité pour applications écrites pour les systèmes antérieurs à Mac OS X. Ces applications ne profitent pas de tous les avantages de Mac OS X.

« Java » : une machine virtuelle « JDK-compliant » pour exécution des applications « Java » pures.

Construction d'application et Windows (projet « Mach-O », projet « CFM », projet « Windows »)

« Carbon » est une collection d'interfaces de programmation. Vous pouvez l'employer dans n'importe quel environnement de développement Macintosh en langage « C » qui supporte le PowerPC pour construire des applications Carbon.

Cependant il y a quelques limitations. Par exemple, les développeurs « Carbon » peuvent créer des applications dans deux formats exécutables différents :

« Mach-O » : c'est le format des exécutables natifs de Mac OS X. Les exécutables « Mach-O » ne peuvent tourner que sur Mac OS X.

« PEF » : le Prefered Executable Format (PEF) était le format des exécutables natifs pour les systèmes Mac OS PowerPC antérieurs à Mac OS X. Avec quelques adaptations, les exécutables « PEF » peuvent tourner sur Mac OS X aussi bien que sur les systèmes anciens.
Les applications « PEF » sont parfois appelées des applications « CFM » parce que le Code Fragment Manager est le mécanisme utilisé pour la préparation et l'exécution de tels fichiers.

Projet CFM

Les fichiers nécessaires à ce projet sont :

NetworkComponents.rsrc
OpenPack.c
MSL_ALL_Carbon.Lib
CarbonLib
4DOpen.rsrc
4Dopen.Carbon.lib

Réglages dans les préférences du projet « CFM »

Projet Mach-0

Les fichiers nécessaires à ce projet sont :

NetworkComponents.rsrc
OpenPack.c
4DOpen.rsrc
MSL_All_Mach-o.lib
Crt1.o
4DopenMacho.a

Réglages dans les préférences du projet « Mach-0 »

Projet Windows

Les fichiers nécessaires sont :

Package.c
OPEN4D.h
4DOPEN.LIB

Réglages dans les préférences du projet « Windows »

L'exécutable « Open4D » est placé dans le dossier « Debug ». Pour le faire fonctionner la DLL « 4D Open » doit être placée au même niveau, comme le montre le graphique ci-dessous :

Le contenu du dossier « Debug » après compilation

IV - Explication de points d'entrées de l'API 4D Open utilisés dans le Code « C »

Phase d'initialisation et sélection du 4D Server

Phase d'initialisation
La phase d'initialisation constitue la première étape dans l'élaboration d'un projet 4D Open, elle comprend les opérations suivantes :

_4D_Init4DWS
Cette routine est à mettre au début du programme, elle consiste à initialiser les données utilisées par le 4D Open ;

_4D_DeInit4DWS
Cette routine permet de déinitialiser les données utilisées par la librairie 4D Open ;

_4D_InitNetworkComponent
Cette routine alloue un bloc de mémoire privé au composant réseau et retourne un handle sur ce bloc. Il faut noter que nous n'utilisons que le composant réseau TCP ;

_4D_DeInitNetworkComponent
Cette routine permet de libérer le bloc mémoire privé, alloué au composant réseau.
Exemple des composants réseau utilisés :
NC_TCPIP 2 Macintosh et Windows.

Sélectionner le 4D server
Prototype
_4D_Select4DServer(pstring Name, NetworkLocationPtr *NetworkLocation, int2 ComponentNumber,NetworkComponentHandle Data)
On récupère de la routine :
« Name » : Le nom du serveur
« NetworkLocation » : L'emplacement réseau

On transmet à la routine :
« ComponentNumber » : Le numéro ID du composant réseau
« Data » : Le handle composant réseau retourné par _4D_InitNetworkComponent.

Ouvrir le 4D Server
Prototype
_4D_Open4DConnection(IDRec *ID, NetworkLocationPtr NetworkLocation, ConnectHandle *CIDH, int2 ComponentNumber, NetworkComponentHandle Data)
On récupère de la routine :
« CIDH » : Le handle sur la connexion

On transmet à la routine :
« ID » : L'enregistrement qui identifie l'utilisateur.
« NetworkLocation » : L'emplacement réseau
« ComponentNumber » : Le numéro ID du composant réseau
« Data » Le handle composant réseau retourné par _4D_InitNetworkComponent
« ID » est de type « IDRec » et représente la structure suivante :

typedef struct IDRec {
st32 StationName;
st32 UserName;
st32 UserPass;
st32 TaskName;
byte isapi;
byte unused;
}IDRec;

Affichage d'informations sur le 4D Server

Cette phase du programme consiste à afficher des informations concernant le 4D Server sélectionné :

- le nom de la base lancée sur le 4D Server ;

- la version du 4D Server, etc.

Elle comprend les routines suivantes :

_4D_GetServerInfo(ConnectHandle CIDH, ServerInfoRec *ServerInfo)
Cette routine retourne le numéro de version du 4D Server

_4D_Server_CurrentTime(ConnectHandle CIDH, int4*ServerTime)
Cette routine retourne l'heure du 4D Server

_4D_Server_CurrentDate(ConnectHandle CIDH, Date4D* ServerDate)
Cette routine retourne la date du 4D Server

_4D_IsConnectionAsync(ConnectHandle CIDH,byte *AsyncMode)
Cette routine retourne « vrai » si la connexion avec le 4D Server est en mode asynchrone et « faux » dans le cas contraire.

Affichage d'informations sur la structure de la base de données

Cette phase du programme consiste à afficher des informations concernant la structure de la base de données ouverte par le 4D Server.

Elle permet de nous renseigner sur les propriétés de chaque table de la base de données, ainsi que de tous les champs contenus dans cette table (Nom, type, taille…).

Elle comprend les routines suivantes :

_4D_CountFiles
Cette routine retourne le nombre de tables dans la base de données
Prototype
_4D_CountFiles(ConnectHandle CIDH, int2 *Count)

_4D_GetFileList
Cette routine nous renseigne sur les tables utilisées dans la base de données
Prototype
_4D_GetFileList(ConnectHandle CIDH, FileListHandle *TheFileList)
« TheFileList » représente la structure suivante :

typedef struct {
int2 nbFiles;
st32 fileNames[1];
}FileList;

FileListHandle est un Handle sur cette structure

_4D_GetFileDefinition
Cette routine nous fournit des informations détaillées sur une table spécifiée et sur les champs qu'elle contient.
Prototype
_4D_GetFileDefinition( ConnectHandle CIDH, int2 Targetfile, FileDefHandle *Fdef)

typedef struct FileDef {
int2 NB_Fields;
int2 Invisible;
int2 unused1;
int2 FileNum;
int2 unused2;
int4 unused4;
Rect4D Frame;
int2 unused3;
char TrigOnSavingNew;
char TrigOnSavingExisting;
char TrigOnDeleting;
char TrigOnLoading;
int2 unused5;
FieldDef Fields[1];
}FileDef;

Si l'on désire par exemple connaître le nombre de champs, nous pouvons écrire :

FileDef->NB_Fields

Pour savoir si le champ est invisible :

FileDef->Invisible

Affichage d'informations sur les process

Cette phase du programme consiste à récupérer des informations sur les process exécutés sur le serveur.

Pour chaque process, nous pourrons connaître les éléments suivants :

« UserName » : Le nom d'utilisateur
« StationName » : Le nom de la station utilisée
« TaskName » : Le nom de la tâche exécutée
« TotalTimeSpent » : Le temps de travail consommé par le process (exprimé en ticks)

_4D_GetNbUsers(ConnectHandle CIDH, int2 *NbUsers)
Cette routine retourne le nombre d'utilisateurs actuellement connectés à la base.

_4D_GetListProcess(ConnectHandle CIDH, ListProcessHandle *List)
Cette routine retourne le nombre de connexions 4D Open, sans prendre en compte les process du moteur de 4D Serveur.

typedef struct ProcessInfo {
st32 UserName;
st32 StationName;
st32 Taskname;
int4 TotalTimeSpent;
int2 State;
}ProcessInfo;

typedef struct ListProcess {
int2 NB_Process;
ProcessInfo Processes[1];
}ListProcess;
typedef struct ListProcess *ListProcessPtr;
#if !MacintoshStyleHandle
typedef Handle4D ListProcessHandle;
#else
typedef ListProcessPtr *ListProcessHandle;
#endif

Le paramètre « list » de type « ListProcessHandle » va permettre d'accéder aux éléments de la structure « ListProcess » :

Pour obtenir le « UserName » , il faut faire: List->UserName
Pour obtenir la « StationName », il faut faire : List->StationName

V - Mode d'emploi de la note technique

Cette note technique est fournie avec deux projets :

Pour la partie Macintosh, nous avons un seul projet qui contient le projet « CFM » et le projet « Mach-0 », le projet a été réalisé sous Metrowerks Code Warrior 9.

Pour la partie Windows, le projet a été réalisé sous Microsoft Visual Studio.NET

La base doit être lancée sur le réseau, le protocole réseau utilisé est TCP :

const short KNC = NC_TCPIP dans le code source en « C ».

Pour faire fonctionner l'exemple, la base doit être ouverte par le 4D Serveur et doit se composer par exemple d'une table contenant des champs de différents types.

Sous Windows, pour lancer l'exécutable, il faut placer le fichier « 4D Open.dll » dans le dossier « Debug », à côté de l'exécutable « Open4D ».

Pour les formats « Windows » et « CFM »

Au lancement du programme « Open4D.exe », nous récupérons une fenêtre « DOS » affichant différentes informations sur le 4D Server ainsi que sur la base de données qui lui est associée :

Les informations affichées sont :

- le numéro de version du 4D Server ;

- l'heure du 4D Server ;

- la date du 4D Server ;

- si la connexion 4D open est en mode asynchrone ;

- le nombre de tables de la base de données ;

- des informations détaillées sur les tables ainsi que sur les champs utilisés ;

- des informations détaillées sur les process exécutés sur le 4D Server ;

- le nombre d'utilisateurs actuellement connectés à la base ;

- le nombre de connexions « 4D Open » sans prendre en considération les process du moteur 4D Server.

Il faut appuyer sur la touche « Entrée » pour afficher le reste des informations. L'affichage des informations est classé par thème.

Pour le format « Mach-O »

Pour le format « Mach-O », la fenêtre ne peut pas être affichée, il faut utiliser la « Console » Mac OsX :

Informations sur 4D Server affichées avec la « Console » Mac OsX

Éléments fournis avec la note technique

Pour Windows

Projet4D 2003
L'exécutable « Open4D » permet d'ouvrir le 4D Server 2003.

Projet 4D2004
L'exécutable « Open4D » permet d'ouvrir le 4D Server 2004.

Pour Macintosh

L'exécutable « Open4D » généré par le projet « CFM » permet d'ouvrir le 4D Server 2003.
L'exécutable « Open4D » généré par le projet « Mach-0 » permet d'ouvrir le 4D Server 2004.

La base exemple 4e Dimension fournie se nomme « OpenLibrairies » mais vous pouvez faire des tests avec d'autres bases de données 4e Dimension, il suffit pour cela qu'elles contiennent au moins une table et quelques champs.

VI - Conclusion

Les utilisateurs des librairies 4D Open peuvent, à partir de cette note technique, construire un client « léger » et récupérer différentes informations sur le 4D Server ainsi que la base de données qui lui est associée (tables, champs, process, utilisateurs, etc..).

Avantage du Client léger

La taille du Client léger « 4Dopen » (même avec la librairie 4D Open) est beaucoup plus petite qu'un 4D Client Classique.

Inconvénient du Client léger

Il faut programmer toute la partie Interface.

De plus, des explications détaillées vous ont été fournies sur les points importants de la programmation sous Macintosh :

« Carbon » qui constitue l'ensemble des interfaces de programmation « C » pour Mac OS X.
« Mach-O » qui représente le format des exécutables natifs de Mac OS X…

…ainsi que des conseils à suivre pour construire et compiler des projets « Carbon » et « Mach-0 ». Les explications fournies peuvent aider à la création de routines externes aux formats « Mach-0 » et « CFM » ou « Windows ».

VII - Annexes : Les Codes Sources utilisés en Language « C »

Code Source Windows

#if __INTEL__
/* #pragma once */
/* #include "ansi_prefix.win32.h" */
/* #include <Windows.h> */
/* Use pre-compiled header instead */
#elif WIN32    /* <-- defined by Visual C++ */
#include <Windows.h>
#endif

#if WINVER
#undef COLOR_WINDOWFRAME
#undef COLOR_BTNSHADOW
#undef COLOR_BTNFACE
#undef COLOR_BTNHIGHLIGHT
#undef COLOR_BTNTEXT
#undef InsertMenuItem
#undef InsertMenu
#undef AppendMenu
//#include "ASIPORT.H"    /*To use Altura headers (in the folder PPC_H, placed in the project folder)*/
#endif

#define Openlib 1

#include "Open4D.h"
#include <stdlib.h>
#include <string.h>

const short KNC = NC_TCPIP;
const unsigned char KStationName[32]="Intel machine\0";
const unsigned char KUserName[32]="APIUser\0";
const unsigned char KUserPass[32]="APIPass\0";
const unsigned char KUserTask[32]="APITask\0";

NetworkComponentHandle hNetworkComponent;
NetworkLocationPtr pNetworkLocation;
ConnectHandle hConnect;
IDRec logRec;
unsigned char szName[256];

void          initialisation(void);
int2          StartWSConnection(void);
void          Check(int2 myErr, char *description);
unsigned char *PversCstring(unsigned char *pstr);
void          DisplayStructureInfo(void);

void          DisplayServerInfo(void);
void          CloseWSConnection(void);

void Check(int2 myErr, char *description)
{
char err[256];
if(myErr)
{
sprintf(err, "%s: returns %d\n", description , myErr);
printf(err);
getchar();
}
}

//Convert Pstring to Cstring
unsigned char *PversCstring(unsigned char *pstr)
{
unsigned char len= *pstr;
memcpy(pstr,pstr+1,len);
pstr[len]='\0';
return (pstr);
}

int2 StartWSConnection(void)
{
int2 myErr;
myErr =_4D_Select4DServer(szName, &pNetworkLocation, KNC, hNetworkComponent);
if(!myErr)
{
_4D_Open4DConnection(&logRec, pNetworkLocation, &hConnect,KNC, hNetworkComponent);
}
return(myErr);
}

void CloseWSConnection(void)
{
_4D_Close4DConnection(hConnect);
}

void initialisation(void)
{
memcpy(&logRec.StationName[1],KStationName, strlen((char *)KStationName));
logRec.StationName[0]=strlen((char *)KStationName);

memcpy(&logRec.UserName[1],KUserName, strlen((char *)KUserName));
logRec.UserName[0]=strlen((char *)KUserName);

memcpy(&logRec.UserPass[1],KUserPass, strlen((char *)KUserPass));
logRec.UserPass[0]=strlen((char *)KUserPass);

memcpy(&logRec.TaskName[1],KUserTask, strlen((char *)KUserTask));
logRec.TaskName[0]=strlen((char *)KUserTask);
}

void DisplayServerInfo(void)
{
ServerInfoRec sInfo;
Date4D        d;
int4          l;
unsigned char b;
printf(" \n APPUYER SUR LA TOUCHE ENTREE POUR AVOIR DES INFOS SUE LE 4D SERVEUR \n");
getchar();
printf("szName : %s\n", PversCstring(szName));
Check(_4D_GetServerInfo(hConnect, &sInfo),"_4D_GetServerInfo\0");
printf("ServerCurVers : %X\n",  ((sInfo.ServerCurVers & 0xfff) << 16) );
printf("InvertedData : %d\n", sInfo.ServerHasInvertedData);
Check(_4D_Server_CurrentTime(hConnect, &l),"_4D_Server_CurrentTime\0");
printf("Server_CurrentTime :  %ld ticks\n", l);
Check(_4D_Server_CurrentDate(hConnect, &d),"_4D_Server_CurrentDate\0");
printf("Server_CurrentDate : %d/%d/%d\n", d.Day, d.Month, d.Year);
Check(_4D_IsConnectionAsync(hConnect, (unsigned char *) &b),"_4D_IsConnectionAsync\0");
printf("IsConnectionAsync ? : %d\n", b);
printf("\n");
}

void DisplayStructureInfo(void)
{
int2 i,f;
FileListHandle    hList=0L;
FileListPtr        pList;
FileDefHandle    hDef =0L;
FileDefPtr        pDef;

printf("\n APPUYER SUR LA TOUCHE ENTREE POUR AVOIR DES INFOS SUR LA STRUCTURE \n");
getchar();

Check(_4D_CountFiles(hConnect, &i),"_4D_CountFiles\0");
printf("CountFiles: %d\n", i);

Check(_4D_GetFileList(hConnect, &hList),"_4D_GetFileList\0");
pList=(FileListPtr)Lock4DHandle((Handle4D)hList);

for ( f=1; f<=pList->nbFiles; f++)
{
Check(_4D_GetFileDefinition(hConnect, f, &hDef), " _4D_GetFileDefinition");
pDef=(FileDefPtr)Lock4DHandle((Handle4D)hDef);

printf("GetFileList : %s\n", PversCstring(pList->fileNames[f-1]));
printf("GetFileDefinition_NB_Fields : %d\n", pDef->NB_Fields);
printf("GetFileDefinition_Invisible : %d\n", pDef->Invisible);
printf("GetFileDefinition_FileNum : %d\n", pDef->FileNum);
printf("GetFileDefinition_Frame : %d/%d/%d/%d\n", pDef->Frame.left,
pDef->Frame.top, pDef->Frame.right, pDef->Frame.bottom);
printf("GetFileDefinition_TrigOnSavingNew : %d\n", pDef->TrigOnSavingNew);
printf("GetFileDefinition_TrigOnSavingExisting : %d\n", pDef->TrigOnSavingExisting);

printf("GetFileDefinition_TrigOnDeleting : %d\n", pDef->TrigOnDeleting);
printf("GetFileDefinition_TrigOnLoading : %d\n", pDef->TrigOnLoading);
printf("\n APPUYER SUR LA TOUCHE ENTREE POUR AVOIR DES INFOS SUR LES CHAMPS \n");
getchar();

for ( i = 0 ; i < pDef->NB_Fields ; i ++ ) {
printf("GetFileDefinition_Fields[%d]_Name : %s\n", i, PversCstring(pDef->Fields[i].Name));
printf("GetFileDefinition_Fields[%d]_Typ : %d\n", i, pDef->Fields[i].Typ);
printf("GetFileDefinition_Fields[%d]_AlphaLen : %d\n", i, pDef->Fields[i].AlphaLen);
printf("GetFileDefinition_Fields[%d]_u_SimpleField_RelatedFile : %d\n", i,
pDef->Fields[i].u.SimpleField.RelatedFile);
printf("GetFileDefinition_Fields[%d]_u_SimpleField_RelatedField : %d\n", i,
pDef->Fields[i].u.SimpleField.RelatedField);
printf("GetFileDefinition_Fields[%d]_u_SimpleField_Att : %X\n", i,
pDef->Fields[i].u.SimpleField.Att);
printf("GetFileDefinition_Fields[%d]_u_SimpleField_DiscriminantField : %d\n", i,
pDef->Fields[i].u.SimpleField.DiscriminantField);
printf("GetFileDefinition_Fields[%d]_u_PictField_PicAtt : %X\n", i,
pDef->Fields[i].u.PictField.PicAtt);
printf("GetFileDefinition_Fields[%d]_u_PictField_CompressDriver : %X\n", i,
pDef->Fields[i].u.PictField.CompressDriver);

printf("\n APPUYER SUR LA TOUCHE ENTREE POUR PASSER AU CHAMP SUIVANT \n");
getchar();
}

Unlock4DHandle((Handle4D)hDef);
Free4DHandle((Handle4D)hDef);
printf("\n");
}
Unlock4DHandle((Handle4D)hList);
Free4DHandle((Handle4D)hList);
}

void DisplayProcessInfo(void)
{
ListProcessHandle    hList = 0L;
ListProcessPtr        pList;
int2                i;

printf("\n APPUYER SUR LA TOUCHE ENTREE POUR AVOIR DES INFORMATIONS PROCESS \n");
getchar();
Check(_4D_GetNbUsers(hConnect, &i),"_4D_GetNbUsers\0");
printf("GetNbUsers : %d\n", i);
Check(_4D_GetNbUserProcesses(hConnect, &i),"_4D_GetNbUserProcesses\0");
printf("GetNbUserProcesses : %d\n", i);
Check(_4D_GetListProcess(hConnect, &hList),"_4D_GetListProcess\0");
pList = (ListProcessPtr) Lock4DHandle((Handle4D)hList);
for ( i = 0 ; i < pList->NB_Process ; i ++ ) {
printf("GetListProcess_ProcessInfo[%d]_UserName : %s\n", i,
PversCstring(pList->Processes[i].UserName));
printf("GetListProcess_ProcessInfo[%d]_StationName : %s\n", i,
PversCstring(pList->Processes[i].StationName));

printf("GetListProcess_ProcessInfo[%d]_Taskname : %s\n", i,
PversCstring(pList->Processes[i].Taskname));
printf("GetListProcess_ProcessInfo[%d]_TotalTimeSpent : %ld ticks\n",
i, pList->Processes[i].TotalTimeSpent);
printf("GetListProcess_ProcessInfo[%d]_State : %d\n",
i, pList->Processes[i].State);
}
Unlock4DHandle((Handle4D)hList);
Free4DHandle((Handle4D)hList);
}

void main(void)
{
initialisation();

_4D_Init4DWS();

printf("LE NUMERO DE VERSION EST: %ld\n", (_4D_GetVersionNumber()>>16));
printf("LE NOMBRE DES COMPOSANTS RESEAU UTILISES EST %ld\n",_4D_NB_NetworkComponent());
printf("\n");

hNetworkComponent= _4D_InitNetworkComponent(KNC);

if(hNetworkComponent)
{
if(!StartWSConnection())
{
DisplayServerInfo();
DisplayProcessInfo();
DisplayStructureInfo();

CloseWSConnection();
}
_4D_DeInitNetworkComponent(KNC,hNetworkComponent);
}
_4D_DeInit4DWS();
}

Code Source Macintosh

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define OpenLib 1

#ifdef __MWERKS__
#ifdef __INTEL__
#define WINVER 0x0400
#define    MACVER 0
#endif
#else
#define WINVER 0x0400
#define    __INTEL__
#endif

#include "Open4D.h"
#ifdef __INTEL__
const    unsigned char    kStationName[32] = "Intel machine\0";
#else
const    unsigned char    kStationName[32] = "Motorola machine\0";
#endif

const unsigned char   kUserName[32] = "APIUser\0";
const unsigned char   kUserPass[32] = "APIPass\0";
const unsigned char   kUserTask[32] = "APITask\0";
unsigned char         *PversCstring(unsigned char *pstr);

void    initialisation();
void    Check(int2    myErr, char    *description);
int2    StartWSConnection(void);
void    CloseWSConnection(void);
void    DisplayServerInfo(void);
void    DisplayProcessInfo(void);
void    DisplayStructureInfo(void);

NetworkComponentHandle hNetworkComponent;
NetworkLocationPtr     pNetworkLocation;
ConnectHandle          hConnect;
IDRec                  logRec;
unsigned char          szName[256];

// converts a pstring to a cstring
unsigned char    *PversCstring(unsigned char    *pstr)
{
unsigned char    len = *pstr;

memmove(pstr, pstr+1, len);
pstr[len] = '\0';
return    pstr;
}

// checks for errors and reports
void    Check(int2    myErr, char    *description)
{
char    err[256];

if ( myErr ) {
sprintf(err,"%s : returns %d\n", description, myErr);
printf(err);
getchar();
}
}

// opens a connection with server and errors if any
int2   StartWSConnection(void)
{
int2  myErr;

myErr = _4D_Select4DServer(szName, &pNetworkLocation, kNC, hNetworkComponent);
if ( ! myErr ) {
myErr = _4D_Open4DConnection(&logRec, pNetworkLocation, &hConnect, kNC, hNetworkComponent);
}
return    myErr;
}

// closes connection
void    CloseWSConnection(void)
{
if (hConnect)
_4D_Close4DConnection (hConnect);
}
void    DisplayServerInfo(void)
{
ServerInfoRec    sInfo;
Date4D            d;
int4            l;
unsigned char    b;

printf("\n INFORMATIONS SUR LE 4D SERVEUR \n");

printf("szName : %s\n", PversCstring(szName));
Check(_4D_GetServerInfo(hConnect, &sInfo),"_4D_GetServerInfo\0");
printf("ServerCurVers : %X\n",  ((sInfo.ServerCurVers & 0xfff) << 16) );
printf("InvertedData : %d\n", sInfo.ServerHasInvertedData);
Check(_4D_Server_CurrentTime(hConnect, &l),"_4D_Server_CurrentTime\0");
printf("Server_CurrentTime :  %ld ticks\n", l);
Check(_4D_Server_CurrentDate(hConnect, &d),"_4D_Server_CurrentDate\0");
printf("Server_CurrentDate : %d/%d/%d\n", d.Day, d.Month, d.Year);
Check(_4D_IsConnectionAsync(hConnect, (unsigned char *) &b),"_4D_IsConnectionAsync\0");
printf("IsConnectionAsync ? : %d\n", b);

printf("\n");
}

// displays running processes on server
void    DisplayProcessInfo(void)
{
ListProcessHandle    hList = 0L;
ListProcessPtr        pList;
int2
i;
printf("\n INFORMATIONS SUR LES PROCESS SERVEUR \n");

Check(_4D_GetNbUsers(hConnect, &i),"_4D_GetNbUsers\0");
printf("GetNbUsers : %d\n", i);
Check(_4D_GetNbUserProcesses(hConnect, &i),"_4D_GetNbUserProcesses\0");
printf("GetNbUserProcesses : %d\n", i);
Check(_4D_GetListProcess(hConnect, &hList),"_4D_GetListProcess\0");
pList = (ListProcessPtr) Lock4DHandle((Handle4D)hList);

for ( i = 0 ; i < pList->NB_Process ; i ++ ) {
printf("GetListProcess_ProcessInfo[%d]_UserName : %s\n",
i, PversCstring(pList->Processes[i].UserName));
printf("GetListProcess_ProcessInfo[%d]_StationName : %s\n",
i, PversCstring(pList->Processes[i].StationName));
printf("GetListProcess_ProcessInfo[%d]_Taskname : %s\n",
i, PversCstring(pList->Processes[i].Taskname));
printf("GetListProcess_ProcessInfo[%d]_TotalTimeSpent : %ld ticks\n",
i, pList->Processes[i].TotalTimeSpent);
printf("GetListProcess_ProcessInfo[%d]_State : %d\n",
i, pList->Processes[i].State);
}
Unlock4DHandle((Handle4D)hList);
Free4DHandle((Handle4D)hList);
}
// displays structure
void    DisplayStructureInfo(void)
{
FileListHandle    hList = 0L;
FileListPtr        pList;
FileDefHandle    hDef = 0L;
FileDefPtr        pDef;
int2            i, f;

printf("\n INFORMATIONS SUR LES TABLES \n");

Check(_4D_CountFiles(hConnect, &i),"_4D_CountFiles\0");
printf("CountFiles : %d\n", i);
Check(_4D_GetFileList(hConnect, &hList),"_4D_GetFileList\0");
pList = (FileListPtr) Lock4DHandle((Handle4D) hList);
for ( f = 1; f <= pList ->nbFiles ; f ++ ) {
Check(_4D_GetFileDefinition(hConnect, f, &hDef),"_4D_GetFileDefinition\0");
pDef = (FileDefPtr) Lock4DHandle((Handle4D)hDef);
printf("GetFileList : %s\n", PversCstring(pList->fileNames[f-1]));
printf("GetFileDefinition_NB_Fields : %d\n", pDef->NB_Fields);
printf("GetFileDefinition_Invisible : %d\n", pDef->Invisible);
printf("GetFileDefinition_FileNum : %d\n", pDef->FileNum);
printf("GetFileDefinition_Frame : %d/%d/%d/%d\n", pDef->Frame.left,
pDef->Frame.top, pDef->Frame.right, pDef->Frame.bottom);
printf("GetFileDefinition_TrigOnSavingNew : %d\n", pDef->TrigOnSavingNew);
printf("GetFileDefinition_TrigOnSavingExisting : %d\n", pDef->TrigOnSavingExisting);
printf("GetFileDefinition_TrigOnDeleting : %d\n", pDef->TrigOnDeleting);
printf("GetFileDefinition_TrigOnLoading : %d\n", pDef->TrigOnLoading);

printf("\n INFORMATIONS SUR LES CHMAPS \n");
for ( i = 0 ; i < pDef->NB_Fields ; i ++ ) {
printf("GetFileDefinition_Fields[%d]_Name : %s\n", i,
PversCstring(pDef->Fields[i].Name));
printf("GetFileDefinition_Fields[%d]_Typ : %d\n", i,
pDef->Fields[i].Typ);
printf("GetFileDefinition_Fields[%d]_AlphaLen : %d\n", i,
pDef->Fields[i].AlphaLen);
printf("GetFileDefinition_Fields[%d]_u_SimpleField_RelatedFile
: %d\n", i, pDef->Fields[i].u.SimpleField.RelatedFile);
printf("GetFileDefinition_Fields[%d]_u_SimpleField_RelatedField
: %d\n", i, pDef->Fields[i].u.SimpleField.RelatedField);
printf("GetFileDefinition_Fields[%d]_u_SimpleField_Att : %X\n",
i, pDef->Fields[i].u.SimpleField.Att);
printf("GetFileDefinition_Fields[%d]_u_SimpleField_DiscriminantField
: %d\n", i, pDef->Fields[i].u.SimpleField.DiscriminantField);
printf("GetFileDefinition_Fields[%d]_u_PictField_PicAtt : %X\n", i,
pDef->Fields[i].u.PictField.PicAtt);
printf("GetFileDefinition_Fields[%d]_u_PictField_CompressDriver
: %X\n", i, pDef->Fields[i].u.PictField.CompressDriver);
}
Unlock4DHandle((Handle4D)hDef);
Free4DHandle((Handle4D)hDef);
printf("\n");
}
Unlock4DHandle((Handle4D)hList);
Free4DHandle((Handle4D)hList);
}

void initialisation(void)
{
memcpy(&logRec.StationName[1], kStationName, strlen((char *)kStationName));
logRec.StationName[0] = strlen((char *)kStationName);
memcpy(&logRec.UserName[1], kUserName, strlen((char *)kUserName));
logRec.UserName[0] = strlen((char *)kUserName);
memcpy(&logRec.UserPass[1], kUserPass, strlen((char *)kUserPass));
logRec.UserPass[0] = strlen((char *)kUserPass);
memcpy(&logRec.TaskName[1], kUserTask, strlen((char *)kUserTask));
logRec.TaskName[0] = strlen((char *)kUserTask);
}

void main(void)
{
_4D_Init4DWS();

printf("GetVersionNumber : %ld\n", ( _4D_GetVersionNumber() >> 16 ));
printf("NB_NetworkComponent : %d\n", _4D_NB_NetworkComponent());

hNetworkComponent = _4D_InitNetworkComponent(kNC);
if ( hNetworkComponent ) {
if ( ! StartWSConnection()) {
initialisation();
DisplayServerInfo();
DisplayProcessInfo();
DisplayStructureInfo();
//CloseWSConnection();
}
_4D_DeInitNetworkComponent(kNC, hNetworkComponent);
}
_4D_DeInit4DWS();
}

VIII - Bases exemples

Téléchargez les bases exemples :

base exemple Windows

base exemple Mac 1

base exemple Mac 2