[win32] - creating controls using class's - Page 2
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 2 of 11 FirstFirst 12345 ... LastLast
Results 16 to 30 of 155

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

  1. #16
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,742

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

    Quote Originally Posted by Cambalinho View Post
    maybe the case is activated, but the msg values are unexpected(the WM_CREATE isn't activated.. for example)
    What values are you receiving for msg? Don't forgot this is a static control and not a 'normal' window.
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  2. #17
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,742

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

    When you subclass a control, you don't receive the WM_CREATE messages etc as these have already been sent before you change the wndproc routine. If you want to receive the WM_CREATE etc mesages for controls you will need to superclass the control (as opposed to subclass that you do now).

    For details see
    http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx
    Last edited by 2kaud; December 28th, 2013 at 08:46 AM.
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  3. #18
    Join Date
    Apr 2009
    Posts
    719

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

    Quote Originally Posted by 2kaud View Post
    What values are you receiving for msg? Don't forgot this is a static control and not a 'normal' window.
    i know that isn't a 'normal' window... but why the WM_CREATE msg isn't activated?
    sorry about the msg values(if you can, test my code.. please), but why the WM_CREATE or other message isn't activated?

  4. #19
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,742

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

    Quote Originally Posted by Cambalinho View Post
    i know that isn't a 'normal' window... but why the WM_CREATE msg isn't activated?
    sorry about the msg values(if you can, test my code.. please), but why the WM_CREATE or other message isn't activated?
    See my post #17.
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  5. #20
    Join Date
    Apr 2009
    Posts
    719

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

    Quote Originally Posted by 2kaud View Post
    See my post #17.
    thanks i never knew that
    i was reading that but i realy don't understand, can you explain to me even with a incomplete example.. please?
    Last edited by Cambalinho; December 28th, 2013 at 10:47 AM.

  6. #21
    Join Date
    Apr 2009
    Posts
    719

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

    almost done.. the WM_CREATE is used:
    Code:
    #include <windows.h>
    #include <iostream>
    #include <string>
    #include <process.h>
    
    using namespace std;
    
    WNDPROC m_pfnPrevWndProc;
    
        LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    
        switch(msg)
        {
            case WM_CREATE:
                SetWindowText(hwnd,"hello world");
            break;
            case WM_KEYDOWN:
                SetWindowText(hwnd,"mouse move");
            break;
            case WM_CLOSE:
                DestroyWindow(hwnd);
            break;
            case WM_DESTROY:
                PostQuitMessage(0);
            break;
            default:
                return CallWindowProc(m_pfnPrevWndProc,hwnd, msg, wParam, lParam);
        }
        return 0;
    }
    
    
    class label
    {
    private:
        HWND hwnd;
        WNDCLASS wc;
    
    
    
    
    
    public:
    
        label(HWND value)
        {
    
    
        ZeroMemory(&wc, sizeof(WNDCLASS));
        GetClassInfo((HINSTANCE)GetModuleHandle(NULL), "STATIC", &wc);
    
        wc.hInstance = (HINSTANCE)GetModuleHandle(NULL);
        wc.lpszClassName = "CSTATIC";
    
        // store the old WNDPROC of the EDIT window class
        m_pfnPrevWndProc = wc.lpfnWndProc;
    
        // replace it with local WNDPROC
        wc.lpfnWndProc = WndProc;
    
        // register the new window class, "ShEdit"
        RegisterClass(&wc);
            hwnd = CreateWindowEx(
                WS_EX_LEFT| WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR,
                "CSTATIC",
                "",
                SS_LEFT|WS_CHILD|WS_VISIBLE,
                0, 0, 100, 100,
                value,
                NULL,
                GetModuleHandle(NULL),
                NULL);
    
                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);
        }
    
    
    };
    but i continue with 2 problems:
    1 - seems the code isn't completed, because the others messages aren't used;
    2 - how can i put the window procedure inside of the class?
    if i put it in 'static', i can't use the m_pfnPrevWndProc variable, unless is static too
    can you tell me something about put the procedure inside of the class?
    heres where i found it: http://cboard.cprogramming.com/windo...dow-class.html
    maybe now i can do it
    but tell me more about what isn't right, please.

  7. #22
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,742

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

    To put the window procedure inside the class, it has to be static. As you say, you then can't access m_pfnPrevWndProc inside of the static procedure. One way round this is to store the value with the window using SetWindowLongPtr and GWLP_USERDATA. This way, the static class function can retrieve the value from the hwnd passed to wndproc using GetWindowLongPtr with GWLP_USERDATA. Note this isn't a good idea for controls (do it with their parent) so don't do this for the actual control itself as it may be using this data for other things. The other way of associating data with a window is to use windows properties. Use GetProp() and SetProp(). See http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx and http://msdn.microsoft.com/en-us/libr...eving_property.

    One of the better books on this topic is

    Windows 95 - A developers guide by Jeffrey Richter.

    I know its quite an old book but this sort of windows detail hasn't changed much over the years (SetWindowLongPtr instead of SetWindowLong etc).
    http://www.amazon.co.uk/Windows-95-D...velopers+guide

    Note that later books by the same author (Advanced Windows, Programming Applications etc) don't cover these topics.

    You may find this code snippet useful to have a look at.

    Code:
    //New wnd proc for edit control in value control
    LRESULT CALLBACK NewEdit(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
    {
    HWND	hanc = GetAncestor(hwnd, GA_ROOT);
    
    PLSGM	lsgm = (PLSGM)GetWindowLong(hanc, WEX_LS);
    
    UINT	id = GetWindowLong(GetParent(hwnd), GWL_ID) - STID;
    
    	//Check for special char tab, CR, shift tab use WM_KEYDOWN so can check for VK_SHIFT
    	if (message == WM_KEYDOWN) {
    
    		//If tab or CR then process as tab/CR from main control and move to other control
    		if ((wparam == VK_TAB) || (wparam == VK_RETURN)) {
    			if (wparam == VK_TAB) {
    				if ((USHORT)GetKeyState(VK_SHIFT) > 1) {
    					wparam = VK_BACK;
    				}
    			}
    
    			//Set lv text and close edit control
    			SetLVtext(lsgm);
    
    			//Process tab/CR
    			//CR now just closes and updates edit control
    			if (wparam != VK_RETURN) {
    				doTabCR(hanc, id + 1, wparam);
    			}
    			return (0);
    		}
    	}
    
    
    	if (message == WM_CHAR) {
    
    		//Ignore tab/CR as processed using WM_KEYDOWN
    		if ((wparam == TAB) || (wparam == CR)) {
    			return (0);
    		} else {
    
    			//If have ESC then close edit window but don't save contents
    			if (wparam == ESC) {
    
    				//Indicate edit control contents not changed
    				lsgm->lvdef.chg = FALSE;
    				DestroyWindow(hwnd);
    				return (0);
    			} else {
    
    				//Indicate contents changed
    				lsgm->lvdef.chg = TRUE;
    			}
    		}
    	}
    
    	//If edit control loose focus, save contents and close edit window
    	if (message == WM_KILLFOCUS) {
    		SetLVtext(lsgm);
    		return (0);
    	}
    
    	//Process message as normal
    	return (CallWindowProc(lsgm->lvdef.old, hwnd, message, wparam, lparam));
    }
    Last edited by 2kaud; December 28th, 2013 at 01:47 PM.
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  8. #23
    Join Date
    Apr 2009
    Posts
    719

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

    so what isn't right?
    Code:
    static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        WNDPROC oldproc =(WNDPROC)SetWindowLongPtr (GetParent(hwnd),GWLP_USERDATA,NULL);
        UINT i=(UINT)GetWindowLongPtr(GetParent(hwnd),GWLP_USERDATA);
        switch(msg)
        {
            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 0;
    }
    (even the control isn't showed)

  9. #24
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,742

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

    Code:
    WNDPROC oldproc =(WNDPROC)SetWindowLongPtr (GetParent(hwnd),GWLP_USERDATA,NULL);
    SetWindowLongPtr goes in the class function that creates the control - and not in wndproc.

    Code:
    UINT i=(UINT)GetWindowLongPtr(GetParent(hwnd),GWLP_USERDATA);
    becomes
    Code:
    WNDPROC oldproc =(WNDPROC)GetWindowLongPtr(GetParent(hwnd),GWLP_USERDATA);
    When you create the control, use

    Code:
    SetWindowLongPtr (GetParent(hwnd),GWLP_USERDATA,m_pfnPrevWndProc);
    But as I mentioned in my post #22, its better to use windows properties.
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  10. #25
    Join Date
    Apr 2009
    Posts
    719

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

    Quote Originally Posted by 2kaud View Post
    Code:
    WNDPROC oldproc =(WNDPROC)SetWindowLongPtr (GetParent(hwnd),GWLP_USERDATA,NULL);
    SetWindowLongPtr goes in the class function that creates the control - and not in wndproc.

    Code:
    UINT i=(UINT)GetWindowLongPtr(GetParent(hwnd),GWLP_USERDATA);
    becomes
    Code:
    WNDPROC oldproc =(WNDPROC)GetWindowLongPtr(GetParent(hwnd),GWLP_USERDATA);
    When you create the control, use

    Code:
    SetWindowLongPtr (GetParent(hwnd),GWLP_USERDATA,m_pfnPrevWndProc);
    But as I mentioned in my post #22, its better to use windows properties.
    i think that i did what you said:
    Code:
    #include <windows.h>
    #include <iostream>
    #include <string>
    #include <process.h>
    
    using namespace std;
    
    
    
    
    
    
    class label
    {
    private:
        HWND hwnd;
        WNDCLASS wc;
        WNDPROC m_pfnPrevWndProc;
    
    
    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_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 0;
    }
    
    public:
    
        label(HWND value)
        {
    
    
        ZeroMemory(&wc, sizeof(WNDCLASS));
        GetClassInfo((HINSTANCE)GetModuleHandle(NULL), "STATIC", &wc);
    
        wc.hInstance = (HINSTANCE)GetModuleHandle(NULL);
        wc.lpszClassName = "CSTATIC";
    
        // store the old WNDPROC of the EDIT window class
        m_pfnPrevWndProc = wc.lpfnWndProc;
    
        // replace it with local WNDPROC
        wc.lpfnWndProc = WndProc;
    
        // register the new window class, "ShEdit"
        RegisterClass(&wc);
            hwnd = CreateWindowEx(
                WS_EX_LEFT| WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR,
                "CSTATIC",
                "",
                SS_LEFT|WS_CHILD|WS_VISIBLE,
                0, 0, 100, 100,
                value,
                NULL,
                GetModuleHandle(NULL),
                NULL);
    SetWindowLongPtr (GetParent(hwnd),GWLP_USERDATA,(LONG_PTR)m_pfnPrevWndProc);
                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);
        }
    
    
    };
    but the control isn't showed

  11. #26
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,742

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

    After the CreateWindowEx call, what is the value of hwnd? You don't check anywhere for errors. When you call an API function, you should always check that an error has not occurred.
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  12. #27
    Join Date
    Apr 2009
    Posts
    719

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

    Quote Originally Posted by 2kaud View Post
    After the CreateWindowEx call, what is the value of hwnd? You don't check anywhere for errors. When you call an API function, you should always check that an error has not occurred.
    yes.. you have right:
    Code:
    ZeroMemory(&wc, sizeof(WNDCLASS));
        GetClassInfo((HINSTANCE)GetModuleHandle(NULL), "STATIC", &wc);
    
        wc.hInstance = (HINSTANCE)GetModuleHandle(NULL);
        wc.lpszClassName = "CSTATIC";
    
        // store the old WNDPROC of the EDIT window class
        m_pfnPrevWndProc = wc.lpfnWndProc;
    
        // replace it with local WNDPROC
        wc.lpfnWndProc = WndProc;
    
        // register the new window class, "ShEdit"
        if (!RegisterClass(&wc)) MessageBox(NULL,"error","error",MB_OK); //the message isn't showed, so i think it's ok
            hwnd = CreateWindowEx(
                WS_EX_LEFT| WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR,
                "CSTATIC",
                "",
                SS_LEFT|WS_CHILD|WS_VISIBLE,
                0, 0, 100, 100,
                value,
                NULL,
                GetModuleHandle(NULL),
                NULL);
                if(hwnd==NULL) MessageBox(NULL,"error","error",MB_OK);//the message is showed, so i think isn't ok
                SetWindowLongPtr (GetParent(hwnd),GWLP_USERDATA,(LONG_PTR)m_pfnPrevWndProc);
                ShowWindow(hwnd,SW_SHOW);
                UpdateWindow(hwnd);
    
        }
    seems the control isn't created... and i don't know why

  13. #28
    Join Date
    Apr 2009
    Posts
    719

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

    after more search the control is showed:
    Code:
    #include <windows.h>
    #include <iostream>
    #include <string>
    #include <process.h>
    
    using namespace std;
    
    
    
    
    
    
    class label
    {
    private:
        HWND hwnd;
        WNDCLASS wc;
        WNDPROC m_pfnPrevWndProc;
    
    
    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: //works, because the control is showed
            {
                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);
    }
    
    public:
    
        label(HWND value)
        {
    
    
        ZeroMemory(&wc, sizeof(WNDCLASS));
        GetClassInfo((HINSTANCE)GetModuleHandle(NULL), "STATIC", &wc);
    
        wc.hInstance = (HINSTANCE)GetModuleHandle(NULL);
        wc.lpszClassName = "CSTATIC";
    
        // store the old WNDPROC of the EDIT window class
        m_pfnPrevWndProc = wc.lpfnWndProc;
    
        // replace it with local WNDPROC
        wc.lpfnWndProc = WndProc;
    
        // register the new window class, "ShEdit"
        if (!RegisterClass(&wc)) MessageBox(NULL,"error","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,
                value,
                NULL,
                GetModuleHandle(NULL),
                NULL);
                if(hwnd==NULL) MessageBox(NULL,"error","error",MB_OK);
                SetWindowLongPtr (GetParent(hwnd),GWLP_USERDATA,(LONG_PTR)m_pfnPrevWndProc);
                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);
        }
    
    
    };
    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

  14. #29
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,742

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

    If hwnd is NULL, the reason for the error is obtained from GetLastError()
    http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx

    The error codes are explained here
    http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  15. #30
    Join Date
    Apr 2009
    Posts
    719

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

    Quote Originally Posted by 2kaud View Post
    If hwnd is NULL, the reason for the error is obtained from GetLastError()
    http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx

    The error codes are explained here
    http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx
    please see my last post

Page 2 of 11 FirstFirst 12345 ... 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
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center