CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 14 of 14
  1. #1
    Join Date
    Aug 2006
    Posts
    98

    Calling non-static functions from WndProc()

    Hello,

    I am just starting out trying to write a Windows application using the Windows API, but I am having problems understanding the WndProc() function. I know that WndProc() is called whenever any user input is detected, such as a key being pressed or the mouse being clicked. So, I want to perform a function (such as drawing a box onto the window) whenever a mouse click is performed. This can be defined as a function inside my class, but it would be a non-static function, because it requires access to certain member variables of my class (such as the location to draw the box - which can change and is non-static). However, I cannot call the non-static function from the static function WndProc()...

    I tried setting this variable as a global variable, but i) isn't this bad practice and ii) this means that I can only have one instance of my window class running. I need to be able to call non-static functions and acces non-static variables from the WndProc() function in order to process the user input.

    How can this be done?

    Thanks!

  2. #2
    Join Date
    Aug 2009
    Posts
    219

    Re: Calling non-static functions from WndProc()

    Try to make other classes for a simple solution.

    You could also make a new variable of the class and call it like that.

  3. #3
    Join Date
    Aug 2006
    Posts
    98

    Re: Calling non-static functions from WndProc()

    I'm sorry, I don't understand your solution....

    Basically I'm confused because WndProc() is static, and so this means that it cannot access any non-static variables or non-static functions in a class. Supposing I have a non-static variable "int my_int" which I want to increment every time the mouse is clicked, then WndProc() cannot access my_int because it is non-static. It could only access my_int if it was static and every object shared the same value for my_int. This means that all my instances of the window class have to have exactly the same values for their variables..... I know that this must be wrong but I can't work out how!

    Thanks...

  4. #4
    Join Date
    Aug 2009
    Posts
    219

    Re: Calling non-static functions from WndProc()

    CWindow is your class for example

    CWINDOW::Wnproc(...)
    {
    case WM_COMMAND:
    CWindow * x = new CWindow();
    CWindow->urfunction();
    }

    Guess that should work, at least I can remember something like that.

    But why not create a seperate class for seperate things?

    Class for handle things etc.

  5. #5
    Join Date
    Aug 2006
    Posts
    98

    Re: Calling non-static functions from WndProc()

    Thanks for your help. This would mean that I would have to create my class from scratch again, which means resetting all variables to their original values in the constructor. All the variable values would be lost so I couldn't continually update variables, when a key is pressed for example. Also, it seems very inefficient to create a new class on every user input. I need to be able to call functions and access variables from the same object instance that called WndProc() .....

    Thanks!

  6. #6
    Join Date
    Aug 2009
    Posts
    219

    Re: Calling non-static functions from WndProc()

    Quote Originally Posted by ejohns85 View Post
    Thanks for your help. This would mean that I would have to create my class from scratch again, which means resetting all variables to their original values in the constructor. All the variable values would be lost so I couldn't continually update variables, when a key is pressed for example. Also, it seems very inefficient to create a new class on every user input. I need to be able to call functions and access variables from the same object instance that called WndProc() .....

    Thanks!
    I was pointing at a class like this

    class CCallBack
    {
    public:
    bool Create(HWND,hParam,lParam)
    bool Paint(...
    bool Notify(...

    etc...

    What kind of values?

  7. #7
    Join Date
    Aug 2006
    Posts
    98

    Re: Calling non-static functions from WndProc()

    Here is my class:
    Code:
    class MyWindow
    {
    public:
    // Attributes
    int num_squares;
    
    // Functions
    MyWindow()
    {
        num_squares = 0;
        // Other stuff like registering the window class
    };
    static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param);
    void DrawSquare();
    
    };
    Suppose that every time I click on the window, I want it to increment the value of num_squares. Then, I want it to draw that number of squares onto the window. Therefore, DrawSquare() must be able to access the value of num_squares. This means that it cannot be static. This then means that it cannot be called by WndProc...

    I can see that your class CCallBack would work in a static sense, but how can you let CCallBack know that value of num_squares?

    Thanks again!

  8. #8
    Join Date
    Aug 2008
    Posts
    902

    Re: Calling non-static functions from WndProc()

    Your Window class should have one callback function which routes the messages to the window instances non-static callback. You can keep a std::map<HWND, Window*>.

  9. #9
    Join Date
    Aug 2009
    Posts
    219

    Re: Calling non-static functions from WndProc()

    Quote Originally Posted by ejohns85 View Post
    Here is my class:
    Code:
    class MyWindow
    {
    public:
    // Attributes
    int num_squares;
    
    // Functions
    MyWindow()
    {
        num_squares = 0;
        // Other stuff like registering the window class
    };
    static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param);
    void DrawSquare();
    
    };
    Suppose that every time I click on the window, I want it to increment the value of num_squares. Then, I want it to draw that number of squares onto the window. Therefore, DrawSquare() must be able to access the value of num_squares. This means that it cannot be static. This then means that it cannot be called by WndProc...

    I can see that your class CCallBack would work in a static sense, but how can you let CCallBack know that value of num_squares?

    Thanks again!
    Why don't you make the int num_squares also in the other class as a static int.

  10. #10
    Join Date
    May 2000
    Location
    Armenia
    Posts
    201

    Re: Calling non-static functions from WndProc()

    I'll suggest you to use SetProp and GetProp functions from Windows API.
    Once the window is created, you can set the pointer to your class as the property of the window using SetProp.
    Then in window procedure you can get the pointer to your class from HWND with GetProp function.
    Also the property should be removed in WM_DESTROY or WM_NCDESTROY with RemoveProp.
    Code:
    class MyWindow
    {
    	public:
    	// Attributes
    	int num_squares;
    
    	// Functions
    	MyWindow()
    	{
       		num_squares = 0;
    
    		// Other stuff like registering the window class
    		
    		// Creating a window.
    		HWND hWnd = CreateWindow(...);
    		SetProp(hWnd, "MyWindow", (HANDLE)this);
    	};
    
    	static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param);
    };
    Then you can access the instance of your class from window procedure:
    Code:
    LRESULT CALLBACK MyWindow::WndProc(HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param)
    {
    	switch(msg)
    	{
    		case WM_LBUTTONDOWN:
    		{
    			MyWindow* pMyWindow = (MyWindow*)GetProp(hwnd, "MyWindow");
    			if(NULL != pMyWindow)
    			{
    				// Increment num_squares.
    				++pMyWindow->num_squares;
    			}
    
    			break;
    		}
    
    		case WM_DESTROY:
    		{
    			RemoveProp(hwnd, "MyWindow");
    
    			break;
    		}
    	}
    
    	return DefWindowProc(hwnd, msg, w_param, l_param);
    }
    For second parameter of SetProp/GetProp/RemoveProp to be unique GlobalAddAtom function can be used or some GUID string.

  11. #11
    Join Date
    Jun 2011
    Posts
    4

    Re: Calling non-static functions from WndProc()

    Your Window class should have one callback function which routes the messages to the window instances non-static callback.

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

    Re: Calling non-static functions from WndProc()

    Quote Originally Posted by ejohns85 View Post
    I am just starting out trying to write a Windows application using the Windows API, but I am having problems understanding the WndProc() function. I know that WndProc() is called whenever any user input is detected, such as a key being pressed or the mouse being clicked. So, I want to perform a function (such as drawing a box onto the window) whenever a mouse click is performed. This can be defined as a function inside my class, but it would be a non-static function, because it requires access to certain member variables of my class (such as the location to draw the box - which can change and is non-static). However, I cannot call the non-static function from the static function WndProc()
    ...
    How can this be done?
    You seem to try reinventing the MFC framework!?
    Well, stepping in the MFC source code for a simple SDI app would be a good start!
    Victor Nijegorodov

  13. #13
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Calling non-static functions from WndProc()

    Quote Originally Posted by ejohns85 View Post
    Hello,

    I am just starting out trying to write a Windows application using the Windows API, but I am having problems understanding the WndProc() function. I know that WndProc() is called whenever any user input is detected, such as a key being pressed or the mouse being clicked. So, I want to perform a function (such as drawing a box onto the window) whenever a mouse click is performed. This can be defined as a function inside my class,
    I tried setting this variable as a global variable, but i) isn't this bad practice and ii) this means that I can only have one instance of my window class running. I need to be able to call non-static functions and acces non-static variables from the WndProc() function in order to process the user input.

    How can this be done?
    Read VictorN's post to you.

    Before you even think about writing classes to encapsulate the Windows API framework, you must know what all of those API functions do and how to use them in a non object-oriented program, since the Windows API is not an object-oriented framework. That is the only way to begin to understand how to write classes to encapsulate the Windows API.

    Write your program without using classes -- look at the structure and how the calls are made and processed. Once you know the API, then you must know C++ at least at an intermediate level, preferably an advanced level to understand how to encapsulate such an API.

    You could throw something together to solve your immediate issue, but what goal would have been reached? You will then want to write more programs, and then you'll come across other issues related to encapsulating the API in an object-oriented framework. Then this thread would become almost endless as to how to properly do something in Windows API within a C++ framework.

    Instead of this, there are many existing frameworks that have encapsulated the Windows API, the major one being MFC, as Victor has pointed out. If you want to see how this framework does things, then step into the MFC source code for a simple application. You will see that it isn't trivial, and the reason is again, it isn't easy to wrap an event-driven, non object-oriented API into C++ classes.

    If not MFC, there are others such as the old Borland OWL library, and what www.relisoft.com has done:

    http://www.relisoft.com/win32/index.htm

    The objective is to study what others have done, so you have a coherent understanding of this endeavor (if this is a learning exercise).

    Otherwise, if this is not a learning exercise, then just use MFC.

    Regards,

    Paul McKenzie

  14. #14
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: Calling non-static functions from WndProc()

    If this is not a learning exercise, then I agree with the comments by VictorN and Paul McKenzie.

    If this is a learning exercise, then I highly recommend the book "Windows ++: Writing Reusable Windows Code in C++" by Paul DiLascia, see http://www.dilascia.com/wpp.htm

    The book explains an OOP philosophy for encapsulating the Windows API, and provides a roadmap of the reasoning behind the OOP framework. Read this book first, if you are trying to understand the MFC framework.

    Note that the book explains concepts that were important in 1992 and 16-bit Windows 3.1, and many of these concepts (like memory management in Chapter 4) are no longer pertinent. But as a guide to understanding a principled roadmap to encapsulation of the Windows API into an OOP framework, it's unmatched.

    Mike

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