<?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[Übergabe eines Pointers von einem Programm zu einer anderen Instanz desselben Programms]]></title><description><![CDATA[<p>Hallo.</p>
<p>In meinem Programm möchte ich, dass wenn man eine weitere Instanz des Programms startet, die neue Instanz einen Zeiger an die erste Instanz &quot;übergibt&quot; und sich dann schließt. Allerdings funktioniert das wie ich es mache nicht.</p>
<p>Am Anfang des Programms erstelle ich einen Mutex, wodurch das Programm erkennen kann, ob schon eine Instanz existiert. Exisitiert schon eine Instanz, dann soll ein Zeiger zu dieser &quot;gesendet&quot; werden:</p>
<pre><code class="language-cpp">int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    HANDLE mutex = CreateMutex(NULL, FALSE, &quot;MutexName&quot;);

    if(mutex == NULL)
        return -1;
    else if(GetLastError() == ERROR_ALREADY_EXISTS) {
        HWND hwnd = FindWindow(&quot;ClassName&quot;, &quot;Title&quot;);
        //jetzt soll __argv[1] an die erste Instanz übermittelt werden
        if(__argc &gt; 1)
            SendMessage(hwnd, WM_USER, (WPARAM)__argv[1], 0);

        return 0;
    }
    //usw... mit WinMain
</code></pre>
<p>Da WPARAM ja ein typedef von unsigned int ist, müsste WPARAM ja die richtige Größe für den Pointer haben. Und SendMessage wartet ja, bis die andere Instanze die WM_USER Nachricht abgearbeitet hat bevor sie returned, also bleibt __argv[1] ein gültiger Zeiger solange er verarbeitet werden soll.</p>
<p>Nun soll __argv[1] zu Testzwecken mal der Titel der ersten Instanz werden. Das steht also in meiner WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam):</p>
<pre><code class="language-cpp">case WM_USER:
    SetWindowText(hwnd, (LPCTSTR)wParam);
    break;
</code></pre>
<p>Allerdings wird mit dieser Methode letztendlich kein neuer Text in der Titelleiste angezeigt, sondern gar keiner. Woran liegt's? Gibt es womöglich einen bessern Weg, diesen Zeiger zu übergeben?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/236206/übergabe-eines-pointers-von-einem-programm-zu-einer-anderen-instanz-desselben-programms</link><generator>RSS for Node</generator><lastBuildDate>Tue, 07 Apr 2026 21:33:10 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/236206.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 12 Mar 2009 08:35:55 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Übergabe eines Pointers von einem Programm zu einer anderen Instanz desselben Programms on Thu, 12 Mar 2009 08:38:54 GMT]]></title><description><![CDATA[<p>Hallo.</p>
<p>In meinem Programm möchte ich, dass wenn man eine weitere Instanz des Programms startet, die neue Instanz einen Zeiger an die erste Instanz &quot;übergibt&quot; und sich dann schließt. Allerdings funktioniert das wie ich es mache nicht.</p>
<p>Am Anfang des Programms erstelle ich einen Mutex, wodurch das Programm erkennen kann, ob schon eine Instanz existiert. Exisitiert schon eine Instanz, dann soll ein Zeiger zu dieser &quot;gesendet&quot; werden:</p>
<pre><code class="language-cpp">int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    HANDLE mutex = CreateMutex(NULL, FALSE, &quot;MutexName&quot;);

    if(mutex == NULL)
        return -1;
    else if(GetLastError() == ERROR_ALREADY_EXISTS) {
        HWND hwnd = FindWindow(&quot;ClassName&quot;, &quot;Title&quot;);
        //jetzt soll __argv[1] an die erste Instanz übermittelt werden
        if(__argc &gt; 1)
            SendMessage(hwnd, WM_USER, (WPARAM)__argv[1], 0);

        return 0;
    }
    //usw... mit WinMain
</code></pre>
<p>Da WPARAM ja ein typedef von unsigned int ist, müsste WPARAM ja die richtige Größe für den Pointer haben. Und SendMessage wartet ja, bis die andere Instanze die WM_USER Nachricht abgearbeitet hat bevor sie returned, also bleibt __argv[1] ein gültiger Zeiger solange er verarbeitet werden soll.</p>
<p>Nun soll __argv[1] zu Testzwecken mal der Titel der ersten Instanz werden. Das steht also in meiner WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam):</p>
<pre><code class="language-cpp">case WM_USER:
    SetWindowText(hwnd, (LPCTSTR)wParam);
    break;
</code></pre>
<p>Allerdings wird mit dieser Methode letztendlich kein neuer Text in der Titelleiste angezeigt, sondern gar keiner. Woran liegt's? Gibt es womöglich einen bessern Weg, diesen Zeiger zu übergeben?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1678492</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1678492</guid><dc:creator><![CDATA[Bier]]></dc:creator><pubDate>Thu, 12 Mar 2009 08:38:54 GMT</pubDate></item><item><title><![CDATA[Reply to Übergabe eines Pointers von einem Programm zu einer anderen Instanz desselben Programms on Thu, 12 Mar 2009 10:32:27 GMT]]></title><description><![CDATA[<p>Hi,</p>
<p>Bier schrieb:</p>
<blockquote>
<p>...<br />
also bleibt __argv[1] ein gültiger Zeiger solange er verarbeitet werden soll.<br />
...</p>
</blockquote>
<p>joa fuer deine aktuelle Instanz, aber da ja deine erste Instanz afaik seinen eigenen virtuellen Speicher hat, steht an der Adresse irgendein Wert. Was z.B. eine Idee waere: in eine Datei deine Werte zu speichern, eine Message an deine erste Instanz zu schicken und diese ließt die Datei dann wieder aus. Oder eine anderes Stichwort waere: Memory-Mapped File.</p>
<p>Gruessli C0de4Fun</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1678569</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1678569</guid><dc:creator><![CDATA[C0de4Fun]]></dc:creator><pubDate>Thu, 12 Mar 2009 10:32:27 GMT</pubDate></item><item><title><![CDATA[Reply to Übergabe eines Pointers von einem Programm zu einer anderen Instanz desselben Programms on Thu, 12 Mar 2009 10:42:10 GMT]]></title><description><![CDATA[<p>WM_COPYDATA</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1678575</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1678575</guid><dc:creator><![CDATA[asdca]]></dc:creator><pubDate>Thu, 12 Mar 2009 10:42:10 GMT</pubDate></item><item><title><![CDATA[Reply to Übergabe eines Pointers von einem Programm zu einer anderen Instanz desselben Programms on Thu, 12 Mar 2009 12:04:27 GMT]]></title><description><![CDATA[<p>WM_COPYDATA funktioniert einwandfrei. Allerdings sende ich hier ja auch einen Zeiger in der COPYDATASTRUCT</p>
<pre><code class="language-cpp">COPYDATASTRUCT cds;
cds.dwData = 0;
cds.cbData = lstrlen(nCmdLine);
cds.lpData = nCmdLine; //&lt;-Zeiger, der &quot;auf Speicher zur zweiten Instanz gehörend&quot; zeigt
</code></pre>
<p>und nicht zu vergessen, dass man SendMessage selbst ja einen Zeiger übergibt:</p>
<pre><code class="language-cpp">SendMessage(hwnd, WM_COPYDATA, (WPARAM)NULL, (LPARAM)&amp;cds);
</code></pre>
<p>Funktioniert ja alles wunderbar, aber wenn C0de4Fun Recht hat, ist das ja eher Glück als sonstwas.</p>
<p>Übrigens habe ich mit __argv noch etwas rumgefiemelt und bemerkt, dass __argv gar nicht das ist bzw. macht, was ich dachte und wie ja auch einige Quellen behaupten. Zumindest arbeitet es bei mir eben nicht wie argv in einer Konsolenanwendung, sondern enthält doch die gesamte Kommandozeile. Dann kann ich aber statt __argv[0] auch gleich bei lpCmdLine bleiben.</p>
<p>Ist zumindest bei mir so...</p>
<p>Den Umweg über eine Datei (bzw. Registry) würde ich letztendlich machen, aber nur wenn's nicht anders geht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1678616</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1678616</guid><dc:creator><![CDATA[Bier]]></dc:creator><pubDate>Thu, 12 Mar 2009 12:04:27 GMT</pubDate></item><item><title><![CDATA[Reply to Übergabe eines Pointers von einem Programm zu einer anderen Instanz desselben Programms on Thu, 12 Mar 2009 12:19:59 GMT]]></title><description><![CDATA[<p>Bier schrieb:</p>
<blockquote>
<p>Übrigens habe ich mit __argv noch etwas rumgefiemelt und bemerkt, dass __argv gar nicht das ist bzw. macht, was ich dachte und wie ja auch einige Quellen behaupten. Zumindest arbeitet es bei mir eben nicht wie argv in einer Konsolenanwendung, sondern enthält doch die gesamte Kommandozeile. Dann kann ich aber statt __argv[0] auch gleich bei lpCmdLine bleiben.</p>
</blockquote>
<p>Nöööö! __argv ist bei MS in der CRT eineKopie von argv!<br />
Schau doch in den Sourcecode...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1678628</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1678628</guid><dc:creator><![CDATA[Martin Richter]]></dc:creator><pubDate>Thu, 12 Mar 2009 12:19:59 GMT</pubDate></item><item><title><![CDATA[Reply to Übergabe eines Pointers von einem Programm zu einer anderen Instanz desselben Programms on Thu, 12 Mar 2009 12:55:50 GMT]]></title><description><![CDATA[<p>Jup, hast Recht, auch in meiner stdlib.h steht das klipp und klar drin.</p>
<pre><code class="language-cpp">int i;
for(i = 0; i &lt; __argc; i++)
    MessageBox(NULL, __argv[i], NULL, MB_OK);
</code></pre>
<p>liefert alles korrekt.<br />
Sorry, hab ich wohl vorher Mist gebaut.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1678657</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1678657</guid><dc:creator><![CDATA[Bier]]></dc:creator><pubDate>Thu, 12 Mar 2009 12:55:50 GMT</pubDate></item><item><title><![CDATA[Reply to Übergabe eines Pointers von einem Programm zu einer anderen Instanz desselben Programms on Thu, 12 Mar 2009 14:50:12 GMT]]></title><description><![CDATA[<blockquote>
<p>&gt; ist das ja eher Glück als sonstwas</p>
</blockquote>
<p>Nein, WM_COPYDATA erzeugt im Adressbereich des Zielprozesses eine Kopie des Datenblocks.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1678750</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1678750</guid><dc:creator><![CDATA[xl]]></dc:creator><pubDate>Thu, 12 Mar 2009 14:50:12 GMT</pubDate></item><item><title><![CDATA[Reply to Übergabe eines Pointers von einem Programm zu einer anderen Instanz desselben Programms on Thu, 12 Mar 2009 15:02:43 GMT]]></title><description><![CDATA[<blockquote>
<p>&gt; cds.cbData = lstrlen(nCmdLine);</p>
</blockquote>
<p>Korrekt ist übrigens</p>
<p>cds.cbData = lstrlen(nCmdLine) + sizeof(TCHAR);</p>
<p>da sonst der abschließende Null-Char nicht kopiert wird und im Zielprozess dann fehlt (falls da nicht zufällig sowieso eine Null im Speicher steht.</p>
<p>Strings ohne Endekennung können zu interessanten Effekten führen ...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1678761</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1678761</guid><dc:creator><![CDATA[xl]]></dc:creator><pubDate>Thu, 12 Mar 2009 15:02:43 GMT</pubDate></item><item><title><![CDATA[Reply to Übergabe eines Pointers von einem Programm zu einer anderen Instanz desselben Programms on Thu, 12 Mar 2009 15:20:05 GMT]]></title><description><![CDATA[<p>Danke für die Aufklärung bzgl. WM_COPYDATA, hab das jetzt auch schon verwendet.</p>
<p>xl schrieb:</p>
<blockquote>
<blockquote>
<p>&gt; cds.cbData = lstrlen(nCmdLine);</p>
</blockquote>
<p>Korrekt ist übrigens</p>
<p>cds.cbData = lstrlen(nCmdLine) + sizeof(TCHAR);</p>
<p>da sonst der abschließende Null-Char nicht kopiert wird und im Zielprozess dann fehlt (falls da nicht zufällig sowieso eine Null im Speicher steht.</p>
<p>Strings ohne Endekennung können zu interessanten Effekten führen ...</p>
</blockquote>
<p>Jo, und du glaubst gar nicht, wie lange ich jetzt gerade noch nach dem Fehler gesucht habe. Bis ich dann endlich mal genauer in die Doku von lstrlen geschaut und gelesen habe, dass das Terminierungszeichen gar nicht mitgezählt wird. Hab dann Gott sei Dank alles fehlerfrei zum laufen gekriegt.<br />
Nach meinem faux pas mit __argv und dem lstrlen-Dilemma insgesamt eine schwere Geburt für ein eigentlich leicht lösbares Problem <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1678772</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1678772</guid><dc:creator><![CDATA[Bier]]></dc:creator><pubDate>Thu, 12 Mar 2009 15:20:05 GMT</pubDate></item><item><title><![CDATA[Reply to Übergabe eines Pointers von einem Programm zu einer anderen Instanz desselben Programms on Thu, 12 Mar 2009 20:17:21 GMT]]></title><description><![CDATA[<p>xl schrieb:</p>
<blockquote>
<blockquote>
<p>&gt; ist das ja eher Glück als sonstwas</p>
</blockquote>
<p>Nein, WM_COPYDATA erzeugt im Adressbereich des Zielprozesses eine Kopie des Datenblocks.</p>
</blockquote>
<p>Genau.<br />
Das System &quot;kennt&quot; WM_COPYDATA, und kopiert die Daten entsprechend in den Zielprozess. Der Zeiger auf den Datenblock wird dabei auch entsprechend angepasst. Das bedeutet auch, dass du in dem über WM_COPYDATA kopierten Block a) keine absoluten Adressen verwenden darsft und b) sowieso keine Zeiger ablegen darfst, die auf ausserhalb des kopierten Datenblocks zeigen.<br />
Falls du zeiger *innerhalb* des Datenblocks brauchst, musst du diese relativ kodieren. z.B. als Offset zum Anfang des Datenblocks, oder als Offset zur Adresse wo der Zeiger selbst abgelegt ist.</p>
<p>Die Daten sind solange gültig, bis der Message-Handler (=die Window-Procedure) fertiggelaufen ist. D.h. wenn man die Daten später noch braucht, muss man sie im Message-Handler nochmal kopieren.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1678941</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1678941</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Thu, 12 Mar 2009 20:17:21 GMT</pubDate></item><item><title><![CDATA[Reply to Übergabe eines Pointers von einem Programm zu einer anderen Instanz desselben Programms on Thu, 12 Mar 2009 21:03:56 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>Das System &quot;kennt&quot; WM_COPYDATA, und kopiert die Daten entsprechend in den Zielprozess. Der Zeiger auf den Datenblock wird dabei auch entsprechend angepasst. Das bedeutet auch, dass du in dem über WM_COPYDATA kopierten Block a) keine absoluten Adressen verwenden darsft und b) sowieso keine Zeiger ablegen darfst, die auf ausserhalb des kopierten Datenblocks zeigen.<br />
Falls du zeiger *innerhalb* des Datenblocks brauchst, musst du diese relativ kodieren. z.B. als Offset zum Anfang des Datenblocks, oder als Offset zur Adresse wo der Zeiger selbst abgelegt ist.</p>
</blockquote>
<p>Okay, ich muss sowieso nur den einen Speicherbereich von __argv[1] kopieren, von daher ist ja alles paletti:<br />
Der Speicherbereich von</p>
<pre><code class="language-cpp">__argv[1][0] bis __argv[1][lstrlen(__argv[1]) + sizeof(TCHAR) - 1]
</code></pre>
<p>wird also in den Adressraum des Zielprozesses in einen Speicherbereich gleicher größe kopiert und der</p>
<pre><code class="language-cpp">cds.lpData
</code></pre>
<p>wird auf den neuen Speicherbereich umgelenkt (wobei lParam=&amp;cds während der WM_COPYDATA wohl auch auf eine kopierte Struktur von cds zeigt, nehm' ich jetzt mal frech an)</p>
<blockquote>
<p>Die Daten sind solange gültig, bis der Message-Handler (=die Window-Procedure) fertiggelaufen ist. D.h. wenn man die Daten später noch braucht, muss man sie im Message-Handler nochmal kopieren.</p>
</blockquote>
<p>Jupp, alles klar.</p>
<p>Danke,<br />
ciao.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1678958</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1678958</guid><dc:creator><![CDATA[Bier]]></dc:creator><pubDate>Thu, 12 Mar 2009 21:03:56 GMT</pubDate></item></channel></rss>