![]() |
![]() |
|
|
||||||||
|
||||||||
L’interface de Microsoft
permettant de communiquer avec un
ordinateur Windows et nos mobiles
sous Windows Mobile est :
·
ActiveSync : pour les ordinateurs dont le système d’exploitation est
XP ou en dessous (Windows
2000, Windows 98…).
·
Windows Mobile Device Center :
pour les ordinateurs dont le système d’exploitation est
Vista.
Nous allons préciser
maintenant les éléments utiles apportés par cette interface pour communiquer
de PC à Mobile ou de
Mobile à PC, puis nos verrons
comment le programme
ThemeGenCE se sert de cette interface pour augmenter les options
de création ou de relecture de Thèmes (TSK), ou donner de multiples
renseignements sur le mobile connecté avec
ActiveSync ou Windows Mobile Device
Center.
Rapi.dll
A l’installation d’
ActiveSync ou Windows Mobile Device
Center une DLL rapi.dll
est mise dans les dossiers systèmes de l’ordinateur (Windows/System32). C’est grâce à
l’utilisation de cette dll que l’on va pouvoir communiquer entre le PC et le
mobile.
Les fonctions déclarées
dans rapi.dll sont :
function
CeRapiInitEx(RInit:
PRAPIINIT): HRESULT;
function
CeRapiInit:
HRESULT;
function
CeRapiUninit:
HRESULT;
function
CeRapiGetError:
HRESULT;
function
CeRapiFreeBuffer(buffer:
pointer): HRESULT;
function
CeRapiInvoke
(pDllPath: LPCWSTR; pFunctionName: LPCWSTR;
cbInput: DWORD; Input: PBYTE; var cbOutput: DWORD; var
pOutput: PBYTE; pIRAPIStream_:pointer{PIRAPIStream}; dwReserved:
DWORD): HRESULT;
function
CeCreateDatabase
(lpszName: LPWSTR; dwDbaseType: DWORD; wNumSortOrder: WORD; rgSortSpecs:
PSORTORDERSPEC): CEOID;
function
CeDeleteDatabase
(oidDbase: CEOID): longbool;
function
CeDeleteRecord
(hDatabase: THANDLE; oidRecord: CEOID): longbool;
function
CeFindFirstDatabase
(dwDbaseType: DWORD): THANDLE;
function
CeFindNextDatabase
(hEnum: THANDLE): CEOID;
function
CeOidGetInfo
(oid: CEOID; oidInfo: pointer {CEOIDINFO [JP]}): longbool;
function
CeOidGetInfoEx
(pceguid : PCEGUID; oid: CEOID; oidInfo: pointer): longbool;
function
CeOpenDatabase(poid:
PCEOID; lpszName: LPWSTR;
SortPropID: CEPROPID; Mode: DWORD;
hwndNotify: HWND): THANDLE;
function
CeReadRecordProps(DBHandle:
THANDLE; Mode: DWORD;
var PropIDCount: WORD; aCEProps: LPDWORD;
var Buf: PChar; var BufSize: DWORD):CEOID;
function
CeSeekDatabase
(hDatabase: THANDLE; dwSeekType: DWORD; dwValue: DWORD;
var dwIndex: DWORD): CEOID;
function
CeSetDatabaseInfo
(oidDbase: CEOID; NewInfo: CEDBASEINFO): longbool;
function
CeWriteRecordProps
(hDbase: THANDLE; oidRecord: CEOID; cPropID: WORD; rgPropVal: PCEPROPVAL):
CEOID;
function
CeFindFirstFile
(lpFileName: LPCWSTR; var FindFileData: CE_FIND_DATA): THANDLE;
function
CeFindNextFile
(hFindFile: THANDLE; var FindFileData: CE_FIND_DATA): longbool;
function
CeFindClose
(hFindFile: THANDLE): longbool;
function
CeGetFileAttributes
(lpFileName: LPCWSTR): DWORD;
function
CeSetFileAttributes
(lpFileName: LPCWSTR; dwFileAttributes: DWORD): longbool;
function
CeCreateFile
(lpFileName: LPCWSTR; dwDesiredAccess: DWORD;
dwShareMode: DWORD; lpSecurityAttributes: PSecurityAttributes;
dwCreationDistribution: DWORD; dwFlagsAndAttributes: DWORD;
hTemplateFile: THANDLE): THANDLE;
function
CeReadFile
(hFile: THANDLE; Buffer : PByte; nNumberOfBytesToRead: DWORD;
var lpNumberOfBytesRead: DWORD; lpOverlapped_: POVERLAPPED): longbool;
function
CeWriteFile
(hFile: THANDLE; Buffer : PByte; nNumberOfBytesToWrite: DWORD;
var lpNumberOfBytesWritten: DWORD; lpOverlapped_: POVERLAPPED):
longbool;
function
CeCloseHandle
(hObject: THANDLE): longbool;
function
CeFindAllFiles
(szPath: LPCWSTR; dwFlags: DWORD; var dwFoundCount: DWORD;
var pFindDataArray: LPCE_FIND_DATA): longbool;
function
CeFindAllDatabases
(dwDbaseType: DWORD; wFlags: WORD; var cFindData : WORD;
var pFindData: LPCEDB_FIND_DATA): longbool;
function
CeEnumDBVolumes(var
pceguid: CEGUID; lpBuf: LPWSTR; dwNumChars: DWORD): longbool;
function
CeFindFirstDatabaseEx(pceguid:
PCEGUID; dwDbaseType: DWORD): THANDLE;
function
CeFindNextDatabaseEx(hEnum
: THANDLE; pceguid : PCEGUID): CEOID;
function
CeGetLastError:
DWORD;
function
CeSetFilePointer
(hFile: THANDLE; lDistanceToMove: LONG;
DistanceToMoveHigh: PLONG; dwMoveMethod: DWORD): DWORD;
function
CeSetEndOfFile
(hFile: THANDLE): longbool;
function
CeCreateDirectory
(lpPathName: LPCWSTR; lpSecurityAttributes: PSecurityAttributes): longbool;
function
CeRemoveDirectory
(lpPathName: LPCWSTR): longbool;
function
CeCreateProcess
(lpApplicationName: LPCWSTR; lpCommandLine: LPCWSTR;
lpProcessAttributes: PSecurityAttributes; lpThreadAttributes:
PSecurityAttributes;
bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment:
Pointer;
lpCurrentDirectory: LPWSTR; lpStartupInfo: Pointer;
var lpProcessInformation: TPROCESSINFORMATION): longbool;
function
CeMoveFile
(lpExistingFileName: LPCWSTR; lpNewFileName: LPCWSTR): longbool;
function
CeCopyFile
(lpExistingFileName: LPCWSTR; lpNewFileName: LPCWSTR; bFailIfExists: BOOL):
longbool;
function
CeDeleteFile
(lpFileName: LPCWSTR): longbool;
function
CeGetFileSize
(hFile: THANDLE; lpFileSizeHigh: LPDWORD): DWORD;
function
CeRegOpenKeyEx
(hKey_: HKEY; lpszSubKey: LPCWSTR; dwReserved: DWORD;
samDesired: REGSAM; phkResult: PHKEY): LONG;
function
CeRegEnumKeyEx
(hKey_: HKEY; dwIndex: DWORD; lpszName: LPWSTR; var cchName: DWORD;
lpReserved: pointer; lpszClass: LPWSTR; lpcchClass: PDWORD;
lpftLastWrite: PFILETIME): LONG;
function
CeRegCreateKeyEx
(hKey_: HKEY; lpszSubKey: LPCWSTR; dwReserved: DWORD; lpszClass: LPWSTR;
dwOptions: DWORD; samDesired: REGSAM; lpSecurityAttributes:
PSECURITYATTRIBUTES;
var hkResult: HKEY; lpdwDisposition: PDWORD): LONG;
function
CeRegCloseKey
(hKey_: HKEY): LONG;
function
CeRegDeleteKey
(hKey_: HKEY; lpszSubKey: LPCWSTR): LONG;
function
CeRegEnumValue
(hKey_: HKEY; dwIndex: DWORD; lpszName: LPWSTR;
var lpcchName: DWORD; lpReserved: Pointer; lpType: PDWORD; lpData:
PBYTE;
lpcbData: PDWORD): LONG;
function
CeRegDeleteValue
(hKey_: HKEY; lpValueName: LPCWSTR): LONG;
function
CeRegQueryInfoKey
(hKey_: HKEY; lpClass: LPWSTR; lpcbClass: LPDWORD;
lpReserved: Pointer; lpcSubKeys, lpcbMaxSubKeyLen, lpcbMaxClassLen,
lpcValues, lpcbMaxValueNameLen, lpcbMaxValueLen,
lpcbSecurityDescriptor: PDWORD;
lpftLastWriteTime: PFileTime): LONG;
function
CeRegQueryValueEx
(hKey_: HKEY; lpValueName: LPCWSTR; lpReserved: Pointer;
lpType: PDWORD; lpData: PBYTE; lpcbData: PDWORD): LONG;
function
CeRegSetValueEx
(hKey_: HKEY; lpValueName: LPCWSTR; Reserved: DWORD;
dwType: DWORD; lpData: Pointer; cbData: DWORD): LONG;
function
CeGetStoreInformation(var
lpsi: STORE_INFORMATION): longbool;
function
CeGetSystemMetrics
(nIndex: integer): LONG;
function
CeGetDesktopDeviceCaps
(nIndex: integer): LONG;
procedure
CeGetSystemInfo
(var lpsi: TSYSTEMINFO);
function
CeSHCreateShortcut
(lpszShortcut: LPWSTR; lpszTarget: LPWSTR): DWORD;
function
CeSHGetShortcutTarget
(lpszShortcut: LPWSTR; lpszTarget: LPWSTR; Arg3: integer): longbool;
function
CeCheckPassword
(lpszPassword: LPWSTR): longbool;
function
CeGetFileTime
(hFile: THandle; lpCreationTime, lpLastAccessTime,
lpLastWriteTime: PFileTime): longbool;
function
CeSetFileTime
(hFile: THandle; lpCreationTime, lpLastAccessTime,
lpLastWriteTime: PFileTime): longbool;
function
CeGetVersionEx
(var lpcov: CEOSVERSIONINFO): longbool;
function
CeGetWindow
(hWnd: HWND; uCmd: DWORD): HWND;
function
CeGetWindowLong
(hWnd: HWND; nIndex: integer): LONG;
function
CeGetWindowText
(hWnd: HWND; lpString: LPWSTR; nMaxCount: integer): LONG;
function
CeGetClassName
(hWnd: HWND; lpClassName: LPWSTR; nMaxCount: integer): LONG;
function
CeGlobalMemoryStatus
(var lpms: TMEMORYSTATUS): longbool;
function
CeGetSystemPowerStatusEx
(var lpsps: SYSTEM_POWER_STATUS_EX; fUpdate: BOOL): longbool;
function
CeGetTempPath
(nBufferLength: DWORD; lpBuffer: LPWSTR): DWORD;
function
CeGetSpecialFolderPath
(nFolder: integer; nBufferLength: DWORD; lpBuffer: LPWSTR): DWORD;
function
CeQueryInstructionSet(dwInstructionSet
: DWORD; lpdwCurrentInstructionSet : LPDWORD): longbool;
Ces fonctions ont en
principe leurs équivalents – sans le
préfixe Ce - sur le
mobile si on les utilise pour des programmes écrits pour Windows Mobile.
Celles utilisées – côté PC – sont toutes préfixées par
Ce.
CeUtil.dll
Une autre dll CeUtil.dll
est aussi dans les fichiers Windows système si
ActiveSync ou
Windows Mobile Device Center sont
installés sur le PC.
Les fonctions déclarées
dans CeUtil.dll sont :
function
CeGetDeviceId:
HRESULT;
function
CeSvcOpen(uSvc:
DWORD; pszPath: LPTSTR; fCreate: boolean; var phSvc: HCESVC): HRESULT;
function
CeSvcOpenEx(hSvcRoot:
HCESVC; pszPath: LPTSTR; fCreate: boolean; var phSvc : HCESVC): HRESULT;
function
CeSvcClose(hSvc:
HCESVC): HRESULT;
function
CeSvcGetString(hSvc:
HCESVC; pszValName: LPCTSTR; pszVal: LPTSTR; cbVal: DWORD): HRESULT;
function
CeSvcGetDword(hSvc:
HCESVC; pszValName: LPCTSTR; var pdwVal: DWORD): HRESULT;
function
CeSvcEnumProfiles(var
phSvc: HCESVC; lProfileIndex: DWORD; var plProfile: DWORD): HRESULT;
Notifications
IDccManSink
L’interface
IDccManSink permet de recevoir des
notifications sur le PC quand un mobile est connecté ou déconnecté à
celui-ci. Cette interface est exécutée dans le thread de
Rapi.
Les notifications sont :
function
OnLogIpAddr(dwIpAddr
: DWORD): HResult; stdcall;
function
OnLogTerminated:
HResult; stdcall;
function
OnLogActive:
HResult; stdcall;
function
OnLogInactive:
HResult; stdcall;
function
OnLogAnswered:
HResult; stdcall;
function
OnLogListen:
HResult; stdcall;
function
OnLogDisconnection:
HResult; stdcall;
function
OnLogError:
HResult; stdcall;
Pour
ThemegenCE j’ai écrit un composant
(en Delphi) qui reçoit ces
notifications en temps réel, ce qui permet d’adapter les options disponibles
du programme en fonction de l’état de connexion du mobile.
Pour apprécier le temps
réel, lancer
ThemeGenCE et connectez
ou déconnectez le mobile. Selon l’état, les « gros » boutons de la barre
supérieure :
·
« Lire
un Thème sur le Pocket PC ».
·
« Transfert
du Thème en cours vers le Pocket PC ».
·
« Informations
PDA si connecté ».
sont
grisés et non « cliquables » si le
mobile est déconnecté ou colorés et
fonctionnels si le mobile est connecté au PC.
ThemeGenCE et
ActiveSync ou Windows Mobile Device Center
Voici quelques exemples
utilisés par
ThemegenCE (en
Delphi mais c’est le principe qui compte):
1.
Recenser sur le mobile tous les thèmes (extension « .tsk ») à partir de la
racine :
type
PCEFDArray = ^TCEFDArray;
TCEFDArray = array[0..32767] of
CE_FIND_DATA;
Fonction Recherche ;
var
foundCount :DWORD;
findDataArray : PCEFDArray;
i : integer;
begin
CeFindAllFiles(PWideChar(WideString(‘\*’)),
FAF_ATTRIBUTES or FAF_NAME, foundCount,
LPCE_FIND_DATA(findDataArray));
if foundCount > 0 then
begin
for i := 0 to foundCount - 1 do
begin
NomFichier := findDataArray[i].cFileName;
if UpperCase(ExtractFileExt(NomFichier)) = '.TSK' then “mettre ce nom
dans la liste”;
end;
end;
Cette petite fonction explore tous les dossiers et tous les sous-dossiers à
partir de la racine et récupère le chemin complet de chaque fichier ayant
pour extension ‘.TSK’.
2.
Ecrire un fichier (en l’occurrence dans
ThemegenCE , un thème) :
function EcrireFichierSurCE(NomFichier, OrigineFichier :
string) : boolean;
var
DestinationHandle : THandle;
Buf: PByte;
NumRead, NumWritten: DWORD;
taille : DWORD;
FileHandle: Integer;
begin
Result := false;
DestinationHandle :=
CeCreateFile(PWideChar(WideString(NomFichier)),
GENERIC_WRITE, FILE_SHARE_READ,
nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if DestinationHandle =
INVALID_HANDLE_VALUE then Result := false
else
begin
FileHandle := FileOpen(OrigineFichier, fmOpenRead);
taille
:= FileSeek(FileHandle,0,2);
FileSeek(FileHandle,0,0);
GetMem(Buf,
taille);
try
NumRead
:= FileRead(FileHandle, Buf^, taille);
if
NumRead = taille then
begin
Result :=
CeWriteFile(DestinationHandle, Buf, taille, NumWritten, nil);
if Result and (taille <> NumWritten) then Result := false;
end;
finally
FreeMem(Buf);
FileClose(FileHandle);
CeCloseHandle(DestinationHandle);
end;
end;
end;
Un fichier est lu sur le PC (par FileOpen) et écrit sur le PDA (par
CeWriteFile).
3.
Lire un fichier sur le Mobile :
function LireUnFichierDuPDA(NomFichier,
Destination : string) : boolean;
var
lngFileHandle : THandle;
lpFindFileData : Ce_Find_Data;
FileHandle: Integer;
Buf: PByte;
NumRead, NumWritten : DWORD;
taille : DWORD;
begin
Result := false;
lngFileHandle :=
CeFindFirstFile(PWideChar(WideString(NomFichier)), lpFindFileData);
if lngFileHandle <>
INVALID_HANDLE_VALUE then //ShowMessage('Le fichier n''existe pas')
begin
CeFindClose(lngFileHandle);
lngFileHandle :=
CeCreateFile(PWideChar(WideString(NomFichier)),
GENERIC_READ, FILE_SHARE_READ,
NIL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if
lngFileHandle <> INVALID_HANDLE_VALUE then
begin
FileHandle := FileCreate(Destination);
taille := lpFindFileData.nFileSizeLow;
GetMem(Buf, taille);
try
Result :=
CeReadFile(lngFileHandle, Buf, taille, NumRead, NIL);
if Result and (taille = NumRead) then
begin
NumWritten := FileWrite(FileHandle, Buf^, taille);
if NumWritten <> taille then Result := false;
end
else Result := false;
finally
FreeMem(Buf);
FileClose(FileHandle);
CeCloseHandle(lngFileHandle);
end;
end;
end;
end;
4.
Rechercher sur le PDA le nom du thème en cours :
Attention, cela nécessite d’aller lire la base de registre du PDA ! Là, ce
n’est pas grave car on ne fait que lire la base, mais on peut aussi utiliser
des fonctions qui écrivent dans la base de registre…
function NomTSKactuel : string;
var
cle : HKEY;
retCode : integer;
dwType : DWORD;
bData : PByte;
cbData : DWORD;
Chaine : WideString;
begin
Result := '';
retCode :=
CeRegOpenKeyEx(HKEY_CURRENT_USER, PWideChar(WideString('Software\Microsoft\Today')), 0,
0, @cle);
if retCode = ERROR_SUCCESS then
begin
Chaine
:= 'Skin';
retCode
:=
CeRegQueryValueEx(cle, PWideChar(Chaine), NIL, @dwType, NIL, @cbData);
if ((retCode
= ERROR_SUCCESS) or (retCode = ERROR_MORE_DATA)) and (dwType = REG_SZ) then
begin
GetMem(bData, cbData);
try
if
CeRegQueryValueEx(cle, PWideChar(Chaine), NIL, @dwType, bData, @cbData)
= ERROR_SUCCESS then Result := String(PWideChar(bData));
finally
FreeMem(bData, cbData);
end;
end;
CeRegCloseKey(cle);
end;
end;
5.
Rechercher la version de Windows Mobile :
Ici on utilise la fonction CeGetVersionEx :
function MajorVersionCe : integer;
var
CV : CeOSVersionInfo;
begin
CV.dwOSVersionInfoSize :=
SizeOf(CV);
CeGetVersionEx(CV);
Result := CV.dwMajorVersion;
end;
6.
…………..
Voilà on peut faire
beaucoup de choses à partir d’un PC connecté à un mobile, et ce dans les 2
sens. Il est vrai que je ne m’en suis pas privé dans mon programme
ThemeGenCE. Pour « me faire
plaisir » j’ai rajouté quelques fonctions, qui je l’avoue n’ont pas
grand-chose à voir avec la création ou la visualisation de Thèmes Windows
Mobile.
|
|