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 ».
« 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
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
Projet Windows▲
Les fichiers nécessaires sont :
Package.c
OPEN4D.h
4DOPEN.LIB
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 :
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 :
É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