<?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>Blog de Nico-pyright(c) &#187; C++/CLI</title>
	<atom:link href="https://blog.developpez.com/nico-pyright/pcategory/ccli/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.developpez.com/nico-pyright</link>
	<description></description>
	<lastBuildDate>Mon, 08 Apr 2013 09:26:35 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.42</generator>
	<item>
		<title>Renouvellement MVP</title>
		<link>https://blog.developpez.com/nico-pyright/p7033/ccli/renouvellement_mvp</link>
		<comments>https://blog.developpez.com/nico-pyright/p7033/ccli/renouvellement_mvp#comments</comments>
		<pubDate>Mon, 05 Jan 2009 19:00:00 +0000</pubDate>
		<dc:creator><![CDATA[nico-pyright(c)]]></dc:creator>
				<category><![CDATA[ASP.Net]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[C++/CLI]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Me voici à nouveau renouvelé pour cette année 2009, toujours à votre service. J&#8217;en profite pour vous adresser mes meilleurs voeux pour cette année, puisse-t-elle être encore pleine de .NET, de tutoriels et de questions marquées résolues]]></description>
				<content:encoded><![CDATA[<p>Me voici à nouveau renouvelé pour cette année 2009, toujours à votre service.</p>
<p>J&rsquo;en profite pour vous adresser mes meilleurs voeux pour cette année, puisse-t-elle être encore pleine de .NET, de tutoriels et de questions marquées résolues <img src="https://blog.developpez.com/nico-pyright/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" /></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>[C++/CLI] Mise à jour de la FAQ C++/CLI.</title>
		<link>https://blog.developpez.com/nico-pyright/p6538/ccli/c_cli_mise_a_jour_de_la_faq_c_cli</link>
		<comments>https://blog.developpez.com/nico-pyright/p6538/ccli/c_cli_mise_a_jour_de_la_faq_c_cli#comments</comments>
		<pubDate>Wed, 08 Oct 2008 23:00:00 +0000</pubDate>
		<dc:creator><![CDATA[nico-pyright(c)]]></dc:creator>
				<category><![CDATA[C++/CLI]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voilà une petite mise à jour de la FAQ C++/CLI. Au programme, 250 réponses à vos questions, dont 29 nouvelles. Aller consulter la FAQ C++/CLI]]></description>
				<content:encoded><![CDATA[<p>Voilà une petite mise à jour de la FAQ C++/CLI.</p>
<p>Au programme, 250 réponses à vos questions, dont 29 nouvelles.</p>
<p><a href="http://dotnet.developpez.com/faq/cppcli/">Aller consulter la FAQ C++/CLI</a></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[C++/CLI] Comment créer un Wrapper C++/CLI, exemple de compression en .Cab</title>
		<link>https://blog.developpez.com/nico-pyright/p6460/ccli/c_cli_comment_creer_un_wrapper_c_cli_exe</link>
		<comments>https://blog.developpez.com/nico-pyright/p6460/ccli/c_cli_comment_creer_un_wrapper_c_cli_exe#comments</comments>
		<pubDate>Sat, 27 Sep 2008 08:58:09 +0000</pubDate>
		<dc:creator><![CDATA[nico-pyright(c)]]></dc:creator>
				<category><![CDATA[C++ Interop]]></category>
		<category><![CDATA[C++/CLI]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[on me demande souvent comment créer un wrapper C++/CLI &#8230; Je vais, dans ce post, vous guider dans la création d&#8217;un tel wrapper. Pour l&#8217;exemple, je vais utiliser la très bonne bibliothèque de compression en .Cab, créée par Elmue sur CodeProject. Cette bibliothèque possède une version C++ et une version .Net, cette dernière ayant été créé avec le Managed C++ de Visual Studio 2002, je vais vous montrer comment on peut encapsuler la version C++ [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>on me demande souvent comment créer un wrapper C++/CLI &#8230;</p>
<p>Je vais, dans ce post, vous guider dans la création d&rsquo;un tel wrapper.<br />
Pour l&rsquo;exemple, je vais utiliser la <a href="http://www.codeproject.com/KB/files/CABCompressExtract.aspx">très bonne bibliothèque de compression en .Cab</a>, créée par Elmue sur CodeProject.</p>
<p>Cette bibliothèque possède une version C++ et une version .Net, cette dernière ayant été créé avec le Managed C++ de Visual Studio 2002, je vais vous montrer comment on peut encapsuler la version C++ pure dans un wrapper C++/CLI afin de l&rsquo;utiliser avec vos projets .Net.</p>
<p><span id="more-36"></span></p>
<p>Pour cet exemple, je vais encapsuler uniquement la compression, donc je vais soulager le projet C++ de quelques fichiers et je vais les modifier pour retirer les références à ces fichiers inutiles.</p>
<p>J&rsquo;ai donc cette liste de fichier qui vont me servir :<br />
&#8211; Blowfish.h<br />
&#8211; Compress.h<br />
&#8211; Error.h<br />
&#8211; File.h<br />
&#8211; Map.h<br />
&#8211; String.h</p>
<p>(notez que j&rsquo;ai renommé les fichiers .hpp en .h parce que j&rsquo;aime mieux &#8230;)</p>
<p>Je créé ensuite un nouveau projet CLR : Class Library que j&rsquo;appelle CabUtil (il est donc <a href="http://dotnet.developpez.com/faq/cppcli/?page=compilationmode#clronly">compilé avec l&rsquo;option /clr</a>).<br />
J&rsquo;y ajoute les fichiers précédemment cités, je compile &#8230; et c&rsquo;est presque terminé !<br />
La fonctionnalité <a href="http://nico-pyright.developpez.com/tutoriel/vc2005/interop/">nommée C++ Interop</a> a fait tout le boulot pour nous. Elle a compilé du code natif dans notre assembly .Net.</p>
<p>Passons désormais à la création du wrapper C++/CLI, qui fera office de wrapper et de façade en même temps.</p>
<p>Je créé une nouvelle classe, que j&rsquo;appelle CabUtil.</p>
<p>Ici, je n&rsquo;ai pas grand chose à wrapper, mais nous allons le faire quand même. On remarque qu&rsquo;on a besoin d&rsquo;un char * qui représente la clé de cryptage du .Cab.</p>
<p>Créons donc un membre privé de type char *</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">char * s8_EncryptionKey;</div></div>
<p>Je vais lui affecter une valeur par défaut dans mon constructeur :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">CabCompress() <br />
{ <br />
&nbsp; s8_EncryptionKey = new char[73]; <br />
&nbsp; strcpy(s8_EncryptionKey, &quot;&quot;); <br />
}</div></div>
<p>Maintenant, on va créer une propriété qui va exposer une String ^ .Net et qui se chargera de convertir en char * :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">property String ^EncryptionKey <br />
{ <br />
&nbsp; void set(String ^value) <br />
&nbsp; { <br />
&nbsp; &nbsp; if (value-&gt;Length &gt; 72) <br />
&nbsp; &nbsp; &nbsp; value = value-&gt;Substring(0, 72); <br />
&nbsp; &nbsp; char* temp = static_cast&lt;char *&gt;(Marshal::StringToHGlobalAnsi(value).ToPointer()); <br />
&nbsp; &nbsp; strcpy(s8_EncryptionKey, temp); <br />
&nbsp; &nbsp; Marshal::FreeHGlobal(safe_cast&lt;IntPtr&gt;(temp)); <br />
&nbsp; } <br />
}</div></div>
<p>Note : la clé ne peut pas dépasser 72 caractères.</p>
<p>Bien sur, il ne faudra pas oublier de désallouer le char * dans les destructeurs et finalizers :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">~CabCompress() <br />
{ <br />
&nbsp; delete s8_EncryptionKey; <br />
&nbsp; s8_EncryptionKey = NULL; <br />
} <br />
&nbsp;<br />
protected: <br />
&nbsp; !CabCompress() <br />
&nbsp; { <br />
&nbsp; &nbsp; delete s8_EncryptionKey; <br />
&nbsp; &nbsp; s8_EncryptionKey = NULL; <br />
&nbsp; }</div></div>
<p>Je vais maintenant passer à l&rsquo;écriture d&rsquo;une méthode qui va compresser une liste de fichier, cette méthode étant une façade pour un algorithme un peu plus complexe.<br />
Il s&rsquo;agit de la méthode :</p>
<p><code class="codecolorer text default"><span class="text">void CompressFileList(IDictionary&lt;String^, String^&gt;^ fileList, String ^compressFile)</span></code></p>
<p>Elle prend en paramètre un dictionnaire qui va contenir le nom du fichier à compresser et sa destination dans l&rsquo;arborescence du .Cab. Le deuxième paramètre est le fichier archive de destination.</p>
<p>Il y a dans cette méthode quelques conversions de String ^ en char *, mais nous n&rsquo;allons pas nous attarder, vu qu&rsquo;on a déjà vu le principe plus haut.<br />
L&rsquo;autre élément intéressant est le mapping d&rsquo;une callback native en delegate .Net. Nous allons créer un événement pour être informé de la mise à jour du status de la compression.</p>
<p>On avait en C++, la définition suivante pour gérer la callback :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Cabinet::CCompress::kCallbacks k_ComprCallbacks; <br />
k_ComprCallbacks.f_UpdateStatus &nbsp; = &amp;CMain::OnUpdateStatus;</div></div>
<p>avec la méthode statique associée :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">static int CMain::OnUpdateStatus(UINT typeStatus, Cabinet::CCompress::kCurStatus *pk_CurStatus, void *p_Param) <br />
{ <br />
... <br />
}</div></div>
<p>pour wrapper ceci, nous allons créer un delegate, dans les membres privés :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">[UnmanagedFunctionPointer(CallingConvention::StdCall)] <br />
delegate int WrapperUpdateStatusHandler(UINT typeStatus, Cabinet::CCompress::kCurStatus *pk_CurStatus, void *p_Param); <br />
WrapperUpdateStatusHandler ^UpdateStatusDelegate;</div></div>
<p>Notez que le delegate a bien sur la même signature que la méthode OnUpdateStatus.</p>
<p>Dans notre méthode, on pourra instancier notre delegate ainsi :</p>
<p><code class="codecolorer text default"><span class="text">UpdateStatusDelegate = gcnew WrapperUpdateStatusHandler(this, &amp;CabCompress::UpdateStatus);</span></code></p>
<p>qui est raccroché à la méthode </p>
<p><code class="codecolorer text default"><span class="text">static int UpdateStatus(UINT typeStatus, Cabinet::CCompress::kCurStatus *pk_CurStatus, void *p_Param)</span></code></p>
<p>(les observateurs auront noté que j&rsquo;ai changé le nom de la méthode C++, qui au passage, n&rsquo;est plus statique)</p>
<p>Ensuite on utilise GetFunctionPointerForDelegate pour raccrocher ce delegate à la callback en C++</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">IntPtr p = Marshal::GetFunctionPointerForDelegate(UpdateStatusDelegate); <br />
k_ComprCallbacks.f_UpdateStatus &nbsp; = (Cabinet::CCompress::kCallbacks::t_UpdateStatus)p.ToPointer(); <br />
i_Compress.SetCallbacks(&amp;k_ComprCallbacks);</div></div>
<p>Maintenant, la méthode UpdateStatus pourra lever l&rsquo;événement suivant (qu&rsquo;on aura défini comme membre public de la classe) :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">delegate void UpdateStatusHandler(int PercentComplete); <br />
event UpdateStatusHandler ^OnUpdateStatus; <br />
&nbsp;<br />
int UpdateStatus(UINT typeStatus, Cabinet::CCompress::kCurStatus *pk_CurStatus, void *p_Param) <br />
{ <br />
&nbsp; if (pk_CurStatus-&gt;FolderPercent &gt; 0) <br />
&nbsp; &nbsp; OnUpdateStatus(pk_CurStatus-&gt;FolderPercent); <br />
&nbsp; return 0; <br />
}</div></div>
<p>Et voilà, il ne nous reste plus qu&rsquo;à compiler et notre assembly est prête.</p>
<p>Reste à l&rsquo;utiliser dans un programme C#. Pour ce faire, on référence cette assembly dans notre projet, et on peut appeler la méthode de compression ainsi :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">static void Main() <br />
{ <br />
&nbsp; CabCompress c = new CabCompress(); <br />
&nbsp; c.OnUpdateStatus += c_OnUpdateStatus; <br />
&nbsp; Dictionary&lt;string, string&gt; dictionary = new Dictionary&lt;string, string&gt; <br />
&nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; {&quot;C:\\test.txt&quot;, &quot;C\\test.txt&quot;}, <br />
&nbsp; &nbsp; &nbsp; {&quot;C:\\temp\\fichier.mp3&quot;, &quot;C\\temp\\fichier.mp3&quot;} <br />
&nbsp; &nbsp; }; <br />
&nbsp; c.CompressFileList(dictionary, &quot;C:\\OutPut_%d.cab&quot;); <br />
} <br />
&nbsp;<br />
static void c_OnUpdateStatus(int PercentComplete) <br />
{ <br />
&nbsp; Console.WriteLine(&quot;Compression : {0} %&quot;, &nbsp;PercentComplete); <br />
}</div></div>
<p>Vous pouvez télécharger les sources de cet exemple : <a href="ftp://ftp-developpez.com/nico-pyright/blog/CabUtil.zip">version zip</a> ou <a href="ftp://ftp-developpez.com/nico-pyright/blog/CabUtil.rar">version rar</a></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Winforms] [C++/CLI][C#] Databinding Bidirectionnel avec les Winforms</title>
		<link>https://blog.developpez.com/nico-pyright/p6425/ccli/winforms_c_cli_c_databinding_bidirection</link>
		<comments>https://blog.developpez.com/nico-pyright/p6425/ccli/winforms_c_cli_c_databinding_bidirection#comments</comments>
		<pubDate>Sun, 21 Sep 2008 08:30:58 +0000</pubDate>
		<dc:creator><![CDATA[nico-pyright(c)]]></dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[C++/CLI]]></category>
		<category><![CDATA[Winforms]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Le binding bidirectionnel consiste à &#171;&#160;associer&#160;&#187; une propriété de classe à un controle de Formulaire. Par exemple, j&#8217;ai un textbox sur ma form qui est associé à une chaine (String) dans ma classe. Toute modification de ce textbox entraine automatiquement une modification de ma chaine. Inversement, toute modification de cette chaine en code, implique une répercution visuelle sur la valeur du textbox. Voici comment implémenter un tel binding : Le principe est d&#8217;utiliser l&#8217;interface INotifyPropertyChanged. [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Le binding bidirectionnel consiste à &laquo;&nbsp;associer&nbsp;&raquo; une propriété de classe à un controle de Formulaire.</p>
<p>Par exemple, j&rsquo;ai un textbox sur ma form qui est associé à une chaine (String) dans ma classe. Toute modification de ce textbox entraine automatiquement une modification de ma chaine. Inversement, toute modification de cette chaine en code, implique une répercution visuelle sur la valeur du textbox.</p>
<p>Voici comment implémenter un tel binding :</p>
<p><span id="more-18"></span></p>
<p>Le principe est d&rsquo;utiliser l&rsquo;interface <a href="http://msdn.microsoft.com/fr-fr/library/system.componentmodel.inotifypropertychanged.aspx">INotifyPropertyChanged</a>. L&rsquo;appel de l&rsquo;événement <a href="http://msdn.microsoft.com/fr-fr/library/system.componentmodel.inotifypropertychanged.propertychanged.aspx">PropertyChanged</a> permet d&rsquo;informer que la valeur a changé et automatiquement répercuter ce changement.</p>
<p>Voici comment faire en C++/CLI (plus loin, la version C#) :</p>
<p>Tout d&rsquo;abord, la form doit implémenter INotifyPropertyChanged</p>
<p><code class="codecolorer text default"><span class="text">public ref class Form1 : public System::Windows::Forms::Form, INotifyPropertyChanged</span></code></p>
<p>Ceci implique de définir l&rsquo;événement suivant :</p>
<p><code class="codecolorer text default"><span class="text">virtual event PropertyChangedEventHandler ^PropertyChanged;</span></code></p>
<p>Il nous faut ensuite une propriété de type String. C&rsquo;est cette propriété qui sera bindée à notre TextBox :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">private: <br />
&nbsp; String ^_chaine; <br />
public: <br />
&nbsp; property String ^Chaine <br />
&nbsp; { <br />
&nbsp; &nbsp; String ^ get() { return _chaine; } <br />
&nbsp; &nbsp; void set(String ^value) &nbsp;<br />
&nbsp; &nbsp; { &nbsp;<br />
&nbsp; &nbsp; &nbsp; if (value != _chaine) <br />
&nbsp; &nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; _chaine = value; <br />
&nbsp; &nbsp; &nbsp; &nbsp; NotifyPropertyChanged(&quot;Chaine&quot;); <br />
&nbsp; &nbsp; &nbsp; } <br />
&nbsp; &nbsp; } <br />
&nbsp; }</div></div>
<p>On note l&rsquo;appel à la méthode NotifyPropertyChanged pour indiquer une changement de valeur.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">private: <br />
&nbsp; void NotifyPropertyChanged(String ^info) <br />
&nbsp; { <br />
&nbsp; &nbsp; PropertyChanged(this, gcnew PropertyChangedEventArgs(info)); <br />
&nbsp; }</div></div>
<p>La méthode NotifyPropertyChanged appelle l&rsquo;événement PropertyChanged pour signaler le changement afin qu&rsquo;il soit répercuté à tous les endroits où le binding est effectué.</p>
<p>Ne pas oublier de définir le binding, au plus tot, dans le form_load par exemple :<br />
<code class="codecolorer text default"><span class="text">textBox1-&gt;DataBindings-&gt;Add(&quot;Text&quot;, this, &quot;Chaine&quot;);</span></code></p>
<p>Et le tour est joué.</p>
<p>Voici la syntaxe pour du C# :</p>
<p><code class="codecolorer text default"><span class="text">public partial class Form1 : Form, INotifyPropertyChanged</span></code></p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">private string _chaine; <br />
public string Chaine <br />
{ <br />
&nbsp; &nbsp; get { return _chaine; } <br />
&nbsp; &nbsp; set <br />
&nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; if (value != _chaine) <br />
&nbsp; &nbsp; &nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _chaine = value; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NotifyPropertyChanged(&quot;Chaine&quot;); <br />
&nbsp; &nbsp; &nbsp; &nbsp; } <br />
&nbsp; &nbsp; } <br />
} <br />
&nbsp;<br />
private void Form1_Load(object sender, EventArgs e) <br />
{ <br />
&nbsp; &nbsp; textBox1.DataBindings.Add(&quot;Text&quot;, this, &quot;Chaine&quot;); <br />
} <br />
&nbsp;<br />
public event PropertyChangedEventHandler PropertyChanged; <br />
&nbsp;<br />
private void NotifyPropertyChanged(String info) <br />
{ <br />
&nbsp; &nbsp; if (PropertyChanged != null) <br />
&nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; PropertyChanged(this, new PropertyChangedEventArgs(info)); <br />
&nbsp; &nbsp; } <br />
}</div></div>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[C#][Winforms] Ne lancer qu&#8217;une seule instance de son application</title>
		<link>https://blog.developpez.com/nico-pyright/p6408/c/c_winforms_ne_lancer_qu_une_seule_instan</link>
		<comments>https://blog.developpez.com/nico-pyright/p6408/c/c_winforms_ne_lancer_qu_une_seule_instan#comments</comments>
		<pubDate>Thu, 18 Sep 2008 20:00:00 +0000</pubDate>
		<dc:creator><![CDATA[nico-pyright(c)]]></dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Pour ce faire, on va utiliser un mutex Il suffit d&#8217;encadrer l&#8217;instanciation par défaut de la form dans le fichier Program.cs bool owned; Mutex mutex = new Mutex(true, &#34;Mon_Mutex_Pour_Mon_Application&#34;, out owned); if (owned) { &#160; Application.EnableVisualStyles(); &#160; Application.SetCompatibleTextRenderingDefault(false); &#160; Application.Run(new Form1()); &#160; mutex.ReleaseMutex(); } else &#160; MessageBox.Show(&#34;L'application est déjà lancée&#34;); Et voilà]]></description>
				<content:encoded><![CDATA[<p>Pour ce faire, on va utiliser <a href="http://msdn.microsoft.com/fr-fr/library/system.threading.mutex(VS.80).aspx">un mutex </a></p>
<p><span id="more-46"></span></p>
<p>Il suffit d&rsquo;encadrer l&rsquo;instanciation par défaut de la form dans le fichier Program.cs</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">bool owned; <br />
Mutex mutex = new Mutex(true, &quot;Mon_Mutex_Pour_Mon_Application&quot;, out owned); <br />
if (owned) <br />
{ <br />
&nbsp; Application.EnableVisualStyles(); <br />
&nbsp; Application.SetCompatibleTextRenderingDefault(false); <br />
&nbsp; Application.Run(new Form1()); <br />
&nbsp; mutex.ReleaseMutex(); <br />
} <br />
else <br />
&nbsp; MessageBox.Show(&quot;L'application est déjà lancée&quot;);</div></div>
<p>Et voilà</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[C++/CLI] Enregistrer un fichier avec SaveFileDialog</title>
		<link>https://blog.developpez.com/nico-pyright/p6056/ccli/c_cli_enregistrer_un_fichier_avec_savefi</link>
		<comments>https://blog.developpez.com/nico-pyright/p6056/ccli/c_cli_enregistrer_un_fichier_avec_savefi#comments</comments>
		<pubDate>Fri, 11 Jul 2008 20:00:00 +0000</pubDate>
		<dc:creator><![CDATA[nico-pyright(c)]]></dc:creator>
				<category><![CDATA[C++/CLI]]></category>
		<category><![CDATA[Winforms]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[J&#8217;étais passé rapidement sur ce point dans mon tutoriel d&#8217;introduction aux winforms, je reviens dessus vu que ca ne semble pas assez clair Pour enregistrer le contenu d&#8217;un textbox avec une SaveFileDialog, il suffit d&#8217;utiliser le stream fournir par OpenFile : saveFileDialog1-&#62;Title = &#34;Sélectionnez un fichier&#34;; saveFileDialog1-&#62;FileName = nullptr; saveFileDialog1-&#62;DefaultExt = &#34;txt&#34;; saveFileDialog1-&#62;Filter = &#34;Fichiers Texte (*.txt)&#124;*.txt&#124;Tous (*.*)&#124;*.*&#34;; if (saveFileDialog1-&#62;ShowDialog() == System::Windows::Forms::DialogResult::OK) { &#160; Stream ^s = saveFileDialog1-&#62;OpenFile(); &#160; StreamWriter ^sw = gcnew StreamWriter(s); &#160; [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>J&rsquo;étais passé rapidement sur ce point dans mon <a href="http://nico-pyright.developpez.com/tutoriel/vc2005/winforms2/#LopensaveDialog">tutoriel d&rsquo;introduction aux winforms</a>, je reviens dessus vu que ca ne semble pas assez clair</p>
<p><span id="more-17"></span></p>
<p>Pour enregistrer le contenu d&rsquo;un textbox avec une SaveFileDialog, il suffit d&rsquo;utiliser le stream fournir par OpenFile :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">saveFileDialog1-&gt;Title = &quot;Sélectionnez un fichier&quot;; <br />
saveFileDialog1-&gt;FileName = nullptr; <br />
saveFileDialog1-&gt;DefaultExt = &quot;txt&quot;; <br />
saveFileDialog1-&gt;Filter = &quot;Fichiers Texte (*.txt)|*.txt|Tous (*.*)|*.*&quot;; <br />
if (saveFileDialog1-&gt;ShowDialog() == System::Windows::Forms::DialogResult::OK) <br />
{ <br />
&nbsp; Stream ^s = saveFileDialog1-&gt;OpenFile(); <br />
&nbsp; StreamWriter ^sw = gcnew StreamWriter(s); <br />
&nbsp; sw-&gt;Write(textBox1-&gt;Text); <br />
&nbsp; sw-&gt;Close(); <br />
}</div></div>
<p>C&rsquo;est tout <img src="https://blog.developpez.com/nico-pyright/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" /></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[C++/CLI] Un addin reflector pour le C++/CLI</title>
		<link>https://blog.developpez.com/nico-pyright/p5337/ccli/c_cli_un_addin_reflector_pour_le_c_cli</link>
		<comments>https://blog.developpez.com/nico-pyright/p5337/ccli/c_cli_un_addin_reflector_pour_le_c_cli#comments</comments>
		<pubDate>Thu, 20 Mar 2008 20:00:00 +0000</pubDate>
		<dc:creator><![CDATA[nico-pyright(c)]]></dc:creator>
				<category><![CDATA[C++/CLI]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Je viens de tomber sur un addin de reflector qui permet d&#8217;avoir le code en C++/CLI. C&#8217;est encore en version Alpha, mais ca a l&#8217;air de plutot pas trop mal marcher. C&#8217;est ici que ca se passe : http://www.sandpapersoftware.com/Main/Reflector.html En tous cas, moi ca m&#8217;éclate]]></description>
				<content:encoded><![CDATA[<p>Je viens de tomber sur un addin de reflector qui permet d&rsquo;avoir le code en C++/CLI.</p>
<p>C&rsquo;est encore en version Alpha, mais ca a l&rsquo;air de plutot pas trop mal marcher.</p>
<p>C&rsquo;est ici que ca se passe : http://www.sandpapersoftware.com/Main/Reflector.html</p>
<p>En tous cas, moi ca m&rsquo;éclate <img src="https://blog.developpez.com/nico-pyright/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" /></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[C# et C++/CLI] Sérialisation et désérialisation binaire</title>
		<link>https://blog.developpez.com/nico-pyright/p5232/ccli/c_et_c_cli_serialisation_et_deserialisat</link>
		<comments>https://blog.developpez.com/nico-pyright/p5232/ccli/c_et_c_cli_serialisation_et_deserialisat#comments</comments>
		<pubDate>Thu, 06 Mar 2008 20:00:00 +0000</pubDate>
		<dc:creator><![CDATA[nico-pyright(c)]]></dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[C++/CLI]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Pour sérialiser et désérialiser en binaire, on va utiliser l&#8217;objet BinaryFormatter qui fait partie du namespace System.Runtime.Serialization.Formatters.Binary. Combiné à un MemoryStream pour que ca se fasse en mémoire, voilà en résultat deux méthodes génériques (une version C++/CLI et une version C#): Exemple en C++/CLI using namespace System; using namespace System::IO; using namespace System::Runtime::Serialization::Formatters::Binary; &#160; generic&#60;typename T&#62; String^ Serialize(T obj) { &#160; BinaryFormatter^ bf = gcnew BinaryFormatter(); &#160; MemoryStream^ ms = gcnew MemoryStream(); &#160; bf-&#62;Serialize(ms, obj); [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Pour sérialiser et désérialiser en binaire, on va utiliser l&rsquo;objet BinaryFormatter qui fait partie du namespace System.Runtime.Serialization.Formatters.Binary.</p>
<p>Combiné à un MemoryStream pour que ca se fasse en mémoire, voilà en résultat deux méthodes génériques (une version C++/CLI et une version C#):<br />
<span id="more-15"></span></p>
<p>Exemple en C++/CLI</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">using namespace System; <br />
using namespace System::IO; <br />
using namespace System::Runtime::Serialization::Formatters::Binary; <br />
&nbsp;<br />
generic&lt;typename T&gt; <br />
String^ Serialize(T obj) <br />
{ <br />
&nbsp; BinaryFormatter^ bf = gcnew BinaryFormatter(); <br />
&nbsp; MemoryStream^ ms = gcnew MemoryStream(); <br />
&nbsp; bf-&gt;Serialize(ms, obj); <br />
&nbsp; array&lt;unsigned char&gt;^ buff = ms-&gt;ToArray(); <br />
&nbsp; ms-&gt;Close(); <br />
&nbsp; return Convert::ToBase64String(buff); <br />
} <br />
&nbsp;<br />
generic&lt;typename T&gt; <br />
T DeSerialize(String ^val) <br />
{ <br />
&nbsp; array&lt;unsigned char&gt;^ buff = Convert::FromBase64String(val); <br />
&nbsp; BinaryFormatter ^bf = gcnew BinaryFormatter(); <br />
&nbsp; MemoryStream ^ms = gcnew MemoryStream(buff); <br />
&nbsp; T result = (T) bf-&gt;Deserialize(ms); <br />
&nbsp; ms-&gt;Close(); <br />
&nbsp; return result; <br />
} <br />
&nbsp;<br />
int main(array&lt;System::String ^&gt; ^args) <br />
{ <br />
&nbsp; array&lt;String ^&gt; ^ tabASerialiser = gcnew array&lt;String ^&gt; {&quot;abc&quot;, &quot;def&quot;, &quot;ghi&quot;}; <br />
&nbsp; array&lt;int&gt; ^ tab2ASerialiser = gcnew array&lt;int&gt; { 123, 456, 789 }; <br />
&nbsp;<br />
&nbsp; // serialisation <br />
&nbsp; String ^val = Serialize(tabASerialiser); <br />
&nbsp; String ^val2 = Serialize(tab2ASerialiser); <br />
&nbsp;<br />
&nbsp; // deserialisation <br />
&nbsp; array&lt;String ^&gt; ^ result = DeSerialize&lt;array&lt;String ^&gt; ^&gt;(val); <br />
&nbsp; array&lt;int&gt; ^ result2 = DeSerialize&lt;array&lt;int&gt; ^&gt;(val2); <br />
&nbsp;<br />
&nbsp; for (int i = 0 ; i &lt; result-&gt;Length ; i++) <br />
&nbsp; &nbsp; Console::WriteLine(result[i]); <br />
&nbsp; Console::WriteLine(); <br />
&nbsp; for (int i = 0; i &lt; result-&gt;Length; i++) <br />
&nbsp; &nbsp; Console::WriteLine(result2[i]); <br />
&nbsp; &nbsp; return 0; <br />
}</div></div>
<p>Exemple en C#</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">public static string Serialize&lt;T&gt;(T obj) <br />
{ <br />
&nbsp; &nbsp; BinaryFormatter bf = new BinaryFormatter(); <br />
&nbsp; &nbsp; MemoryStream ms = new MemoryStream(); <br />
&nbsp; &nbsp; bf.Serialize(ms, obj); <br />
&nbsp; &nbsp; byte[] buff = ms.ToArray(); <br />
&nbsp; &nbsp; ms.Close(); <br />
&nbsp; &nbsp; return Convert.ToBase64String(buff); <br />
} <br />
&nbsp;<br />
public static T DeSerialize&lt;T&gt;(string val) <br />
{ <br />
&nbsp; &nbsp; byte[] buff = Convert.FromBase64String(val); <br />
&nbsp; &nbsp; BinaryFormatter bf = new BinaryFormatter(); <br />
&nbsp; &nbsp; MemoryStream ms = new MemoryStream(buff); <br />
&nbsp; &nbsp; T result = (T) bf.Deserialize(ms); <br />
&nbsp; &nbsp; ms.Close(); <br />
&nbsp; &nbsp; return result; <br />
} <br />
&nbsp;<br />
static void Main() <br />
{ <br />
&nbsp; &nbsp; string[] tabASerialiser = new string[] {&quot;abc&quot;, &quot;def&quot;, &quot;ghi&quot;}; <br />
&nbsp; &nbsp; int[] tab2ASerialiser = new int[] { 123, 456, 789 }; <br />
&nbsp;<br />
&nbsp; &nbsp; // serialisation <br />
&nbsp; &nbsp; string val = Serialize(tabASerialiser); <br />
&nbsp; &nbsp; string val2 = Serialize(tab2ASerialiser); <br />
&nbsp;<br />
&nbsp; &nbsp; // deserialisation <br />
&nbsp; &nbsp; string[] result = DeSerialize&lt;string[]&gt;(val); <br />
&nbsp; &nbsp; int[] result2 = DeSerialize&lt;int[]&gt;(val2); <br />
&nbsp;<br />
&nbsp; &nbsp; for (int i = 0 ; i &lt; result.Length ; i++) <br />
&nbsp; &nbsp; &nbsp; &nbsp; Console.WriteLine(result[i]); <br />
&nbsp; &nbsp; Console.WriteLine(); <br />
&nbsp; &nbsp; for (int i = 0; i &lt; result.Length; i++) <br />
&nbsp; &nbsp; &nbsp; &nbsp; Console.WriteLine(result2[i]); <br />
}</div></div>
<p>NB : J&rsquo;utilise une conversion en base 64 car dans mon cas, j&rsquo;ai eu besoin de stocker l&rsquo;information sérialisée sous forme de chaine.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[C#] Une PictureBox qu&#8217;on peut déplacer et redimensionner à la souris</title>
		<link>https://blog.developpez.com/nico-pyright/p5104/c/c_une_picturebox_qu_on_peut_deplacer_et_</link>
		<comments>https://blog.developpez.com/nico-pyright/p5104/c/c_une_picturebox_qu_on_peut_deplacer_et_#comments</comments>
		<pubDate>Fri, 15 Feb 2008 20:00:00 +0000</pubDate>
		<dc:creator><![CDATA[nico-pyright(c)]]></dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[J&#8217;ai écrit vite fait cette petite classe qui surcharge la classe PictureBox pour les besoins d&#8217;un copain. Et puis, je me dis qu&#8217;il pourrait être bon d&#8217;en faire profiter tout le monde. Au menu, une surcharge de l&#8217;événement Paint et un dessin de rectangle (très moche, je sais ) et les surcharges des événements de click souris (down et up) et de son mouvement. class MaPictureBox : PictureBox { private bool isResizing; private bool isCandidateToResize; [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>J&rsquo;ai écrit vite fait cette petite classe qui surcharge la classe PictureBox pour les besoins d&rsquo;un copain. Et puis, je me dis qu&rsquo;il pourrait être bon d&rsquo;en faire profiter tout le monde.</p>
<p><span id="more-41"></span></p>
<p>Au menu, une surcharge de l&rsquo;événement Paint et un dessin de rectangle (très moche, je sais <img src="https://blog.developpez.com/nico-pyright/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" /> ) et les surcharges des événements de click souris (down et up) et de son mouvement.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">class MaPictureBox : PictureBox <br />
{ <br />
private bool isResizing; <br />
private bool isCandidateToResize; <br />
private Point positionClick; <br />
&nbsp;<br />
protected override void OnPaint(PaintEventArgs pe) <br />
{ <br />
&nbsp; &nbsp; base.OnPaint(pe); <br />
&nbsp; &nbsp; if (isResizing) <br />
&nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; pe.Graphics.DrawRectangle(new Pen(Color.Red), new Rectangle(0, 0, Width - 1, Height - 1)); <br />
&nbsp; &nbsp; } <br />
} <br />
&nbsp;<br />
protected override void OnMouseMove(MouseEventArgs e) <br />
{ <br />
&nbsp; &nbsp; if (isResizing) <br />
&nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; Width = e.X; <br />
&nbsp; &nbsp; &nbsp; &nbsp; Height = e.Y; <br />
&nbsp; &nbsp; &nbsp; &nbsp; SizeMode = PictureBoxSizeMode.StretchImage; <br />
&nbsp; &nbsp; } <br />
&nbsp; &nbsp; else <br />
&nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; if (e.X &gt;= Width - 4 &amp;&amp; e.Y &gt;= Height - 4) <br />
&nbsp; &nbsp; &nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Cursor = Cursors.SizeNWSE; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; isCandidateToResize = true; <br />
&nbsp; &nbsp; &nbsp; &nbsp; } <br />
&nbsp; &nbsp; &nbsp; &nbsp; else <br />
&nbsp; &nbsp; &nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; isCandidateToResize = false; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!isResizing) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (e.Button == MouseButtons.Left) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Location = new Point(Location.X + e.X - positionClick.X, Location.Y + e.Y - positionClick.Y); <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Cursor = Cursors.Arrow; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br />
&nbsp; &nbsp; &nbsp; &nbsp; } <br />
&nbsp; &nbsp; } <br />
&nbsp; &nbsp; Refresh(); <br />
&nbsp; &nbsp; base.OnMouseMove(e); <br />
} <br />
&nbsp;<br />
protected override void OnMouseDown(MouseEventArgs e) <br />
{ <br />
&nbsp; &nbsp; if (e.Button == MouseButtons.Left) <br />
&nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; if (isCandidateToResize) <br />
&nbsp; &nbsp; &nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; isResizing = true; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Refresh(); <br />
&nbsp; &nbsp; &nbsp; &nbsp; } <br />
&nbsp; &nbsp; &nbsp; &nbsp; else <br />
&nbsp; &nbsp; &nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; isResizing = false; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; positionClick = e.Location; <br />
&nbsp; &nbsp; &nbsp; &nbsp; } <br />
&nbsp; &nbsp; } <br />
&nbsp; &nbsp; base.OnMouseDown(e); <br />
} <br />
&nbsp;<br />
protected override void OnMouseUp(MouseEventArgs e) <br />
{ <br />
&nbsp; &nbsp; if (e.Button == MouseButtons.Left) <br />
&nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; isResizing = false; <br />
&nbsp; &nbsp; &nbsp; &nbsp; isCandidateToResize = false; <br />
&nbsp; &nbsp; &nbsp; &nbsp; Refresh(); <br />
&nbsp; &nbsp; } <br />
&nbsp; &nbsp; base.OnMouseUp(e); <br />
} <br />
}</div></div>
<p>C&rsquo;est pas du tout optimisé, mais bon, c&rsquo;est une première base.</p>
<p>Ca s&rsquo;utilise comme une picturebox bien sur :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">MaPictureBox pic = new MaPictureBox(); <br />
pic.Image = Image.FromFile(@&quot;C:\test.png&quot;); <br />
pic.Width = pic.Image.Width; <br />
pic.Height = pic.Image.Height; <br />
Controls.Add(pic);</div></div>
<p><a href="ftp://ftp-developpez.com/nico-pyright/blog/testResize.rar">Télécharger le programme de test </a></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[C++/CLI] Participez à l&#8217;augmentation de la bibliothèque marshal_as</title>
		<link>https://blog.developpez.com/nico-pyright/p5097/ccli/c_cli_participez_a_l_augmentation_de_la_</link>
		<comments>https://blog.developpez.com/nico-pyright/p5097/ccli/c_cli_participez_a_l_augmentation_de_la_#comments</comments>
		<pubDate>Thu, 14 Feb 2008 20:00:00 +0000</pubDate>
		<dc:creator><![CDATA[nico-pyright(c)]]></dc:creator>
				<category><![CDATA[C++ Interop]]></category>
		<category><![CDATA[C++/CLI]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Une nouveauté dans visual studio 2008 est l&#8217;utilisation du template marshal_as pour faire du marshaling. Incomplète encore à l&#8217;heure actuelle, retrouvez le blog dédié à son enrichissement à cette adresse : http://www.marshal-as.net/ Vous pouvez également envoyer vos contributions à Kate Gregory]]></description>
				<content:encoded><![CDATA[<p>Une nouveauté dans visual studio 2008 est l&rsquo;utilisation du template marshal_as pour faire du marshaling. </p>
<p>Incomplète encore à l&rsquo;heure actuelle, retrouvez le blog dédié à son enrichissement à cette adresse : http://www.marshal-as.net/<br />
Vous pouvez également envoyer vos contributions à Kate Gregory</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
