Aide - Recherche - Membres - Calendrier
Version complète : Bouts de code reutilisable
Les Forums de PalmAttitude.org > GENERAL PalmOS > Développement sous PalmOS
Eddy
On essaye de regrouper dans ce thread des bouts de code reutilisable par les developpeurs. On precisera en sujet des messages la fonction du code qu'on publie.
Eddy
Pour afficher une image declarée dans les ressources de l'appli :

CODE


void DrawIcon (UInt16 resourceID, UInt16 posx, UInt16 posy) {

 MemHandle hResource;

 hResource = DmGet1Resource(bitmapRsc, resourceID);

 if (hResource != 0) {

   BitmapPtr pBitmap = (BitmapPtr) MemHandleLock(hResource);

   WinDrawBitmap(pBitmap, posx, posy);

   MemPtrUnlock(pBitmap);

   DmReleaseResource(hResource);

 }

}


avec resourceID : l'ID du bitmap, posx et posy les coordonnées où afficher l'image.
Patrice
A noter que ta fonction peut aussi être utilisée pour dessiner l'icône de l'appli (dans une boîte "à propos" par exemple), l'accès à la ressource est alors :
CODE
DmGet1Resource(iconType, resID);

où resID est l'ID de l'icône (1000 en général ?).
oupsman
Je fais remonter ce thread (qu'il ne serait pas idiot de voir en post-it d'ailleurs) anim_wink.gif

Voici un bout de code qui permet d'afficher la version à partir de la ressource déclarée (celle qui apparait dans l'écran Info du Palm) :
IL faut avoir ceci dans le .rcp :

CODE
// Dans la form, tu ajoutes un field comme ceci :



FIELD ID F_ABOUT_VERSION AT (108 31 50 13) MAXCHARS 10 FONT 7



VERSION ID S_VERSION "numéro de version"

NB : Le S_VERSION doit OBLIGATOIREMENT valoir 1 pour que PalmOS affiche correctement le numéro de version dans l'écran Info.

Et dans le .c, on met cela :

CODE
char *verstring;

char versionstring[10];



switch (event-eType) {

     case frmOpenEvent :

             versionstring = DmGet1Resource (verRsc,S_VERSION);

             if (versionstring == NULL) {

                 StrCopy (numeroversion, "Problème");

             } else {

                         verstring = MemHandleLock (versionstring);

                         if (verstring != NULL) {

                                      StrCopy (numeroversion, verstring);

                         } else {

                                      StrCopy (numeroversion, "Problème");

                         }

             }

             SetFieldTextFromStr (F_ABOUT_VERSION,numeroversion,true);

             handled=1;

          break;

}


La fonction SetFieldTextFromStr ne fait pas parti du SDK. Voici son source :

CODE
FieldPtr SetFieldTextFromStr (Word fieldID, CharPtr strP, Boolean redraw) {

 VoidHand txtH;



 txtH = MemHandleNew (StrLen (strP) + 1);



 if (!txtH) {

   return NULL;

 }



 StrCopy (MemHandleLock (txtH), strP);



 MemHandleLock (txtH);



 return SetFieldTextFromHandle (fieldID, txtH, redraw);

}



FieldPtr SetFieldTextFromHandle (Word fieldID, Handle txtH, Boolean redraw) {

 

 VoidHand oldTxtH;

 FormPtr frm = FrmGetActiveForm ();

 FieldPtr fldP;



 fldP = FrmGetObjectPtr (frm, FrmGetObjectIndex (frm,fieldID));

 ErrNonFatalDisplayIf (!fldP, "missing field");

 oldTxtH = (VoidHand) FldGetTextHandle (fldP);



 FldSetTextHandle (fldP, (Handle) txtH);



 if (redraw) FldDrawField (fldP);

 if (oldTxtH) MemHandleFree (oldTxtH);

 return fldP;

}
Patrice
Merci Oups. Je fais un post-it anim_wink.gif
blueberry
je viens de trouver cette page de bouts de codes pour palm. Très bien faite !
Patrice
Pour ceux qui voudraient créer un panneau de préférences, consultez ce sujet, proposant entre autres, un squelette de source en C.
Patrice
Quelques autres pointeurs utiles pour les développeurs sont disponibles dans ce sujet.
zakharov
un bout de code que je viens de faire pour debugger mes applis compilées sur le palm:
il renvoie la description du code d'erreur renvoyé par une API tel que décrit dans le palm OS reference.

il s'utilise avec une database dispo ici Cliquez pour voir le fichier-joint (également à l'intérieur de l'archive: le script perl qui a créé la base de données à partir de la page ErrorCodes.html du PalmOS reference)

CODE
char *readErrorCode(Err erreur) {
        Err codeErreur;
        char *nomErreur;
        struct {
                Err code;
                char nom[1];
        } *packedErrCode;
        MemHandle errH = NULL;
        DmOpenRef errListDB;
        LocalID errListID = DmFindDatabase(0, "APIErrorCodes");
        nomErreur = "...";
        if (errListID && erreur < 0x7000) {
                errListDB = DmOpenDatabase(0,errListID,dmModeReadOnly);
                UInt16 nbrCodes = DmNumRecords (errListDB);
                for (UInt16 index = 0; index < nbrCodes; index++) {
                        errH = DmQueryRecord(errListDB, index);
                        if (errH) {
                                packedErrCode = MemHandleLock(errH);
                                codeErreur = packedErrCode->code;
                                nomErreur = packedErrCode->nom;
                                MemHandleUnlock(errH);
                        }
                        if (codeErreur == erreur) break;
                }
                DmCloseDatabase(errListDB);
        }
        return nomErreur;
}


si cela peut être utile à quelqu'un...
mrpropre
Une compilation de code de chez TalmsPalm:


Determining if your app runs on a Zodiac

John Wilund, TamsPalm reader and Programmer extraordinaire, felt like sharing the following bit of code with all of you:

CODE
#ifdef __OBC__
#define sysFtrNumOEMCompanyID 20
#endif
#define twCreatorID 'Tpwv' // from TwDefs.h
Boolean isTapwave(void){
Err err;
UInt32 manufacturer;
if(FtrGet(sysFileCSystem, sysFtrNumOEMCompanyID, &manufacturer)== errNone)
return(manufacturer == twCreatorID);
return false;
}


It returns true if the device your program runs on is a TapWave Zodiac PDA. Feel free to use the source code in your programs!



Runs unsigned app on a Zodiac

To avoid the protection, just copy this little code on your source and call the TwGfxOpen() by this one:

CODE
static asm char TwGfxOpenNoSign (void *p, void *q)
{
stmfd sp!, {r4-r11,lr}
ldr r9, [r9]
ldr r9, [r9]
sub sp, sp, #0x24
mov r6, r0
mov r7, r1
ldr pc, =0x200995F0
}




Detecting vibrators and alarm leds programmatically

Sometimes, you really need to know if the handheld that your app runs on has a vibrator or a alert LED. These routines can help you:

Boolean hasLED()
{
UInt32 capabilities;
FtrGet(kAttnFtrCreator, kAttnFtrCapabilities, &capabilities);
if (capabilities & kAttnFlagsHasLED)
{
return true;
}
else
{
return false;
}
}
Boolean hasVibration()
{
UInt32 capabilities;
FtrGet(kAttnFtrCreator, kAttnFtrCapabilities, &capabilities);
if (capabilities & kAttnFlagsHasVibrate)
{
return true;
}
else
{
return false;
}
}
These routines worked in both PODS 1.1 and OnBoardC. Feel free to use them in your own apps!


Tapwave Rumble effects

CODE
TwDeviceHandle rumblerH;

typedef struct
{
void * data; // Volume & duration pairs.
Int32 size;
} EffectInfo;

void HostPlayRumble(short int effect);
void HostPlayRumble(short int effect)
{
   // A real scheme would important data from resources.
  
   // A single, short bump.
   UInt8 EffectBump[] =
   {
    255,20,0,5,255,10
};
   EffectInfo EffectData[1];
   EffectData[0].data = EffectBump;
   EffectData[0].size = sizeof(EffectBump);

   // Send to the rumbler
   TwDeviceControl(rumblerH, 'play',
    EffectData[effect].data,
    EffectData[effect].size);
}

In appstart

   TwDeviceOpen(&rumblerH, "vibrator0", "w");

and in appstop

   TwDeviceClose(rumblerH);



and play rumble with

CODE
   HostPlayRumble(0);



Detecting color screens programatically

Sometimes, you will need to determine if your application is running on a device with a color screen. This ultra-sleek C routine returns true if your app runs on a handheld with a color screen:

CODE
Boolean hasColorCrt()
{
Boolean enableColor;
WinScreenMode(winScreenModeGet, NULL,NULL, NULL,&enableColor );
return enableColor;
}


It was tested on a OS4 Palm V, a Tungsten T3 and a Tungsten E2. It compiled perfectly in PODS 1.1 and OnBoardC. Feel free to use it in your apps!



Debugging with decoy printfs

Most people make mistakes when programming. Today, I had an interesting debug session with Mr. Stuttner(he still does good LAN parties) today. Since the stuff we looked at may be interestinf for more of you, here is a brain-dump of what we did!
The program was designed to convert characters without using library functions(just macros), but it didnt work. It always converted to lower. Anyways, we decided to trace the program by intersting a few decoy alerts into the program:

CODE
#include "stdafx.h"
#define Upper(c)((c>='a'&&c< ='z')?(c-'a'+'A'):(c))
#define Lower(c)((c>=’A'&&c< ='Z')?(c-'A'+'a'):(c))
int _tmain(int argc, _TCHAR* argv[])
{
char c;
printf("Buchstabe Eingeben der Gros geschreiben werden soll:\n");
scanf("%c",&c);
printf("Ihre Eingabe: %c\n",c);
if ((c<=65) && (c>=90))
{ printf(”If”);
c=Upper(c);
}
else
{ printf(”Else”);
c=Lower(c);
}
printf(”Auswertung: %c”,c);
scanf(”%d”,c);
return 0;
}


Now, we knew what happened. And indeed, the condition of the loop was erroneously formulated. This led to the following program:

CODE
#include "stdafx.h"
#define Upper(c)((c>='a'&&c< ='z')?(c-'a'+'A'):(c))
#define Lower(c)((c>=’A'&&c< ='Z')?(c-'A'+'a'):(c))
int _tmain(int argc, _TCHAR* argv[])
{
char c;
printf("Buchstabe Eingeben der Gros geschreiben werden soll:\n");
scanf("%c",&c);
printf("Ihre Eingabe: %c\n",c);
if ((c>=65) && (c< =90))
{
c=Upper(c);
}
else
{
c=Lower(c);
}
printf("Auswertung: %c",c);
scanf("%d",c);
return 0;
}



This program worked better, but still was unreliable. It now simply returned the character given. SO, we fed in decoys yet again!

CODE
#include "stdafx.h"
#define Upper(c)((c>='a'&&c< ='z')?(c-'a'+'A'):(c))
#define Lower(c)((c>=’A'&&c< ='Z')?(c-'A'+'a'):(c))
int _tmain(int argc, _TCHAR* argv[])
{
char c;
printf("Buchstabe Eingeben der Gros geschreiben werden soll:\n");
scanf("%c",&c);
printf("Ihre Eingabe: %c\n",c);
if ((c>=65) && (c< =90))
{ printf("Converting to upper");
c=Upper(c);
}
else
{ printf("Converting to lower");
c=Lower(c);
}
printf("Auswertung: %c",c);
scanf("%d",c);
return 0;
}



We now saw that the statements need to be exchanged! And so, finally, we exchanged the upper and lower macros to get a nice and working routine!

CODE
#include "stdafx.h"
#define Upper(c)((c>='a'&&c< ='z')?(c-'a'+'A'):(c))
#define Lower(c)((c>=’A'&&c< ='Z')?(c-'A'+'a'):(c))
int _tmain(int argc, _TCHAR* argv[])
{
char c;
printf("Buchstabe Eingeben der Gros geschreiben werden soll:\n");
scanf("%c",&c);
printf("Ihre Eingabe: %c\n",c);
if ((c>=65) && (c< =90))
{
c=Lower(c);
}
else
{
c=Upper(c);
}
printf("Auswertung: %c",c);
scanf("%d",c);
return 0;
}


So, overall, this was funky! Indeed, debugging gets much easier if you insert decoy alerts into your program. This is much easier than using breakpoints,… . For the Palm OS, FrmAlert and FrmCustomAlert may be suitable decoys!
malloc and free for Palm OS
This code was posted by Estêvão Samuel Procópio to the OnBoardC newsgroup. It replaces the malloc and free functions of regular C compilers, this can be useful when using code from books. Altough these two functions can easily be replaced by calls to MemPtrNew and MemPtrFree(with other functions, the parameters need to be switched), this code is very interesting and thus is beeing posted here. You know, one never reads enough code…

CODE
MemPtr malloc(UInt16 size) {
MemHandle h = MemHandleNew(size);
if (!h) return NULL;
return (MemPtr) MemHandleLock(h);
}
void free(MemPtr ptr) {
MemHandle h = MemPtrRecoverHandle(ptr);
if(!h) return;
MemHandleUnlock(h);
MemHandleFree(h);
ptr = NULL;
}




Determining if a handheld has a rectangular screen

Ever since BinaryClock 2.0 was released, users were annoyed about how the fullscreen mode option was shown on all handhelds with Palm’s new Pen Input Manager.
However, I now found a new routine that accurately determines if a handheld has a “retractable DIA”. In fact, on a TUngsten T3, it even offers Fullscreen mode when the slider is closed(hides the status bar then).

CODE
Boolean PlmsDia()
{
Err err;
UInt32 version;
//dont ask why-obc wants null here or fatal alert
err=FtrGet(pinCreator, pinFtrAPIVersion, &version);
if(!err)
{
return true;
}
else
{
return false;
}
}
if(PlmsDia() && PINGetInputAreaState()!=2)//Works bc PlmsDia gets evaluated first
{
MenuShowItem(MenuFullscreen);
}
else
{
MenuHideItem(MenuFullscreen);
}
break;


PlmsDia is a security function, all it does is make sure that the call doesn’t “kill” handhelds without the latest version of the Pen Input Manager.
You can play around with this code in a few hours, as a golden beta of BinaryClock 2.1 will be released soon!
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.