CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 3 of 11 FirstFirst 123456 ... LastLast
Results 31 to 45 of 155
  1. #31
    Join Date
    Apr 1999
    Posts
    27,449

    Re: [win32] - creating controls using class's

    Quote Originally Posted by Cambalinho View Post
    but the window procedure isn't correctly... i did something wrong on it but i don't know... please help me more for i learn more
    Where is the message pump?

    Regards,

    Paul McKenzie

  2. #32
    Join Date
    Apr 2009
    Posts
    1,355

    Re: [win32] - creating controls using class's

    Quote Originally Posted by Paul McKenzie View Post
    Where is the message pump?

    Regards,

    Paul McKenzie
    the CreateWindowEx() works with window procedure, if the window procedure isn't correct, so the control isn't created:
    Code:
    static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        WNDPROC oldproc =(WNDPROC)GetWindowLongPtr(GetParent(hwnd),GWLP_USERDATA);
        UINT i=(UINT)GetWindowLongPtr(GetParent(hwnd),GWLP_USERDATA);
        switch(msg)
        {
            case WM_NCCREATE:
            {
                CREATESTRUCT *createstruct = (CREATESTRUCT*)lParam;
    
                SetWindowLong(hwnd, GWL_USERDATA, (long)createstruct->lpCreateParams);
            }
            break;
            case WM_CREATE:
            {
                SetWindowText(hwnd,"hello world");
    
                break;
            }
            case WM_MOUSEMOVE:
            {
                SetWindowText(hwnd,"mouse move");
                break;
            }
            case WM_CLOSE:
                DestroyWindow(hwnd);
            break;
            case WM_DESTROY:
                PostQuitMessage(0);
            break;
            default:
                return (CallWindowProc(oldproc, hwnd, msg, wParam, lParam));
        }
        return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    but maybe i did something wrong with it

  3. #33
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: [win32] - creating controls using class's

    When you process the WM_NCCREATE and WM_CREATE messages, you break out of the switch and then call DefWindowProc. You only call CallWindowProc if you don't handle the message in your WndProc routine. Unless you have a very good reason not too, you should always call CallWindowProc and not DefWindowProc for sub/super classing. In this case, the control isn't getting the WM_ messages it expects.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  4. #34
    Join Date
    Apr 2009
    Posts
    1,355

    Re: [win32] - creating controls using class's

    Quote Originally Posted by 2kaud View Post
    When you process the WM_NCCREATE and WM_CREATE messages, you break out of the switch and then call DefWindowProc. You only call CallWindowProc if you don't handle the message in your WndProc routine. Unless you have a very good reason not too, you should always call CallWindowProc and not DefWindowProc for sub/super classing. In this case, the control isn't getting the WM_ messages it expects.
    i did:
    Code:
    static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        WNDPROC oldproc =(WNDPROC)GetWindowLongPtr(GetParent(hwnd),GWLP_USERDATA);
        UINT i=(UINT)GetWindowLongPtr(GetParent(hwnd),GWLP_USERDATA);
        switch(msg)
        {
            case WM_NCCREATE:
            {
                CREATESTRUCT *createstruct = (CREATESTRUCT*)lParam;
    
                SetWindowLong(hwnd, GWL_USERDATA, (long)createstruct->lpCreateParams);
            }
            break;
            case WM_CREATE:
            {
                CREATESTRUCT *createstruct = (CREATESTRUCT*)lParam;
    
                SetWindowLong(hwnd, GWL_USERDATA, (long)createstruct->lpCreateParams);
    
                SetWindowText(hwnd,"hello world");
    
                break;
            }
            case WM_MOUSEMOVE:
            {
                SetWindowText(hwnd,"mouse move");
                break;
            }
            case WM_CLOSE:
                DestroyWindow(hwnd);
            break;
            case WM_DESTROY:
                PostQuitMessage(0);
            break;
            default:
                return CallWindowProc(oldproc, hwnd, msg, wParam, lParam);
        }
        return CallWindowProc(oldproc, GetParent(hwnd), msg, wParam, lParam);
    }
    but the control isn't created.. the CreateWindowEx() give me error
    the last error, give me '0'.

  5. #35
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: [win32] - creating controls using class's

    Code:
    return CallWindowProc(oldproc, GetParent(hwnd), msg, wParam, lParam);
    Why Getparent()? Why not just hwnd?

    Also, why are you setting GWL_USERDATA in WM_CREATE and WM_NCCREATE?

    If you post a complete program that compiles, I'll have a look at it.
    Last edited by 2kaud; December 29th, 2013 at 05:36 AM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  6. #36
    Join Date
    Apr 2009
    Posts
    1,355

    Re: [win32] - creating controls using class's

    Quote Originally Posted by 2kaud View Post
    Code:
    return CallWindowProc(oldproc, GetParent(hwnd), msg, wParam, lParam);
    Why Getparent()? Why not just hwnd?

    Also, why are you setting GWL_USERDATA in WM_CREATE and WM_NCCREATE?

    If you post a complete program that compiles, I'll have a look at it.
    label.h:
    (in window procedure i will need put some variables(like the events)... but i realy need avoid the static... anotherthing: if the window procedure is static, will be the same for all instances?(will be a problem?)
    Code:
    #include <windows.h>
    #include <iostream>
    #include <string>
    #include <process.h>
    
    using namespace std;
    HWND hwnd;
    HHOOK _hook;
    WNDPROC previous_boring_subclassed_edit_proc;
    LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        WNDPROC oldproc =(WNDPROC)GetWindowLongPtr(GetParent(hwnd),GWLP_USERDATA);
        UINT i=(UINT)GetWindowLongPtr(GetParent(hwnd),GWLP_USERDATA);
        switch(msg)
        {
            case WM_NCCREATE:
            {
                 CREATESTRUCT *createstruct = (CREATESTRUCT*)lParam;
    
                SetWindowLong(hwnd, GWL_USERDATA, (long)createstruct->lpCreateParams);
    
    
            }
            break;
            case WM_CREATE:
                SetWindowText(hwnd,"hello");
            break;
            case WM_MOUSEMOVE:
                SetWindowText(hwnd,"hello");
            break;
            case WM_CLOSE:
                DestroyWindow(hwnd);
            break;
            case WM_DESTROY:
                PostQuitMessage(0);
            break;
            default:
                return CallWindowProc(previous_boring_subclassed_edit_proc, hwnd, msg, wParam, lParam);
        }
        //return 0;
    }
    
    class label
    {
    private:
    
    
    
    
    
    public:
    
        label(HWND value)
        {
    
            hwnd = CreateWindowEx(
                WS_EX_LEFT| WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR,
                "STATIC",
                "",
                SS_LEFT|WS_CHILD|WS_VISIBLE,
                0, 0, 100, 100,
                value,
                NULL,
                GetModuleHandle(NULL),
                NULL);
    
                ShowWindow(hwnd,SW_SHOW);
                UpdateWindow(hwnd);
                previous_boring_subclassed_edit_proc = (WNDPROC)GetWindowLong(hwnd, GWL_WNDPROC);//get the default procedure
                SetWindowLong(hwnd, GWL_WNDPROC, (LONG_PTR)WndProc);//set your custom procedure :)
        }
    
        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);
        }
    
    
    };
    main.cpp:
    Code:
    #include <windows.h>
    #include "Label.h"
    
    /*  Declare Windows procedure  */
    LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
    
    /*  Make the class name into a global variable  */
    char szClassName[ ] = "CodeBlocksWindowsApp";
    
    
    //creating the window
    int WINAPI WinMain (HINSTANCE hThisInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR lpszArgument,
                         int nCmdShow)
    {
        HWND hwnd;               /* This is the handle for our window */
        MSG messages;            /* Here messages to the application are saved */
        WNDCLASSEX wincl;        /* Data structure for the windowclass */
    
        /* The Window structure */
        wincl.hInstance = hThisInstance;
        wincl.lpszClassName = szClassName;
        wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
        wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
        wincl.cbSize = sizeof (WNDCLASSEX);
    
        /* Use default icon and mouse-pointer */
        wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
        wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
        wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
        wincl.lpszMenuName = NULL;                 /* No menu */
        wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
        wincl.cbWndExtra = 0;                      /* structure or the window instance */
        /* Use Windows's default colour as the background of the window */
        wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
    
        /* Register the window class, and if it fails quit the program */
        if (!RegisterClassEx (&wincl))
            return 0;
    
        /* The class is registered, let's create the program*/
        hwnd = CreateWindowEx (
               0,                   /* Extended possibilites for variation */
               szClassName,         /* Classname */
               "Code::Blocks Template Windows App",       /* Title Text */
               WS_OVERLAPPEDWINDOW, /* default window */
               CW_USEDEFAULT,       /* Windows decides the position */
               CW_USEDEFAULT,       /* where the window ends up on the screen */
               544,                 /* The programs width */
               375,                 /* and height in pixels */
               HWND_DESKTOP,        /* The window is a child-window to desktop */
               NULL,                /* No menu */
               hThisInstance,       /* Program Instance handler */
               NULL                 /* No Window Creation data */
               );
    
        /* Make the window visible on the screen */
        ShowWindow (hwnd, nCmdShow);
    
        /* Run the message loop. It will run until GetMessage() returns 0 */
        while (GetMessage (&messages, NULL, 0, 0))
        {
            /* Translate virtual-key messages into character messages */
            TranslateMessage(&messages);
            /* Send message to WindowProcedure */
            DispatchMessage(&messages);
        }
    
        /* The program return-value is 0 - The value that PostQuitMessage() gave */
        return messages.wParam;
    }
    
    
    /*  This function is called by the Windows function DispatchMessage()  */
    
    LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)                  /* handle the messages */
        {
            case WM_CREATE:
            {
                //create my label
                label label1(hwnd);
                label1.SetText("oi");
    
            }
                break;
    
            case WM_DESTROY:
                PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
                break;
            default:                      /* for messages that we don't deal with */
                return DefWindowProc (hwnd, message, wParam, lParam);
        }
    
        return 0;
    }
    i'm sorry, but i'm trying

  7. #37
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: [win32] - creating controls using class's

    Quote Originally Posted by Cambalinho View Post
    main.cpp:
    Code:
    #include <windows.h>
    #include "Label.h"
    
    ....
    /*  This function is called by the Windows function DispatchMessage()  */
    
    LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)                  /* handle the messages */
        {
            case WM_CREATE:
            {
                //create my label
                label label1(hwnd);
                label1.SetText("oi");
            }
                break;
    
            case WM_DESTROY:
                PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
                break;
            default:                      /* for messages that we don't deal with */
                return DefWindowProc (hwnd, message, wParam, lParam);
        }
    
        return 0;
    }
    i'm sorry, but i'm trying
    Your label instance exists only within case WM_CREATE block. Then it goes out of scope and destroyed.
    Victor Nijegorodov

  8. #38
    Join Date
    Apr 2009
    Posts
    1,355

    Re: [win32] - creating controls using class's

    Quote Originally Posted by VictorN View Post
    Your label instance exists only within case WM_CREATE block. Then it goes out of scope and destroyed.
    you have right.. thanks for that.. i change that

  9. #39
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: [win32] - creating controls using class's

    Try this. It will create the label and will write to file debug.txt the message numbers received. The file winuser.h details what they mean. It uses windows properites to store the old proc detail.

    Code:
    #include <windows.h>
    #include <fstream>
    #include <iostream>
    #include <string>
    #include <iomanip>
    using namespace std;
    
    static char propname[] = "Cambalinho";
    static char debugname[] = "debug.txt";
    
    class label
    {
    private:
        HWND hwnd;
    
    static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    static ofstream os(debugname, ios_base::app);
    
    WNDPROC oldproc = (WNDPROC)GetProp(GetParent(hwnd), propname);
    
    	if (oldproc == NULL)
    		MessageBox(NULL, "null", "null", MB_OK);
    
        switch(msg) {
            case WM_CREATE:
    			//This doesn't work as the window hasn't been created!
                SetWindowText(hwnd, "hello world");
                break;
    
            default:
    			os << "0x" << hex << setw(4) << setfill('0') << msg << endl;
    			break;
        }
    
    	//If oldproc is NULL then use DefWindowProc - but shouldn't be!
    	return oldproc ? CallWindowProc(oldproc, hwnd, msg, wParam, lParam) : DefWindowProc(hwnd, msg, wParam, lParam);
    }
    
    public:
        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, propname, (HANDLE)wc.lpfnWndProc);
    
    		// 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);
        }
    };
    
    /*  Declare Windows procedure  */
    LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
    
    /*  Make the class name into a global variable  */
    char szClassName[] = "CodeBlocksWindowsApp";
    
    //creating the window
    int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE, LPSTR lpszArgument, int nCmdShow)
    {
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */
    
    	DeleteFile(debugname);
    
        /* The Window structure */
        wincl.hInstance = hThisInstance;
        wincl.lpszClassName = szClassName;
        wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
        wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
        wincl.cbSize = sizeof (WNDCLASSEX);
    
        /* Use default icon and mouse-pointer */
        wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
        wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
        wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
        wincl.lpszMenuName = NULL;                 /* No menu */
        wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
        wincl.cbWndExtra = 0;                      /* structure or the window instance */
        /* Use Windows's default colour as the background of the window */
        wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
    
        /* Register the window class, and if it fails quit the program */
        if (!RegisterClassEx (&wincl))
            return 0;
    
        /* The class is registered, let's create the program*/
        hwnd = CreateWindowEx (
               0,                   /* Extended possibilites for variation */
               szClassName,         /* Classname */
               "Code::Blocks Template Windows App",       /* Title Text */
               WS_OVERLAPPEDWINDOW, /* default window */
               CW_USEDEFAULT,       /* Windows decides the position */
               CW_USEDEFAULT,       /* where the window ends up on the screen */
               544,                 /* The programs width */
               375,                 /* and height in pixels */
               HWND_DESKTOP,        /* The window is a child-window to desktop */
               NULL,                /* No menu */
               hThisInstance,       /* Program Instance handler */
               NULL                 /* No Window Creation data */
               );
    
        /* Make the window visible on the screen */
        ShowWindow (hwnd, nCmdShow);
    	UpdateWindow(hwnd);
    
        label label1(hwnd);
    	label1.SetText("oi");
    
        /* Run the message loop. It will run until GetMessage() returns 0 */
        while (GetMessage (&messages, NULL, 0, 0))
        {
            /* Translate virtual-key messages into character messages */
            TranslateMessage(&messages);
            /* Send message to WindowProcedure */
            DispatchMessage(&messages);
        }
    
        /* The program return-value is 0 - The value that PostQuitMessage() gave */
        return messages.wParam;
    }
    
    
    /*  This function is called by the Windows function DispatchMessage()  */
    LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)                  /* handle the messages */
        {
            case WM_CREATE:
                break;
    
            case WM_DESTROY:
                PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
                break;
    
            default:                      /* for messages that we don't deal with */
                return DefWindowProc (hwnd, message, wParam, lParam);
        }
    
        return 0;
    }
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  10. #40
    Join Date
    Apr 2009
    Posts
    1,355

    Re: [win32] - creating controls using class's

    Quote Originally Posted by 2kaud View Post
    Try this. It will create the label and will write to file debug.txt the message numbers received. The file winuser.h details what they mean. It uses windows properites to store the old proc detail.

    Code:
    #include <windows.h>
    #include <fstream>
    #include <iostream>
    #include <string>
    #include <iomanip>
    using namespace std;
    
    static char propname[] = "Cambalinho";
    static char debugname[] = "debug.txt";
    
    class label
    {
    private:
        HWND hwnd;
    
    static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    static ofstream os(debugname, ios_base::app);
    
    WNDPROC oldproc = (WNDPROC)GetProp(GetParent(hwnd), propname);
    
    	if (oldproc == NULL)
    		MessageBox(NULL, "null", "null", MB_OK);
    
        switch(msg) {
            case WM_CREATE:
    			//This doesn't work as the window hasn't been created!
                SetWindowText(hwnd, "hello world");
                break;
    
            default:
    			os << "0x" << hex << setw(4) << setfill('0') << msg << endl;
    			break;
        }
    
    	//If oldproc is NULL then use DefWindowProc - but shouldn't be!
    	return oldproc ? CallWindowProc(oldproc, hwnd, msg, wParam, lParam) : DefWindowProc(hwnd, msg, wParam, lParam);
    }
    
    public:
        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, propname, (HANDLE)wc.lpfnWndProc);
    
    		// 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);
        }
    };
    
    /*  Declare Windows procedure  */
    LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
    
    /*  Make the class name into a global variable  */
    char szClassName[] = "CodeBlocksWindowsApp";
    
    //creating the window
    int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE, LPSTR lpszArgument, int nCmdShow)
    {
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */
    
    	DeleteFile(debugname);
    
        /* The Window structure */
        wincl.hInstance = hThisInstance;
        wincl.lpszClassName = szClassName;
        wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
        wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
        wincl.cbSize = sizeof (WNDCLASSEX);
    
        /* Use default icon and mouse-pointer */
        wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
        wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
        wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
        wincl.lpszMenuName = NULL;                 /* No menu */
        wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
        wincl.cbWndExtra = 0;                      /* structure or the window instance */
        /* Use Windows's default colour as the background of the window */
        wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
    
        /* Register the window class, and if it fails quit the program */
        if (!RegisterClassEx (&wincl))
            return 0;
    
        /* The class is registered, let's create the program*/
        hwnd = CreateWindowEx (
               0,                   /* Extended possibilites for variation */
               szClassName,         /* Classname */
               "Code::Blocks Template Windows App",       /* Title Text */
               WS_OVERLAPPEDWINDOW, /* default window */
               CW_USEDEFAULT,       /* Windows decides the position */
               CW_USEDEFAULT,       /* where the window ends up on the screen */
               544,                 /* The programs width */
               375,                 /* and height in pixels */
               HWND_DESKTOP,        /* The window is a child-window to desktop */
               NULL,                /* No menu */
               hThisInstance,       /* Program Instance handler */
               NULL                 /* No Window Creation data */
               );
    
        /* Make the window visible on the screen */
        ShowWindow (hwnd, nCmdShow);
    	UpdateWindow(hwnd);
    
        label label1(hwnd);
    	label1.SetText("oi");
    
        /* Run the message loop. It will run until GetMessage() returns 0 */
        while (GetMessage (&messages, NULL, 0, 0))
        {
            /* Translate virtual-key messages into character messages */
            TranslateMessage(&messages);
            /* Send message to WindowProcedure */
            DispatchMessage(&messages);
        }
    
        /* The program return-value is 0 - The value that PostQuitMessage() gave */
        return messages.wParam;
    }
    
    
    /*  This function is called by the Windows function DispatchMessage()  */
    LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)                  /* handle the messages */
        {
            case WM_CREATE:
                break;
    
            case WM_DESTROY:
                PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
                break;
    
            default:                      /* for messages that we don't deal with */
                return DefWindowProc (hwnd, message, wParam, lParam);
        }
    
        return 0;
    }
    heres the debug.txt file:

    Code:
    0x0081
    0x0083
    0x000c
    0x0005
    0x0003
    0x0018
    0x0046
    0x0047
    0x000c
    0x000f
    0x0085
    0x0014
    0x0084
    0x0084
    0x0084
    0x0084
    0x0084
    0x0084
    0x0084
    0x0084
    0x0084
    0x0084
    0x0084
    0x0084
    0x0084
    0x0084
    0x0084
    0x0084
    0x0002
    0x0082
    but why the WM_CREATE isn't executed?

  11. #41
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: [win32] - creating controls using class's

    but why the WM_CREATE isn't executed?
    It is! The WM_CREATE msg isn't output to the file if you look at the code. The below is the replacement wndproc that will output all msg to file.

    Code:
    static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    static ofstream os(debugname, ios_base::app);
    
    WNDPROC oldproc = (WNDPROC)GetProp(GetParent(hwnd), propname);
    
    	if (oldproc == NULL)
    		MessageBox(NULL, "null", "null", MB_OK);
    
    	os << "0x" << hex << setw(4) << setfill('0') << msg << endl;
    
        switch(msg) {
            case WM_CREATE:
    			//This doesn't work as the window hasn't been created!
                SetWindowText(hwnd, "hello world");
                break;
    
            default:
    			break;
        }
    
    	//If oldproc is NULL then use DefWindowProc - but shouldn't be!
    	return oldproc ? CallWindowProc(oldproc, hwnd, msg, wParam, lParam) : DefWindowProc(hwnd, msg, wParam, lParam);
    }
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  12. #42
    Join Date
    Apr 2009
    Posts
    1,355

    Re: [win32] - creating controls using class's

    Quote Originally Posted by 2kaud View Post
    It is! The WM_CREATE msg isn't output to the file if you look at the code. The below is the replacement wndproc that will output all msg to file.

    Code:
    static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    static ofstream os(debugname, ios_base::app);
    
    WNDPROC oldproc = (WNDPROC)GetProp(GetParent(hwnd), propname);
    
        if (oldproc == NULL)
            MessageBox(NULL, "null", "null", MB_OK);
    
        os << "0x" << hex << setw(4) << setfill('0') << msg << endl;
    
        switch(msg) {
            case WM_CREATE:
                //This doesn't work as the window hasn't been created!
                SetWindowText(hwnd, "hello world");
                break;
    
            default:
                break;
        }
    
        //If oldproc is NULL then use DefWindowProc - but shouldn't be!
        return oldproc ? CallWindowProc(oldproc, hwnd, msg, wParam, lParam) : DefWindowProc(hwnd, msg, wParam, lParam);
    }
    yes you have right.. i have tested now with a message box and it's showed.
    but now i have a new problem
    how can i create variables(not static) for use them inside of window procedure?
    i understand that the message loop must be static for put it inside of the class
    please tell me more about these

  13. #43
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: [win32] - creating controls using class's

    The way you do this is to have a window property that contains the address of the class instance.

    The code below demonstrates the idea. The label class constructor sets the value of text which is then displayed when WM_CREATE control message is processed.

    Code:
    #include <windows.h>
    #include <fstream>
    #include <iostream>
    #include <string>
    #include <iomanip>
    using namespace std;
    
    static char propname[] = "Cambalinho";
    static char classprop[] = "classaddr";
    static char debugname[] = "debug.txt";
    
    class label
    {
    private:
        HWND hwnd;
    	string text;
    
    static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    static ofstream os(debugname, ios_base::app);
    
    WNDPROC oldproc = (WNDPROC)GetProp(GetParent(hwnd), propname);
    
    label *inst = (label*)GetProp(GetParent(hwnd), classprop);
    
    	if (oldproc == NULL)
    		MessageBox(NULL, "null", "null", MB_OK);
    
    	os << "0x" << hex << setw(4) << setfill('0') << msg << endl;
    
        switch(msg) {
            case WM_CREATE:
    			MessageBox(NULL, inst->text.c_str(), "From class instance", MB_OK);
    
    			//This doesn't work as the window hasn't been created!
                SetWindowText(hwnd, "hello world");
                break;
    
            default:
    			break;
        }
    
    	//If oldproc is NULL then use DefWindowProc - but shouldn't be!
    	return oldproc ? CallWindowProc(oldproc, hwnd, msg, wParam, lParam) : DefWindowProc(hwnd, msg, wParam, lParam);
    }
    
    public:
        label(HWND parent) {
    		text = "qwerty";
    
    	    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, propname, (HANDLE)wc.lpfnWndProc);
    		SetProp(parent, classprop, (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);
        }
    };
    
    /*  Declare Windows procedure  */
    LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
    
    /*  Make the class name into a global variable  */
    char szClassName[] = "CodeBlocksWindowsApp";
    
    //creating the window
    int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE, LPSTR lpszArgument, int nCmdShow)
    {
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */
    
    	DeleteFile(debugname);
    
        /* The Window structure */
        wincl.hInstance = hThisInstance;
        wincl.lpszClassName = szClassName;
        wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
        wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
        wincl.cbSize = sizeof (WNDCLASSEX);
    
        /* Use default icon and mouse-pointer */
        wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
        wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
        wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
        wincl.lpszMenuName = NULL;                 /* No menu */
        wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
        wincl.cbWndExtra = 0;                      /* structure or the window instance */
        /* Use Windows's default colour as the background of the window */
        wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
    
        /* Register the window class, and if it fails quit the program */
        if (!RegisterClassEx (&wincl))
            return 0;
    
        /* The class is registered, let's create the program*/
        hwnd = CreateWindowEx (
               0,                   /* Extended possibilites for variation */
               szClassName,         /* Classname */
               "Code::Blocks Template Windows App",       /* Title Text */
               WS_OVERLAPPEDWINDOW, /* default window */
               CW_USEDEFAULT,       /* Windows decides the position */
               CW_USEDEFAULT,       /* where the window ends up on the screen */
               544,                 /* The programs width */
               375,                 /* and height in pixels */
               HWND_DESKTOP,        /* The window is a child-window to desktop */
               NULL,                /* No menu */
               hThisInstance,       /* Program Instance handler */
               NULL                 /* No Window Creation data */
               );
    
        /* Make the window visible on the screen */
        ShowWindow (hwnd, nCmdShow);
    	UpdateWindow(hwnd);
    
        label label1(hwnd);
    	label1.SetText("oi");
    
        /* Run the message loop. It will run until GetMessage() returns 0 */
        while (GetMessage (&messages, NULL, 0, 0))
        {
            /* Translate virtual-key messages into character messages */
            TranslateMessage(&messages);
            /* Send message to WindowProcedure */
            DispatchMessage(&messages);
        }
    
        /* The program return-value is 0 - The value that PostQuitMessage() gave */
        return messages.wParam;
    }
    
    
    /*  This function is called by the Windows function DispatchMessage()  */
    LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)                  /* handle the messages */
        {
            case WM_CREATE:
                break;
    
            case WM_DESTROY:
                PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
                break;
    
            default:                      /* for messages that we don't deal with */
                return DefWindowProc (hwnd, message, wParam, lParam);
        }
    
        return 0;
    }
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  14. #44
    Join Date
    Apr 2009
    Posts
    1,355

    Re: [win32] - creating controls using class's

    Code:
    #include <windows.h>
    #include <fstream>
    #include <iostream>
    #include <string>
    #include <iomanip>
    using namespace std;
    
    static char propname[] = "Cambalinho";
    static char classprop[] = "classaddr";
    static char debugname[] = "debug.txt";
    
    class label
    {
    private:
        HWND hndlabel;
    	string text;
    
    static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    
    
    WNDPROC oldproc = (WNDPROC)GetProp(GetParent(hwnd), propname);
    
    label *inst = (label*)GetProp(GetParent(hwnd), classprop);
    
    	if (oldproc == NULL)
    		MessageBox(NULL, "null", "null", MB_OK);
    
        switch(msg) {
            case WM_MOUSEMOVE:
    
                SetWindowText(inst->hndlabel, "hello world"); //isn't changed
                break;
    
            default:
    			break;
        }
    
    	//If oldproc is NULL then use DefWindowProc - but shouldn't be!
    	return oldproc ? CallWindowProc(oldproc, hwnd, msg, wParam, lParam) : DefWindowProc(hwnd, msg, wParam, lParam);
    }
    
    public:
        label(HWND parent) {
    		text = "qwerty";
    
    	    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, propname, (HANDLE)wc.lpfnWndProc);
    		SetProp(parent, classprop, (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);
    
            hndlabel = 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 (hndlabel == NULL)
    			MessageBox(NULL, "error in create", "error", MB_OK);
        }
    
        COORD GetSize()
        {
            RECT LabelSize;
            GetWindowRect(hndlabel,&LabelSize);
            COORD crdSize={LabelSize.right-LabelSize.left,LabelSize.bottom-LabelSize.top};
            return crdSize;
        }
    
        void SetText(string text)
        {
            char* chrText=(char*)text.c_str();
            SetWindowText(hndlabel, chrText);
        }
    };
    
    /*  Declare Windows procedure  */
    LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
    
    /*  Make the class name into a global variable  */
    char szClassName[] = "CodeBlocksWindowsApp";
    
    //creating the window
    int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE, LPSTR lpszArgument, int nCmdShow)
    {
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */
    
    	DeleteFile(debugname);
    
        /* The Window structure */
        wincl.hInstance = hThisInstance;
        wincl.lpszClassName = szClassName;
        wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
        wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
        wincl.cbSize = sizeof (WNDCLASSEX);
    
        /* Use default icon and mouse-pointer */
        wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
        wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
        wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
        wincl.lpszMenuName = NULL;                 /* No menu */
        wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
        wincl.cbWndExtra = 0;                      /* structure or the window instance */
        /* Use Windows's default colour as the background of the window */
        wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
    
        /* Register the window class, and if it fails quit the program */
        if (!RegisterClassEx (&wincl))
            return 0;
    
        /* The class is registered, let's create the program*/
        hwnd = CreateWindowEx (
               0,                   /* Extended possibilites for variation */
               szClassName,         /* Classname */
               "Code::Blocks Template Windows App",       /* Title Text */
               WS_OVERLAPPEDWINDOW, /* default window */
               CW_USEDEFAULT,       /* Windows decides the position */
               CW_USEDEFAULT,       /* where the window ends up on the screen */
               544,                 /* The programs width */
               375,                 /* and height in pixels */
               HWND_DESKTOP,        /* The window is a child-window to desktop */
               NULL,                /* No menu */
               hThisInstance,       /* Program Instance handler */
               NULL                 /* No Window Creation data */
               );
    
        /* Make the window visible on the screen */
        ShowWindow (hwnd, nCmdShow);
    	UpdateWindow(hwnd);
    
        label label1(hwnd);
    	//label1.SetText("oi");
    
        /* Run the message loop. It will run until GetMessage() returns 0 */
        while (GetMessage (&messages, NULL, 0, 0))
        {
            /* Translate virtual-key messages into character messages */
            TranslateMessage(&messages);
            /* Send message to WindowProcedure */
            DispatchMessage(&messages);
        }
    
        /* The program return-value is 0 - The value that PostQuitMessage() gave */
        return messages.wParam;
    }
    
    
    /*  This function is called by the Windows function DispatchMessage()  */
    LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)                  /* handle the messages */
        {
            case WM_CREATE:
                break;
    
            case WM_DESTROY:
                PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
                break;
    
            default:                      /* for messages that we don't deal with */
                return DefWindowProc (hwnd, message, wParam, lParam);
        }
    
        return 0;
    }
    i'm using the pointer: why the SetWindowText() isn't used? the inst->hndlabel can be the problem... but tell more please?
    (i need use some functions inside of the window procedure)

  15. #45
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: [win32] - creating controls using class's

    You should also have a destructor for class label.

    Code:
    ~label() {
    		DestroyWindow(hwnd);
    		hwnd = 0;
    	}
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

Page 3 of 11 FirstFirst 123456 ... LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured