<?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[Benutzerdefinierte(s) Steuerelement(klasse)]]></title><description><![CDATA[<p>Moin,</p>
<p>ich möchte mir eine eigene Klasse für ein Steuerelement schreiben und bin nun etwas ratlos ...</p>
<p>Ich habe die letzten Wochen recherchiert und gegoogled bis die Augen bluteten ... <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 />
Diverse Quellen habe ich gefunden und durchforstet, u.a. hier im Forum.</p>
<p>Das Ergebnis lässt sich kompilieren, gibt aber 278 Warnungen aus.</p>
<p>Nun das Problem: Die Fensterprozedur wird nicht aufgerufen, bzw. das Fenster wird nicht erstellt !?</p>
<p>Ich hoffe, dass mir jemand helfen kann das Problem zu lösen ...</p>
<p>Bevor ich nun den Beispielcode poste, noch ein paar Erläuterungen wie der Ablauf sein soll:</p>
<p>Das Steuerelement soll ganz normal wie jedes Fenster erstellt werden, d.h. das Klassen-Objekt für jedes Steuerelement soll dynamisch zur Laufzeit erstellt werden.<br />
Man muss lediglich zuvor die Fenster-Klasse initialisieren/registrieren, dies soll über eine globale Funktion möglich sein.</p>
<p>Der benötigte Zeiger auf das Klassen-Objekt soll über cbWndExtra erhalten/gesetzt werden, da ich GWL_USERDATA vllt noch anderweitig nutzen möchte.</p>
<p>Der Rest sollte aus dem Code ersichtlich sein. <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>
<p>Bevor ich es vergesse zu Erwähnen, ich bin noch in der Lernphase und dies ist mein erster Versuch eine &quot;eigene&quot; Klasse zu kreiren. <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><strong>Klasse.h</strong></p>
<pre><code class="language-cpp">#ifndef CUSTOM_BUTTON_H
#define CUSTOM_BUTTON_H

#include &lt;windows.h&gt;

void InitCustomButtonControls();

struct BUTTONRECT {
    int left;
    int top;
    int width;
    int height;
};

class BmpButton {
    public:
        BmpButton(){}      // Standardkonstruktor
        BmpButton(HWND hwnd, CREATESTRUCT *cs);
        virtual ~BmpButton();

        static bool InitButtonClass();
        void PaintBitmap(HWND hwnd, HBITMAP bmp);

        static LRESULT CALLBACK StartWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

        LRESULT BmpButtonProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

    private:
        HWND       hWndCtrl;
        HMENU      BtnID;
        HBITMAP    BtnDefault;
        HBITMAP    BtnOnHover;
        HBITMAP    BtnOnClick;
        BUTTONRECT BtnRect;
        bool       IsOnHover;

};

#endif
</code></pre>
<p><strong>Klasse.cpp</strong></p>
<pre><code class="language-cpp">#include &quot;CustomButton.h&quot;

const TCHAR buttonClassName [] = TEXT(&quot;BmpButtonClass&quot;);

        /////////////////////////////////////////////////////
        //  Fensterklasse initialisieren und registrieren  //
        /////////////////////////////////////////////////////

void InitCustomButtonControls() {

    bool result = BmpButton::InitButtonClass();

    if (!result)
        ::MessageBox(NULL, TEXT(&quot;Die Fensterklasse konnte nicht registriert werden!&quot;),
                            buttonClassName, MB_ICONERROR);
}

bool BmpButton::InitButtonClass() {

    WNDCLASSEX BtnWcl;

    BtnWcl.hInstance      = (HINSTANCE) ::GetModuleHandle(0);
    BtnWcl.lpszClassName  = buttonClassName;
    BtnWcl.lpfnWndProc    = ::BmpButton::StartWndProc;
    BtnWcl.style          = CS_DBLCLKS;
    BtnWcl.cbSize         = sizeof(WNDCLASSEX);
    BtnWcl.hIcon          = NULL;
    BtnWcl.hIconSm        = NULL;
    BtnWcl.hCursor        = NULL;
    BtnWcl.lpszMenuName   = NULL;
    BtnWcl.cbClsExtra     = 0;
    BtnWcl.cbWndExtra     = sizeof(BmpButton *);
    BtnWcl.hbrBackground  = (HBRUSH) ::GetStockObject(WHITE_BRUSH);

    if (!::RegisterClassEx (&amp;BtnWcl)) {
        return false;
    } else {
        return true;
    }
}

        ///////////////////////
        //  Konstruktor      //
        ///////////////////////

BmpButton::BmpButton(HWND hwnd, CREATESTRUCT *cs) {

    hWndCtrl       = hwnd;
    BtnID          = cs-&gt;hMenu;
    BtnRect.left   = cs-&gt;x;
    BtnRect.top    = cs-&gt;y;
    BtnRect.width  = cs-&gt;cx;
    BtnRect.height = cs-&gt;cy;

}

        ///////////////////////
        //  Destruktor       //
        ///////////////////////

BmpButton::~BmpButton() {
    // Aufräumen
    ::DeleteObject(BtnDefault);
    ::DeleteObject(BtnOnHover);
    ::DeleteObject(BtnOnClick);
}

        ///////////////////////
        //  Startprozedur    //
        ///////////////////////

LRESULT CALLBACK BmpButton::StartWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {

    BmpButton *bbp = reinterpret_cast&lt;BmpButton *&gt; (::GetWindowLong(hwnd, 0));

    if (bbp == 0) {
        if (msg == WM_NCCREATE) {
            bbp = new BmpButton(hwnd, reinterpret_cast&lt;LPCREATESTRUCT&gt; (lParam));
            ::SetWindowLong(hwnd, 0, reinterpret_cast&lt;LONG&gt; (bbp));
            ::MessageBox(NULL, TEXT(&quot;WM_NCCREATE OK&quot;), buttonClassName, MB_ICONINFORMATION);
            return bbp-&gt;BmpButtonProc(hwnd, msg, wParam, lParam);
        } else {
            return ::DefWindowProc(hwnd, msg, wParam, lParam);
        }
    } else {
        if (msg == WM_NCDESTROY) {
            delete bbp;
            ::SetWindowLong(hwnd, 0, 0);
            return ::DefWindowProc(hwnd, msg, wParam, lParam);
        } else {
            return bbp-&gt;BmpButtonProc(hwnd, msg, wParam, lParam);
        }
    }
}

        ///////////////////////
        //  Fensterprozedur  //
        ///////////////////////

LRESULT BmpButton::BmpButtonProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {

    BmpButton *bbp = reinterpret_cast&lt;BmpButton *&gt; (::GetWindowLong(hwnd, 0));

    switch (msg) {
        case WM_MOUSEHOVER:
            if (bbp-&gt;IsOnHover = false) {
                bbp-&gt;PaintBitmap(hwnd, bbp-&gt;BtnOnHover);
                bbp-&gt;IsOnHover = true;
            }
            break;

        case WM_MOUSELEAVE:
            bbp-&gt;PaintBitmap(hwnd, bbp-&gt;BtnDefault);
            bbp-&gt;IsOnHover = false;
            break;

        case WM_LBUTTONDOWN:
            ::SetWindowPos(hwnd, HWND_TOPMOST, bbp-&gt;BtnRect.left + 1,
                                             bbp-&gt;BtnRect.top  + 1,
                                             bbp-&gt;BtnRect.width  - 1,
                                             bbp-&gt;BtnRect.height - 1,
                                             SWP_SHOWWINDOW);
            bbp-&gt;PaintBitmap(hwnd, bbp-&gt;BtnOnClick);
            break;

        case WM_LBUTTONUP:
            ::SetWindowPos(hwnd, HWND_TOPMOST, bbp-&gt;BtnRect.left,
                                             bbp-&gt;BtnRect.top,
                                             bbp-&gt;BtnRect.width,
                                             bbp-&gt;BtnRect.height,
                                             SWP_SHOWWINDOW);
            bbp-&gt;PaintBitmap(hwnd, bbp-&gt;BtnOnHover);
            ::SendMessage(GetParent(hwnd), WM_COMMAND, 0, 0);
            break;

        case WM_KEYDOWN:
            break;

        case WM_PAINT:
            //bbp-&gt;PaintBitmap(hwnd, bbp-&gt;BtnOnHover);
            break;
        default:
            return ::DefWindowProc (hwnd, msg, wParam, lParam);
    }

    return 0;

}

        ////////////////////////
        //  Fenster Zeichnen  //
        ////////////////////////

void BmpButton::PaintBitmap(HWND hwnd, HBITMAP hbmp) {

    HDC hdc, hdcMem;
    RECT rect;
    HBITMAP hbmOld;

    GetWindowRect(hwnd, &amp;rect);

    hdc    = GetDC(hwnd);
    hdcMem = CreateCompatibleDC(hdc);
    hbmOld = (HBITMAP) SelectObject(hdcMem, hbmp);
    BitBlt(hdc, 0, 0, BtnRect.width, BtnRect.height, hdcMem, 0, 0, SRCCOPY);
    SelectObject(hdcMem, hbmOld);
    DeleteDC(hdc);

}
</code></pre>
<p><strong>Main.cpp</strong></p>
<pre><code class="language-cpp">#include &quot;stdafx.h&quot;
#include &quot;Resource.h&quot;
#include &quot;BmpButton.h&quot;

#define IDC_BUTTON_1    1

LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

char szClassName[ ] = &quot;MainWndClass&quot;;

int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow)
{
    HWND hwnd;
    MSG messages;
    WNDCLASSEX wincl;

    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;
    wincl.style = CS_DBLCLKS;
    wincl.cbSize = sizeof (WNDCLASSEX);
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;
    wincl.cbClsExtra = 0;
    wincl.cbWndExtra = 0;
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

    if (!RegisterClassEx (&amp;wincl))
        return 0;

    hwnd = CreateWindowEx (
           0,
           szClassName,
           TEXT(&quot;Test the Custom Control ...&quot;),
           WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
           CW_USEDEFAULT,
           CW_USEDEFAULT,
           544,
           375,
           HWND_DESKTOP,
           NULL,
           hThisInstance,
           NULL
           );

    ShowWindow (hwnd, nCmdShow);
    UpdateWindow(hwnd);

    // Custom Control-Klasse initialisieren/registrieren
    InitBmpButtonControls();

    while (GetMessage (&amp;messages, NULL, 0, 0))
    {
        TranslateMessage(&amp;messages);
        DispatchMessage(&amp;messages);
    }

    return messages.wParam;
}

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HWND hwndButton;
    HWND hwndBut;
    HINSTANCE hInst = (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE);

    switch (message)
    {
        case WM_CREATE:
            hwndButton = CreateWindowEx(0, TEXT(&quot;BmpButtonClass&quot;), TEXT(&quot;&quot;),
                                WS_CHILD | WS_VISIBLE | WS_POPUP | WS_TABSTOP | WS_CLIPSIBLINGS,
                                20, 20, 100, 25,
                                hwnd, (HMENU) IDC_BUTTON_1, hInst, NULL);
            hwndBut = CreateWindowEx(0, TEXT(&quot;Button&quot;), TEXT(&quot;&quot;),
                                WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_CLIPSIBLINGS,
                                60, 60, 100, 25,
                                hwnd, (HMENU) 2, hInst, NULL);
            break;

        case WM_DESTROY:
            PostQuitMessage (0);
            break;

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

    return 0;
}
</code></pre>
<p>So, das isses im groben ...</p>
<p>Ich habe mich auch durch den Sourcecode von Scintilla gewühlt, da ist es eigentlich genauso wie ich es habe, aber meines funzt eben nicht ...</p>
<p>Vielen Dank</p>
<p>Gruß</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/217302/benutzerdefinierte-s-steuerelement-klasse</link><generator>RSS for Node</generator><lastBuildDate>Wed, 15 Apr 2026 09:22:49 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/217302.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 06 Jul 2008 06:19:14 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Benutzerdefinierte(s) Steuerelement(klasse) on Sun, 06 Jul 2008 07:17:41 GMT]]></title><description><![CDATA[<p>Moin,</p>
<p>ich möchte mir eine eigene Klasse für ein Steuerelement schreiben und bin nun etwas ratlos ...</p>
<p>Ich habe die letzten Wochen recherchiert und gegoogled bis die Augen bluteten ... <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 />
Diverse Quellen habe ich gefunden und durchforstet, u.a. hier im Forum.</p>
<p>Das Ergebnis lässt sich kompilieren, gibt aber 278 Warnungen aus.</p>
<p>Nun das Problem: Die Fensterprozedur wird nicht aufgerufen, bzw. das Fenster wird nicht erstellt !?</p>
<p>Ich hoffe, dass mir jemand helfen kann das Problem zu lösen ...</p>
<p>Bevor ich nun den Beispielcode poste, noch ein paar Erläuterungen wie der Ablauf sein soll:</p>
<p>Das Steuerelement soll ganz normal wie jedes Fenster erstellt werden, d.h. das Klassen-Objekt für jedes Steuerelement soll dynamisch zur Laufzeit erstellt werden.<br />
Man muss lediglich zuvor die Fenster-Klasse initialisieren/registrieren, dies soll über eine globale Funktion möglich sein.</p>
<p>Der benötigte Zeiger auf das Klassen-Objekt soll über cbWndExtra erhalten/gesetzt werden, da ich GWL_USERDATA vllt noch anderweitig nutzen möchte.</p>
<p>Der Rest sollte aus dem Code ersichtlich sein. <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>
<p>Bevor ich es vergesse zu Erwähnen, ich bin noch in der Lernphase und dies ist mein erster Versuch eine &quot;eigene&quot; Klasse zu kreiren. <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><strong>Klasse.h</strong></p>
<pre><code class="language-cpp">#ifndef CUSTOM_BUTTON_H
#define CUSTOM_BUTTON_H

#include &lt;windows.h&gt;

void InitCustomButtonControls();

struct BUTTONRECT {
    int left;
    int top;
    int width;
    int height;
};

class BmpButton {
    public:
        BmpButton(){}      // Standardkonstruktor
        BmpButton(HWND hwnd, CREATESTRUCT *cs);
        virtual ~BmpButton();

        static bool InitButtonClass();
        void PaintBitmap(HWND hwnd, HBITMAP bmp);

        static LRESULT CALLBACK StartWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

        LRESULT BmpButtonProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

    private:
        HWND       hWndCtrl;
        HMENU      BtnID;
        HBITMAP    BtnDefault;
        HBITMAP    BtnOnHover;
        HBITMAP    BtnOnClick;
        BUTTONRECT BtnRect;
        bool       IsOnHover;

};

#endif
</code></pre>
<p><strong>Klasse.cpp</strong></p>
<pre><code class="language-cpp">#include &quot;CustomButton.h&quot;

const TCHAR buttonClassName [] = TEXT(&quot;BmpButtonClass&quot;);

        /////////////////////////////////////////////////////
        //  Fensterklasse initialisieren und registrieren  //
        /////////////////////////////////////////////////////

void InitCustomButtonControls() {

    bool result = BmpButton::InitButtonClass();

    if (!result)
        ::MessageBox(NULL, TEXT(&quot;Die Fensterklasse konnte nicht registriert werden!&quot;),
                            buttonClassName, MB_ICONERROR);
}

bool BmpButton::InitButtonClass() {

    WNDCLASSEX BtnWcl;

    BtnWcl.hInstance      = (HINSTANCE) ::GetModuleHandle(0);
    BtnWcl.lpszClassName  = buttonClassName;
    BtnWcl.lpfnWndProc    = ::BmpButton::StartWndProc;
    BtnWcl.style          = CS_DBLCLKS;
    BtnWcl.cbSize         = sizeof(WNDCLASSEX);
    BtnWcl.hIcon          = NULL;
    BtnWcl.hIconSm        = NULL;
    BtnWcl.hCursor        = NULL;
    BtnWcl.lpszMenuName   = NULL;
    BtnWcl.cbClsExtra     = 0;
    BtnWcl.cbWndExtra     = sizeof(BmpButton *);
    BtnWcl.hbrBackground  = (HBRUSH) ::GetStockObject(WHITE_BRUSH);

    if (!::RegisterClassEx (&amp;BtnWcl)) {
        return false;
    } else {
        return true;
    }
}

        ///////////////////////
        //  Konstruktor      //
        ///////////////////////

BmpButton::BmpButton(HWND hwnd, CREATESTRUCT *cs) {

    hWndCtrl       = hwnd;
    BtnID          = cs-&gt;hMenu;
    BtnRect.left   = cs-&gt;x;
    BtnRect.top    = cs-&gt;y;
    BtnRect.width  = cs-&gt;cx;
    BtnRect.height = cs-&gt;cy;

}

        ///////////////////////
        //  Destruktor       //
        ///////////////////////

BmpButton::~BmpButton() {
    // Aufräumen
    ::DeleteObject(BtnDefault);
    ::DeleteObject(BtnOnHover);
    ::DeleteObject(BtnOnClick);
}

        ///////////////////////
        //  Startprozedur    //
        ///////////////////////

LRESULT CALLBACK BmpButton::StartWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {

    BmpButton *bbp = reinterpret_cast&lt;BmpButton *&gt; (::GetWindowLong(hwnd, 0));

    if (bbp == 0) {
        if (msg == WM_NCCREATE) {
            bbp = new BmpButton(hwnd, reinterpret_cast&lt;LPCREATESTRUCT&gt; (lParam));
            ::SetWindowLong(hwnd, 0, reinterpret_cast&lt;LONG&gt; (bbp));
            ::MessageBox(NULL, TEXT(&quot;WM_NCCREATE OK&quot;), buttonClassName, MB_ICONINFORMATION);
            return bbp-&gt;BmpButtonProc(hwnd, msg, wParam, lParam);
        } else {
            return ::DefWindowProc(hwnd, msg, wParam, lParam);
        }
    } else {
        if (msg == WM_NCDESTROY) {
            delete bbp;
            ::SetWindowLong(hwnd, 0, 0);
            return ::DefWindowProc(hwnd, msg, wParam, lParam);
        } else {
            return bbp-&gt;BmpButtonProc(hwnd, msg, wParam, lParam);
        }
    }
}

        ///////////////////////
        //  Fensterprozedur  //
        ///////////////////////

LRESULT BmpButton::BmpButtonProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {

    BmpButton *bbp = reinterpret_cast&lt;BmpButton *&gt; (::GetWindowLong(hwnd, 0));

    switch (msg) {
        case WM_MOUSEHOVER:
            if (bbp-&gt;IsOnHover = false) {
                bbp-&gt;PaintBitmap(hwnd, bbp-&gt;BtnOnHover);
                bbp-&gt;IsOnHover = true;
            }
            break;

        case WM_MOUSELEAVE:
            bbp-&gt;PaintBitmap(hwnd, bbp-&gt;BtnDefault);
            bbp-&gt;IsOnHover = false;
            break;

        case WM_LBUTTONDOWN:
            ::SetWindowPos(hwnd, HWND_TOPMOST, bbp-&gt;BtnRect.left + 1,
                                             bbp-&gt;BtnRect.top  + 1,
                                             bbp-&gt;BtnRect.width  - 1,
                                             bbp-&gt;BtnRect.height - 1,
                                             SWP_SHOWWINDOW);
            bbp-&gt;PaintBitmap(hwnd, bbp-&gt;BtnOnClick);
            break;

        case WM_LBUTTONUP:
            ::SetWindowPos(hwnd, HWND_TOPMOST, bbp-&gt;BtnRect.left,
                                             bbp-&gt;BtnRect.top,
                                             bbp-&gt;BtnRect.width,
                                             bbp-&gt;BtnRect.height,
                                             SWP_SHOWWINDOW);
            bbp-&gt;PaintBitmap(hwnd, bbp-&gt;BtnOnHover);
            ::SendMessage(GetParent(hwnd), WM_COMMAND, 0, 0);
            break;

        case WM_KEYDOWN:
            break;

        case WM_PAINT:
            //bbp-&gt;PaintBitmap(hwnd, bbp-&gt;BtnOnHover);
            break;
        default:
            return ::DefWindowProc (hwnd, msg, wParam, lParam);
    }

    return 0;

}

        ////////////////////////
        //  Fenster Zeichnen  //
        ////////////////////////

void BmpButton::PaintBitmap(HWND hwnd, HBITMAP hbmp) {

    HDC hdc, hdcMem;
    RECT rect;
    HBITMAP hbmOld;

    GetWindowRect(hwnd, &amp;rect);

    hdc    = GetDC(hwnd);
    hdcMem = CreateCompatibleDC(hdc);
    hbmOld = (HBITMAP) SelectObject(hdcMem, hbmp);
    BitBlt(hdc, 0, 0, BtnRect.width, BtnRect.height, hdcMem, 0, 0, SRCCOPY);
    SelectObject(hdcMem, hbmOld);
    DeleteDC(hdc);

}
</code></pre>
<p><strong>Main.cpp</strong></p>
<pre><code class="language-cpp">#include &quot;stdafx.h&quot;
#include &quot;Resource.h&quot;
#include &quot;BmpButton.h&quot;

#define IDC_BUTTON_1    1

LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

char szClassName[ ] = &quot;MainWndClass&quot;;

int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow)
{
    HWND hwnd;
    MSG messages;
    WNDCLASSEX wincl;

    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;
    wincl.style = CS_DBLCLKS;
    wincl.cbSize = sizeof (WNDCLASSEX);
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;
    wincl.cbClsExtra = 0;
    wincl.cbWndExtra = 0;
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

    if (!RegisterClassEx (&amp;wincl))
        return 0;

    hwnd = CreateWindowEx (
           0,
           szClassName,
           TEXT(&quot;Test the Custom Control ...&quot;),
           WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
           CW_USEDEFAULT,
           CW_USEDEFAULT,
           544,
           375,
           HWND_DESKTOP,
           NULL,
           hThisInstance,
           NULL
           );

    ShowWindow (hwnd, nCmdShow);
    UpdateWindow(hwnd);

    // Custom Control-Klasse initialisieren/registrieren
    InitBmpButtonControls();

    while (GetMessage (&amp;messages, NULL, 0, 0))
    {
        TranslateMessage(&amp;messages);
        DispatchMessage(&amp;messages);
    }

    return messages.wParam;
}

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HWND hwndButton;
    HWND hwndBut;
    HINSTANCE hInst = (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE);

    switch (message)
    {
        case WM_CREATE:
            hwndButton = CreateWindowEx(0, TEXT(&quot;BmpButtonClass&quot;), TEXT(&quot;&quot;),
                                WS_CHILD | WS_VISIBLE | WS_POPUP | WS_TABSTOP | WS_CLIPSIBLINGS,
                                20, 20, 100, 25,
                                hwnd, (HMENU) IDC_BUTTON_1, hInst, NULL);
            hwndBut = CreateWindowEx(0, TEXT(&quot;Button&quot;), TEXT(&quot;&quot;),
                                WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_CLIPSIBLINGS,
                                60, 60, 100, 25,
                                hwnd, (HMENU) 2, hInst, NULL);
            break;

        case WM_DESTROY:
            PostQuitMessage (0);
            break;

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

    return 0;
}
</code></pre>
<p>So, das isses im groben ...</p>
<p>Ich habe mich auch durch den Sourcecode von Scintilla gewühlt, da ist es eigentlich genauso wie ich es habe, aber meines funzt eben nicht ...</p>
<p>Vielen Dank</p>
<p>Gruß</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1541676</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1541676</guid><dc:creator><![CDATA[C++Greenhorn 0]]></dc:creator><pubDate>Sun, 06 Jul 2008 07:17:41 GMT</pubDate></item><item><title><![CDATA[Reply to Benutzerdefinierte(s) Steuerelement(klasse) on Sun, 06 Jul 2008 06:43:25 GMT]]></title><description><![CDATA[<p>C++Greenhorn schrieb:</p>
<blockquote>
<p>Moin,<br />
Nun das Problem: Die Fensterprozedur wird nicht aufgerufen, bzw. das Fenster wird nicht erstellt !?</p>
</blockquote>
<p>Dann scheint es an der Parametrierung der Fensterklasse zu liegen. Die hast Du aber vorsichtshalber nicht gepostet. Oder welches &quot;Fenster&quot; meinst Du?</p>
<p>Außerdem wäre es gut, wenn Du Dich zwischen OOP und prozeduraler Programmierung entscheiden könntest. <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/1541681</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1541681</guid><dc:creator><![CDATA[Elektronix]]></dc:creator><pubDate>Sun, 06 Jul 2008 06:43:25 GMT</pubDate></item><item><title><![CDATA[Reply to Benutzerdefinierte(s) Steuerelement(klasse) on Sun, 06 Jul 2008 07:18:34 GMT]]></title><description><![CDATA[<p>Elektronix schrieb:</p>
<blockquote>
<p>Dann scheint es an der Parametrierung der Fensterklasse zu liegen. Die hast Du aber vorsichtshalber nicht gepostet. Oder welches &quot;Fenster&quot; meinst Du?</p>
</blockquote>
<p>Die Fensterprozedur ::BmpButton::StartWndProc wird nicht aufgerufen.</p>
<p>Elektronix schrieb:</p>
<blockquote>
<p>Außerdem wäre es gut, wenn Du Dich zwischen OOP und prozeduraler Programmierung entscheiden könntest. <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>Ähm, was genau meinst Du denn damit ? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /></p>
<p>Gruß</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1541684</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1541684</guid><dc:creator><![CDATA[C++Greenhorn 0]]></dc:creator><pubDate>Sun, 06 Jul 2008 07:18:34 GMT</pubDate></item><item><title><![CDATA[Reply to Benutzerdefinierte(s) Steuerelement(klasse) on Sun, 06 Jul 2008 09:57:05 GMT]]></title><description><![CDATA[<p>Daß Du die Klasse des Hauptfensters in guter alter C-Manier erstellst</p>
<pre><code>WNDCLASSEX wincl;
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;
    wincl.style = CS_DBLCLKS;
    wincl.cbSize = sizeof (WNDCLASSEX);
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;
    wincl.cbClsExtra = 0;
    wincl.cbWndExtra = 0;
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
</code></pre>
<p>, für die BmpButton dann aber ein C++-Objekt erstellst:</p>
<pre><code>class BmpButton {
    public:
        BmpButton(){}      // Standardkonstruktor
        BmpButton(HWND hwnd, CREATESTRUCT *cs);
        virtual ~BmpButton();

        static bool InitButtonClass();
        void PaintBitmap(HWND hwnd, HBITMAP bmp);

        static LRESULT CALLBACK StartWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

        LRESULT BmpButtonProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

    private:
        HWND       hWndCtrl;
        HMENU      BtnID;
        HBITMAP    BtnDefault;
        HBITMAP    BtnOnHover;
        HBITMAP    BtnOnClick;
        BUTTONRECT BtnRect;
        bool       IsOnHover;

};
</code></pre>
<p>Es spricht nichts dagegen, für die WinAPI eigene Wrapper-Klassen zu erstellen. Dann sollte man es aber einheitlich machen und nicht C und C++ bunt durcheinander würfeln.</p>
<p>Übrigens: Für die Structur ButtonRect stellt die WinAPI schon eine Struct RECT bereit.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1541754</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1541754</guid><dc:creator><![CDATA[Elektronix]]></dc:creator><pubDate>Sun, 06 Jul 2008 09:57:05 GMT</pubDate></item><item><title><![CDATA[Reply to Benutzerdefinierte(s) Steuerelement(klasse) on Thu, 10 Jul 2008 06:22:19 GMT]]></title><description><![CDATA[<p>Elektronix schrieb:</p>
<blockquote>
<p>Daß Du die Klasse des Hauptfensters in guter alter C-Manier erstellst, für die BmpButton dann aber ein C++-Objekt erstellst:<br />
...</p>
<p>Es spricht nichts dagegen, für die WinAPI eigene Wrapper-Klassen zu erstellen. Dann sollte man es aber einheitlich machen und nicht C und C++ bunt durcheinander würfeln.</p>
</blockquote>
<p>Ich wollte eigentlich nur eine eigene Steuerelement-Klasse schreiben und das soll in C++ ja recht einfach sein, wie ich bei meinen Recherchen immer wieder zu lesen bekam.<br />
Wie das Hauptfenster erstellt wird - ob nun C, C++ oder meinetwegen auch sonstirgendwas -, ist mir persönlich egal, mir kommt es im Moment nur auf die zu erstellende Klasse an.</p>
<p>Elektronix schrieb:</p>
<blockquote>
<p>Übrigens: Für die Structur ButtonRect stellt die WinAPI schon eine Struct RECT bereit.</p>
</blockquote>
<p>Die Struktur RECT habe ich nicht benutzt, weil sie mir eben nicht die Infos liefert, die ich erhalten/speichern möchte.</p>
<p>So, nachdem mein Programmierstil und Code nun ordentlich madig geredet wurde, wäre ich für ein paar konstruktive Antworten dankbar. <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>So long</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1544679</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1544679</guid><dc:creator><![CDATA[C++Greenhorn 0]]></dc:creator><pubDate>Thu, 10 Jul 2008 06:22:19 GMT</pubDate></item><item><title><![CDATA[Reply to Benutzerdefinierte(s) Steuerelement(klasse) on Thu, 10 Jul 2008 12:58:52 GMT]]></title><description><![CDATA[<p>C++Greenhorn schrieb:</p>
<blockquote>
<p>Elektronix schrieb:</p>
<blockquote>
<p>Daß Du die Klasse des Hauptfensters in guter alter C-Manier erstellst, für die BmpButton dann aber ein C++-Objekt erstellst:<br />
...</p>
<p>Es spricht nichts dagegen, für die WinAPI eigene Wrapper-Klassen zu erstellen. Dann sollte man es aber einheitlich machen und nicht C und C++ bunt durcheinander würfeln.</p>
</blockquote>
<p>Ich wollte eigentlich nur eine eigene Steuerelement-Klasse schreiben und das soll in C++ ja recht einfach sein, wie ich bei meinen Recherchen immer wieder zu lesen bekam.<br />
Wie das Hauptfenster erstellt wird - ob nun C, C++ oder meinetwegen auch sonstirgendwas -, ist mir persönlich egal, mir kommt es im Moment nur auf die zu erstellende Klasse an.</p>
</blockquote>
<p>Nun, wie Du siehst, ist das nicht einfacher. Wenn Du sowas &quot;einfacher&quot; haben willst, mußt MFC einsetzen. Das ist aber ein Kapitel für sich.</p>
<p>Die Windows-Fensterklassen sind nicht gleich mit C++-Objektklassen. Fensterklassen werden erstellt, indem man die WNDCLASS(EX)-Struktur ausfüllt und RegisterClassEx() aufruft. Das ist reines C.</p>
<p>Man kann sowas auch in einen Wrapper packen, das entbindet Dich aber nicht davon, erstmal die Klassenstruktur auszufüllen und zu registrieren.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1545022</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1545022</guid><dc:creator><![CDATA[Elektronix]]></dc:creator><pubDate>Thu, 10 Jul 2008 12:58:52 GMT</pubDate></item><item><title><![CDATA[Reply to Benutzerdefinierte(s) Steuerelement(klasse) on Thu, 10 Jul 2008 14:50:29 GMT]]></title><description><![CDATA[<p>Nun, vielen Dank erstmal, dass Du meinem Problem überhaupt Aufmerksamkeit schenkst.</p>
<blockquote>
<p>Nun, wie Du siehst, ist das nicht einfacher.</p>
</blockquote>
<p>Das sehe ich wirklich <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="😃"
    /> <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 mich bis jetzt nach diesem Beispiel gerichtet <a href="http://www.catch22.net/tuts/custctrl.asp" rel="nofollow">http://www.catch22.net/tuts/custctrl.asp</a>, aber irgenetwas fehlt da ...</p>
<blockquote>
<p>Man kann sowas auch in einen Wrapper packen, das entbindet Dich aber nicht davon, erstmal die Klassenstruktur auszufüllen und zu registrieren.</p>
</blockquote>
<p>Aber genau das habe ich doch getan ...</p>
<pre><code class="language-cpp">/////////////////////////////////////////////////////
        //  Fensterklasse initialisieren und registrieren  //
        /////////////////////////////////////////////////////

void InitCustomButtonControls() {

    bool result = BmpButton::InitButtonClass();

    if (!result)
        ::MessageBox(NULL, TEXT(&quot;Die Fensterklasse konnte nicht registriert werden!&quot;),
                            buttonClassName, MB_ICONERROR);
}

bool BmpButton::InitButtonClass() {

    WNDCLASSEX BtnWcl;

    BtnWcl.hInstance      = (HINSTANCE) ::GetModuleHandle(0);
    BtnWcl.lpszClassName  = buttonClassName;
    BtnWcl.lpfnWndProc    = ::BmpButton::StartWndProc;
    BtnWcl.style          = CS_DBLCLKS;
    BtnWcl.cbSize         = sizeof(WNDCLASSEX);
    BtnWcl.hIcon          = NULL;
    BtnWcl.hIconSm        = NULL;
    BtnWcl.hCursor        = NULL;
    BtnWcl.lpszMenuName   = NULL;
    BtnWcl.cbClsExtra     = 0;
    BtnWcl.cbWndExtra     = sizeof(BmpButton *);
    BtnWcl.hbrBackground  = (HBRUSH) ::GetStockObject(WHITE_BRUSH);

    if (!::RegisterClassEx (&amp;BtnWcl)) {
        return false;
    } else {
        return true;
    }
}
</code></pre>
<p>Ich bin bei meinen weiteren Nachforschungen auf einige interessante Beispiele aufmerksam geworden, die es ähnlich wie Scintilla machen, mit einer Basisklasse und einer davon abgeleiteten ...<br />
Werde mich mal daran versuchen und Erfolg/Misserfolg posten.</p>
<p>Gruß<br />
Greenhorn</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1545151</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1545151</guid><dc:creator><![CDATA[C++Greenhorn 0]]></dc:creator><pubDate>Thu, 10 Jul 2008 14:50:29 GMT</pubDate></item></channel></rss>