-
July 3rd, 2011, 05:19 PM
#1
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!
-
July 3rd, 2011, 05:22 PM
#2
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.
-
July 3rd, 2011, 05:35 PM
#3
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...
-
July 3rd, 2011, 05:39 PM
#4
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.
-
July 3rd, 2011, 05:48 PM
#5
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!
-
July 3rd, 2011, 05:52 PM
#6
Re: Calling non-static functions from WndProc()
Originally Posted by ejohns85
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?
-
July 3rd, 2011, 06:06 PM
#7
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!
-
July 3rd, 2011, 06:22 PM
#8
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*>.
-
July 4th, 2011, 02:53 AM
#9
Re: Calling non-static functions from WndProc()
Originally Posted by ejohns85
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.
-
July 4th, 2011, 08:58 PM
#10
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.
-
July 4th, 2011, 10:13 PM
#11
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.
-
July 5th, 2011, 04:34 AM
#12
Re: Calling non-static functions from WndProc()
Originally Posted by ejohns85
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
-
July 5th, 2011, 08:46 AM
#13
Re: Calling non-static functions from WndProc()
Originally Posted by ejohns85
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
-
July 5th, 2011, 02:10 PM
#14
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|