<?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[Controls (Button etc.) in Klassen, Design Frage]]></title><description><![CDATA[<p>Ich brauch mal eure Meinung.<br />
Ich programmiere ein mittelgroßes Projekt, in dem einige Std. Controls sehr sehr Häufig Vorkommen. Meinen kompletten Wrapper dafür einzubinden finde ich Übertrieben, daher will ich nur das was ich brauch in Klassen packen, mit Subclassing der Controlls selbstverständlich.</p>
<p>Da es nichts Aufwendiges ist, dachte ich, ich werde mal von meinem üblichen Still abweichen und die Klassenzeiger in einer Map packen, da ich diese eh benötige. Mein folgender Code funktioniert natürlich, aber ich habe ein ungutes Gefühl wegem den Design, vorallem benutze ich ungern Cast.</p>
<p>Was meint ihr, ist das OK und ich mache mir unnötig gedanken?<br />
PS: Lehrlinge bekommen den Code auch Vorgelegt und sollen ihn Verstehen, meinem Wrapper würden die derzeit eh nicht verstehen.</p>
<p>Der Code:</p>
<pre><code class="language-cpp">#include &lt;windows.h&gt;
#include &lt;map&gt;

static LRESULT CALLBACK MyControlProc (HWND, UINT, WPARAM, LPARAM);

class MyControl;
typedef void (*Event)(MyControl*); 
class MyControl {
    protected:
        HWND Handle;
        HINSTANCE AppInst;
        WNDPROC DefaultProc;
        /* weitere Parameter, ala left width etc. */
    public:
        virtual void InitControl(HINSTANCE hinst, HWND hwnd)
        { /* Überschreiben in Erben */ }       
        WNDPROC Get_DefaultProc() { return DefaultProc; }
        Event OnClick;
        Event OnMouseDown;
        Event OnMouseUp;
        Event OnKeyDown;
        Event OnKeyUp;
        /* u.s.w. */
};

std::map&lt;HWND, MyControl*&gt;MyControlMap;

class MyWind : public MyControl {
    public:
        /* Members für diesen Control type */
        void InitControl(HINSTANCE hinst, HWND hwnd)
        { /* Überschrieben */ }
};

/* +++++++++++++++++++++++++++++++++++++++++++++ */
// Die WndProc der Controls: 

LRESULT CALLBACK MyControlProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    MyControl* obj = dynamic_cast&lt;MyControl*&gt;(MyControlMap[hwnd]);
    if (obj != 0) 
    {    
        switch (message) {
                case WM_KEYDOWN:
                     if (obj-&gt;OnKeyDown) (*obj-&gt;OnKeyDown)(obj);
                     break;
        /* etc. */
</code></pre>
<p>Und? Ist der Codedesign ok, für einen eigentlich einfachen Zweck?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/99879/controls-button-etc-in-klassen-design-frage</link><generator>RSS for Node</generator><lastBuildDate>Tue, 28 Apr 2026 17:38:21 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/99879.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 01 Feb 2005 19:02:43 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Controls (Button etc.) in Klassen, Design Frage on Tue, 01 Feb 2005 19:02:43 GMT]]></title><description><![CDATA[<p>Ich brauch mal eure Meinung.<br />
Ich programmiere ein mittelgroßes Projekt, in dem einige Std. Controls sehr sehr Häufig Vorkommen. Meinen kompletten Wrapper dafür einzubinden finde ich Übertrieben, daher will ich nur das was ich brauch in Klassen packen, mit Subclassing der Controlls selbstverständlich.</p>
<p>Da es nichts Aufwendiges ist, dachte ich, ich werde mal von meinem üblichen Still abweichen und die Klassenzeiger in einer Map packen, da ich diese eh benötige. Mein folgender Code funktioniert natürlich, aber ich habe ein ungutes Gefühl wegem den Design, vorallem benutze ich ungern Cast.</p>
<p>Was meint ihr, ist das OK und ich mache mir unnötig gedanken?<br />
PS: Lehrlinge bekommen den Code auch Vorgelegt und sollen ihn Verstehen, meinem Wrapper würden die derzeit eh nicht verstehen.</p>
<p>Der Code:</p>
<pre><code class="language-cpp">#include &lt;windows.h&gt;
#include &lt;map&gt;

static LRESULT CALLBACK MyControlProc (HWND, UINT, WPARAM, LPARAM);

class MyControl;
typedef void (*Event)(MyControl*); 
class MyControl {
    protected:
        HWND Handle;
        HINSTANCE AppInst;
        WNDPROC DefaultProc;
        /* weitere Parameter, ala left width etc. */
    public:
        virtual void InitControl(HINSTANCE hinst, HWND hwnd)
        { /* Überschreiben in Erben */ }       
        WNDPROC Get_DefaultProc() { return DefaultProc; }
        Event OnClick;
        Event OnMouseDown;
        Event OnMouseUp;
        Event OnKeyDown;
        Event OnKeyUp;
        /* u.s.w. */
};

std::map&lt;HWND, MyControl*&gt;MyControlMap;

class MyWind : public MyControl {
    public:
        /* Members für diesen Control type */
        void InitControl(HINSTANCE hinst, HWND hwnd)
        { /* Überschrieben */ }
};

/* +++++++++++++++++++++++++++++++++++++++++++++ */
// Die WndProc der Controls: 

LRESULT CALLBACK MyControlProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    MyControl* obj = dynamic_cast&lt;MyControl*&gt;(MyControlMap[hwnd]);
    if (obj != 0) 
    {    
        switch (message) {
                case WM_KEYDOWN:
                     if (obj-&gt;OnKeyDown) (*obj-&gt;OnKeyDown)(obj);
                     break;
        /* etc. */
</code></pre>
<p>Und? Ist der Codedesign ok, für einen eigentlich einfachen Zweck?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/712343</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/712343</guid><dc:creator><![CDATA[MichaM.]]></dc:creator><pubDate>Tue, 01 Feb 2005 19:02:43 GMT</pubDate></item><item><title><![CDATA[Reply to Controls (Button etc.) in Klassen, Design Frage on Wed, 02 Feb 2005 09:31:11 GMT]]></title><description><![CDATA[<p>1. warum der cast überhaupt? in der map befinden sich doch ein pointer auf MyControl</p>
<p>2. wäre es nicht besser in der map über einen iterator zu suchen als darauf zurückzugreifen und einen pointer zu prüfen</p>
<pre><code class="language-cpp">typedef std::map&lt;HWND, MyControl*&gt; CtrlMap;
CtrlMap MyControlMap;
//----------------------------------
MyControl *pObj;
CtrlMap::iterator it = m_MyControlMap.find(hwnd);

if(it != m_MyControlMap.end())
    pObj = it-&gt;second;
else
    return 0;
</code></pre>
<p>3. vom design her find ich es <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="👍"
    /> wahrscheinlich machst du wirklich zu viele gedanken. <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>
]]></description><link>https://www.c-plusplus.net/forum/post/712642</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/712642</guid><dc:creator><![CDATA[miller_m]]></dc:creator><pubDate>Wed, 02 Feb 2005 09:31:11 GMT</pubDate></item><item><title><![CDATA[Reply to Controls (Button etc.) in Klassen, Design Frage on Wed, 02 Feb 2005 11:20:17 GMT]]></title><description><![CDATA[<p>Zu 1., stimmt ist mir nach dem Posten erst aufgefallen, ich werde alt <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /><br />
Das war ein Überbleibsel, da ich zuvor noch eine Klasse drüber hatte, namens MyObject, dessen Type in die Map sollte, das hatte ich aber abgeändert, da es überflüßig war und ich den DownCast einsparen wollte, nur das ich das geändert hatte um den Cast zu sparen, das hatte ich vergessen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
<p>Zu 2. Ja, wird in der endgültigen WndProc auch so geschehen, beim testen der Klassen reicht das aus.</p>
<p>zu 3. Danke, ja ich mach mir immer viele Gedanken am Anfang 1000 Blätter mit Notizen, dafür erlebe ich aber mitten drinn oder am Ende keine bösen Überraschungen <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>
]]></description><link>https://www.c-plusplus.net/forum/post/712730</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/712730</guid><dc:creator><![CDATA[MichaM.]]></dc:creator><pubDate>Wed, 02 Feb 2005 11:20:17 GMT</pubDate></item><item><title><![CDATA[Reply to Controls (Button etc.) in Klassen, Design Frage on Wed, 02 Feb 2005 11:24:38 GMT]]></title><description><![CDATA[<p>MichaM. schrieb:</p>
<blockquote>
<p>zu 3. Danke, ja ich mach mir immer viele Gedanken am Anfang 1000 Blätter mit Notizen, dafür erlebe ich aber mitten drinn oder am Ende keine bösen Überraschungen <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>
</blockquote>
<p>so ist es ja auch richtig als einfach darauf los zu [ironie]proggen[/ironie] <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>
]]></description><link>https://www.c-plusplus.net/forum/post/712731</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/712731</guid><dc:creator><![CDATA[miller_m]]></dc:creator><pubDate>Wed, 02 Feb 2005 11:24:38 GMT</pubDate></item><item><title><![CDATA[Reply to Controls (Button etc.) in Klassen, Design Frage on Wed, 02 Feb 2005 11:32:15 GMT]]></title><description><![CDATA[<p>den pointer auf das objekt kannst übrigens mit SetWindowLong (...GWL_USERDATA mit dem hwnd verknüpfen. dann brauchste keine std::map mehr. vorteil daran ist, dass wenn das hwnd recycled wird keine fehler passieren können. sonst müssteste ja immer das hwnd/objektpointer aus der map löschen wenn das fenster gekillt wird.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/712737</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/712737</guid><dc:creator><![CDATA[net 0]]></dc:creator><pubDate>Wed, 02 Feb 2005 11:32:15 GMT</pubDate></item><item><title><![CDATA[Reply to Controls (Button etc.) in Klassen, Design Frage on Wed, 02 Feb 2005 13:08:30 GMT]]></title><description><![CDATA[<p>net schrieb:</p>
<blockquote>
<p>den pointer auf das objekt kannst übrigens mit SetWindowLong (...GWL_USERDATA mit dem hwnd verknüpfen. dann brauchste keine std::map mehr. vorteil daran ist, dass wenn das hwnd recycled wird keine fehler passieren können. sonst müssteste ja immer das hwnd/objektpointer aus der map löschen wenn das fenster gekillt wird.</p>
</blockquote>
<p>Dann kommt der böße Micha und Macht: SetWindowLong(Object-&gt;Get_Handle(),GWL_USERDATA,123); und dann ist vorbei.</p>
<p>In meinem eigentlichen Wrapper benutze ich auch keine map, aber auch kein UserData. <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="😉"
    /><br />
Ich habe da auch &quot;nicht Visuelle&quot; Klassen, die keinen HWND haben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/712806</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/712806</guid><dc:creator><![CDATA[MichaM.]]></dc:creator><pubDate>Wed, 02 Feb 2005 13:08:30 GMT</pubDate></item><item><title><![CDATA[Reply to Controls (Button etc.) in Klassen, Design Frage on Wed, 02 Feb 2005 13:34:32 GMT]]></title><description><![CDATA[<blockquote>
<p>In meinem eigentlichen Wrapper benutze ich auch keine map, aber auch kein UserData.</p>
</blockquote>
<p>was denn?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/712826</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/712826</guid><dc:creator><![CDATA[proggger?]]></dc:creator><pubDate>Wed, 02 Feb 2005 13:34:32 GMT</pubDate></item><item><title><![CDATA[Reply to Controls (Button etc.) in Klassen, Design Frage on Wed, 02 Feb 2005 15:43:08 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">HINSTANCE AppInst;

/* weitere Parameter, ala left width etc. */
</code></pre>
<p>Find ich nicht gut. Das kann man doch alles mit den Winapi Funktionen abfragen und setzen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/712982</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/712982</guid><dc:creator><![CDATA[schlechtes design]]></dc:creator><pubDate>Wed, 02 Feb 2005 15:43:08 GMT</pubDate></item><item><title><![CDATA[Reply to Controls (Button etc.) in Klassen, Design Frage on Wed, 02 Feb 2005 15:44:34 GMT]]></title><description><![CDATA[<p>Und wie kommt man in OnKeyDown an WPARAM und LPARAM?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/712985</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/712985</guid><dc:creator><![CDATA[schlechtes design]]></dc:creator><pubDate>Wed, 02 Feb 2005 15:44:34 GMT</pubDate></item><item><title><![CDATA[Reply to Controls (Button etc.) in Klassen, Design Frage on Wed, 02 Feb 2005 15:50:39 GMT]]></title><description><![CDATA[<p>naja ich würd sagen den funktionpointer erweitern <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
<pre><code class="language-cpp">typedef void (*Event)(MyControl*, WPARAM, LPARAM);
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/712988</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/712988</guid><dc:creator><![CDATA[miller_m]]></dc:creator><pubDate>Wed, 02 Feb 2005 15:50:39 GMT</pubDate></item><item><title><![CDATA[Reply to Controls (Button etc.) in Klassen, Design Frage on Wed, 02 Feb 2005 18:19:02 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/30146">@pro</a>...<br />
das ist zu Umfassend um es kurz zu erwähnen</p>
<p>@schlechtes design<br />
ich speichere width height etc, da ich mit get_xxx dies Abfrage und mit set_xxxx setzte, die entsprechenden API Funktionen sitzen dann in diese, dafür ist OOP da, um einen guten Überblick zu bewahren.</p>
<p>Der gezeigte Code ist ein Beispiel für das Design, das wird doch nicht so 1:1 Übernommen, zur Beruhigung:</p>
<pre><code class="language-cpp">typedef void (*MouseEvent)(MyControl*,int,int,WPARAM); //Klasse,x,y,Shift
typedef void (*KeyEvent)(MyControl*,int,LPARAM); //Klasse,Keycode,Keydata
//u.s.w.
</code></pre>
<p>Also, den gezeigten code nicht als endcode ansehen</p>
]]></description><link>https://www.c-plusplus.net/forum/post/713134</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/713134</guid><dc:creator><![CDATA[MichaM.]]></dc:creator><pubDate>Wed, 02 Feb 2005 18:19:02 GMT</pubDate></item><item><title><![CDATA[Reply to Controls (Button etc.) in Klassen, Design Frage on Wed, 02 Feb 2005 18:22:41 GMT]]></title><description><![CDATA[<p>krieg ich auch kein stichwort?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/713136</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/713136</guid><dc:creator><![CDATA[pro...]]></dc:creator><pubDate>Wed, 02 Feb 2005 18:22:41 GMT</pubDate></item><item><title><![CDATA[Reply to Controls (Button etc.) in Klassen, Design Frage on Wed, 02 Feb 2005 18:46:39 GMT]]></title><description><![CDATA[<blockquote>
<p>ich speichere width height etc, da ich mit get_xxx dies Abfrage und mit set_xxxx setzte, die entsprechenden API Funktionen sitzen dann in diese, dafür ist OOP da, um einen guten Überblick zu bewahren.</p>
</blockquote>
<p>versteh ich irgendwie nicht. warum sollen die daten an 2 plätzen gespeichert werden? einmal in windows und einmal in deinem programm. dann muss man die werte ja immer aktuell halten. das ist doch quatsch.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/713154</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/713154</guid><dc:creator><![CDATA[schlechtes design]]></dc:creator><pubDate>Wed, 02 Feb 2005 18:46:39 GMT</pubDate></item><item><title><![CDATA[Reply to Controls (Button etc.) in Klassen, Design Frage on Wed, 02 Feb 2005 21:11:26 GMT]]></title><description><![CDATA[<p>pro... schrieb:</p>
<blockquote>
<p>krieg ich auch kein stichwort?</p>
</blockquote>
<p>Bei Fenstern, auch Childwindows, kann man den Zusatzspeicher erweitern und bei standard controls kann man was nehmen, was sie nicht verwenden (z.b. Menu).</p>
<p>schlechtes design schrieb:</p>
<blockquote>
<p>versteh ich irgendwie nicht. warum sollen die daten an 2 plätzen gespeichert werden? einmal in windows und einmal in deinem programm. dann muss man die werte ja immer aktuell halten. das ist doch quatsch.</p>
</blockquote>
<p>Hmmm, hast recht. Danke, hatte ich so nicht darauf geachtet, ich muß meinen großen Wrapper angleichen, da der Programmierer die Möglichkeit hat durch das Handle eigene Operation durchzuführen, hatte ich die &quot;get&quot; Auslesung entsprechend angeglichen, so das es aus Windows gelesen wird, bei set aber in den Klassen Members geschrieben wird und z.B. mit MoveWindow() ausgeübt wird, demnach sind die Member nutzlos, wer hätte das gedacht.<br />
Danke für den Tip, da kann man ja noch Speicher sparen, bevor 512MB voll sind. <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>
]]></description><link>https://www.c-plusplus.net/forum/post/713275</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/713275</guid><dc:creator><![CDATA[MichaM.]]></dc:creator><pubDate>Wed, 02 Feb 2005 21:11:26 GMT</pubDate></item><item><title><![CDATA[Reply to Controls (Button etc.) in Klassen, Design Frage on Thu, 03 Feb 2005 22:23:37 GMT]]></title><description><![CDATA[<p>hi,</p>
<p>wieso verwendest du statt der function pointer keine virtuellen Funktionen, mit Basisklasse/abgeleiteten Klassen etc., wäre eleganter meiner Meinung nach.<br />
(ich denk du weißt was ich meine ;))</p>
<p>Oder hast verhalten die sich alle unterschiedlich und du hast so sehr viele?</p>
<p>Naja, nur so als Einwurf, aber wahrscheinlich auch zu mühselig nochmal alles zu ändern <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /></p>
<p>MfG<br />
DDR-RAM</p>
]]></description><link>https://www.c-plusplus.net/forum/post/714158</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/714158</guid><dc:creator><![CDATA[DDR-RAM]]></dc:creator><pubDate>Thu, 03 Feb 2005 22:23:37 GMT</pubDate></item><item><title><![CDATA[Reply to Controls (Button etc.) in Klassen, Design Frage on Fri, 04 Feb 2005 11:00:29 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/8880">@DDR-RAM</a><br />
Virtuelle Funktionen zu überschreiben wäre wesentlich aufwendiger bei der Masse, zumal einige Buttons etwas dürfen und andere nicht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/714424</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/714424</guid><dc:creator><![CDATA[MichaM.]]></dc:creator><pubDate>Fri, 04 Feb 2005 11:00:29 GMT</pubDate></item></channel></rss>