<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Methode zurückgeben]]></title><description><![CDATA[<p>Hallo Leute,</p>
<p>ich bin erst seit Kurzem von Delphi zu C++ konvertiert und habe jetzt mal angefangen mir einen eigenen Wrapper der WinAPI zu bauen (klingt jetzt nach API-Frage, ist es aber keine).</p>
<p>Dazu habe ich mal dieses Tutorial gemacht <a href="http://www.gamedev.net/reference/articles/article1810.asp" rel="nofollow">http://www.gamedev.net/reference/articles/article1810.asp</a> - im Prinzip gehts darin um eine Fensterklasse mit dynamischer Messagemap (also kein switch). Gelöst wird das ganze per std::map.</p>
<p>Funktionierte dann (nach einigen kleinen Anpassungen wegen neuerer STL usw.) auch alles wunderbar. Jetzt möchte ich allerdings anfangen andere Komponenten zu entwickeln, dazu wäre es schön wenn ich die Messagehandler einfach vererben könnte und ggf. dann abändern. Das Problem bei dem Tutorial ist jedoch, dass die Handler einfache Funktionen und keine Methoden sind. Also habe ich als erstes mal folgendes gemacht:</p>
<pre><code class="language-cpp">//vorher: typedef long (* tyMessageHandler)(CWindow &amp;, HWND, long, long);
typedef long (CWindow::* tyMessageHandler)(CWindow &amp;, HWND, long, long);
typedef std::map&lt;long, tyMessageHandler&gt; tyMessageMap;
typedef tyMessageMap::iterator tyMessageIterator;

//Handler werden dann so zugewiesen (im Konstruktor):
RegisterMessageHandler(WM_CLOSE, &amp;CWindow::OnClose);
</code></pre>
<p>Und jetzt das Problem. Es gibt eine statische Routingfunktion, die das jeweilige Fenster ermittelt und prüft ob ein Handler für die Message registriert wurde.</p>
<p>Wenn nein -&gt; DefWndProc</p>
<p>Wenn ja:</p>
<pre><code class="language-cpp">tyMessageIterator it;
CWindow *wnd = 0;

wnd = reinterpret_cast&lt;CWindow *&gt;(::GetWindowLong(hwnd, GWL_USERDATA));
it = wnd-&gt;GetMessageHandler(message);

if(it != wnd-&gt;m_MsgHandlers.end())
return (it-&gt;second)(*wnd, hwnd, wparam, lparam);
</code></pre>
<p>VC++ 2010 RC2 schrieb:</p>
<blockquote>
<p>error C2064: Ausdruck ergibt keine Funktion, die 4 Argumente übernimmt</p>
</blockquote>
<p>Ich schätze jetzt mal dass das Problem darin liegt dass der Compiler nicht weis zu welcher Instanz von CWindow der Handler gehört.</p>
<p>Hab auch ein wenig rumexperimentiert,</p>
<pre><code class="language-cpp">return wnd.* (it-&gt;second)(*wnd, hwnd, wparam, lparam);
</code></pre>
<p>funktioniert jedenfalls auch nicht.</p>
<p>Hat irgendwer ne Idee was ich da machen könnte?</p>
<p>Danke schonmal <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f44d.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--thumbs_up"
      title=":+1:"
      alt="👍"
    /></p>
<p>Grüße,</p>
<p>spline</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/258978/methode-zurückgeben</link><generator>RSS for Node</generator><lastBuildDate>Tue, 08 Sep 2026 19:43:04 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/258978.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 17 Jan 2010 18:58:45 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Methode zurückgeben on Sun, 17 Jan 2010 18:58:45 GMT]]></title><description><![CDATA[<p>Hallo Leute,</p>
<p>ich bin erst seit Kurzem von Delphi zu C++ konvertiert und habe jetzt mal angefangen mir einen eigenen Wrapper der WinAPI zu bauen (klingt jetzt nach API-Frage, ist es aber keine).</p>
<p>Dazu habe ich mal dieses Tutorial gemacht <a href="http://www.gamedev.net/reference/articles/article1810.asp" rel="nofollow">http://www.gamedev.net/reference/articles/article1810.asp</a> - im Prinzip gehts darin um eine Fensterklasse mit dynamischer Messagemap (also kein switch). Gelöst wird das ganze per std::map.</p>
<p>Funktionierte dann (nach einigen kleinen Anpassungen wegen neuerer STL usw.) auch alles wunderbar. Jetzt möchte ich allerdings anfangen andere Komponenten zu entwickeln, dazu wäre es schön wenn ich die Messagehandler einfach vererben könnte und ggf. dann abändern. Das Problem bei dem Tutorial ist jedoch, dass die Handler einfache Funktionen und keine Methoden sind. Also habe ich als erstes mal folgendes gemacht:</p>
<pre><code class="language-cpp">//vorher: typedef long (* tyMessageHandler)(CWindow &amp;, HWND, long, long);
typedef long (CWindow::* tyMessageHandler)(CWindow &amp;, HWND, long, long);
typedef std::map&lt;long, tyMessageHandler&gt; tyMessageMap;
typedef tyMessageMap::iterator tyMessageIterator;

//Handler werden dann so zugewiesen (im Konstruktor):
RegisterMessageHandler(WM_CLOSE, &amp;CWindow::OnClose);
</code></pre>
<p>Und jetzt das Problem. Es gibt eine statische Routingfunktion, die das jeweilige Fenster ermittelt und prüft ob ein Handler für die Message registriert wurde.</p>
<p>Wenn nein -&gt; DefWndProc</p>
<p>Wenn ja:</p>
<pre><code class="language-cpp">tyMessageIterator it;
CWindow *wnd = 0;

wnd = reinterpret_cast&lt;CWindow *&gt;(::GetWindowLong(hwnd, GWL_USERDATA));
it = wnd-&gt;GetMessageHandler(message);

if(it != wnd-&gt;m_MsgHandlers.end())
return (it-&gt;second)(*wnd, hwnd, wparam, lparam);
</code></pre>
<p>VC++ 2010 RC2 schrieb:</p>
<blockquote>
<p>error C2064: Ausdruck ergibt keine Funktion, die 4 Argumente übernimmt</p>
</blockquote>
<p>Ich schätze jetzt mal dass das Problem darin liegt dass der Compiler nicht weis zu welcher Instanz von CWindow der Handler gehört.</p>
<p>Hab auch ein wenig rumexperimentiert,</p>
<pre><code class="language-cpp">return wnd.* (it-&gt;second)(*wnd, hwnd, wparam, lparam);
</code></pre>
<p>funktioniert jedenfalls auch nicht.</p>
<p>Hat irgendwer ne Idee was ich da machen könnte?</p>
<p>Danke schonmal <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f44d.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--thumbs_up"
      title=":+1:"
      alt="👍"
    /></p>
<p>Grüße,</p>
<p>spline</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1840380</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1840380</guid><dc:creator><![CDATA[spline]]></dc:creator><pubDate>Sun, 17 Jan 2010 18:58:45 GMT</pubDate></item><item><title><![CDATA[Reply to Methode zurückgeben on Sun, 17 Jan 2010 19:30:08 GMT]]></title><description><![CDATA[<p>Das Problem ist, dass das hier:</p>
<blockquote>
<pre><code class="language-cpp">typedef long (CWindow::* tyMessageHandler)(CWindow &amp;, HWND, long, long);
</code></pre>
</blockquote>
<p>nicht 4, sondern 5 Parameter sind. Der erste (Zeiger auf ein CWindow Objekt) ist implizit.<br />
Du hast ja selbst gesagt, dass es keine Memberfunktion ist, also musst du das emulieren und das geht nicht, wenn du trotzdem eine Memberfunktion nehmen willst. Nimm da einfach eine ganz normale Funktion und du holst dir dann den Zeiger auf die Instanz ja selbst (mit GetWindowLong). Bei Bedarf kannst du diese Funktion ja friend in <code>CWindow</code> deklarieren, dann hast du genau die gleichen Möglichkeiten, wie wenn das eine Memberfunktion wäre.</p>
<p>btw:<br />
Ich mache das selbst auch in etwa so.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1840393</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1840393</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Sun, 17 Jan 2010 19:30:08 GMT</pubDate></item><item><title><![CDATA[Reply to Methode zurückgeben on Sat, 23 Jan 2010 12:41:38 GMT]]></title><description><![CDATA[<p>So, konnte mich leider erst jetzt wieder damit beschäftigen, ich hoffe mal das fällt jetzt nicht schon unter thread necromancy <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";-)"
      alt="😉"
    /></p>
<p>Also erstmal danke für deine Antwort, hab mir diese Friendfunktionen jetzt mal angeschaut, eigentlich eine interessante Sache. Zwar kann ich damit jetzt auf private Felder zugreifen, aber das Problem mit der Vererbung bleibt das gleiche. Langsam denke ich mir es ist doch praktischer das ganze per Switch und festen Methoden zu machen... Oder übersehe ich da irgendwas?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1843667</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1843667</guid><dc:creator><![CDATA[spline]]></dc:creator><pubDate>Sat, 23 Jan 2010 12:41:38 GMT</pubDate></item><item><title><![CDATA[Reply to Methode zurückgeben on Sat, 23 Jan 2010 13:03:20 GMT]]></title><description><![CDATA[<p>Ich weiss jetzt nicht, was du mit der Vererbung meinst..</p>
<p>Aber das hier:</p>
<pre><code class="language-cpp">typedef long (CWindow::* tyMessageHandler)(CWindow &amp;, HWND, long, long);
</code></pre>
<p>Machst du besser so:</p>
<pre><code class="language-cpp">typedef long (*tyMessageHandler)(CWindow &amp;, HWND, long, long);
</code></pre>
<p>Also eine normale Funktion, die long zurückgibt und 4 Parameter nimmt.</p>
<p>Eine passende Funktion wäre z.B das hier:</p>
<pre><code class="language-cpp">long do_something (CWindow&amp; w, HWND hw, long l, long l2 ){ return 0;}
</code></pre>
<p>oder aber auch das hier:</p>
<pre><code class="language-cpp">struct foo
{
 static long do_something (CWindow&amp; w, HWND hw, long l, long l2 ){ return 0; }
}
</code></pre>
<p>Das <code>static</code> bewirkt, dass die Funktion nicht von einer Instanz abhängt.</p>
<p>Der Aufruf sollte dann so klappen, wie du ihn vorgeschlagen hast:</p>
<pre><code class="language-cpp">return (it-&gt;second)(*wnd, hwnd, wparam, lparam);
</code></pre>
<p>Das, was ich mit dem <code>friend</code> meinte war lediglich, dass, wenn du eine solche freie Funktion hast keinen Zugriff auf die privaten Member der Klasse hast und das könntest du mit <code>friend</code> lösen. (oder gleich die statische Variante innerhalb der Klasse benutzen).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1843683</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1843683</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Sat, 23 Jan 2010 13:03:20 GMT</pubDate></item><item><title><![CDATA[Reply to Methode zurückgeben on Sat, 23 Jan 2010 13:10:15 GMT]]></title><description><![CDATA[<p>Du könntest dir auch std::tr1::function und std::tr1::bind anschauen, damit sind Funktionszeiger ein Kinderspiel.</p>
<p>Ansonsten denke ich aber, dass virtuelle Funktionen (etwa <code>virtual bool onClose()</code> ) mit switch-Kaskade in der WndProc einige Vorteile haben, so kannst du auch jeder Nachricht eine eigene Signatur mitgeben: WM_CLOSE braucht (afair) keine Parameter, beim Handler für WM_COMMAND kannst du gleich die &quot;entpackten&quot; und entsprechend typisierten Parameter mitgeben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1843688</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1843688</guid><dc:creator><![CDATA[Badestrand_]]></dc:creator><pubDate>Sat, 23 Jan 2010 13:10:15 GMT</pubDate></item><item><title><![CDATA[Reply to Methode zurückgeben on Sat, 23 Jan 2010 13:29:17 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/18422">@Drakon</a>: Ja das habe ich bereits alles gemacht, so ist es ja eigentlich auch im Tutorial gelöst. Mit Vererbung meine ich, dass ich z.B. nicht jedes mal DestroyWindow() aufrufen muss, sondern einmal einen WM_CLOSE Handler implementiere und den an alle abgeleiteten Klassen erben - trotzdem aber weitere Funktionalität hinzufügen können. Das wäre bei einer externen Funktion natürlich nicht möglich.</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/13210">@Badestrand</a>: Ok danke ich sehs mir mal an, aber ich denke du hast recht bezüglich dem Switch.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1843701</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1843701</guid><dc:creator><![CDATA[spline]]></dc:creator><pubDate>Sat, 23 Jan 2010 13:29:17 GMT</pubDate></item><item><title><![CDATA[Reply to Methode zurückgeben on Sat, 23 Jan 2010 17:42:40 GMT]]></title><description><![CDATA[<p>Sooo, also ich hab jetzt mehrere Stunden versucht das ganze mit einer std::tr1::function zum laufen zu kriegen - leider erfolglos.</p>
<pre><code class="language-cpp">typedef std::tr1::function&lt;long(CWindow &amp;, HWND, long, long)&gt; tyMessageHandler;
</code></pre>
<p>Auch hier habe ich keinen Weg finden können eine Memberfunktion zuzuweisen - oder hast du das anders gemeint?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1843814</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1843814</guid><dc:creator><![CDATA[spline]]></dc:creator><pubDate>Sat, 23 Jan 2010 17:42:40 GMT</pubDate></item><item><title><![CDATA[Reply to Methode zurückgeben on Sat, 23 Jan 2010 19:12:59 GMT]]></title><description><![CDATA[<p>spline schrieb:</p>
<blockquote>
<p>Methode zurückgeben</p>
</blockquote>
<p>Soweit ich weiß, bekommst du nur einen Gutschein, aber kein Geld, wenn du die Methode zurück gibts.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1843838</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1843838</guid><dc:creator><![CDATA[Fachverkäufer]]></dc:creator><pubDate>Sat, 23 Jan 2010 19:12:59 GMT</pubDate></item><item><title><![CDATA[Reply to Methode zurückgeben on Sun, 24 Jan 2010 13:13:48 GMT]]></title><description><![CDATA[<p>Ich sehe dein Problem ehrlichgesagt nicht ganz. Mach mal ein kleines Programm, wie du das gerne haben möchtest, aber ansonsten komplett ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1844018</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1844018</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Sun, 24 Jan 2010 13:13:48 GMT</pubDate></item></channel></rss>