<?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>Andreas Awenius' blog &#187; .NET</title>
	<atom:link href="http://www.awenius.de/blog/category/net/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.awenius.de/blog</link>
	<description>Infos zu .NET und Modellierung</description>
	<lastBuildDate>Mon, 20 Jun 2011 21:15:20 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Interfaces in C#</title>
		<link>http://www.awenius.de/blog/2011/05/02/interfaces-in-c/</link>
		<comments>http://www.awenius.de/blog/2011/05/02/interfaces-in-c/#comments</comments>
		<pubDate>Mon, 02 May 2011 08:39:16 +0000</pubDate>
		<dc:creator>Andreas</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Softwareentwicklung]]></category>

		<guid isPermaLink="false">http://www.awenius.de/blog/?p=164</guid>
		<description><![CDATA[Hallo,
kürzlich habe ich zur Auffrischung meines C#-Wissens die neue Auflage von &#8220;Effective C#&#8220;  bestellt und begonnen, die einzelnen Items durchzuschauen. Das Item 23 &#8220;Understand How Interfaces differ from Virtual Methods&#8221; hat mich dann doch einigermaßen beeindruckt, gibt es doch einen Eindruck von der Fülle an Konzepten die zum Thema &#8220;Interfaces&#8221; in C# relevant sind. Beim [...]]]></description>
			<content:encoded><![CDATA[<p>Hallo,</p>
<p>kürzlich habe ich zur Auffrischung meines C#-Wissens die neue Auflage von &#8220;<a href="http://www.amazon.de/Effective-covers-4-0-Specific-Development/dp/0321658701/ref=sr_1_1?ie=UTF8&amp;qid=1303830103&amp;sr=8-1">Effective C#</a>&#8220;  bestellt und begonnen, die einzelnen Items durchzuschauen. Das Item 23 &#8220;Understand How Interfaces differ from Virtual Methods&#8221; hat mich dann doch einigermaßen beeindruckt, gibt es doch einen Eindruck von der Fülle an Konzepten die zum Thema &#8220;Interfaces&#8221; in C# relevant sind. Beim Versuch eine Webpage oder Blog-posting zu finden, in dem ein mehr oder weniger vollständiger Überblick über dieses Thema gegeben wird, habe ich aber nichts brauchbares gefunden. Die meisten Fundstellen waren Einführungen in das Thema Interfaces im allgemeinen und begnügten sich damit, das Konzept vorzustellen und zu motivieren.</p>
<p>In diesem Posting versuche ich einen eher Referenz-artigen aber hoffentlich vollständigen Überblick über die Eigenheiten und Möglichkeiten von Interfaces in C# zu geben. Das Konzept an sich und die übliche Verwendung werde ich nicht weiter Erläutern.</p>
<p><strong>Methoden in Interfaces sind per default nicht virtuell</strong></p>
<p>Per default sind Methoden in Interfaces nicht virtuell. D.h. wenn eine Objektreferenz den Typ des Interfaces hat, wird immer die Methode der obersten Klasse in der Vererbungshierarchie gerufen, die die Methode implementiert. Die erneute Implementierung einer Interfaces-Methode in einer abgeleiteten Klasse ist überhaupt nur unter Verwendung des Schlüsselwortes <em>new </em>möglich,  was bereits auf das beschriebene Verhalten hinweist.</p>
<p><strong>Interfaces können in verschiedenen Ebenen der Vererbungshierarchie implementiert werden</strong></p>
<p>Wenn man von einer vorhandenen Klasse ableitet und mit deren Implementierung eines Interfaces nicht zufrieden ist, besteht die Möglichkeit, das Interface in der abgeleiteten Klasse erneut zu implementieren. Dazu erklärt man auch in der abgeleiteten Klasse, dass man das Interface definiert. In diesem Fall wird bei Verwendung einer Objektreferenz vom Typ des Interfaces die &#8220;tiefstmögliche&#8221; (bezogen auf die Vererbungshierarchie) Implementierung gerufen.</p>
<p>Dieses Vorgehen ist aber auch nicht ganz unproblematisch:</p>
<ul>
<li>Die Verwendung des Schlüsselwortes <em>new</em> ist immer noch nötig</li>
<li>Es müssen alle Methoden des Interfaces implementiert werden, auch wenn man nur eine Teilmenge ersetzen will</li>
<li>Wenn man eine Referenz mit dem Typ einer direkten oder indirekten Superklasse zum Aufruf einer Methode verwendet, die Teil des Interfaces ist, wird die Implementierung des Klasse, die dem Typ der Referenz entspricht, gerufen. Dieses Verhalten ist bei virtuellen Methoden gerade nicht so.</li>
</ul>
<p><strong>Methoden in Interfaces können <em>abstract</em> definiert werden</strong></p>
<p>Wenn eine Klasse als <em>abstract</em> definiert ist, dürfen auch Methoden aus Interfaces (die in einer Klasse, die ein Interface implementiert, eigentlich auch implementiert sein müssen) als <em>abstract</em> definiert sein. In diesem Fall müssen diese Methoden in der Basisklasse nicht implementiert werden. Die abgeleiteten Klassen müssen die Methode dann implementieren. Damit könnte man z.B. in einer gemeinsamen Basisklasse sinnvolle Default-Implementierungen einer Teilmenge der Interface-Member implementieren während man von den abgeleiteten Klassen erwartet, dass sie die restlichen Member des Interfaces selbst implementieren.</p>
<p><strong>Methoden in Interfaces können virtuell sein</strong></p>
<p>Wie bei normalen Methoden (die kein Bestandteil eines Interfaces sind) kann eine Methode als <em>virtual </em>deklariert werden und verhält sich dann entsprechend. D.h. es wird immer die Implementierung in der tiefsten Ebene der Vererbungshierarchie gerufen, egal welchen Typ die Referenz hat, über die man die Methode aufruft.<br />
Dazu muss die Methode in der Interface-Definition nicht <em>virtual</em> sein.</p>
<p><strong>Es ist möglich, mehrere Interfaces zu implementieren, die die gleichen Member haben</strong></p>
<p>Grundsätzlich kann eine Klasse einen gegebenen Member nur einmal implementieren. Nun ist es nicht unrealistisch, dass man in einer Klasse mehrere Interfaces implementiert und die Gefahr identischer Member in zwei oder mehr Interfaces ist durchaus real. Dieses Problem lässt sich einfach lösen, indem vor jeder Implementierung eines Members der Interfaces-Name vorangestellt wird. Diese explizite Qualifizierung  muss dann auch beim Aufruf der Methode verwendet werden, sofern nicht eine Referenz vom Typ eines der Interfaces verwendet wird (sondern eine Referenz auf die konkrete Klasse).</p>
<p>Viele Grüße,<br />
Andreas</p>
<p>Technorati Tags: <a href="http://technorati.com/tag/C%23" rel="tag">C#</a>, <a href="http://technorati.com/tag/Interface" rel="tag">Interface</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.awenius.de/blog/2011/05/02/interfaces-in-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Neues Hilfesystem für Visual Studio 2010 mit Service Pack 1</title>
		<link>http://www.awenius.de/blog/2011/02/20/neues-hilfesystem-fur-visual-studio-2010-mit-service-pack-1/</link>
		<comments>http://www.awenius.de/blog/2011/02/20/neues-hilfesystem-fur-visual-studio-2010-mit-service-pack-1/#comments</comments>
		<pubDate>Sun, 20 Feb 2011 10:34:53 +0000</pubDate>
		<dc:creator>Andreas</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Softwareentwicklung]]></category>

		<guid isPermaLink="false">http://www.awenius.de/blog/?p=141</guid>
		<description><![CDATA[Hallo,
in einem früheren Posting habe ich mein Unverständnis ausgedrückt, dass Microsoft die Hilfe-Funktion in Visual Studio 2010 quasi abgeschafft hat. Auch in Zeiten des Internet und der Suchmaschinen ist eine gute Hilfe-Funktion wichtig.
Nachdem diese Klage ja sehr verbreitet  war, scheint Microsoft ein Einsehen zu haben, und bringt mit dem Service Pack (SP) 1 für Visual [...]]]></description>
			<content:encoded><![CDATA[<p>Hallo,</p>
<p>in einem <a href="http://www.awenius.de/blog/2010/06/20/visual-c-2010-kann-nur-fur-das-net-framework-4-0-code-erzeugen/">früheren Posting</a> habe ich mein Unverständnis ausgedrückt, dass Microsoft die Hilfe-Funktion in Visual Studio 2010 quasi abgeschafft hat. Auch in Zeiten des Internet und der Suchmaschinen ist eine gute Hilfe-Funktion wichtig.</p>
<p>Nachdem diese Klage ja sehr verbreitet  war, scheint Microsoft ein Einsehen zu haben, und <a href="http://thirdblogfromthesun.com/2010/10/the-story-of-help-in-visual-studio-2010-part-3/">bringt mit dem Service Pack (SP) 1 für Visual Studio 2010 wieder eine richtige Hilfe-Funktion</a>.<br />
Ich bin sicher, dass der lokale Help-Viewer eine Verbesserung gegenüber der aktuellen Situation darstellt.</p>
<p>An der fehlenden Intellisense-Funktion für managed C++/CLI (managed C++), die ja auch viele Benutzer vermissen, <a href="https://connect.microsoft.com/VisualStudio/feedback/details/626825/intellisense-not-working-with-vs2010-c-cli-projects">scheint sich nichts getan zu haben</a>. Microsoft scheint hier auch einen der Nachteile einer &#8216;buy&#8217;-Lösung zu erfahren: die fehlende Möglichkeit der individuellen Anpassung. Vermutlich lässt sich der hinzugekaufte Compiler der Edison Design Group, der ja <a href="http://blogs.msdn.com/b/vcblog/archive/2009/05/27/rebuilding-intellisense.aspx">in Visual Studio 2010 für die Bereitstellung der Intellisense-Fetaures in C++ verwendet wird</a>, nicht ohne weiteres so erweitern, dass er mit den Spracherweiterungen von C++/CLI vernünftig umgeht.</p>
<p>Auf der anderen Seite muss man sagen, dass der Intellisense-Support für Standard C++ in Visual Studio 2010 viel besser ist als in älteren Versionen von Visual Studio und die Produktivität spürbar steigert. Insbesondere, dass Fehler direkt beim Tippen angezeigt werden, ist eine große Hilfe (man könnte auch sagen, dass dieses Feature langsam überfällig war).</p>
<p>Viele Grüße,<br />
Andreas</p>
<p>Technorati Tags: <a href="http://technorati.com/tag/Visual+Studio+2010" rel="tag">Visual Studio 2010</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.awenius.de/blog/2011/02/20/neues-hilfesystem-fur-visual-studio-2010-mit-service-pack-1/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Einschränkungen beim Debuggen mit mixed moded Anwendungen im 64-Bit Modus</title>
		<link>http://www.awenius.de/blog/2010/06/27/einschrankungen-beim-debuggen-mit-mixed-moded-anwendungen-im-64-bit-modus/</link>
		<comments>http://www.awenius.de/blog/2010/06/27/einschrankungen-beim-debuggen-mit-mixed-moded-anwendungen-im-64-bit-modus/#comments</comments>
		<pubDate>Sun, 27 Jun 2010 19:57:04 +0000</pubDate>
		<dc:creator>Andreas</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Softwareentwicklung]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.awenius.de/blog/?p=103</guid>
		<description><![CDATA[Hallo,
kürzlich bekam ich vom Visual Studio 2010 Debugger beim Starten einer Anwendung folgende Fehlermeldung:
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;
Microsoft Visual Studio
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;
Fehler beim Ausführen des Projekts: Das Programm &#8220;&#8230;\unittest\bin\Debug\unittest.exe&#8221; kann nicht gestartet werden.
Das Debuggen im gemischten Modus für x64-Prozesse wird nur bei Verwendung von Microsoft .NET Framework vor Version 4 unterstützt.
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;
OK   Hilfe
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;
Die Konstellation war dabei folgende:

Ein reines C#-Programm referenziert eine Assembly, [...]]]></description>
			<content:encoded><![CDATA[<p>Hallo,</p>
<p>kürzlich bekam ich vom Visual Studio 2010 Debugger beim Starten einer Anwendung folgende Fehlermeldung:</p>
<blockquote><p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
Microsoft Visual Studio<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
Fehler beim Ausführen des Projekts: Das Programm &#8220;&#8230;\unittest\bin\Debug\unittest.exe&#8221; kann nicht gestartet werden.</p>
<p>Das Debuggen im gemischten Modus für x64-Prozesse wird nur bei Verwendung von Microsoft .NET Framework vor Version 4 unterstützt.<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
OK   Hilfe<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p></blockquote>
<p>Die Konstellation war dabei folgende:</p>
<ul>
<li>Ein reines C#-Programm referenziert eine Assembly, die mit managed C++ erstellt war. Diese Assembly bindet auch native code ein (mixed mode).</li>
<li>Als Compiler wurde der vc90 verwendet.</li>
<li>Als Targetversion für das .NET-Framework wurde für alle Komponenten 2.0 verwendet.</li>
<li>Alle Anwendungen waren als 32-Bit-Anwendungen in Visual Studio 2008 erstellt und wurden von Visual Studio 2010 zur Version 2010 konvertiert.</li>
</ul>
<p>Für die in C# erstellte (reine .NET) Anwendung war in den Einstellungen als Zielplattform &#8220;Any CPU&#8221; eingetragen, wie bereits in der Vorgängerversion:</p>
<p><img class="alignleft size-full wp-image-107" title="AnyCPU" src="http://www.awenius.de/blog/wp-content/uploads/2010/06/AnyCPU2.png" alt="AnyCPU" width="387" height="36" /></p>
<p style="text-align: left;">
<p style="text-align: left;">
<p style="text-align: left;">
<p style="text-align: left;">
<p style="text-align: left;">
<p style="text-align: left;">Nach der Umstellung auf X86 konnte die Anwendung erfolgreich im Debugger gestartet werden.</p>
<p><img class="alignleft size-full wp-image-105" title="X86" src="http://www.awenius.de/blog/wp-content/uploads/2010/06/X86.png" alt="X86" width="383" height="34" /></p>
<p>Die Fehlermeldung ist grundsätzlich ziemlich irreführend. Alle beteiligten Komponenten waren ja explizit für .NET 2.0 konfiguriert.</p>
<p>Oder ist sie gar falsch?</p>
<p>Auf <a href="http://msdn.microsoft.com/de-de/library/ms184681.aspx">dieser Seite</a> findet man folgendes Zitat:</p>
<blockquote><p><span id="xn29_db15abbc0f57576bc6cfd4a341858a19">Debugging  im gemischten Modus (Aufrufe von systemeigenem Code bis zu verwalteten  Codes, oder umgekehrt) wird für x64-Prozesse unterstützt, wenn der  verwaltete Code Microsoft .NET Framework, Version 4 oder höher,  verwendet.</span></p>
<p><span id="xn30_02695e6e38b9f206b8b6137aa93f0c7b">Debugging im gemischten Modus wird nicht für  IA64-Prozesse oder x64-Prozesse unterstützt, die frühere .NET  Framework-Versionen als 4 verwenden.</span></p></blockquote>
<p><span>was ja ein klarer Gegensatz zur oben zitieren Fehlermeldung ist.</span></p>
<p><span>Grundsätzlich ist es schon etwas unschön, wenn man für die reine .NET-Komponent nicht mehr &#8220;Any CPU&#8221; wählen kann, nur weil sie eine mixed mode Assembly nutzt, die im 32-Bit Modus erstellt wurde.</span></p>
<p><span>Eine Rolle könnte auch spielen, dass ich inzwischen Windows 7 x64 benutze, während ich zuvor Windows XP X86 verwendet habe.<br />
</span></p>
<p><span>Viele Grüße,<br />
Andreas<br />
</span></p>
<p><span><p>Technorati Tags: <a href="http://technorati.com/tag/Visual+Studio" rel="tag">Visual Studio</a>, <a href="http://technorati.com/tag/mixed+mode" rel="tag">mixed mode</a>, <a href="http://technorati.com/tag/debugging" rel="tag">debugging</a></p><br />
</span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.awenius.de/blog/2010/06/27/einschrankungen-beim-debuggen-mit-mixed-moded-anwendungen-im-64-bit-modus/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DoDragDrop und SelectedNode in WinForms TreeViews</title>
		<link>http://www.awenius.de/blog/2009/11/30/dodragdrop-und-selectednode-in-winforms-treeviews/</link>
		<comments>http://www.awenius.de/blog/2009/11/30/dodragdrop-und-selectednode-in-winforms-treeviews/#comments</comments>
		<pubDate>Mon, 30 Nov 2009 21:59:41 +0000</pubDate>
		<dc:creator>Andreas</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Softwareentwicklung]]></category>

		<guid isPermaLink="false">http://www.awenius.de/blog/?p=67</guid>
		<description><![CDATA[Hallo,
kürzlich fiel mir ein überraschender Effekt im Zusammenhang mit WinForms TreeViews und drag and drop auf. Fall man im MouseDown-Event eine DragDrop-Operation mit der Methode DoDragDrop() startet, wird der selektierte Knoten nicht auf den angeklickten Knoten gesetzt.
In folgendem Beispiel wurde der Knoten &#8220;BasicActivities&#8221; angeklickt und damit zum selected node. Anschließend wurde der Knoten ActivityFinalNode angeklickt. [...]]]></description>
			<content:encoded><![CDATA[<p>Hallo,</p>
<p>kürzlich fiel mir ein überraschender Effekt im Zusammenhang mit WinForms TreeViews und drag and drop auf. Fall man im MouseDown-Event eine DragDrop-Operation mit der Methode DoDragDrop() startet, wird der selektierte Knoten nicht auf den angeklickten Knoten gesetzt.</p>
<p>In folgendem Beispiel wurde der Knoten &#8220;BasicActivities&#8221; angeklickt und damit zum selected node. Anschließend wurde der Knoten ActivityFinalNode angeklickt. Der Focus-ähnliche Rahmen um den Knoten &#8220;BasicActivities&#8221; blieb aber erhalten:</p>
<p><img src="http://www.awenius.de/blog/wp-content/uploads/2009/11/SelektierterKnotenFalsch.png" alt="SelektierterKnotenFalsch" title="SelektierterKnotenFalsch" width="314" height="208" class="aligncenter size-full wp-image-68" /></p>
<p>Das hat zur Konsequenz, dass der zuvor selektierte Knoten &#8220;BasicActivities&#8221; nach einer anschließenden Mousebewegung <strong>ohne click</strong> wieder selektiert wird. </p>
<p>Dieses Verhalten tritt nicht auf, wenn der Aufruf der Methode DoDragDrop() unterbleibt.</p>
<p>Wenn man den Knoten im MouseDown-Event explizit selektiert (wie <a href="http://www.syncfusion.com/FAQ/windowsforms/faq_c91c.aspx#q807q">hier</a> beschrieben), tritt dieser Effekt nicht auf und das TreeView verhält sich wie gewohnt.</p>
<pre lang="C#" line="1">
theTreeView.SelectedNode = nodeAt;
DoDragDrop(nodeAt.TheClass, DragDropEffects.Copy);
</pre>
<p>Viele Grüße,<br />
Andreas<br /><p>Technorati Tags: <a href="http://technorati.com/tag/WinForms" rel="tag">WinForms</a>, <a href="http://technorati.com/tag/Drag+and+Drop" rel="tag">Drag and Drop</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.awenius.de/blog/2009/11/30/dodragdrop-und-selectednode-in-winforms-treeviews/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wie kann man native Methoden in managed C++ Klassen nutzen?</title>
		<link>http://www.awenius.de/blog/2009/10/04/wie-kann-man-native-methoden-in-managed-c-klassen-nutzen/</link>
		<comments>http://www.awenius.de/blog/2009/10/04/wie-kann-man-native-methoden-in-managed-c-klassen-nutzen/#comments</comments>
		<pubDate>Sun, 04 Oct 2009 19:17:04 +0000</pubDate>
		<dc:creator>Andreas</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://www.awenius.de/blog/?p=66</guid>
		<description><![CDATA[Hallo,
Microsoft hat mit der Einführung des .NET-Frameworks auch C++-Erweiterungen (C++/CLI) definiert, mit denen vorhandener C++ source code für .NET-Anwendungen verfügbar gemacht werden kann.
Die Intention dabei war die Steigerung der Akzeptanz des .NET-Frameworks, da es relativ einfach gemacht wird, bereits vorhandenen C++ code in .NET-Anwendungen zu integrieren. Meiner persönlichen Erfahrung nach geht das sehr gut, d.h. [...]]]></description>
			<content:encoded><![CDATA[<p>Hallo,</p>
<p>Microsoft hat mit der Einführung des <a href="http://de.wikipedia.org/wiki/.NET">.NET</a>-Frameworks auch C++-Erweiterungen (<a href="http://de.wikipedia.org/wiki/C%2B%2B/CLI">C++/CLI</a>) definiert, mit denen vorhandener C++ source code für .NET-Anwendungen verfügbar gemacht werden kann.</p>
<p>Die Intention dabei war die Steigerung der Akzeptanz des .NET-Frameworks, da es relativ einfach gemacht wird, bereits vorhandenen C++ code in .NET-Anwendungen zu integrieren. Meiner persönlichen Erfahrung nach geht das sehr gut, d.h. es ist ziemlich einfach vorhanden C++ code mit C++/CLI .NET-tauglich zu machen und die entstandenen <a href="http://de.wikipedia.org/wiki/.NET#Assemblys">Assemblys</a> haben keine nennenswerten Einschränkungen (abgesehen davon, dass sie nur für die Plattform geeignet sind, für die der native code kompiliert wurde).</p>
<p>Der übliche Weg besteht darin eine neue Assembly zu erstellen, die C++/CLI Klassen (und ggf. native Klassen) enthält. Diese Klassen rufen dann den eigentlichen legacy code, typischerweise in bereits vorhandenen Libraries/DLLs.</p>
<p>Folgende Frage stellt sich bei der Erstellung eines Managed C++ Wrappers um vorhanden C++ code schnell:</p>
<p>Wie kann ich innerhalb des .NET-Wrappers native Datenstrukturen zwischen managed Klassen austauschen?</p>
<p>Dies ist grundsätzlich nicht ohne weiteres möglich, da in der öffentlichen Schnittstelle nur CLR-kompatible Datentypen verwendet werden dürfen (ansonsten könnten nicht alle Elemente der Schnittstelle von anderen .NET kompatiblen Komponenten konsumiert werden).</p>
<p>Es ist allerdings möglich, private Methoden zu definieren, die nicht CLR-konforme Datentypen konsumieren oder zurückgeben dürfen. Damit solche Methoden von anderen Klassen in der C++/CLI Wrapper-Assembly gerufen werden dürfen, müsste man alle diese Klassen als <code>friend</code> definieren, was eine etwas unbefriedigende Lösung ist.</p>
<p>Diese Überlegung führt aber zur optimalen Lösung: die Deklaration der entsprechenden Methoden als <code>public private</code>.<code> public private</code> ist in C++/CLI die Entsprechung zu <code>internal</code> in C# und bedeutet &#8220;sichtbar innerhalb der Assembly&#8221;.<br />
Da die entsprechenden Methoden nur von den C++-Klassen innerhalb der Wrapper-Assembly gerufen werden, gibt es keinen Grund sie zu verbieten (was der Compiler dann auch nicht macht).</p>
<p>Viele Grüße,<br />
Andreas</p>
<p>Technorati Tags: <a href="http://technorati.com/tag/.NET" rel="tag">.NET</a>, <a href="http://technorati.com/tag/Managed+C%2B%2B" rel="tag">Managed C++</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.awenius.de/blog/2009/10/04/wie-kann-man-native-methoden-in-managed-c-klassen-nutzen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Prüfen auf Schreibrechte für eine Datei in C#</title>
		<link>http://www.awenius.de/blog/2009/02/28/prufen-auf-schreibrechte-fur-eine-datei-in-c/</link>
		<comments>http://www.awenius.de/blog/2009/02/28/prufen-auf-schreibrechte-fur-eine-datei-in-c/#comments</comments>
		<pubDate>Sat, 28 Feb 2009 10:15:35 +0000</pubDate>
		<dc:creator>Andreas</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Softwareentwicklung]]></category>

		<guid isPermaLink="false">http://www.awenius.de/blog/?p=61</guid>
		<description><![CDATA[Hallo,
manchmal möchte man wissen, ob ein bestimmter Benutzer bestimmte Rechte (z.B. Schreibrechte) für eine bestimmte Datei besitzt. Wie sich herausstellt, ist diese Anforderung alles andere als leicht umzusetzen, weil dabei viele verschiedene Aspekte eine Rolle spielen. Die Vorgehensweise sieht prinzipiell so aus:

Abfragen der Access Control Listen für die Datei
Itererieren über alle Einträge und prüfen ob [...]]]></description>
			<content:encoded><![CDATA[<p>Hallo,</p>
<p>manchmal möchte man wissen, ob ein bestimmter Benutzer bestimmte Rechte (z.B. Schreibrechte) für eine bestimmte Datei besitzt. Wie sich <a href="http://discuss.joelonsoftware.com/default.asp?dotnet.12.589499.7">herausstellt</a>, ist diese Anforderung alles andere als leicht umzusetzen, weil dabei viele verschiedene Aspekte eine Rolle spielen. Die Vorgehensweise sieht prinzipiell so aus:</p>
<ul>
<li>Abfragen der Access Control Listen für die Datei</li>
<li>Itererieren über alle Einträge und prüfen ob man für die Kennung oder die Gruppe des gewünschten Benutzers Einträge findet</li>
<li>Dabei die Präzedenz der Einträge beachten (explizite kommen vor vererbten Regeln, &#8220;Deny&#8221;-Regeln kommen for &#8220;Allow&#8221;-Regeln)</li>
</ul>
<p>Den nicht unerheblichen Code hat dankenswerterweise <a href="http://purinvesting.com/principal_hatt.htm">Bruce Hatt</a> in einem <a href="http://www.codeproject.com/KB/files/UserFileAccessRights.aspx">Artikel auf CodeProject.com</a> veröffentlicht.</p>
<p>Man sollte bedenken, dass die Möglichkeit in eine Datei zu schreiben zusätzlich durch das &#8220;ReadOnly-flag&#8221; und die .NET Code Access Security eingeschränkt sein könnte. Beides wird in dieser Klasse nicht berücksichtigt.</p>
<p>Die Prüfung auf das ReadOnly-flag könnte man so schreiben:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp">FileAttributes attrs <span style="color: #008000;">=</span> File.<span style="color: #0000FF;">GetAttributes</span><span style="color: #000000;">&#40;</span>fileName<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
<span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span>attrs <span style="color: #008000;">&amp;</span>amp<span style="color: #008000;">;</span> FileAttributes.<span style="color: #0600FF;">ReadOnly</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">!=</span> <span style="color: #FF0000;">0</span><span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
    <span style="color: #0600FF;">readOnly</span> <span style="color: #008000;">=</span> true<span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>Und für die Prüfung im Rahmen der CAS könnte man folgenden Code verwenden:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp">FileIOPermission fp <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> FileIOPermission<span style="color: #000000;">&#40;</span>FileIOPermissionAccess.<span style="color: #0000FF;">Write</span>, fileName<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #0600FF;">try</span>
<span style="color: #000000;">&#123;</span>
    fp.<span style="color: #0000FF;">Demand</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span>
&nbsp;
<span style="color: #0600FF;">catch</span> <span style="color: #000000;">&#40;</span>SecurityException<span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
    <span style="color: #0600FF;">readOnly</span> <span style="color: #008000;">=</span> true<span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>Wenn es nur um die Prüfung auf Schreibrechte geht, hört man oft den Vorschlag, einfach den Schreibvorgang auszuführen und ggf. die geworfene Exception zu fangen. Dieser Vorschlag ist aber nicht immer geeignet. In meinem Fall war es so, dass ich an einer Anwendung arbeite, in der Dateien editiert werden können. Falls Dateien nicht geschrieben werden können, soll dies visualisiert werden. Man möchte aber vermeiden, dazu bei jedem Start der Anwendung die zu editierenden Texte zu speichern, da damit der Timestamp verändert wäre, obwohl der Benutzer die Datei gar nicht geändert hat und auch nicht speichern wollte.</p>
<p>Viele Grüße,<br />
Andreas</p>
<p>Technorati Tags: <a href="http://technorati.com/tag/.NET+Security" rel="tag">.NET Security</a>, <a href="http://technorati.com/tag/File+Permissions" rel="tag"> File Permissions</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.awenius.de/blog/2009/02/28/prufen-auf-schreibrechte-fur-eine-datei-in-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>.NET Assembly-Ladevorgang loggen</title>
		<link>http://www.awenius.de/blog/2009/01/26/net-assembly-ladevorgang-loggen/</link>
		<comments>http://www.awenius.de/blog/2009/01/26/net-assembly-ladevorgang-loggen/#comments</comments>
		<pubDate>Mon, 26 Jan 2009 20:41:05 +0000</pubDate>
		<dc:creator>Andreas</dc:creator>
				<category><![CDATA[.NET]]></category>

		<guid isPermaLink="false">http://www.awenius.de/blog/?p=59</guid>
		<description><![CDATA[Hallo,
kürzlich hatte ich folgende Situation:
In einer C#-Solution wurde eine in Managed C++ erstellte .NET Assembly referenziert. Sobald die C#-Anwendung eine Klasse aus der referenzierten Library benutzen wollte, gab es eine Exception der Form:

System.IO.FileNotFoundException: Die Datei oder Assembly "etocl, Version=1.0.3306.20332, Culture=de, PublicKeyToken=null" oder eine Abhängigkeit davon wurde nicht gefunden. Das System kann die angegebene Datei nicht [...]]]></description>
			<content:encoded><![CDATA[<p>Hallo,</p>
<p>kürzlich hatte ich folgende Situation:</p>
<p>In einer C#-Solution wurde eine in Managed C++ erstellte .NET Assembly referenziert. Sobald die C#-Anwendung eine Klasse aus der referenzierten Library benutzen wollte, gab es eine Exception der Form:</p>
<p><code><br />
System.IO.FileNotFoundException: Die Datei oder Assembly "etocl, Version=1.0.3306.20332, Culture=de, PublicKeyToken=null" oder eine Abhängigkeit davon wurde nicht gefunden. Das System kann die angegebene Datei nicht finden.<br />
Dateiname: "etocl, Version=1.0.3306.20332, Culture=de, PublicKeyToken=null"<br />
</code></p>
<p>Die referenzierte Assembly fand sich aber wie es sein sollte im Arbeitsverzeichnis des C#-Programms. Um ein Protokoll des Ladevorgangs zu bekommen kann man nun folgenden Registry-Eintrag anlegen:</p>
<p><code><br />
[HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) = 1<br />
</code></p>
<p>Danach enthält die Fehlermeldung eine Aufstellung der Pfade, die der Loader durchsucht hat:</p>
<p><code><br />
LOG: Download von neuem URL file:///K:/Develop/et/etroot/src/apps/etoclide/bin/Debug/de/etocl.DLL.<br />
LOG: Download von neuem URL file:///K:/Develop/et/etroot/src/apps/etoclide/bin/Debug/de/etocl/etocl.DLL.<br />
LOG: Download von neuem URL file:///K:/Develop/et/etroot/src/apps/etoclide/bin/Debug/de/etocl.EXE.<br />
LOG: Download von neuem URL file:///K:/Develop/et/etroot/src/apps/etoclide/bin/Debug/de/etocl/etocl.EXE.<br />
</code></p>
<p>und das Problem wird schnell sichtbar: der loader sucht im Unterverzeichnis &#8220;de&#8221;. Mit diesem Hinweis ausgerüstet sieht man schnell, dass das AssemblyInfo.cpp-file der referenzierten Library einen expliziten Eintrag für das locale enthielt:</p>
<p><code><br />
[assembly:AssemblyCultureAttribute("de")]<br />
</code></p>
<p>Nach Entfernung dieses Eintrags und erneuter Erstellung der library  funktionierte dann auch alles wieder.</p>
<p>Fairerweise muss ich sagen, dass bereits die ursprüngliche Meldung einen Hinweis auf das Problem enthielt, allerdings nicht so deutlich:</p>
<p><code><br />
System.IO.FileNotFoundException: Die Datei oder Assembly "etocl, Version=1.0.3306.20332, Culture=<strong>de</strong>, PublicKeyToken=null" oder eine Abhängigkeit davon wurde nicht gefunden. Das System kann die angegebene Datei nicht finden.<br />
Dateiname: "etocl, Version=1.0.3306.20332, <strong>Culture=de</strong>, PublicKeyToken=null"<br />
</code></p>
<p>Microsoft empfiehlt, den Registry-Eintrag wieder zu löschen da er zu einer Performance-Einbusse führen könnte.</p>
<p>Viele Grüße,<br />
Andreas</p>
<p>Technorati Tags: <a href="http://technorati.com/tag/.NET" rel="tag">.NET</a>, <a href="http://technorati.com/tag/Assembly+loading" rel="tag">Assembly loading</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.awenius.de/blog/2009/01/26/net-assembly-ladevorgang-loggen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ClickOnce-Installation und der Fehler &#8220;Datei&#8230;wurde seit ihrer ersten Veröffentlichung geändert&#8221; Fehler</title>
		<link>http://www.awenius.de/blog/2008/10/20/clickonce-installation-und-der-fehler-dateiwurde-seit-ihrer-ersten-veroffentlichung-geandert-fehler/</link>
		<comments>http://www.awenius.de/blog/2008/10/20/clickonce-installation-und-der-fehler-dateiwurde-seit-ihrer-ersten-veroffentlichung-geandert-fehler/#comments</comments>
		<pubDate>Mon, 20 Oct 2008 07:45:21 +0000</pubDate>
		<dc:creator>Andreas</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Microsoft Office Programmierung]]></category>

		<guid isPermaLink="false">http://www.awenius.de/blog/?p=48</guid>
		<description><![CDATA[Hallo,
bei einer ClickOnce-Installation einer Microsoft .NET Software kann bei der Erstellung des setup-Programmes in Visual Studio eine Option gewählt werden, die bewirkt dass vorausgesetzte Software (&#8221;redistributable prerequisites&#8221; &#8211; wie etwas das .NET framework selbst) automatisch als Teil der Installation geladen und installiert werden.
Dabei kann angegeben werden, ob die Komponenten von der Website des Hersteller oder [...]]]></description>
			<content:encoded><![CDATA[<p>Hallo,</p>
<p>bei einer ClickOnce-Installation einer Microsoft .NET Software kann bei der Erstellung des setup-Programmes in Visual Studio eine Option gewählt werden, die bewirkt dass vorausgesetzte Software (&#8221;redistributable prerequisites&#8221; &#8211; wie etwas das .NET framework selbst) automatisch als Teil der Installation geladen und installiert werden.</p>
<p>Dabei kann angegeben werden, ob die Komponenten von der Website des Hersteller oder von einer anderen Quelle geladen werden sollen.</p>
<p><a href="http://www.awenius.de/blog/wp-content/uploads/2008/09/erforderlichekomponenten.png"><img class="aligncenter size-medium wp-image-49" title="Erforderliche Komponenten für ClickOnce Installation Dialog in Visual Studio" src="http://www.awenius.de/blog/wp-content/uploads/2008/09/erforderlichekomponenten-300x245.png" alt="Erforderliche Komponenten für ClickOnce Installation Dialog in Visual Studio" width="300" height="245" /></a></p>
<p>Im ersteren Fall kann folgendes Fehlerszenario entstehen:</p>
<p>Der Entwickler hat eines der vorausgesetzten Softwarepakete (z.B. das deutsche language pack vstor_lp_de_30.exe für die VSTO 3.0 runtime) lokal installiert. Beim Erstellen des setup-Programmes wird dieses Paket nicht integriert, wohl aber Information über die verwendete Version.</p>
<p>Nun wird die Installation auf einem beliebigen anderen Rechner gestartet. Der installer sieht dass auf der Website des Komponentenherstellers (also Microsoft für obiges Beispiel) eine andere Version der Komponente verfügbar ist. Genau dann wird diese Fehlermeldung generiert:</p>
<p><strong>Error: Die Datei &#8220;C:\DOKUME~1\awa\LOKALE~1\Temp\VSD6.tmp\VSTOR30\vstor_lp_de_30.exe&#8221; wurde seit ihrer ersten Veröffentlichung geändert.</strong></p>
<p>Die lokal auf dem Entwicklungsrechner mit Visual Studio 2008 SP1 installierte Version war vom 27.12.2007 während die Version auf der Microsoft Website vom 12.08.2008 war.</p>
<p>Dieses Verhalten ist ziemlich problematisch, kann doch ein update auf der Website des Komponentenherstellers grundsätzlich zu einem beliebigen Zeitpunkt erfolgen. Danach müssten alle ClickOnce-setups, die die aktualisierte Komponente benötigen, aktualisiert werden.</p>
<p>Es wäre sinnvoll, zumindest kleinere Abhängigkeiten direkt in das setup zu integrieren. Leider kann das Verhalten nicht für einzelne Abhängigkeiten individuell eingestellt werden, so dass in diesem Fall auch die .NET runtime in das setup integriert werden müsste, was nicht wirklich attraktiv ist.</p>
<p>Falls prerequisites ausgeschlossen werden bricht die Installation ohne konkrete Fehlermeldung ab, wenn die prerquisites nicht vorhanden sind bzw. nicht in der richtigen Version vorhanden sind.</p>
<p>Insgesamt würde ich empfehlen ausser den .NET runtimes alle erforderlichen prerequistes dem setup mit der Option &#8220;Erforderliche Komponenten vom demselben Speicherort wie die Anwendung herunterladen&#8221; hinzuzufügen. Die Installationsanleitung muss dann einen deutlichen Hinweis auf die erforderliche .NET runtime bzw. weitere nicht eingeschlossene prerequistes beinhalten.</p>
<p>Vielen Dank an <a href="http://joewirtley.blogspot.com/">Joe Wirtley</a> für den <a href="http://joewirtley.blogspot.com/2007/07/clickonce-and-reportviewer.html">Hinweis</a> auf die root cause.</p>
<p>Viele Grüße,<br />
Andreas</p>
<p>Technorati Tags: <a href="http://technorati.com/tag/ClickOnce" rel="tag">ClickOnce</a>, <a href="http://technorati.com/tag/.NET" rel="tag">.NET</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.awenius.de/blog/2008/10/20/clickonce-installation-und-der-fehler-dateiwurde-seit-ihrer-ersten-veroffentlichung-geandert-fehler/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Erstellung eines AddIns für Word 2007 &#8211; Teil 5 (Finden der OCL-Fragmente)</title>
		<link>http://www.awenius.de/blog/2008/09/27/erstellung-eines-addins-fur-word-2007-teil-5-finden-der-ocl-fragmente/</link>
		<comments>http://www.awenius.de/blog/2008/09/27/erstellung-eines-addins-fur-word-2007-teil-5-finden-der-ocl-fragmente/#comments</comments>
		<pubDate>Sat, 27 Sep 2008 16:24:59 +0000</pubDate>
		<dc:creator>Andreas</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Microsoft Office Programmierung]]></category>

		<guid isPermaLink="false">http://www.awenius.de/blog/?p=19</guid>
		<description><![CDATA[Hallo,
wie erwartet war dieser Teil einfach zu lösen, da es im Internet genügend Beispiele gibt, wie man mit dem Word-Objektmodell arbeitet. Die OCL-Fragmente werden anhand ihrer Vorlage identifiziert. Die Vorlage muss &#8220;OCL&#8221; heißen, kann ansonsten aber beliebig gestaltet werden. Die Verwendung eines fonst mit fester Zeichenbreite (&#8221;fixed width&#8221;) empfiehlt sich.
Ein wenig mehr Zeit als nötig [...]]]></description>
			<content:encoded><![CDATA[<p>Hallo,</p>
<p>wie erwartet war dieser Teil einfach zu lösen, da es im Internet genügend Beispiele gibt, wie man mit dem Word-Objektmodell arbeitet. Die OCL-Fragmente werden anhand ihrer Vorlage identifiziert. Die Vorlage muss &#8220;OCL&#8221; heißen, kann ansonsten aber beliebig gestaltet werden. Die Verwendung eines fonst mit fester Zeichenbreite (&#8221;fixed width&#8221;) empfiehlt sich.</p>
<p>Ein wenig mehr Zeit als nötig habe ich benötigt, weil mir anfangs nicht klar war, dass der englische Begriff für &#8220;Formatvorlage&#8221; &#8220;Style&#8221; ist und nicht &#8220;Format&#8221;.</p>
<p>Bei der Umsetzung  merkt man, dass die Kompatibilität zu Visual Basic for Applications (VBA) kein Designziel für C# war. Ein komfortabler Umgang mit den Office-Objektmodellen setzt einige features voraus, die Visual Basic.NET hat, C# <a href="http://www.mycsharp.de/wbb2/thread.php?postid=134936#post134936">aber nicht</a> (z.B. default parameter). Deshalb sollte man grössere Anbindungen von Office-Objektmodellen in eigenen Visual Basic.NET assemblies erstellen. Für unser kleines Word-AddIn spielt das aber keine Rolle, da wir nur minimal auf die Word-Objekte zugreifen.</p>
<p>Um die OCL-Fragement zu finden, wird das Word &#8220;Find&#8221;-Objekt benutzt:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp">IList<span style="color: #008000;">&lt;</span>TextFragment<span style="color: #008000;">&gt;</span> FindFragmentsByStyle<span style="color: #000000;">&#40;</span>Word.<span style="color: #0000FF;">Document</span> doc, <span style="color: #FF0000;">Object</span> styleName<span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
            List<span style="color: #008000;">&lt;</span>TextFragment<span style="color: #008000;">&gt;</span> result <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> List<span style="color: #008000;">&lt;</span>TextFragment<span style="color: #008000;">&gt;</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
            <span style="color: #FF0000;">Object</span> start <span style="color: #008000;">=</span> <span style="color: #FF0000;">0</span><span style="color: #008000;">;</span>
            <span style="color: #FF0000;">Object</span> end <span style="color: #008000;">=</span> doc.<span style="color: #0000FF;">Characters</span>.<span style="color: #0000FF;">Count</span><span style="color: #008000;">;</span>
            Word.<span style="color: #0000FF;">Range</span> range <span style="color: #008000;">=</span> doc.<span style="color: #0000FF;">Range</span><span style="color: #000000;">&#40;</span><span style="color: #0600FF;">ref</span> start, <span style="color: #0600FF;">ref</span> end<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
            Word.<span style="color: #0000FF;">Find</span> find <span style="color: #008000;">=</span> range.<span style="color: #0000FF;">Find</span><span style="color: #008000;">;</span>
&nbsp;
            <span style="color: #FF0000;">Object</span> style <span style="color: #008000;">=</span> null<span style="color: #008000;">;</span>
&nbsp;
            <span style="color: #0600FF;">try</span>
            <span style="color: #000000;">&#123;</span>
                style <span style="color: #008000;">=</span> doc.<span style="color: #0000FF;">Styles</span>.<span style="color: #0000FF;">get_Item</span><span style="color: #000000;">&#40;</span><span style="color: #0600FF;">ref</span> styleName<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #000000;">&#125;</span>
&nbsp;
            <span style="color: #0600FF;">catch</span> <span style="color: #000000;">&#40;</span>Exception<span style="color: #000000;">&#41;</span>
            <span style="color: #000000;">&#123;</span>
                <span style="color: #008080; font-style: italic;">/*
                 * Style not found.
                 */</span>
                <span style="color: #0600FF;">return</span> <span style="color: #000000;">&#40;</span>result<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #000000;">&#125;</span>
&nbsp;
            find.<span style="color: #0000FF;">set_Style</span><span style="color: #000000;">&#40;</span><span style="color: #0600FF;">ref</span> style<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
            ExecuteFind<span style="color: #000000;">&#40;</span>find<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #0600FF;">while</span> <span style="color: #000000;">&#40;</span>find.<span style="color: #0000FF;">Found</span><span style="color: #000000;">&#41;</span>
            <span style="color: #000000;">&#123;</span>
                <span style="color: #FF0000;">string</span> text <span style="color: #008000;">=</span> range.<span style="color: #0000FF;">Text</span><span style="color: #008000;">;</span>
                <span style="color: #FF0000;">int</span> linenum <span style="color: #008000;">=</span> GetRelativeLineNum<span style="color: #000000;">&#40;</span>doc, range<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
                <span style="color: #FF0000;">int</span> pagenum <span style="color: #008000;">=</span>     <span style="color: #000000;">&#40;</span><span style="color: #FF0000;">int</span><span style="color: #000000;">&#41;</span>range.<span style="color: #0000FF;">get_Information</span><span style="color: #000000;">&#40;</span>Microsoft.<span style="color: #0000FF;">Office</span>.<span style="color: #0000FF;">Interop</span>.<span style="color: #0000FF;">Word</span>.<span style="color: #0000FF;">WdInformation</span>.<span style="color: #0000FF;">wdActiveEndPageNumber</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
                result.<span style="color: #0000FF;">Add</span><span style="color: #000000;">&#40;</span><span style="color: #008000;">new</span> TextFragment<span style="color: #000000;">&#40;</span>text, linenum, pagenum<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
                ExecuteFind<span style="color: #000000;">&#40;</span>find<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #000000;">&#125;</span>
&nbsp;
            <span style="color: #0600FF;">return</span> <span style="color: #000000;">&#40;</span>result<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>Die Methode ExecuteFind() enthält einige low level Details beim Suchen nach dem nächsten Treffer:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp"><span style="color: #0600FF;">private</span> <span style="color: #FF0000;">bool</span> ExecuteFind<span style="color: #000000;">&#40;</span>Word.<span style="color: #0000FF;">Find</span> find, <span style="color: #FF0000;">Object</span> wrapFind, <span style="color: #FF0000;">Object</span> forwardFind<span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
            <span style="color: #008080; font-style: italic;">// Simple wrapper around Find.Execute:</span>
            <span style="color: #FF0000;">Object</span> forward <span style="color: #008000;">=</span> forwardFind<span style="color: #008000;">;</span>
            <span style="color: #FF0000;">Object</span> wrap <span style="color: #008000;">=</span> wrapFind<span style="color: #008000;">;</span>
&nbsp;
            <span style="color: #0600FF;">return</span> find.<span style="color: #0000FF;">Execute</span><span style="color: #000000;">&#40;</span><span style="color: #0600FF;">ref</span> missing, <span style="color: #0600FF;">ref</span> missing, <span style="color: #0600FF;">ref</span> missing,
              <span style="color: #0600FF;">ref</span> missing, <span style="color: #0600FF;">ref</span> missing, <span style="color: #0600FF;">ref</span> missing,
              <span style="color: #0600FF;">ref</span> forward, <span style="color: #0600FF;">ref</span> wrap, <span style="color: #0600FF;">ref</span> missing, <span style="color: #0600FF;">ref</span> missing, <span style="color: #0600FF;">ref</span> missing,
              <span style="color: #0600FF;">ref</span> missing, <span style="color: #0600FF;">ref</span> missing, <span style="color: #0600FF;">ref</span> missing,
              <span style="color: #0600FF;">ref</span> missing<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>Als Ergebnis gibt die Methode FindFragmentsByStyle() eine Liste von Objekten der (selbst erstellen) Klasse TextFragment zurück. Diese Klasse speichert den eigentlichen Text und Informationen zur Position des Textes im Dokument (Seiten- und Zeilennummer).</p>
<p>Viele Grüße,<br />
Andreas</p>
<p>Technorati Tags: <a href="http://technorati.com/tag/Word.Find" rel="tag">Word.Find</a>, <a href="http://technorati.com/tag/Office+Programmierung" rel="tag">Office Programmierung</a>, <a href="http://technorati.com/tag/.NET" rel="tag">.NET</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.awenius.de/blog/2008/09/27/erstellung-eines-addins-fur-word-2007-teil-5-finden-der-ocl-fragmente/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Nette Silverlight Demo</title>
		<link>http://www.awenius.de/blog/2008/09/04/nette-silverlight-demo/</link>
		<comments>http://www.awenius.de/blog/2008/09/04/nette-silverlight-demo/#comments</comments>
		<pubDate>Thu, 04 Sep 2008 07:35:31 +0000</pubDate>
		<dc:creator>Andreas</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Softwareentwicklung]]></category>

		<guid isPermaLink="false">http://www.awenius.de/blog/?p=45</guid>
		<description><![CDATA[Hallo,
Microsofts Silverlight stellt eine Plattform dar, mit der man &#8220;Rich Internet Applications&#8221; (RIAs) mit Schwerpunkt auf grafische Darstellung erstellen kann.
Wer sich für Silverlight interessiert findet unter http://foidoschess.tv/ eine nette Demonstration der Möglichkeiten von Silverlight. Dummerweise ist eine Registrierung erforderlich, ich habe hierfür eine Email-Adresse @mailinator.com verwendet.
Ausserdem muss man noch die Silverlight Runtime installieren, was aber [...]]]></description>
			<content:encoded><![CDATA[<p>Hallo,</p>
<p>Microsofts <a href="http://de.wikipedia.org/wiki/Silverlight">Silverlight</a> stellt eine Plattform dar, mit der man &#8220;Rich Internet Applications&#8221; (<a href="http://de.wikipedia.org/wiki/Rich_Internet_Application">RIAs</a>) mit Schwerpunkt auf grafische Darstellung erstellen kann.</p>
<p>Wer sich für Silverlight interessiert findet unter <a href="http://foidoschess.tv/">http://foidoschess.tv/</a> eine nette Demonstration der Möglichkeiten von Silverlight. Dummerweise ist eine Registrierung erforderlich, ich habe hierfür eine Email-Adresse @mailinator.com verwendet.</p>
<p>Ausserdem muss man noch die Silverlight Runtime installieren, was aber schnell und unkompliziert geht.</p>
<p>Da ich öfter das Internet nutze um Schachpartien live zu verfolgen (z.B. soweit möglich bei dem im Oktober anstehenden <a href="http://www.uep-chess.com/cms_german/index.php?option=com_content&amp;task=view&amp;id=3&amp;Itemid=4">Weltmeisterschaftskampf</a>) kann ich den Mehrwert der Foidos-Plattform durchaus erkennen.</p>
<p>Viele Grüße,<br />
Andreas</p>
<p>Technorati Tags: <a href="http://technorati.com/tag/Microsoft" rel="tag">Microsoft</a>, <a href="http://technorati.com/tag/Silverlight" rel="tag">Silverlight</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.awenius.de/blog/2008/09/04/nette-silverlight-demo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

