<?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[WinAPI Objektorientiert]]></title><description><![CDATA[<p>Hat jemand für mich ein günstiges Klassenkonzept für Window und Controllclasses?</p>
<p>Ein Steuerelement könnte ja theoretisch von der Fensterklasse einige Funktionen erben??<br />
Und wie kann ich es bewältigen das jede WindowFrame Instanz eine eigene WndProc bekommt, sodass ich für jedes &quot;Hauptfenster&quot; die Nachrichten verarbeiten kann?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/122449/winapi-objektorientiert</link><generator>RSS for Node</generator><lastBuildDate>Mon, 06 Jul 2026 06:12:27 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/122449.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 05 Oct 2005 19:40:17 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to WinAPI Objektorientiert on Wed, 05 Oct 2005 19:40:17 GMT]]></title><description><![CDATA[<p>Hat jemand für mich ein günstiges Klassenkonzept für Window und Controllclasses?</p>
<p>Ein Steuerelement könnte ja theoretisch von der Fensterklasse einige Funktionen erben??<br />
Und wie kann ich es bewältigen das jede WindowFrame Instanz eine eigene WndProc bekommt, sodass ich für jedes &quot;Hauptfenster&quot; die Nachrichten verarbeiten kann?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/886016</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/886016</guid><dc:creator><![CDATA[Tc++H]]></dc:creator><pubDate>Wed, 05 Oct 2005 19:40:17 GMT</pubDate></item><item><title><![CDATA[Reply to WinAPI Objektorientiert on Wed, 05 Oct 2005 19:54:07 GMT]]></title><description><![CDATA[<p>Bei CreateWindow() kannst Du einen Parameter &quot;lParam&quot; uebergeben, den Du aus WM_CREATE wieder abfragen kannst. Dann nimmst Du SetWindowLongPtr() mit GWL_USERDATA und speicherst den Pointer dorthin; bei anderen Messages mit GetWindowLongPtr() und GWL_USERDATA wieder auslesen. So uebergist Du den this-Pointer.</p>
<p>Die Fensterprozedur kann ruhig immer dieselbe sein, sie ruft dann den Code einer pure virtual Class auf, von der alle anderen Fensterklassen abgeleitet sind. Dann ist es Kaese-einfach.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/886030</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/886030</guid><dc:creator><![CDATA[Power Off]]></dc:creator><pubDate>Wed, 05 Oct 2005 19:54:07 GMT</pubDate></item><item><title><![CDATA[Reply to WinAPI Objektorientiert on Wed, 05 Oct 2005 20:28:33 GMT]]></title><description><![CDATA[<p>@ Power Off: hat dann jede klasse ihre eigene callback?<br />
wie dem auch sei, &quot;damals&quot; als ich noch aktiver codete schrieb ich folgendes (es ist bissl komplizierter, aber wenn esso einfach wie bei dir wäre, power off, hätte ich es damals ja so gemacht). Ich denke bei meinem zeugs kann man für fenster derselben klasse eigene callbacks haben. aber kA ^^<br />
Also:<br />
CWndUnknown.cpp:</p>
<pre><code>/*
* Description: creates a CALLBACK-thunk.
* For more information see readme.txt
*/

#include &lt;windows.h&gt;
#include &quot;CWndUnknown.h&quot;

void CWndProcThunk::Init(WNDPROC WndProc, void* pThis)
{
	thunk.m_mov		= 0x042444C7;  //C7 44 24 04
	thunk.m_this	= (DWORD)pThis;
	thunk.m_jmp		= 0xe9;
	thunk.m_relproc	= *((int*)&amp;WndProc) - ((int)this + 
						sizeof(_WndProcThunk));

	FlushInstructionCache(GetCurrentProcess(), 
            &amp;thunk, sizeof(thunk));
}

CWndUnknown::CWndUnknown()
{
	m_hwnd	= 0;
}

LRESULT CWndUnknown::ProcessWindowMessage(HWND hwnd, UINT message,
									WPARAM wParam, LPARAM lParam)
{
	return false;
}

LRESULT CALLBACK CWndUnknown::StartWindowProc(HWND hwnd, UINT message,
										WPARAM wParam, LPARAM lParam)
{
	if(message == WM_CREATE)
	{
		CWndUnknown *pThis = (CWndUnknown*)((LPCREATESTRUCT)lParam)-&gt;lpCreateParams;
		pThis-&gt;m_hwnd = hwnd;
		pThis-&gt;m_thunk.Init(WindowProc, pThis);
		WNDPROC pProc = (WNDPROC)&amp;(pThis-&gt;m_thunk.thunk);
		SetWindowLong(hwnd, GWL_WNDPROC, (LONG)pProc);
		return pProc(hwnd, message, wParam, lParam);
	}

	return DefWindowProc(hwnd, message, wParam, lParam);
}

LRESULT CALLBACK CWndUnknown::WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	CWndUnknown *pThis = (CWndUnknown*)hwnd;
	return pThis-&gt;ProcessWindowMessage(pThis-&gt;m_hwnd, message, wParam, lParam);
}

void* CWndUnknown::GetUnknownClassPtr()
{
	return this;
}

WNDPROC CWndUnknown::GetStartWndProc()
{
	return (WNDPROC)&amp;StartWindowProc;
}
</code></pre>
<p>CWndUnknown.h:</p>
<pre><code>#ifndef _CWNDUNKNOWN_H_
#define _CWNDUNKNOWN_H_

#pragma pack(push,1)
struct _WndProcThunk
{
	DWORD   m_mov;          // mov dword ptr [esp+0x4], pThis (esp+0x4 is hWnd)
	DWORD   m_this;
	BYTE    m_jmp;          // jmp WndProc
	DWORD   m_relproc;      // relative jmp
};
#pragma pack(pop)

class CWndProcThunk
{
public:
	_WndProcThunk thunk;
	void Init(WNDPROC WndProc, void* pThis);
};

class CWndUnknown
{
public:
	CWndUnknown();
	void* GetUnknownClassPtr();
	static WNDPROC GetStartWndProc();

protected:
	HWND			m_hwnd;
	CWndProcThunk	m_thunk;

	virtual LRESULT ProcessWindowMessage(HWND, UINT, WPARAM, LPARAM);

	static LRESULT CALLBACK StartWindowProc(HWND, UINT, WPARAM, LPARAM);
	static LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM);

};

#endif
</code></pre>
<p>einmaliges Initialisieren der Fensterklasse:</p>
<pre><code>wc.cbSize		= sizeof(WNDCLASSEX);
	wc.cbClsExtra	= 0;
	wc.cbWndExtra	= 0;
	wc.hbrBackground= (HBRUSH)GetStockObject(BLACK_BRUSH);
	wc.hCursor		= LoadCursor(0, IDC_ARROW);
	wc.hIcon		= 0;
	wc.hIconSm		= 0;
	wc.hInstance	= hInstance;
	wc.lpfnWndProc	= CWndUnknown::GetStartWndProc();
	wc.lpszClassName= g_pszUnknownClass;
	wc.lpszMenuName	= 0;
	wc.style		= 0;
	if(!RegisterClassEx(&amp;wc))
		return false;
</code></pre>
<p>(g_pszUnknownClass musst du irgendwo global definiern, eigentlich könnte man es auch als static in die klasse rein, aber kA)</p>
<p>willst jetzt ein fenster haben das in der Klasse CWndMain ist, sieht diese klasse so aus (ausschnitt):</p>
<pre><code>#ifndef _CMAINWND_H_
#define _CMAINWND_H_

#include &quot;CWndUnknown.h&quot;

class CMainWnd : public CWndUnknown
{
public:
	CMainWnd();
	~CMainWnd();

private:
	HINSTANCE	m_hInstance;

	virtual LRESULT ProcessWindowMessage(HWND, UINT, WPARAM, LPARAM);
};

#endif
</code></pre>
<p>so erstellst du das fenster in der Klasse (CMainWnd::Create):</p>
<pre><code>HWND CMainWnd::Create()
{
	m_hInstance = GetModuleHandle(0);
	CreateWindowEx(0, g_pszUnknownClass, &quot;itel&quot;,
				WS_VISIBLE, 100, 100, 400, 600,
				0, 0, m_hInstance, GetUnknownClassPtr());
	return m_hwnd;
}
</code></pre>
<p>irgendwas schlummert in meinm kopf dass man m_hwnd nicht speichern darf und auch nicht klassmember sein darf, kA. s. CWndUnknown Klasse ^^.<br />
jo das wars.</p>
<p>mfg</p>
]]></description><link>https://www.c-plusplus.net/forum/post/886046</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/886046</guid><dc:creator><![CDATA[Black Shadow]]></dc:creator><pubDate>Wed, 05 Oct 2005 20:28:33 GMT</pubDate></item><item><title><![CDATA[Reply to WinAPI Objektorientiert on Wed, 05 Oct 2005 21:37:42 GMT]]></title><description><![CDATA[<p>So tief runter (Thunking) braucht man gar nicht.</p>
<p>Was ich oben gesagt habe, reicht.</p>
<p>(Falls ich ein passendes Codebeispiel finde, poste ich es hier; EDIT: nix! war wohl doch in einer Firma gewesen, wo ich das programmiert habe, sorry! <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /> )</p>
]]></description><link>https://www.c-plusplus.net/forum/post/886080</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/886080</guid><dc:creator><![CDATA[Power Off]]></dc:creator><pubDate>Wed, 05 Oct 2005 21:37:42 GMT</pubDate></item><item><title><![CDATA[Reply to WinAPI Objektorientiert on Thu, 06 Oct 2005 08:56:20 GMT]]></title><description><![CDATA[<p>Nee, so schwer ist das auch nicht. Ich habe das bei mir in eine Basisklasse &quot;Widget&quot; gepackt, die so aussieht:</p>
<pre><code class="language-cpp">// Widget.h
class Widget {
public:
   Widget();
   virtual ~Widget();

   const HWND getHandle();

protected:
   static LRESULT CALLBACK WindowProc(HWND _Handle, UINT _Message, WPARAM _wParam, LPARAM _lParam);

   virtual LRESULT DefWindowProc(UINT _Message, WPARAM _wParam, LPARAM _lParam);

   HWND         Handle;
   WNDPROC      PrevWndProc;

private:

};
</code></pre>
<pre><code class="language-cpp">// Widget.cpp
#include &quot;Widget.h&quot;

// -----------------------------------------------------------------------------
Widget::Widget() : Handle(0), PrevWndProc(0), Text(&quot;&quot;), Parent(0), 
                   BackgroundColor(0xFFFFFF), PaintBackground(true) {
}

Widget::~Widget() {
}
// -----------------------------------------------------------------------------
const HWND Widget::getHandle() {
   return reinterpret_cast&lt;HWND&gt;(this-&gt;Handle);
}
// -----------------------------------------------------------------------------
LRESULT Widget::DefWindowProc(UINT _Message, WPARAM _wParam, LPARAM _lParam) {

	// hier Message-Verarbeitung

	if (this-&gt;PrevWndProc) {
      return ::CallWindowProc(this-&gt;PrevWndProc, this-&gt;getHandle(), _Message, _wParam, _lParam);
	}

   return ::DefWindowProc(this-&gt;getHandle(), _Message, _wParam, _lParam);
}
// -----------------------------------------------------------------------------
// default windowproc for all objects based on this class
LRESULT CALLBACK Widget::WindowProc(HWND _Handle, UINT _Message, WPARAM _wParam, LPARAM _lParam) {

	if(_Message == WM_CREATE) { // übergebenen this merken
		::SetWindowLong(_Handle, GWL_USERDATA, (LONG)((CREATESTRUCT*)_lParam)-&gt;lpCreateParams);
	}

	Widget* pReceiver = reinterpret_cast&lt;Widget*&gt;(GetWindowLong(_Handle, GWL_USERDATA));

	if (!pReceiver) {
      return ::DefWindowProc(_Handle, _Message, _wParam, _lParam);
	}

	return pReceiver-&gt;DefWindowProc(_Message, _wParam, _lParam);
}
// -----------------------------------------------------------------------------
</code></pre>
<p>In einer weiteren Klasse (hier Window) kann man dann CreateWindow z.B. so aufrufen:</p>
<pre><code class="language-cpp">...
wc.lpfnWndProc   = Widget::WindowProc;
...
   this-&gt;Handle = ::CreateWindowEx(0,
                                   &quot;Window&quot;,
                                   this-&gt;Text.c_str(),
                                   WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | (this-&gt;Parent ? WS_CHILD : 0),
                                   _x, _y, _Width, _Height,
                                   (this-&gt;Parent ? this-&gt;Parent-&gt;getHandle() : 0), 
                                   0, 0, this);
</code></pre>
<p>Wichtig dabei ist, dass der this-Zeiger übergeben wird und vorher die WndProc der Fensterklasse auf die static-WndProc von Widget gesetzt wird. Bei Buttons, etc. muss man die halt später mit SetWindowLong(Ptr) ändern, da diese ja bereits eine registierte Fensterklasse haben. Aber das war's dann auch schon.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/886218</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/886218</guid><dc:creator><![CDATA[mantiz]]></dc:creator><pubDate>Thu, 06 Oct 2005 08:56:20 GMT</pubDate></item><item><title><![CDATA[Reply to WinAPI Objektorientiert on Thu, 06 Oct 2005 09:02:23 GMT]]></title><description><![CDATA[<p>mit dieser lösung verpasst man aber ein paar nachrichten. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f921.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--clown_face"
      title=":clown:"
      alt="🤡"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/886225</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/886225</guid><dc:creator><![CDATA[..............]]></dc:creator><pubDate>Thu, 06 Oct 2005 09:02:23 GMT</pubDate></item><item><title><![CDATA[Reply to WinAPI Objektorientiert on Thu, 06 Oct 2005 09:08:29 GMT]]></title><description><![CDATA[<p>Weiß jetzt nicht genau, was Du meinst. Bei eigenen Fenstern müsstest Du alle bekommen, bei Buttons, etc., die die bereits eine registrierte Fensterklasse haben, verpasst man die CREATE-Messages, was aber klar sein dürfte, weil man da die WndProc erst ändern kann, wenn man nen Handle auf der Button hat, welches man aber erst bekommt, wenn der Button erzeugt wurde.</p>
<p>Wenn es hierfür noch andere Möglichkeiten gibt, nur her damit. <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/886233</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/886233</guid><dc:creator><![CDATA[mantiz]]></dc:creator><pubDate>Thu, 06 Oct 2005 09:08:29 GMT</pubDate></item><item><title><![CDATA[Reply to WinAPI Objektorientiert on Thu, 06 Oct 2005 09:52:51 GMT]]></title><description><![CDATA[<blockquote>
<p>Und wie kann ich es bewältigen das jede WindowFrame Instanz eine eigene WndProc bekommt, sodass ich für jedes &quot;Hauptfenster&quot; die Nachrichten verarbeiten kann?</p>
</blockquote>
<p>Das beste Framework das ich jemals gehsen habe:<br />
<a href="http://download.nvidia.com/developer/Third_Party/Nature/NatureScene.zip" rel="nofollow">http://download.nvidia.com/developer/Third_Party/Nature/NatureScene.zip</a></p>
<p>bauste dir noch ne add Methode in die Window-Klasse und fertig <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>Window.add(new Label(&quot;Hallo Welt&quot;));</p>
<p>wenn du willst kann ich mal den ganzen Grafikcode rausschmeißen und es so programmieren, das Window.add(new Label(&quot;Hallo Welt&quot;)); funktioniert</p>
]]></description><link>https://www.c-plusplus.net/forum/post/886282</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/886282</guid><dc:creator><![CDATA[Vertexwahn]]></dc:creator><pubDate>Thu, 06 Oct 2005 09:52:51 GMT</pubDate></item><item><title><![CDATA[Reply to WinAPI Objektorientiert on Thu, 06 Oct 2005 18:46:52 GMT]]></title><description><![CDATA[<p>Würd mich freuen, wenn du es machst, aber ich brauche es zu OpeGL programmierung.</p>
<p>Ich wollte eine Anwendung mit Steuerelementen proggen, sodass ich einige OpenGL States Checken und ihre Eigenschaften lernen kann.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/886658</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/886658</guid><dc:creator><![CDATA[Tc++H]]></dc:creator><pubDate>Thu, 06 Oct 2005 18:46:52 GMT</pubDate></item></channel></rss>