how can pointer a class?

heres my form class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/////////For EVENTS//////////////
#if defined __GNUC__
    #define EVENT [[gnu::weak]]
#elif defined __clang__
    #define EVENT [[llvm::weak]]
#endif

#define IS_EVENT_DEFINED(sym) (static_cast<bool>(sym))
#define MouseEvents() EVENT void MouseClick();  EVENT void Move();

#define ClassWithEvents(ClassName, ClassParent) class ClassName: public  ClassParent<ClassName>{public: ClassName() : ClassParent(this) { ; }~ClassName() { ; } MouseEvents() }ClassName;
////////////////////////////////


using namespace std;

void *GetWindowPointer(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
     void *pWindow;
     if(msg==WM_NCCREATE)
     {
         CREATESTRUCT *p = (CREATESTRUCT *)lParam;
        pWindow = (void *)(p->lpCreateParams);
        SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pWindow);
     }
     else
        pWindow=(void*)GetWindowLongPtr(hwnd,GWLP_USERDATA);

    return pWindow;
}

template <typename CBase>
class Form
{
public:
    string g_szClassName = "Form";
    WNDCLASSEX wc;
    HWND hwnd;
    MSG Msg;
    unsigned int FormCount=0;
    CBase *atPointer ;
    EVENT void MouseClick();

    // Step 4: the Window Procedure
     static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        Form *pWindow;
        static unsigned int FormCount =0;
       pWindow =(Form*) GetWindowPointer(hwnd, msg,wParam,lParam);

        switch(msg)
        {
            case WM_CREATE:
                FormCount++;
            break;
            case WM_CLOSE:
                DestroyWindow(pWindow->hwnd);
            break;
            case WM_KEYUP:
                if(wParam==VK_ESCAPE) DestroyWindow(pWindow->hwnd);
            break;
            case WM_RBUTTONUP:
                if (IS_EVENT_DEFINED(&CBase::MouseClick))
                        pWindow->atPointer->MouseClick();
            break;
            case WM_DESTROY:
                FormCount--;
                if(FormCount==0) PostQuitMessage(0);
            break;
            default:
                return DefWindowProc(hwnd, msg, wParam, lParam);
        }
        return 0;
    }

    Form(CBase *clsPointer, string Caption="", unsigned int PosX = CW_USEDEFAULT,unsigned int PosY = CW_USEDEFAULT, unsigned int Width = CW_USEDEFAULT, unsigned int Height = CW_USEDEFAULT) : atPointer(clsPointer)
    {
        static unsigned int FormIndex;
        FormCount=FormIndex;
        g_szClassName+=to_string(FormIndex);
        if(Caption=="") Caption = "Form " + to_string(FormIndex);

        //Step 1: Registering the Window Class
        wc.cbSize        = sizeof(WNDCLASSEX);
        wc.style         = 0;
        wc.lpfnWndProc   = WndProc;
        wc.cbClsExtra    = 0;
        wc.cbWndExtra    = 0;
        wc.hInstance     = GetModuleHandle(NULL);
        wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
        wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
        wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
        wc.lpszMenuName  = NULL;
        wc.lpszClassName = g_szClassName.c_str();
        wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);
        if(!RegisterClassEx(&wc))
        {
            MessageBox(NULL, "Window Class not Register!!!", "Windows Creation Errors:", MB_OK);
        }

        // Step 2: Creating the Window
        hwnd = CreateWindowEx(
            WS_EX_CLIENTEDGE,
            g_szClassName.c_str(),
            Caption.c_str(),
            WS_OVERLAPPEDWINDOW,
            PosX, PosY, Width, Height,
            NULL, NULL, GetModuleHandle(NULL),(LPVOID) this);

        if(hwnd == NULL)
        {
            MessageBox(NULL, "Window Creation Failed!", "Error!",
                MB_ICONEXCLAMATION | MB_OK);
        }

        ShowWindow(hwnd, TRUE);
        UpdateWindow(hwnd);
        FormIndex++;
    }

    inline WPARAM MessageLoop()
    {
        // Step 3: The Message Loop
        while(GetMessage(&Msg, NULL, 0, 0) > 0)
        {
            TranslateMessage(&Msg);
            DispatchMessage(&Msg);
        }
        return Msg.wParam;
    }

};

how i use it:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
class Test: public Form<Test>
{
public:
    Test()  : Form(this)
    {
        ;
    }

    ~Test()
    {
        ;
    }
    EVENT void MouseClick();

}Test;


void Test::MouseClick()
{
   MessageBox(NULL, "Test", "Mouse Event", MB_OK);
}


class Test1: public Form<Test1>
{
public:
    Test1()  : Form(this)
    {
        ;
    }

    ~Test1()
    {
        ;
    }
    EVENT void MouseClick();

}Test1;


void Test1::MouseClick()
{
   MessageBox(NULL, "Test1", "Mouse Event1", MB_OK);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
    return Test1.MessageLoop();
}

why the pointer:
1
2
3
4
5
class Test1: public Form<Test1>
{
public:
    Test1()  : Form(this)
.............

isn't added correctly?
i'm asking these, because i get the same pointer, but i get the 2 forms... the 'Test1::MouseClick()' isn't executed... only the 'Test::MouseClick()'.
and the:
1
2
3
4
Form(CBase *clsPointer, string Caption="", unsigned int PosX = CW_USEDEFAULT,unsigned int PosY = CW_USEDEFAULT, unsigned int Width = CW_USEDEFAULT, unsigned int Height = CW_USEDEFAULT) : atPointer(clsPointer)
    {
        static unsigned int FormIndex;
        FormCount=FormIndex;

'FormIndex'(on last line constructur: 'FormIndex++;') isn't added :(
Last edited on
Here's a relevant thread (from 2018)
https://www.cplusplus.com/forum/general/236444/#msg1058106
And another, from 3 weeks later:
https://www.cplusplus.com/forum/general/237657/

After four years I still have no idea what your program is supposed to do.
Last edited on
LOL! It's like being trapped in samsara.

Cambalinho, you keep asking these questions and multiple, very experienced people have told you multiple times they don't understand what you're asking. Do you think it may be time to consider that you might be approaching the problem the wrong way, and not that the problem you're trying to solve is so novel that none of us has seen it before?
helios wrote:
It's like being trapped in samsara.

I'd kinda prefer Samadhi myself.
Reading 237657 again is a blast!
Now now, Cambalinho did assure than learning occurs ... albeit very slowly. Alas, I'm not sure what is actually learned and whether it is Cambalinho or us that does learn. Perhaps, in a century we shall be wise enough to answer or to not comment at all.
1st i'm sorry to all.

'Form' creates a Window using it's own class instance for read the messages....
until here fine.
now i update my Form class for use that events class.. basically creates a function with a definition name. for i test if that function was defined.
but for works i must send the 'Test1'(Form child class) for use that EVENT macro.
but something is wrong: when the Form is created the:
1
2
3
4
5
6
 Form(CBase *clsPointer, string Caption="", unsigned int PosX = CW_USEDEFAULT,unsigned int PosY = CW_USEDEFAULT, unsigned int Width = CW_USEDEFAULT, unsigned int Height = CW_USEDEFAULT) : atPointer(clsPointer)
    {
        static unsigned int FormIndex;
        FormCount=FormIndex;
//..............
FormIndex++;

why the 'FormIndex' isn't counted?
seems that the 'clsPointer', on 'Test1', isn't send correctly or something.
(every class's have their own functions... must be virtual for be changed on child class)
You're almost certainly running into weird semantics from using weak symbols in a way they're not meant to be used. I wish I could tell you what to use instead, but I would need to understand what you're trying to do, first.
after several time and work and tests, i get it to work a simple test:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <iostream>

/////////For EVENTS//////////////
//Active the macros definitions:
#if defined __GNUC__
    #define EVENT [[gnu::weak]]
#elif defined __clang__
    #define EVENT [[llvm::weak]]
#endif

//test if the function was definided with with macro events:
#define IS_EVENT_DEFINED(sym) (static_cast<bool>(sym))

//define a macro for mouse events:
#define MouseEvents() EVENT  void MouseClick();  EVENT  void Move();

//a macro for create a class with events:
//seems like a variable declaration, but convert it to a class:
#define ClassWithEvents(ClassName, ClassParent) class ClassName: public ClassParent<ClassName> { public: MouseEvents(); ClassName(): ClassParent(this)  {  }  ~ClassName() { } }ClassName;
////////////////////////////////

#define Static static inline

using namespace std;

//for add the child class pointer
//on parent class:
template <typename ChildPointer>

class Form
{
public:
    Static int FormCount=0;

    //the child class pointer
    ChildPointer *ChildClassPointer;

    //child class pointer constructor parameter
    Form(ChildPointer *ChildClass)
    {
        //getting child class pointer:
        ChildClassPointer=ChildClass;
        FormCount++;
    }
    void call()
    {
        //test if the function was defined
        //if was defined, we execute the function:
        if(IS_EVENT_DEFINED(&ChildPointer::MouseClick)) ChildClassPointer->MouseClick();
    }
};


class Window: public Form<Window>//now we add these class name for parent class template pointer
{
public:
    Window():Form(this)//these is for add these class pointer on parent
    {
        ;
    }

    MouseEvents();
}Window;

//define the MouseClick function from Window class:
void Window::MouseClick()
{
    cout << "Window Mouse Click\n";
}


class Window2: public Form<Window2>
{
    public:
    Window2():Form(this)
    {
        ;
    }

    MouseEvents();

}Window2;


//define the MouseClick function from Window class:
void Window2::MouseClick()
{
    cout << "Window2 Mouse Click\n";
}

int main()
{
    Window.call();
    Window2.call();
    return 0;
}

with more time i will fix the error on previous 'Form' class.
these is a sample test...
and, yes, i can use these way with macros:
1
2
ClassWithEvents(Window,Form);
ClassWithEvents(Window2,Form);


thanks for all to all
Last edited on
Registered users can post here. Sign in or register to post.