<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Optimatek</title>
	<atom:link href="http://www.optimatek.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.optimatek.com</link>
	<description>Programmation et autres trucs du genre</description>
	<lastBuildDate>Wed, 16 May 2012 02:32:32 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Utiliser l’API URL Shortener de Google avec C++Builder</title>
		<link>http://www.optimatek.com/2012/05/utiliser_url_shortener/</link>
		<comments>http://www.optimatek.com/2012/05/utiliser_url_shortener/#comments</comments>
		<pubDate>Wed, 16 May 2012 02:32:32 +0000</pubDate>
		<dc:creator>Crayon</dc:creator>
				<category><![CDATA[C++Builder]]></category>
		<category><![CDATA[FireMonkey]]></category>
		<category><![CDATA[JSON]]></category>

		<guid isPermaLink="false">http://www.optimatek.com/?p=654</guid>
		<description><![CDATA[Dans mon dernier article j&#8217;avais expliqué l&#8217;utilisation l&#8217;API PageSpeed de Google. Pour continuer dans cette direction, j&#8217;aborderai dans celui-ci l&#8217;API URL Shortener. L&#8217;utilisation de cet API comporte beaucoup de similitude avec le précédent. Encore une fois l&#8217;information sera prise sur une page web utilisant SSL et la réponse sera dans le format JSON (JavaScript Object [...]]]></description>
			<content:encoded><![CDATA[<p>Dans mon dernier <a href="http://www.optimatek.com/2012/05/utiliser-pagespeed/" title="Utiliser l’API PageSpeed de Google avec C++Builder">article</a> j&#8217;avais expliqué l&#8217;utilisation l&#8217;API PageSpeed de Google. Pour continuer dans cette direction, j&#8217;aborderai dans celui-ci l&#8217;API URL Shortener.</p>
<p>L&#8217;utilisation de cet API comporte beaucoup de similitude avec le précédent. Encore une fois l&#8217;information sera prise sur une page web utilisant SSL et la réponse sera dans le format JSON (JavaScript Object Notation). Par contre, au lieu d’utiliser la méthode GET, ce sera la méthode POST qui sera utilisée par le protocole HTTP.</p>
<p>La première étape est de créer un nouveau projet FireMonkey HD. Dans la Form il faut insérer un <strong>TIdHTTP</strong>, un <strong>TIdSSLIOHandlerSocketOpenSSL</strong>, deux contrôles <strong>TEdit</strong> et un <strong>TButton</strong>. Vous pouvez donner comme texte à votre bouton le mot « Réduire ». Je vous propose de placer les composants dans la fenêtre de la manière suivante:<br />
<img src="http://www.optimatek.com/wp-content/uploads/2012/05/url_shortener.png" alt="Réducteur d’URL" width="526" height="218" class="aligncenter size-full wp-image-669" />La capture d&#8217;écran a été faite sous MAC OS X. C&#8217;est effectivement l&#8217;un des avantages de FireMonkey, l&#8217;application pourra fonctionner avec un système d&#8217;exploitation Windows ou MAC OS.</p>
<p>Dans votre fichier cpp voici le fichier d’en-tête à ajouter:</p>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;Data.DBXJSON.hpp&gt;
</pre>
<p>Voici le code à ajouter dans votre constructeur:</p>
<pre class="brush: cpp; title: ; notranslate">
    IdHTTP1-&gt;IOHandler = IdSSLIOHandlerSocketOpenSSL1;

    Edit2-&gt;ReadOnly = true; // L'URL réduit ne peut pas être changé
</pre>
<p>La prochaine étape est d’ajouter le code dans l’événement <strong>OnClick</strong> du bouton.</p>
<pre class="brush: cpp; title: ; notranslate">
    Edit2-&gt;Text = &quot;&quot;; // On efface le texte
    Application-&gt;ProcessMessages();

    System::Classes::TStringStream* SourceFile =
        new System::Classes::TStringStream(&quot;{\&quot;longUrl\&quot;: \&quot;&quot; + Edit1-&gt;Text + &quot;\&quot;}&quot;);

    IdHTTP1-&gt;Request-&gt;ContentType = &quot;application/json&quot;;
    System::UnicodeString Response = IdHTTP1-&gt;Post(
        &quot;https://www.googleapis.com/urlshortener/v1/url&quot;, SourceFile);

    TJSONObject* Obj = static_cast&lt;TJSONObject*&gt;(TJSONObject::ParseJSONValue(Response));
    if(Obj)
    {
        TJSONPair* Pair = Obj-&gt;Get(&quot;id&quot;);
        if(Pair)
        {
            TJSONString* Answer = static_cast&lt;TJSONString*&gt;(Pair-&gt;JsonValue);
            Edit2-&gt;Text = AnsiDequotedStr(Answer-&gt;ToString(), '\&quot;');
        }
    }

    delete SourceFile;
</pre>
<p>La première ligne de code efface le texte dans le contrôle de saisie monoligne. Par contre cette action ne sera pas exécutée sur le champ parce que le reste du code est bloquant car une requête HTTP au serveur doit s&#8217;effectuer. Cette requête pourrait prendre quelques secondes donc à la deuxième ligne on laisse du temps pour exécuter l&#8217;action précédente qui est dans la file d&#8217;attente des messages. Le contrôle <strong>TEdit</strong> sera alors redessiné sans le texte.</p>
<p>La méthode <strong>Post</strong> sert à appeler l’API et mettre la réponse dans la variable <strong>Response</strong>, en voici un exemple:</p>
<pre class="brush: jscript; title: ; notranslate">
{
 &quot;kind&quot;: &quot;urlshortener#url&quot;,
 &quot;id&quot;: &quot;http://goo.gl/bT3bc&quot;,
 &quot;longUrl&quot;: &quot;http://imgs.xkcd.com/comics/time_management.png&quot;
}
</pre>
<p>Voilà, vous savez maintenant utiliser l’API URL Shortener avec C++Builder. Si vous préférez utiliser les services de TinyURL au lieu de Google, alors voici le code dont il faut vous servir dans l’événement <strong>OnClick</strong> du bouton:</p>
<pre class="brush: cpp; title: ; notranslate">
    Edit2-&gt;Text = &quot;&quot;; // On efface le texte
    Application-&gt;ProcessMessages();

    Edit2-&gt;Text = IdHTTP1-&gt;Get(&quot;http://tinyurl.com/api-create.php?url=&quot; + Edit1-&gt;Text);
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.optimatek.com/2012/05/utiliser_url_shortener/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Utiliser l&#8217;API PageSpeed de Google avec C++Builder</title>
		<link>http://www.optimatek.com/2012/05/utiliser-pagespeed/</link>
		<comments>http://www.optimatek.com/2012/05/utiliser-pagespeed/#comments</comments>
		<pubDate>Sat, 12 May 2012 19:40:30 +0000</pubDate>
		<dc:creator>Crayon</dc:creator>
				<category><![CDATA[C++Builder]]></category>
		<category><![CDATA[FireMonkey]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[TChart]]></category>

		<guid isPermaLink="false">http://www.optimatek.com/?p=619</guid>
		<description><![CDATA[PageSpeed est un outil développé par Google qui sert à analyser une page Web. Dans cet article il sera utilisé pour obtenir le nombre d&#8217;octets de chaque élément qui composent une page web. Les résultats seront présentés dans un diagramme circulaire à l&#8217;aide du contrôle TChart. Avant de débuter, il faut aller sur le site [...]]]></description>
			<content:encoded><![CDATA[<p>PageSpeed est un outil développé par Google qui sert à analyser une page Web. Dans cet article il sera utilisé pour obtenir le nombre d&#8217;octets de chaque élément qui composent une page web. Les résultats seront présentés dans un diagramme circulaire à l&#8217;aide du contrôle <strong>TChart</strong>.</p>
<p>Avant de débuter, il faut aller sur le site de <a href="https://code.google.com/apis/console">Google</a> pour activer l&#8217;API Page Speed Online dans la section <em>Services</em>. Il vous faudra créer une clef d&#8217;API qui sera utilisée à chaque requête. Il est à noter que Google vous donne le droit d&#8217;exécuter 2500 requêtes par jour pour cet API.</p>
<div id="attachment_623" class="wp-caption aligncenter" style="width: 317px"><img class="size-full wp-image-623 " style="border: 1px solid black;" src="http://www.optimatek.com/wp-content/uploads/2012/04/PageSpeedOnlineAPION.png" alt="Page Speed Online API ON" width="307" height="33" /><p class="wp-caption-text">Page Speed Online API Activé</p></div>
<p>La première étape est de créer un nouveau projet FireMonkey HD. Dans la Form il faut insérer un <strong>TIdHTTP</strong>, un <strong>TIdSSLIOHandlerSocketOpenSSL</strong>, un <strong>TChart</strong> et un <strong>TLayout</strong> dans lequel il y aura un <strong>TEdit</strong> un <strong>TButton</strong>. On aligne le contrôle <strong>TLayout</strong> à <strong>alBottom</strong> et le <strong>TChart</strong> à <strong>alClient</strong>. Vous pouvez donner comme texte à votre bouton le mot &laquo;&nbsp;Analyser&nbsp;&raquo;. </p>
<p>Avant même de voir le code, je vous présente le résultat final. Ceci vous permettra de mieux comprendre vers où nous nous dirigeons.<br />
<img src="http://www.optimatek.com/wp-content/uploads/2012/04/analyseur_de_site_web.png" alt="Analyseur de site web" width="550" height="457" class="aligncenter size-full wp-image-632" /></p>
<p>Dans votre fichier cpp voici la liste de fichier d’en-tête à utiliser ainsi que la macro qui va contenir votre clef d&#8217;API. N&#8217;essayer pas d&#8217;utiliser celle-ci, il s&#8217;agit de caractères écrits de façon aléatoire.</p>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;Data.DBXJSON.hpp&gt;
#include &lt;FMXTee.Series.hpp&gt;
#define GOOGLEAPIKEY &quot;dskk1j3sW4WBYdkjds8sSDSD&quot; // Clef d'API
</pre>
<p>Voici le code à ajouter dans votre constructeur:</p>
<pre class="brush: cpp; title: ; notranslate">
    IdHTTP1-&gt;IOHandler = IdSSLIOHandlerSocketOpenSSL1;

    Chart1-&gt;Title-&gt;Text-&gt;Text = &quot;Statistique de la page&quot;; // Titre du diagramme
    Chart1-&gt;Legend-&gt;Title-&gt;Text-&gt;Text = &quot;Ressource en octets&quot;; // Titre de la légende
    Series::TPieSeries *Series = new Series::TPieSeries(this); // Diagramme circulaire
    Series-&gt;Marks-&gt;Visible = false; // Ce n'est pas nécessaire car on a déjà une légende
    Chart1-&gt;AddSeries(Series);
</pre>
<p>Étant donné que nous accéderons à un site web qui utilise SSL (https), la première ligne de code est critique. Sans elle, une exception dans la classe <strong>EIdIOHandlerPropInvalid</strong> produira le message &laquo;&nbsp;IOHandler value is not valid&nbsp;&raquo;. Parce que nous utilisons OpenSSL, les fichiers <em>ssleay32.dll</em> et <em>libeay32.dll</em> devront être distribués avec votre application.</p>
<p>Les lignes 3 à 7 servent à ajouter des informations au graphique.</p>
<p>La prochaine étape est d&#8217;ajouter le code dans l’événement <strong>OnClick</strong> du bouton.</p>
<pre class="brush: cpp; title: ; notranslate">
    Chart1-&gt;Series[0]-&gt;Clear(); // Efface le contenu du diagramme

    String Response = IdHTTP1-&gt;Get(
        &quot;https://www.googleapis.com/pagespeedonline/v1/runPagespeed?url=&quot; +
        Edit1-&gt;Text + &quot;&amp;key=&quot; GOOGLEAPIKEY);

    TJSONObject* Obj = static_cast&lt;TJSONObject*&gt;(TJSONObject::ParseJSONValue(Response));
    TJSONPair* Pair = Obj-&gt;Get(&quot;pageStats&quot;);
    if(Pair)
    {
        String Value;
        TJSONString* Answer;
        TJSONObject* PageStats = static_cast&lt;TJSONObject*&gt;(Pair-&gt;JsonValue);
        if((Pair = PageStats-&gt;Get(&quot;htmlResponseBytes&quot;)) != NULL)
        {
            Answer = static_cast&lt;TJSONString*&gt;(Pair-&gt;JsonValue);
            Value = AnsiDequotedStr(Answer-&gt;ToString(), '\&quot;');
            Chart1-&gt;Series[0]-&gt;Add(Value.ToIntDef(0), &quot;HTML&quot;, claGreen);
        }
        if((Pair = PageStats-&gt;Get(&quot;cssResponseBytes&quot;)) != NULL)
        {
            Answer = static_cast&lt;TJSONString*&gt;(Pair-&gt;JsonValue);
            Value = AnsiDequotedStr(Answer-&gt;ToString(), '\&quot;');
            Chart1-&gt;Series[0]-&gt;Add(Value.ToIntDef(0), &quot;CSS&quot;, claOrange);
        }
        if((Pair = PageStats-&gt;Get(&quot;imageResponseBytes&quot;)) != NULL)
        {
            Answer = static_cast&lt;TJSONString*&gt;(Pair-&gt;JsonValue);
            Value = AnsiDequotedStr(Answer-&gt;ToString(), '\&quot;');
            Chart1-&gt;Series[0]-&gt;Add(Value.ToIntDef(0), &quot;Image&quot;, claYellow);
        }
        if((Pair = PageStats-&gt;Get(&quot;javascriptResponseBytes&quot;)) != NULL)
        {
            Answer = static_cast&lt;TJSONString*&gt;(Pair-&gt;JsonValue);
            Value = AnsiDequotedStr(Answer-&gt;ToString(), '\&quot;');
            Chart1-&gt;Series[0]-&gt;Add(Value.ToIntDef(0), &quot;JavaScript&quot;, claRed);
        }
        if((Pair = PageStats-&gt;Get(&quot;otherResponseBytes&quot;)) != NULL)
        {
            Answer = static_cast&lt;TJSONString*&gt;(Pair-&gt;JsonValue);
            Value = AnsiDequotedStr(Answer-&gt;ToString(), '\&quot;');
            Chart1-&gt;Series[0]-&gt;Add(Value.ToIntDef(0), &quot;Autre&quot;, claBlue);
        }
    }
</pre>
<p>Les lignes 3 à 5 servent à appeler l&#8217;API et mettre la réponse dans la variable <strong>Response</strong>. Cette réponse utilise le format JSON (JavaScript Object Notation). Voici la section qui nous intéresse pour notre projet:</p>
<pre class="brush: jscript; title: ; notranslate">
{
 &quot;pageStats&quot;: {
  &quot;numberResources&quot;: 89,
  &quot;numberHosts&quot;: 11,
  &quot;totalRequestBytes&quot;: &quot;18788&quot;,
  &quot;numberStaticResources&quot;: 72,
  &quot;htmlResponseBytes&quot;: &quot;511838&quot;,
  &quot;cssResponseBytes&quot;: &quot;127217&quot;,
  &quot;imageResponseBytes&quot;: &quot;399484&quot;,
  &quot;javascriptResponseBytes&quot;: &quot;396089&quot;,
  &quot;otherResponseBytes&quot;: &quot;4023&quot;,
  &quot;numberJsResources&quot;: 19,
  &quot;numberCssResources&quot;: 4
 }
}
</pre>
<p>Comme on peut le voir certaines valeurs numériques utilisent des guillemets doubles, c&#8217;est pour cette raison que nous utiliserons la fonction <strong>AnsiDequotedStr</strong> pour les enlever.</p>
<p>En terminant, je voulais juste vous faire une petite mise en garde. Faites attention de protéger votre clef d&#8217;API car il est très facile pour n&#8217;importe qui de la retrouver en regardant le contenu de votre fichier exécutable. Même pas besoin d&#8217;éditeur hexadécimal compliqué, il suffit du Bloc-notes comme démontré ici:<br />
<img src="http://www.optimatek.com/wp-content/uploads/2012/05/fichier_exe_ouvert_dans_le_bloc-notes.png" alt="Fichier exécutable ouvert dans le Bloc-notes" width="582" height="162" class="aligncenter size-full wp-image-639" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.optimatek.com/2012/05/utiliser-pagespeed/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Utiliser Subversion 1.7 avec C++Builder XE2</title>
		<link>http://www.optimatek.com/2012/03/subversion-avec-cppbuilder-xe2/</link>
		<comments>http://www.optimatek.com/2012/03/subversion-avec-cppbuilder-xe2/#comments</comments>
		<pubDate>Thu, 29 Mar 2012 01:16:10 +0000</pubDate>
		<dc:creator>Crayon</dc:creator>
				<category><![CDATA[C++Builder]]></category>
		<category><![CDATA[EDI]]></category>
		<category><![CDATA[Subversion]]></category>

		<guid isPermaLink="false">http://www.optimatek.com/?p=599</guid>
		<description><![CDATA[Ça faisait déjà plusieurs fois que j&#8217;étais confronté à ce message d&#8217;erreur dans C++Builder XE2, sans toutefois comprendre pourquoi. C&#8217;est pourtant simple, ma copie de travail utilise la plus récente version de Subversion et le client intégré dans l&#8217;IDE utilise la version 1.6. C&#8217;est pour cette raison que ça ne fonctionne pas et qu&#8217;une mise [...]]]></description>
			<content:encoded><![CDATA[<p>Ça faisait déjà plusieurs fois que j&#8217;étais confronté à ce message d&#8217;erreur dans C++Builder XE2, sans toutefois comprendre pourquoi.<br />
<img src="http://www.optimatek.com/wp-content/uploads/2012/03/SubversionUpgradeError.png" alt="Subversion Upgrade Error in C++Builder XE2" width="490" height="148" class="aligncenter size-full wp-image-597" />C&#8217;est pourtant simple, ma copie de travail utilise la plus récente version de Subversion et le client intégré dans l&#8217;IDE utilise la version 1.6. C&#8217;est pour cette raison que ça ne fonctionne pas et qu&#8217;une mise à jour du client s&#8217;impose.</p>
<p>Les fichiers à modifier sont ceux qui se trouvent dans le dossier <em>$(BDS)\bin\subversion</em>. Il s&#8217;agit des DLLs qu&#8217;utilise RAD Studio pour faire fonctionner son client svn. Dans ledit dossier on y trouve le fichier <em>readme.txt</em> suivant qui explique comment faire la mise à jour:</p>
<blockquote><p>===============================================================================<br />
Information about bin/subversion.<br />
===============================================================================<br />
This directory contains the Subversion .dll files used by the IDE&#8217;s Subversion<br />
integration.  These files can be upgraded by going to www.collab.net and<br />
downloading the subversion client and extracting it to this location.  Other<br />
subversion installations will not be used be default.  The IDE only looks in<br />
this location, this behavior can be changed by setting the registry string<br />
SvnDllDir under the Subversion key to the location of your Subversion<br />
installation.  This will not work with all Subversion installation because not<br />
all installation use the same .dll names.</p></blockquote>
<p>Pour télécharger sur le site Web de <a href="http://www.collab.net">CollabNet</a> il faut s&#8217;enregistrer, pour cette raison j&#8217;ai préféré prendre mes fichiers dans le projet <a href="https://sourceforge.net/projects/win32svn/">Win32Svn</a> qui se trouve sur SourceForge. Même si votre système est 64 bits il faut prendre une version 32 bits des fichiers car l&#8217;IDE est 32 bits.</p>
<p>Une fois l&#8217;archive enregistrée sur votre disque dur, il faut extraire tous les fichiers *.dll du dossier <em>bin</em> dans le dossier <em>$(BDS)\bin\subversion</em>. Si vous n&#8217;êtes pas certain de ce que vous faites n&#8217;hésitez pas à faire une copie de sauvegarde des fichiers utilisés par Embarcadero.</p>
<p>Si C++Builder était ouvert alors il faut le redémarrer. Maintenant vous devriez avoir accès aux options de révision de code et enfin pouvoir cliquer sur le bouton <em>Commit</em> à l&#8217;intérieur de votre IDE préféré.</p>
<p><img src="http://www.optimatek.com/wp-content/uploads/2012/03/SubversionCommitCompleted.png" alt="Subversion Commit Completed in C++Builder XE2" width="579" height="176" class="aligncenter size-full wp-image-602" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.optimatek.com/2012/03/subversion-avec-cppbuilder-xe2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Charger une image à partir des ressources avec FireMonkey</title>
		<link>http://www.optimatek.com/2011/10/charger-une-image-a-partir-des-ressources-avec-firemonkey/</link>
		<comments>http://www.optimatek.com/2011/10/charger-une-image-a-partir-des-ressources-avec-firemonkey/#comments</comments>
		<pubDate>Mon, 24 Oct 2011 02:21:30 +0000</pubDate>
		<dc:creator>Crayon</dc:creator>
				<category><![CDATA[C++Builder]]></category>
		<category><![CDATA[FireMonkey]]></category>
		<category><![CDATA[TResourceStream]]></category>

		<guid isPermaLink="false">http://www.optimatek.com/?p=587</guid>
		<description><![CDATA[Dans un article précédent j&#8217;avais expliqué comment charger une image à partir des ressources en utilisant la VCL. Maintenant, voici l&#8217;équivalent mais cette fois-ci avec FireMonkey. Une des première chose à connaître dans FireMonkey est les formats d&#8217;images supportés par la classe TBitmap. Voici la liste des formats supportés sur toutes les plates-formes : JPEG [...]]]></description>
			<content:encoded><![CDATA[<p>Dans un <a title="Charger une image dans les ressources" href="http://www.optimatek.com/2010/03/charger-une-image-dans-les-ressources/">article précédent</a> j&#8217;avais expliqué comment charger une image à partir des ressources en utilisant la VCL. Maintenant, voici l&#8217;équivalent mais cette fois-ci avec FireMonkey.</p>
<p><img src="http://www.optimatek.com/wp-content/uploads/2011/10/FireMonkey-HD-Application.png" alt="New FireMonkey HD Application" width="522" height="440" class="aligncenter size-full wp-image-595" /></p>
<p>Une des première chose à connaître dans FireMonkey est les formats d&#8217;images supportés par la classe <strong>TBitmap</strong>.</p>
<p>Voici la liste des formats supportés sur toutes les plates-formes :</p>
<ul>
<li>JPEG (.jpeg, .jpg)</li>
<li>TIFF (.tiff, .tif)</li>
<li>GIF</li>
<li>PNG</li>
<li>BMP</li>
</ul>
<p>Voici la liste des formats supplémentaires avec Direct2D sur Windows :</p>
<ul>
<li>JPEG XR (.hdp, .jxr, .wdp)</li>
<li>ICO</li>
</ul>
<p>Voici la liste des formats supplémentaires avec GDI+ sur Windows :</p>
<ul>
<li>WMF</li>
<li>ICO</li>
</ul>
<p>Finalement, la liste des formats supplémentaires sur OS X :</p>
<ul>
<li>JPEG 2000 (.jp2)</li>
<li>PSD</li>
<li>TGA</li>
<li>ICNS</li>
</ul>
<p>Étant donné que <strong>TBitmap</strong> gère tous ces types d&#8217;images, cela simplifie beaucoup le code nécessaire pour charger une image des ressources. Avec ces trois lignes, vous allez pouvoir charger n&#8217;importe quelle image mentionnée plus haut.</p>
<pre class="brush: cpp; title: ; notranslate">
    TResourceStream *Res = new TResourceStream((unsigned)HInstance, &quot;PNG_LOGO&quot;, (System::WideChar *)RT_RCDATA);
    Image1-&gt;Bitmap-&gt;LoadFromStream(Res);
    delete Res;
</pre>
<p>Pour utiliser ce code il faut que toutes les images dans les ressources soient de type RCDATA. Faites attention dans l&#8217;IDE lorsque vous ajoutez une image Bitmap: le type par défaut est BITMAP, donc il faut le changer.</p>
<p>Bonne chance dans vos projets FireMonkey!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.optimatek.com/2011/10/charger-une-image-a-partir-des-ressources-avec-firemonkey/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Compression de fichiers avec C++Builder XE2</title>
		<link>http://www.optimatek.com/2011/09/compression-de-fichiers-avec-cbuilder-xe2/</link>
		<comments>http://www.optimatek.com/2011/09/compression-de-fichiers-avec-cbuilder-xe2/#comments</comments>
		<pubDate>Tue, 20 Sep 2011 01:18:50 +0000</pubDate>
		<dc:creator>Crayon</dc:creator>
				<category><![CDATA[C++Builder]]></category>
		<category><![CDATA[TZipFile]]></category>

		<guid isPermaLink="false">http://www.optimatek.com/?p=561</guid>
		<description><![CDATA[Depuis le début du mois de septembre, j&#8217;évalue la version d’essai de C++Builder XE2. Une des fonctionnalités que j’apprécie particulièrement est de pouvoir compresser et décompresser des fichiers zip. C&#8217;est la nouvelle classe TZipFile qui se chargera de ce travail. Il existe déjà plusieurs composants et bibliothèques pour faire cela, mais je trouve ça intéressant [...]]]></description>
			<content:encoded><![CDATA[<p>Depuis le début du mois de septembre, j&#8217;évalue la version d’essai de C++Builder XE2. Une des fonctionnalités que j’apprécie particulièrement est de pouvoir compresser et décompresser des fichiers zip. C&#8217;est la nouvelle classe <strong>TZipFile</strong> qui se chargera de ce travail. Il existe déjà plusieurs composants et bibliothèques pour faire cela, mais je trouve ça intéressant de pouvoir le faire nativement. Pour ma part, j&#8217;utilisais ZipArchive Library de <a href="http://www.artpol-software.com" title="Artpol Software">Artpol Software</a>.</p>
<p><a href="http://www.optimatek.com/2011/09/compression-de-fichiers-avec-cbuilder-xe2/rad-studio-xe2-splash-screen/" rel="attachment wp-att-563"><img src="http://www.optimatek.com/wp-content/uploads/2011/09/RAD-Studio-XE2-Splash-Screen-590x373.png" alt="RAD Studio XE2 Splash Screen" title="RAD Studio XE2 Splash Screen" width="590" height="373" class="aligncenter size-large wp-image-563" /></a></p>
<p>Maintenant, voyons comment utiliser cette classe. Tout d&#8217;abord, voici l&#8217;entête qu&#8217;il faudra ajouter à votre projet.</p>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;System.Zip.hpp&gt;
</pre>
<p>Voici un exemple très simple de code pour effectuer la compression d&#8217;un fichier.</p>
<pre class="brush: cpp; title: ; notranslate">
    TZipFile *ZipFile = new TZipFile(); // Création de l'objet

    ZipFile-&gt;Open(&quot;c:\\fichier.zip&quot;, zmWrite); // Ouverture du fichier en mode écriture

    ZipFile-&gt;Add(&quot;c:\\test.xml&quot;, &quot;test.xml&quot;); // Ajout d'un fichier dans l'archive

    ZipFile-&gt;Close(); // Fermeture du fichier

    delete ZipFile; // Libération de la mémoire
</pre>
<p>Ce n&#8217;est pas plus compliqué que cela!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.optimatek.com/2011/09/compression-de-fichiers-avec-cbuilder-xe2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Détecter la fermeture d&#8217;un TPopupMenu</title>
		<link>http://www.optimatek.com/2011/09/detecter-la-fermeture-dun-tpopupmenu/</link>
		<comments>http://www.optimatek.com/2011/09/detecter-la-fermeture-dun-tpopupmenu/#comments</comments>
		<pubDate>Sun, 04 Sep 2011 18:04:40 +0000</pubDate>
		<dc:creator>Crayon</dc:creator>
				<category><![CDATA[C++Builder]]></category>
		<category><![CDATA[TPopupMenu]]></category>

		<guid isPermaLink="false">http://www.optimatek.com/?p=549</guid>
		<description><![CDATA[Le composant TPopupMenu possède peu d&#8217;évènements. Seulement OnChange et OnPopup sont disponibles. Dans certains cas, il pourrait être pratique de détecter la fermeture d&#8217;un menu contextuel. Malheureusement, cet évènement n&#8217;existe pas, mais il est par contre possible de le coder. Lorsqu&#8217;un menu contextuel se ferme, l&#8217;évènement WM_MENUSELECT est envoyé avec certains paramètres. Le seul problème [...]]]></description>
			<content:encoded><![CDATA[<p>Le composant <strong>TPopupMenu</strong> possède peu d&#8217;évènements. Seulement <strong>OnChange</strong> et <strong>OnPopup</strong> sont disponibles. Dans certains cas, il pourrait être pratique de détecter la fermeture d&#8217;un menu contextuel. Malheureusement, cet évènement n&#8217;existe pas, mais il est par contre possible de le coder.</p>
<p>Lorsqu&#8217;un menu contextuel se ferme, l&#8217;évènement <strong>WM_MENUSELECT</strong> est envoyé avec certains paramètres. Le seul problème c&#8217;est que ce n&#8217;est pas la fenêtre qui reçoit l&#8217;évènement. C&#8217;est la classe <strong>TPopupList</strong> qui a cette responsabilité. Dans <em>Menus.hpp</em> on retrouve cette ligne de code:</p>
<pre class="brush: cpp; title: ; notranslate">extern PACKAGE TPopupList* PopupList;</pre>
<p>L&#8217;objet <strong>PopupList</strong> est créé à l&#8217;initialisation, il va donc falloir capturer les messages qu&#8217;il reçoit pour appeler une méthode lors de la fermeture du menu.</p>
<p>Voici la liste des méthodes et attributs à ajouter a votre fichier .h:</p>
<pre class="brush: cpp; title: ; notranslate">
private:	// User declarations
    void __fastcall PopupWndProc(Messages::TMessage &amp;Message);

    WNDPROC OldPopupProc;
    TFNWndProc FPopupProcInst;
    TPopupMenu *FLastOpenPopupMenu;
protected:
    void __fastcall DoPopupExit(TPopupMenu *PopupMenu);
</pre>
<p>La première étape est de rediriger les messages vers la méthode <strong>PopupWndProc</strong>. Avant de faire cela on va d&#8217;abord enregistrer l&#8217;ancienne adresse de la procédure de fenêtre dans <strong>OldPopupProc</strong>. Voici le code à ajouter à votre constructeur:</p>
<pre class="brush: cpp; title: ; notranslate">
    FPopupProcInst = MakeObjectInstance(PopupWndProc);
    OldPopupProc = (WNDPROC)SetWindowLongPtr(PopupList-&gt;Window, GWL_WNDPROC,
        (LONG_PTR)FPopupProcInst);
</pre>
<p>Dans le destructeur on va restaurer l&#8217;appel vers la méthode <strong>WndProc</strong> originale et libérer la mémoire allouée par la fonction <strong>MakeObjectInstance</strong>:</p>
<pre class="brush: cpp; title: ; notranslate">
    if(FPopupProcInst != NULL)
    {
        SetWindowLong(PopupList-&gt;Window, GWL_WNDPROC, (LONG)OldPopupProc);
        FreeObjectInstance(FPopupProcInst);
    }
</pre>
<p>À la réception du message <strong>WM_MENUSELECT</strong> on regarde si <strong>MenuFlag</strong> est à 0xFFFF et <strong>Menu</strong> à NULL. Si c&#8217;est le cas, alors le menu est fermé et on appelle <strong>DoPopupExit</strong>. Cette méthode a pour paramètre un pointeur vers le <strong>TPopupMenu</strong> qui vient de se fermer. La variable <strong>FLastOpenPopupMenu</strong> contient cette information. On lui affecte une valeur à la réception du message <strong>WM_INITMENUPOPUP</strong> qui est appelé lorsqu&#8217;un <strong>TPopupMenu</strong> est sur le point d&#8217;être actif. À la place de ce message, l&#8217;évènement <strong>OnPopup</strong> aurait pu être utilisé, mais je l&#8217;ai fait de cette manière pour rendre le code plus général. Les lignes 25 et 26 servent à appeler la méthode <strong>WndProc</strong> originale.</p>
<pre class="brush: cpp; title: ; notranslate">
void __fastcall TForm1::PopupWndProc(Messages::TMessage &amp;Message)
{
    if(Message.Msg == WM_MENUSELECT)
    {
        TWMMenuSelect *MenuSelect = (TWMMenuSelect *)&amp;Message;
        if(MenuSelect-&gt;MenuFlag == 0xFFFF &amp;&amp; MenuSelect-&gt;Menu == NULL)
        {
            DoPopupExit(FLastOpenPopupMenu);
        }
    }
    else if(Message.Msg == WM_INITMENUPOPUP)
    {
        TWMInitMenuPopup *InitMenuPopup = (TWMInitMenuPopup *)&amp;Message;
        const int ListCount = PopupList-&gt;Count;
        for(int i = 0; i &lt; ListCount; ++i)
        {
            TPopupMenu *LPopupMenu = (TPopupMenu *)PopupList-&gt;Items[i];
            if(LPopupMenu-&gt;Handle == InitMenuPopup-&gt;MenuPopup)
            {
                FLastOpenPopupMenu = LPopupMenu;
                break;
            }
        }
    }
    Message.Result = CallWindowProc(OldPopupProc, PopupList-&gt;Window,
        Message.Msg, Message.WParam, Message.LParam);
}
</pre>
<p>La seule chose qui manque est de mettre votre code à l&#8217;intérieur de cette méthode.</p>
<pre class="brush: cpp; title: ; notranslate">
void __fastcall TForm1::DoPopupExit(TPopupMenu *PopupMenu)
{
}
</pre>
<p>Avec le code plus haut, il serait très facile de faire un composant que l&#8217;on pourrait utiliser dans plusieurs projets qui nécessitent d&#8217;être notifiés lors de la fermeture d&#8217;un menu contextuel. L&#8217;ajout d&#8217;une propriété <strong>OnPopupExit</strong> serait simple à implémenter.</p>
<p>J&#8217;espère que cet article vous sera pratique.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.optimatek.com/2011/09/detecter-la-fermeture-dun-tpopupmenu/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Changer le texte des ressources à l&#8217;exécution</title>
		<link>http://www.optimatek.com/2011/04/resourcestring/</link>
		<comments>http://www.optimatek.com/2011/04/resourcestring/#comments</comments>
		<pubDate>Sun, 24 Apr 2011 03:07:54 +0000</pubDate>
		<dc:creator>Crayon</dc:creator>
				<category><![CDATA[C++Builder]]></category>
		<category><![CDATA[TResStringRec]]></category>

		<guid isPermaLink="false">http://www.optimatek.com/?p=531</guid>
		<description><![CDATA[Dans cet article je vous expliquerai comment changer le texte contenu dans les ressources de C++Builder pendant l&#8217;exécution de votre programme. Si vous concevez une application multilingue, cette technique sera pratique. Dans votre fichier d’en-tête, ajoutez la déclaration suivante: Voici la méthode à ajouter à votre code: Le code est assez simple: on change la [...]]]></description>
			<content:encoded><![CDATA[<p>Dans cet article je vous expliquerai comment changer le texte contenu dans les ressources de C++Builder pendant l&#8217;exécution de votre programme. Si vous concevez une application multilingue, cette technique sera pratique.</p>
<p>Dans votre fichier d’en-tête, ajoutez la déclaration suivante:</p>
<pre class="brush: cpp; title: ; notranslate">
    void __fastcall HookResourceString(TResStringRec&amp; ResStringRec, Char* StrID);
</pre>
<p>Voici la méthode à ajouter à votre code:</p>
<pre class="brush: cpp; title: ; notranslate">
void __fastcall TForm1::HookResourceString(TResStringRec&amp; ResStringRec, Char* StrID)
{
    DWORD OldProtect;

    VirtualProtect(&amp;ResStringRec, sizeof(ResStringRec), PAGE_EXECUTE_READWRITE, &amp;OldProtect);
#if __BORLANDC__ &gt;= 0x630
    // Pour C++Builder XE et plus
    ResStringRec.Identifier = Integer(StrID);
#else
    ResStringRec.ident = Integer(StrID);
#endif
    VirtualProtect(&amp;ResStringRec, sizeof(ResStringRec), OldProtect, &amp;OldProtect);
}</pre>
<p>Le code est assez simple: on change la protection sur <strong>ResStringRec</strong> pour que l&#8217;on puisse y mettre un pointeur vers la chaîne de caractères <strong>StrID</strong>. Lorsque la modification est terminée, on remet la protection précédente.</p>
<p>Il est à noter que la structure <strong>TResStringRec</strong> n&#8217;est pas la même sur C++Builder 2010 et C++Builder XE. Étant donné que je n&#8217;ai pas d&#8217;autre version à ma disposition, je n&#8217;ai pas pu les vérifier.</p>
<p>Sur C++Builder 2010:
<pre class="brush: cpp; collapse: false; gutter: false; title: ; notranslate">
struct PACKAGE TResStringRec
{
    long *module;
    long ident;
};</pre>
<p>Sur C++Builder XE:
<pre class="brush: cpp; collapse: false; gutter: false; title: ; notranslate">
struct DECLSPEC_DRECORD TResStringRec
{
public:
    unsigned *Module;
    int Identifier;
};</pre>
<p>Voici un exemple d&#8217;utilisation avec la fonction <strong>MessageDlg</strong>:</p>
<pre class="brush: cpp; title: ; notranslate">
HookResourceString(_SMsgDlgConfirm, L&quot;Mon titre&quot;);
HookResourceString(_SMsgDlgYes, L&quot;Absolument&quot;);
HookResourceString(_SMsgDlgNo, L&quot;Pas du tout&quot;);
HookResourceString(_SMsgDlgCancel, L&quot;Laisse faire&quot;);

MessageDlg(&quot;Veux-tu faire quelque chose?&quot;, mtConfirmation,
        TMsgDlgButtons() &lt;&lt; mbYes &lt;&lt; mbNo &lt;&lt; mbCancel, 0, mbCancel);
</pre>
<p>Le premier paramètre de la méthode est le nom de la ressource qui correspond aux noms que l&#8217;on retrouve dans le fichier <em>Consts.hpp</em>. Donc, il est important d&#8217;inclure ce fichier d&#8217;en-tête dans votre code. Si vous êtes intéressés à connaître le texte original, alors je vous conseille de jeter un coup d&#8217;œil au fichier <em>Consts.pas</em>.</p>
<p>Je vous laisse avec une capture d&#8217;écran du résultat.<br />
<img src="http://www.optimatek.com/wp-content/uploads/2011/04/custom_dialog.png" alt="Boîte de dialogue personnalisée" width="408" height="163" class="aligncenter size-full wp-image-545" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.optimatek.com/2011/04/resourcestring/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>La fonction GRRLIB_DrawImg</title>
		<link>http://www.optimatek.com/2011/04/grrlib_drawimg/</link>
		<comments>http://www.optimatek.com/2011/04/grrlib_drawimg/#comments</comments>
		<pubDate>Wed, 06 Apr 2011 20:46:55 +0000</pubDate>
		<dc:creator>Crayon</dc:creator>
				<category><![CDATA[Wii]]></category>
		<category><![CDATA[GRRLIB]]></category>

		<guid isPermaLink="false">http://www.optimatek.com/?p=510</guid>
		<description><![CDATA[Dans cet article, je tenterai d&#8217;expliquer l&#8217;utilisation de certains paramètres de la fonction GRRLIB_DrawImg de la bibliothèque GRRLIB. Tout d&#8217;abord, voici le prototype de la fonction qui sert à dessiner une texture à l&#8217;écran: Le dernier paramètre de la fonction, color, sert à changer la couleur d&#8217;une texture. Le format de la couleur est le [...]]]></description>
			<content:encoded><![CDATA[<p>Dans cet article, je tenterai d&#8217;expliquer l&#8217;utilisation de certains paramètres de la fonction <strong>GRRLIB_DrawImg</strong> de la bibliothèque GRRLIB.</p>
<p>Tout d&#8217;abord, voici le prototype de la fonction qui sert à dessiner une texture à l&#8217;écran:</p>
<pre class="brush: cpp; collapse: false; gutter: false; title: ; notranslate">
void GRRLIB_DrawImg (
	const f32  	xpos,			// Position de l'image sur l'axe horizontal
	const f32  	ypos,			// Position de l'image sur l'axe vertical
	const GRRLIB_texImg *  tex,	// La texture à dessiner
	const f32  	degrees,		// La rotation en degré
	const f32  	scaleX,			// Proportion sur l'axe horizontal
	const f32  	scaleY,			// Proportion sur l'axe vertical
	const u32  	color			// La couleur
)
</pre>
<p>Le dernier paramètre de la fonction, <strong>color</strong>, sert à changer la couleur d&#8217;une texture. Le format de la couleur est le codage RGBA, qui est codé sur 4 octets (32 bits). Le premier octet représente le rouge, le second le vert, le troisième le bleu et finalement le dernier octet est pour l&#8217;opacité. 0 veut dire que la couleur n&#8217;est pas présente, tandis que 255, FF en hexadécimal, signifie que l&#8217;intensité de la couleur est à son maximum. Pour le canal alpha, 0 veut dire que l&#8217;image sera complètement transparente, donc dans cet exemple, l&#8217;opacité sera fixée à 255.</p>
<p>À partir de l&#8217;image PNG suivante on va afficher à l&#8217;écran quatre fantômes de différentes couleurs.<br />
<img src="http://www.optimatek.com/wp-content/uploads/2011/04/ghost.png" alt="Fantômes de Pac-Man" width="192" height="192" class="aligncenter size-full wp-image-514" />Il suffit d&#8217;ajouter quelque lignes seulement pour faire un test. Les lignes surlignées sont celles ajoutées au code du template du dossier <em>examples</em> de GRRLIB.</p>
<pre class="brush: cpp; highlight: [6,15,16,28,29,30,31,37]; title: ; notranslate">
#include &lt;grrlib.h&gt;

#include &lt;stdlib.h&gt;
#include &lt;wiiuse/wpad.h&gt;

#include &quot;ghost.h&quot;

int main(int argc, char **argv) {
    // Initialise the Graphics &amp; Video subsystem
    GRRLIB_Init();

    // Initialise the Wiimotes
    WPAD_Init();

    GRRLIB_SetBackgroundColour(0xFE, 0xCF, 0x07, 0xFF);
    GRRLIB_texImg *Fantome = GRRLIB_LoadTexture(ghost);

    // Loop forever
    while(1) {

        WPAD_ScanPads();  // Scan the Wiimotes

        // If [HOME] was pressed on the first Wiimote, break out of the loop
        if (WPAD_ButtonsDown(0) &amp; WPAD_BUTTON_HOME)  break;

        // -------------------------------------------------------------------
        // Place your drawing code here
        GRRLIB_DrawImg(50, 50, Fantome, 0, 1, 1, 0xEF1E23FF); // Blinky
        GRRLIB_DrawImg(50, 250, Fantome, 0, 1, 1, 0xEE5395FF); // Pinky
        GRRLIB_DrawImg(250, 50, Fantome, 0, 1, 1, 0x6ECEDEFF); // Inky
        GRRLIB_DrawImg(250, 250, Fantome, 0, 1, 1, 0xF67E1FFF); // Clyde
        // -------------------------------------------------------------------

        GRRLIB_Render();  // Render the frame buffer to the TV
    }

    GRRLIB_FreeTexture(Fantome);
    GRRLIB_Exit(); // Be a good boy, clear the memory allocated by GRRLIB

    exit(0);
}
</pre>
<p>Le code est assez simple: à l&#8217;aide de la fonction <strong>GRRLIB_SetBackgroundColour</strong> on choisit une couleur d&#8217;arrière plan. Une texture est créée à la ligne 16 qui sera utilisée pour dessiner les fantômes aux lignes 28 à 31. Finalement la texture est détruite à la ligne 37.</p>
<p>Voici une capture d&#8217;écran du résultat final sous l&#8217;émulateur Dolphin révision 6972.<br />
<img src="http://www.optimatek.com/wp-content/uploads/2011/04/dolphin-with-four-ghost.png" alt="Dolphin avec les fantômes de Pac-Man" width="515" height="325" class="aligncenter size-full wp-image-516" /></p>
<p>Une autre petite astuce est d&#8217;utiliser les paramètres <strong>scaleX</strong> et <strong>scaleY</strong> pour faire pivoter respectivement la texture horizontalement et verticalement. Pour effectuer cela il suffit de mettre une valeur négative. J&#8217;ai fait un petit bout de code qui déplace un fantôme de gauche à droite. Lorsque le fantôme se dirige vers la gauche, il regarde dans cette direction, même si sur l&#8217;image originale il regarde vers la droite.</p>
<pre class="brush: cpp; highlight: [6,8,17,18,19,21,22,23,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,54]; title: ; notranslate">
#include &lt;grrlib.h&gt;

#include &lt;stdlib.h&gt;
#include &lt;wiiuse/wpad.h&gt;

#include &quot;ghost.h&quot;

typedef enum DirectionX {dGauche, dDroite} DirectionX;

int main(int argc, char **argv) {
    // Initialise the Graphics &amp; Video subsystem
    GRRLIB_Init();

    // Initialise the Wiimotes
    WPAD_Init();

    GRRLIB_SetBackgroundColour(0xFE, 0xCF, 0x07, 0xFF);
    GRRLIB_texImg *Fantome = GRRLIB_LoadTexture(ghost);
    GRRLIB_SetMidHandle(Fantome, true);

    f32 Xposition = 0.0f;   // Position de l'image sur l'axe horizontal
    f32 FlipImage = 1.0f;   // Retourne l'image horizontalement
    DirectionX Direction = dDroite; // Direction (gauche ou droite)

    // Loop forever
    while(1) {

        WPAD_ScanPads();  // Scan the Wiimotes

        // If [HOME] was pressed on the first Wiimote, break out of the loop
        if (WPAD_ButtonsDown(0) &amp; WPAD_BUTTON_HOME)  break;

        // --------------------------------------------------------------------
        if(Xposition &lt; Fantome-&gt;w / 2.0f) {
            Xposition = Fantome-&gt;w / 2.0f;
            Direction = dDroite; // On change la direction
            FlipImage = 1.0f;    // Le fantôme regarde vers la droite
        }
        else if(Xposition &gt; (rmode-&gt;fbWidth - (Fantome-&gt;w / 2.0f))) {
            Xposition = rmode-&gt;fbWidth - (Fantome-&gt;w / 2.0f);
            Direction = dGauche; // On change la direction
            FlipImage = -1.0f;   // Le fantôme regarde vers la gauche
        }
        if(Direction == dGauche)
            Xposition -= 1.5f; // On se déplace un peu plus vers la gauche
        else
            Xposition += 1.5f; // On se déplace un peu plus vers la droite
        GRRLIB_DrawImg(Xposition, 150, Fantome, 0, FlipImage, 1, 0xEF1E23FF);
        // --------------------------------------------------------------------

        GRRLIB_Render();  // Render the frame buffer to the TV
    }

    GRRLIB_FreeTexture(Fantome);
    GRRLIB_Exit(); // Be a good boy, clear the memory allocated by GRRLIB

    exit(0);
}
</pre>
<p>Lorsque le fantôme atteint la gauche de l&#8217;écran du téléviseur, on entre dans la condition à la ligne 34. Quand on arrive à la droite, c&#8217;est la condition de la ligne 39 qui est vraie. L&#8217;image devrait être dessinée 50 ou 60 fois par seconde dépendant si l&#8217;affichage de votre téléviseur est 50 ou 60 Hz. En anglais on parle de FPS (frame per second). La valeur 1.5 aux lignes 45 et 47 correspond à la vitesse de déplacement de l&#8217;image, elle est calculée en nombre de pixels par frame.</p>
<p>La fonction <strong>GRRLIB_DrawImg</strong> est la base de tout jeu 2D conçu avec GRRLIB, donc il est important de bien la comprendre. J&#8217;espère que cet article vous a aidé.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.optimatek.com/2011/04/grrlib_drawimg/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Dolphin et les homebrews</title>
		<link>http://www.optimatek.com/2010/09/dolphin-et-les-homebrews/</link>
		<comments>http://www.optimatek.com/2010/09/dolphin-et-les-homebrews/#comments</comments>
		<pubDate>Wed, 22 Sep 2010 02:33:11 +0000</pubDate>
		<dc:creator>Crayon</dc:creator>
				<category><![CDATA[Wii]]></category>
		<category><![CDATA[Dolphin]]></category>
		<category><![CDATA[GRRLIB]]></category>

		<guid isPermaLink="false">http://www.optimatek.com/?p=461</guid>
		<description><![CDATA[Dans un article précédent j&#8217;avais mentionné que l&#8217;émulateur Dolphin avait un problème avec l’infrarouge de la Wii Remote. Eh bien ce problème a été réglé. En effet, il est désormais possible de contrôler le pointeur d&#8217;une Wii Remote à l&#8217;aide de la souris de votre ordinateur. C&#8217;est un avancement formidable pour ceux qui testent leur [...]]]></description>
			<content:encoded><![CDATA[<p>Dans un <a href="http://www.optimatek.com/2010/02/programmers-notepad-dolphin">article précédent</a> j&#8217;avais mentionné que l&#8217;émulateur Dolphin avait un problème avec l’infrarouge de la Wii Remote. Eh bien ce problème a été réglé. En effet, il est désormais possible de contrôler le pointeur d&#8217;une Wii Remote à l&#8217;aide de la souris de votre ordinateur. C&#8217;est un avancement formidable pour ceux qui testent leur homebrew avec ce logiciel.</p>
<p>C&#8217;est un programmeur du nom de godisgovernment qui a finalement fixé le problème à la révision <a href="http://code.google.com/p/dolphin-emu/source/detail?r=6177">6177</a>. Cette modification ne fait donc pas partie de la version 2.0, qui est la dernière version officielle à être distribuée. Les dernières versions de Dolphin sous Subversion sont quand même disponibles en téléchargement à partir de ce <a href="http://www.dolphin-emulator.com/download.html">site Web</a>.</p>
<p>Étant donné que ce n&#8217;est pas mon habitude de terminer un article sans code, je vous laisse avec un programme qui vous permettra de faire vous-même le test sous Dolphin. La bibliothèque GRRLIB sera utilisée pour la partie graphique. Comme pour tous les homebrews sur la Wii, c&#8217;est wiiuse qui servira pour la communication avec la Wii Remote.</p>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;grrlib.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;wiiuse/wpad.h&gt;

#include &quot;player1_point_png.h&quot;

#define HOTSPOTX 48 // Cursor hot spot for x coordinate
#define HOTSPOTY 48 // Cursor hot spot for y coordinate

int main(int argc, char **argv) {
    // Initialise the Graphics &amp; Video subsystem
    GRRLIB_Init();

    GRRLIB_texImg *Cursor0 = GRRLIB_LoadTexture(player1_point_png);
    GRRLIB_SetHandle(Cursor0, HOTSPOTX, HOTSPOTY);// Not needed, by default center is selected

    // Initialise the Wiimotes
    WPAD_Init();
    WPAD_SetDataFormat(WPAD_CHAN_ALL, WPAD_FMT_BTNS_ACC_IR);
    WPAD_SetVRes(WPAD_CHAN_ALL, rmode-&gt;fbWidth, rmode-&gt;efbHeight);

    // Loop forever
    while(1) {
        WPAD_ScanPads();  // Scan the Wiimotes
        WPADData *WPadData0 = WPAD_Data(WPAD_CHAN_0);

        // If [HOME] was pressed on the first Wiimote, break out of the loop
        if (WPadData0-&gt;btns_d &amp; WPAD_BUTTON_HOME)  break;

        // ---------------------------------------------------------------------
        if(WPadData0-&gt;ir.valid) {
            GRRLIB_DrawImg(WPadData0-&gt;ir.x - HOTSPOTX,
                WPadData0-&gt;ir.y - HOTSPOTY, Cursor0,
                WPadData0-&gt;ir.angle, 1, 1, 0xFFFFFFFF);
        }
        // ---------------------------------------------------------------------

        GRRLIB_Render();  // Render the frame buffer to the TV
    }

    GRRLIB_Exit(); // Be a good boy, clear the memory allocated by GRRLIB

    GRRLIB_FreeTexture(Cursor0);

    exit(0);
}
</pre>
<p>À la ligne 14 on charge l&#8217;image dans une texture. L&#8217;image utilisée pour le pointeur est celle-ci: <a href="http://www.optimatek.com/2010/09/dolphin-et-les-homebrews/player1_point/" rel="attachment wp-att-465"><img src="http://www.optimatek.com/wp-content/uploads/2010/09/player1_point.png" alt="Player 1 Wii pointer" width="96" height="96" class="aligncenter size-full wp-image-465" /></a>Il s&#8217;agit d&#8217;une image qui fait partie d&#8217;un <a href="http://www.wiibrew.org/wiki/Wii_Homebrew_Cursors">ensemble de curseurs</a> pour la Wii conçus par drmr. Toutes les images sont de 96&#215;96 pixels et le point sensible, habituellement le bout du doigt, est situé au centre. L&#8217;auteur a renoncé à ses droits sur les images pour les mettre dans le domaine public. Vous pouvez donc les utiliser dans vos applications sans problème de copyright.</p>
<p>À la ligne 19 on spécifie le format des données qui seront prises sur la Wii Remote. BTNS_ACC_IR veut dire boutons + accéléromètre + infrarouge. Par la suite, la fonction <strong>WPAD_SetVRes</strong> sert à définir la résolution d&#8217;écran virtuel pour la localisation de l&#8217;infrarouge. Pour ces opérations on utilise le paramètre <strong>WPAD_CHAN_ALL</strong> pour que tous les contrôleurs soient affectés. Pour que la fonction affecte une télécommande en particulier on doit utiliser <strong>WPAD_CHAN_0</strong>, <strong>WPAD_CHAN_1</strong>, <strong>WPAD_CHAN_2</strong> ou <strong>WPAD_CHAN_3</strong>.</p>
<p>À la ligne 25 on va chercher les données de la première Wii Remote avec la fonction <strong>WPAD_Data</strong>. Les lignes 31 à 35 servent à faire afficher le curseur avec le bon angle à la position vers laquelle la télécommande pointe. Et ce, seulement si les coordonnés sont valides. Donc, si vous mettez votre main devant la Wii Remote, le pointeur disparaîtra de l&#8217;écran de votre téléviseur.</p>
<p>J&#8217;aurais pu ajouter bien des choses dans le code, mais j&#8217;ai décidé de le garder simple.</p>
<p>Bonne programmation&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.optimatek.com/2010/09/dolphin-et-les-homebrews/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Écrire du texte avec GRRLIB</title>
		<link>http://www.optimatek.com/2010/08/texte-avec-grrlib/</link>
		<comments>http://www.optimatek.com/2010/08/texte-avec-grrlib/#comments</comments>
		<pubDate>Wed, 01 Sep 2010 03:37:24 +0000</pubDate>
		<dc:creator>Crayon</dc:creator>
				<category><![CDATA[Wii]]></category>
		<category><![CDATA[GRRLIB]]></category>

		<guid isPermaLink="false">http://www.optimatek.com/?p=383</guid>
		<description><![CDATA[Il existe trois manières différentes d&#8217;écrire du texte à l&#8217;aide de la bibliothèque GRRLIB. On peut utiliser une texture, un fichier BMF ou un fichier TTF. Chacune de ces méthodes possède des avantages et des inconvénients. La première méthode qui sera expliquée sera l&#8217;utilisation d&#8217;une texture. Bien sûr, lorsqu&#8217;on parle de texture, on parle d&#8217;une [...]]]></description>
			<content:encoded><![CDATA[<p>Il existe trois manières différentes d&#8217;écrire du texte à l&#8217;aide de la bibliothèque GRRLIB. On peut utiliser une texture, un fichier BMF ou un fichier TTF. Chacune de ces méthodes possède des avantages et des inconvénients.</p>
<p>La première méthode qui sera expliquée sera l&#8217;utilisation d&#8217;une texture. Bien sûr, lorsqu&#8217;on parle de texture, on parle d&#8217;une image. Même si GRRLIB supporte les formats JPEG et Bitmap, il serait préférable que celle-ci soit en format PNG, car ce format permet l&#8217;utilisation de transparence. Il existe plusieurs logiciels qui permettent de générer de telles images. Celui que j&#8217;utilise est <a href="http://wiibrew.org/wiki/WiiBuilder/fr">WiiBuilder</a>. Voici l&#8217;image qui sera utilisée pour cet article:<br />
<a href="http://www.optimatek.com/2010/08/texte-avec-grrlib/demofont/" rel="attachment wp-att-384"><img src="http://www.optimatek.com/wp-content/uploads/2010/08/demofont.png" alt="Police de caractères pour GRRLIB" width="312" height="92" class="aligncenter size-full wp-image-384" /></a> Vous pouvez vous rendre compte de certaines limites simplement en regardant l&#8217;image. Tous les caractères qui seront nécessaires dans l&#8217;application devront être générés dans l&#8217;image. Dans celle-ci, il n&#8217;y a que les caractères 32 à 128, qui sont les caractères visibles du code <a href="http://fr.wikipedia.org/wiki/ASCII">ASCII</a>. Donc, pas question d&#8217;utiliser un E accent aigu ou un A accent grave. Ces caractères auraient pu être générés, mais l&#8217;image aurait été plus grande.</p>
<p>Le plus grand inconvénient à utiliser une image est que chaque caractère doit avoir la même largeur. Dans l&#8217;exemple ci-dessus, c&#8217;est 13 pixels. Cela veut dire que même si on décide d&#8217;afficher un i ou un !, ils vont prendre la même place qu&#8217;un m ou w, qui sont généralement plus grand. Donc, à l&#8217;écran le mot Wii, pourrait avoir l&#8217;air de <code>"</code>W i  i <code>"</code>. Bien sûr cela dépend toujours de la police utilisée. Dans celle que j&#8217;ai choisie, tous les caractères ont sensiblement la même largeur. On dit que c&#8217;est une police d&#8217;écriture à chasse fixe.</p>
<p>Il faut convertir l&#8217;image en fichier d&#8217;entête et la transformer en texture à l&#8217;aide de la fonction <strong>GRRLIB_LoadTexture</strong>. Ces manipulations ont déjà été abordées dans un <a href="http://www.optimatek.com/2010/07/initiation-a-grrlib">article précédent</a>, donc veuillez vous y référer si vous avez besoin d&#8217;aide. Il existe deux différences entre l&#8217;affichage de texte et l&#8217;affichage d&#8217;images. La première est qu&#8217;après avoir chargé l&#8217;image dans une structure de type <strong>GRRLIB_texImg</strong>, il faut spécifier les détails de notre image avec la fonction <strong>GRRLIB_InitTileSet</strong>. Les paramètres de la fonction dans l&#8217;ordre sont un pointeur vers la texture, la largeur et la hauteur d&#8217;un caractère et le caractère de départ. La seconde différence est l&#8217;utilisation de <strong>GRRLIB_Printf</strong> au lieu de <strong>GRRLIB_DrawImg</strong>.</p>
<p>Voici donc le code. Les lignes surlignées sont celles ajoutées au code du template du dossier <em>examples</em> de GRRLIB.</p>
<pre class="brush: cpp; highlight: [6,12,13,28,29,35]; title: ; notranslate">
#include &lt;grrlib.h&gt;

#include &lt;stdlib.h&gt;
#include &lt;wiiuse/wpad.h&gt;

#include &quot;demofont.h&quot;

int main(int argc, char **argv) {
    // Initialise the Graphics &amp; Video subsystem
    GRRLIB_Init();

    GRRLIB_texImg *demo_font = GRRLIB_LoadTexture(demofont);
    GRRLIB_InitTileSet(demo_font, 13, 23, 32);

    // Initialise the Wiimotes
    WPAD_Init();

    // Loop forever
    while(1) {

        WPAD_ScanPads();  // Scan the Wiimotes

        // If [HOME] was pressed on the first Wiimote, break out of the loop
        if (WPAD_ButtonsDown(0) &amp; WPAD_BUTTON_HOME)  break;

        // ---------------------------------------------------------------------
        // Place your drawing code here
        GRRLIB_Printf(5, 100, demo_font, 0xFFFFFFFF, 1,
            &quot;Ceci est un test de texture&quot;);
        // ---------------------------------------------------------------------

        GRRLIB_Render();  // Render the frame buffer to the TV
    }

    GRRLIB_FreeTexture(demo_font);
    GRRLIB_Exit(); // Be a good boy, clear the memory allocated by GRRLIB

    exit(0);
}
</pre>
<p>Cela fait le tour de la première méthode. La prochaine dont il va être question est l&#8217;utilisation de fichier BMF pour afficher du texte. BMF est l&#8217;extension qui désigne un bitmap font. Ce type de fichier peut être téléchargé sur le site Web suivant: <a href="http://bmf.wz.cz">http://bmf.wz.cz</a>. La police que j&#8217;ai choisie se nomme NOSTK. Elle possède seulement 35 caractères et les lettres minuscules ne sont pas présentes. </p>
<p>Les étapes pour afficher du texte sont assez simples. Encore une fois, on transforme le fichier en entête qui sera inclus dans le <em>main.c</em>. On charge l&#8217;image dans une structure. Cette fois-ci, il s&#8217;agit d&#8217;un <strong>GRRLIB_bytemapFont</strong>. On dessine le texte avec <strong>GRRLIB_PrintBMF</strong> et la mémoire est libérée grâce à <strong>GRRLIB_FreeBMF</strong>.</p>
<p>Voici le code avec les nouvelles lignes surlignées:</p>
<pre class="brush: cpp; highlight: [7,15,32,33,40]; title: ; notranslate">
#include &lt;grrlib.h&gt;

#include &lt;stdlib.h&gt;
#include &lt;wiiuse/wpad.h&gt;

#include &quot;demofont.h&quot;
#include &quot;nostk.h&quot;

int main(int argc, char **argv) {
    // Initialise the Graphics &amp; Video subsystem
    GRRLIB_Init();

    GRRLIB_texImg *demo_font = GRRLIB_LoadTexture(demofont);
    GRRLIB_InitTileSet(demo_font, 13, 23, 32);
    GRRLIB_bytemapFont *bmf_font = GRRLIB_LoadBMF(nostk);

    // Initialise the Wiimotes
    WPAD_Init();

    // Loop forever
    while(1) {

        WPAD_ScanPads();  // Scan the Wiimotes

        // If [HOME] was pressed on the first Wiimote, break out of the loop
        if (WPAD_ButtonsDown(0) &amp; WPAD_BUTTON_HOME)  break;

        // ---------------------------------------------------------------------
        // Place your drawing code here
        GRRLIB_Printf(10, 100, demo_font, 0xFFFFFFFF, 1,
            &quot;Ceci est un test de texture&quot;);
        GRRLIB_PrintBMF(10, 150, bmf_font,
            &quot;CECI EST UN TEST DE FICHIER BMF&quot;);
        // ---------------------------------------------------------------------

        GRRLIB_Render();  // Render the frame buffer to the TV
    }

    GRRLIB_FreeTexture(demo_font);
    GRRLIB_FreeBMF(bmf_font);
    GRRLIB_Exit(); // Be a good boy, clear the memory allocated by GRRLIB

    exit(0);
}
</pre>
<p>La dernière méthode est l&#8217;utilisation de fichier TTF. TTF est l&#8217;extension pour désigner une police de caractères de format TrueType. Les polices TrueType sont constituées de vecteurs donc la qualité du texte ne diminue pas contrairement au bitmap lorsque la taille augmente. La police que j’ai choisie se nomme Miama et elle possède 1110 caractères. Par contre, sa taille est de 106 Ko, ce qui reste quand même raisonnable. Elle a été téléchargée sur le site <a href="http://openfontlibrary.org">Open Font Library.org</a>.</p>
<p>Les étapes pour afficher du texte sont les mêmes que pour les BMF, sauf que l&#8217;on remplace le mot BMF par TTF. On charge l’image dans une structure de type <strong>GRRLIB_ttfFont</strong> avec la fonction <strong>GRRLIB_LoadTTF</strong>. On dessine le texte avec <strong>GRRLIB_PrintfTTF</strong> et la mémoire est libérée grâce à <strong>GRRLIB_FreeTTF</strong>. Il est possible d&#8217;utiliser des chaînes de caractères de type <strong>wchar_t</strong> avec la fonction <strong>GRRLIB_PrintfTTFW</strong>.</p>
<p>Voici le code avec les nouvelles lignes surlignées:</p>
<pre class="brush: cpp; highlight: [8,17,36,37,45]; title: ; notranslate">
#include &lt;grrlib.h&gt;

#include &lt;stdlib.h&gt;
#include &lt;wiiuse/wpad.h&gt;

#include &quot;demofont.h&quot;
#include &quot;nostk.h&quot;
#include &quot;Miama.h&quot;

int main(int argc, char **argv) {
    // Initialise the Graphics &amp; Video subsystem
    GRRLIB_Init();

    GRRLIB_texImg *demo_font = GRRLIB_LoadTexture(demofont);
    GRRLIB_InitTileSet(demo_font, 13, 23, 32);
    GRRLIB_bytemapFont *bmf_font = GRRLIB_LoadBMF(nostk);
    GRRLIB_ttfFont *ttf_font = GRRLIB_LoadTTF(Miama, Miama_size);

    // Initialise the Wiimotes
    WPAD_Init();

    // Loop forever
    while(1) {

        WPAD_ScanPads();  // Scan the Wiimotes

        // If [HOME] was pressed on the first Wiimote, break out of the loop
        if (WPAD_ButtonsDown(0) &amp; WPAD_BUTTON_HOME)  break;

        // ---------------------------------------------------------------------
        // Place your drawing code here
        GRRLIB_Printf(10, 100, demo_font, 0xFFFFFFFF, 1,
            &quot;Ceci est un test de texture&quot;);
        GRRLIB_PrintBMF(10, 150, bmf_font,
            &quot;CECI EST UN TEST DE FICHIER BMF&quot;);
        GRRLIB_PrintfTTF(10, 200, ttf_font,
            &quot;Ceci est un test de police TrueType&quot;, 60, 0xFFFFFFFF);
        // ---------------------------------------------------------------------

        GRRLIB_Render();  // Render the frame buffer to the TV
    }

    GRRLIB_FreeTexture(demo_font);
    GRRLIB_FreeBMF(bmf_font);
    GRRLIB_FreeTTF(ttf_font);
    GRRLIB_Exit(); // Be a good boy, clear the memory allocated by GRRLIB

    exit(0);
}
</pre>
<p>L&#8217;encodage par défaut des fichiers dans Programmer’s Notepad pourrait vous causer des problèmes avec certains caractères de la langue française. Si c&#8217;est la cas, il faut donc aller dans <em>File</em> / <em>Properties&#8230;</em> ou sinon utiliser le raccourci Alt + Entrée avec le bon fichier ouvert. Au lieu de <em>Default</em> dans la liste <em>Encoding</em>, vous pouvez sélectionner <em>UTF-8</em>. Si vous désirez ne pas altérer votre fichier qui contient le code, vous pouvez alors créer un fichier d&#8217;entête avec l&#8217;encodage de votre choix qui contiendra tout le texte dans des directives <strong>#define</strong>.</p>
<p>Je vous laisse avec une image du résultat final.<br />
<img src="http://www.optimatek.com/wp-content/uploads/2010/08/texte-avec-grrlib.png" alt="Texte avec GRRLIB" width="566" height="432" class="aligncenter size-full wp-image-432" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.optimatek.com/2010/08/texte-avec-grrlib/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

