I'm starting to get a grasp of how to make a win32 app. So far I've been able to create a pretty decent clone of Notepad. I have a few questions about the way that I am doing things though.
My WinMain() basically creates the main and a text window and moves into the message handler. It seems like I should move the creation of the text window into the WM_CREATE portion of the main message switch case (in MainWndProc()). This doesn't look right though, I don't want to declare/initialize variables I'm not using for every loop.
So in the end, my process means that in order to get access to the edit window from within MainWndProc(), I have to declare the edit window (HWND) as a global variable. Eventually, my process is going to leave me with quite a few global variables. Should I be concerned about that?
Its actually not necessary to have any global variables in a GUI windows app LowestOne.
I'm sure that statement has you wondering how that could be possible.
There are actually a couple ways to go about it. One sort of halfway approach is to use statics which retain their values across invocations of the WndProc. However, to me that's cheating. I prefer to go the whole route, and do without them entirely.
Here is a high level description of how its done.
One decides which variables one needs to hold 'state' data, i.e., data that must persist across invocations of the WndPoc. Examples of these sorts of variables in your Notepad clone would be the position of the caret if you've created your own 'edit' control, or the address of the text buffer. One would then create a struct or class definition containing these variables. You would not declare any stack based instances of these objects though; rather you would allocate memory from the heap for an instance in your WM_CREATE handler, and you would de-allocate in WM_DESTROY. The address of the 'state' object you would store in WNDCLASSEX::cbWndExtra bytes. That way it would be available in every invocation of the WndProc through the HWND variable in the 1st parameter. As an aside, the address could also be stored in Window Properties with Get/SetProp().
Creating controls in WM_CREATE is ok, it's a standard pattern.
For a simple app with one control, a global's fine. When you have a more stuff, it can get tricky.
The app needs to know about the main window. But the main window can store information about its state (as required) and immediate children.
You cdo this by creating a struct on the heap holds all your data and store it's address with SetWindowLong with option GWL_USERDATA. You retrieve the pointer with GetWindowLong.
Thanks. I might be reading these responses wrong, but they both sort of boil down to the same thing, and that is that the main window can/should hold data about its children. Maybe I will have to redo the way I created the windows, I have a class at this point:
1 2 3 4 5 6 7 8 9 10 11
class WWindow
{
public:
WWindow() { _hwnd = NULL; } ;
HWND Create(// Arguments needed to create a WindowEx);
BOOL Show(int dCmdShow = SW_SHOWNORMAL);
operator HWND();
protected:
HWND _hwnd;
};
All of the functions are pretty basic, don't think I need to show them. Should I continue to work with a class like this? Sorry if that question is complicated. My main window and edit window are both instances of this class (who's scope is WinMain), and the edit box is a global variable that HWND that Create() returns.
Am I on the dart board? The pleasure of being so new to this is that any answers I get shake all of my fundamental knowledge :) I'm also pretty new to c++ in general.
@kbw: "You cdo this..." is this a typo that should be "You do this"? I hope so, google results for "cdo c++" are pretty scary, but not entirely out of context (I think).
Thanks again. If you want to post any code that you think will help, please feel free :). Perhaps any links to things that helped you get started? All ears here.
Please don't use GetWindowLong/SetWindowLong with GWL_USERDATA as suggested here if you ever want to compile for x64 platform or anything other than x86, you will get a crash.
Always use GetWindowLongPtr/SetWindowLongPtr with GWLP_USERDATA instead.
@modoran: Already there my friend. However, by the time I'm done with this program you would switch back to 32 XP anyway. lol. (now, do i want a scrollbar or a button.... how does a button work.....)
My guess is the actual moving could be better. I would think that I could get a RECT that was all positions (rather than the right and bottom being the size of the main window).
Anyway, this is exciting to see work.
My question now is that I'm going to have more than one child window.
When I created the original tWnd, I used the line: