i'm building the label1 class, but i'm getting bad results... so i ask: how can i use the SetWindowLongPtr() for use a window procedure?
(i can show the label and change it's properties... but i'm getting problems for active it's own window procedure :( )
see the entire code\class:

#include <windows.h>
#include <iostream>
#include <string>
#include <process.h>

using namespace std;
HWND hwnd;
HHOOK _hook;
LRESULT __stdcall HookCallback(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode >= 0)
    {
        // the action is valid: HC_ACTION.
        if (wParam == WM_LBUTTONUP)
        {
            MessageBox(NULL, "hi","hello",MB_OK);
        }
    }
   return CallNextHookEx(NULL, nCode, wParam, lParam);
}

class label
{
private:





public:

    label(HWND value)
    {

        hwnd = CreateWindowEx(
            WS_EX_LEFT| WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR,
            "STATIC",
            "hello world",
            SS_LEFT|WS_CHILD|WS_VISIBLE,
            0, 0, 100, 100,
            value,
            NULL,
            GetModuleHandle(NULL),
            NULL);
            SetWindowsHookEx(WH_CALLWNDPROC, HookCallback, NULL, 0);
            ShowWindow(hwnd,SW_SHOW);
            UpdateWindow(hwnd);
    }

    COORD GetSize()
    {
        RECT LabelSize;
        GetWindowRect(hwnd,&LabelSize);
        COORD crdSize={LabelSize.right-LabelSize.left,LabelSize.bottom-LabelSize.top};
        return crdSize;
    }

    void SetText(string text)
    {
        char* chrText=(char*)text.c_str();
        SetWindowText(hwnd, chrText);
    }


};

i'm trying connect the STATIC class with my own window procedure....
please some one give me more info
anotherthing: why i can't put the window procedure inside of the class?

Dani AI

Generated

Short summary: the crash at the line that calls inst->Move(...) is almost always because inst is NULL or otherwise invalid. That in turn comes from how the instance pointer and the original WNDPROC are being stored and retrieved, plus a few other bugs in the message handler and GetText implementation.

Why it fails (practical points for )

  • Storing data on the parent (SetProp(parent,...)) is fragile. If you create more than one label under the same parent, or the parent changes, the property will not reliably point to the correct instance. Store per-control data on the control itself (use SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)this) or SetProp(hwnd, ...)) and retrieve it from the control HWND inside your WndProc.
  • Casting function pointers to HANDLE and back is not portable/clean (and problematic on some architectures). For per-instance subclassing prefer SetWindowLongPtr(..., GWLP_WNDPROC, ...) and save the returned old proc, or use SetWindowSubclass/DefSubclassProc which is safer.
  • A WndProc must be a free/static function (non-static member methods have an implicit this and wrong signature). Your static WndProc is correct; make sure you obtain the instance pointer from GWLP_USERDATA (or subclass data) before calling instance methods and check it for NULL.
  • GetText is reading into an uninitialized char * — allocate a buffer (use GetWindowTextLength+1 or a std::string/vector) before calling GetWindowText.
  • Avoid static locals inside the WndProc for per-call data (they persist and can cause reentrancy problems). For coordinate extraction use the proper macros (GET_X_LPARAM/GET_Y_LPARAM) or cast as (int)(short)LOWORD/HIWORD but do not make them static.

Quick actionable checklist

  • After CreateWindowEx: SetWindowLongPtr(childHWND, GWLP_USERDATA, (LONG_PTR)this);
  • Subclass per-instance with SetWindowLongPtr(childHWND, GWLP_WNDPROC, (LONG_PTR)MyStaticWndProc) and keep the returned old proc to call via CallWindowProc.
  • In your WndProc: retrieve instance via GetWindowLongPtr(hwnd, GWLP_USERDATA) and guard against NULL; on WM_NCDESTROY restore original proc or remove subclass to avoid dangling pointers.
  • Fix GetText to allocate a buffer or use GetWindowTextLength; check all pointer casts for 64-bit safety.

Those changes remove the root causes (invalid instance pointer, bad buffer usage, unsafe pointer casts) and will prevent the intermittent crashes you see.

ok.. now works cool(with some help):

#include <windows.h>
#include <string>
#include <functional>
#define event(eventname, ... ) std::function<void(__VA_ARGS__ )> eventname

using namespace std;

const char *labelpropname = "Cambalinho";
const char *labelclassprop = "classaddr";

struct Position
{
    int X;
    int Y;
};

struct Size
{
    int Width;
    int Height;
};

class label
{
private:
    HWND hwnd;

    static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        WNDPROC oldproc = (WNDPROC)GetProp(GetParent(hwnd), labelpropname);

        label *inst = (label*)GetProp(GetParent(hwnd), labelclassprop);

        if (oldproc == NULL)
            MessageBox(NULL, "null", "null", MB_OK);


        switch(msg)
        {

            case WM_MOVE:
            {
                static int xPos = (int)(short) LOWORD(lParam);
                static int yPos = (int)(short) HIWORD(lParam);
                inst->Move(xPos,yPos);//why these line make my progra, give me an error for get support? :(
            }
            break;
            case WM_NCHITTEST:
                return DefWindowProc(hwnd, msg, wParam, lParam);

            case WM_LBUTTONUP:
                SetFocus(inst->hwnd);
                inst->SetText("Left mouse button up");
            break;

            case WM_MOUSEMOVE:
                inst->SetText("mouse move");

            break;

            case WM_KEYUP:

                inst->SetText(to_string(wParam));
            break;

                default:
            break;
        }

        return oldproc ? CallWindowProc(oldproc, hwnd, msg, wParam, lParam) : DefWindowProc(hwnd, msg, wParam, lParam);
    }

public:

    //is these 2 lines ok?
    //see the #define on top
    event(Create,(int x, int y));
    event(Move,(int x, int y));
    ~label()
    {
        DestroyWindow(hwnd);
        hwnd = 0;
    }

    label(HWND parent)
    {

        WNDCLASS wc;
        HINSTANCE mod = (HINSTANCE)GetModuleHandle(NULL);

        ZeroMemory(&wc, sizeof(WNDCLASS));
        GetClassInfo(mod, "STATIC", &wc);

        wc.hInstance = mod;
        wc.lpszClassName = "CSTATIC";

        // store the old WNDPROC of the EDIT window class
        SetProp(parent, labelpropname, (HANDLE)wc.lpfnWndProc);
        SetProp(parent, labelclassprop, (HANDLE)this);

        // replace it with local WNDPROC
        wc.lpfnWndProc = WndProc;

        // register the new window class, "ShEdit"
        if (!RegisterClass(&wc))
            MessageBox(NULL, "error in register", "error", MB_OK);

        hwnd = CreateWindowEx(
            WS_EX_LEFT| WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR,
            "CSTATIC",
            "hello",
            SS_LEFT|WS_CHILD|WS_VISIBLE,
            0, 0, 100, 100,
            parent,
            NULL,
            mod,
            NULL);

        if (hwnd == NULL)
            MessageBox(NULL, "error in create", "error", MB_OK);
    }

    COORD GetSize()
    {
        RECT LabelSize;
        GetWindowRect(hwnd,&LabelSize);
        COORD crdSize = {LabelSize.right-LabelSize.left,LabelSize.bottom-LabelSize.top};
        return crdSize;
    }

    void SetText(string text)
    {
        char* chrText = (char*)text.c_str();
        SetWindowText(hwnd, chrText);
    }

    string GetText()
    {
        char *lbltext;
        GetWindowText(hwnd,lbltext,255);
        string strtext=lbltext;
        return strtext;
    }
};

please see the line 45, these line can crash my program and i don't understand why. these line is dependent of lines 77, 78 and 4.
heres the image:

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.