0

As I push forward my first winapi UI, I find myself creating large, uncomfortable stacks of HWND variables in my WinMain file:

HWND foo;
HWND bar;
HWND baz;
HWND etc;

int WINAPI WinMain(...) {}

Of course, these variables are used in the functions in the rest of the file - the message loop, for example - so they must be accessible.

For my relatively small UI, I'll have something like 30 HWNDs piled up so they're in a visible scope. This makes me very suspicious that I'm doing it wrong.

Is this what should be happening, or is there a more practical way to organize this?

Ben
  • 54,723
  • 49
  • 178
  • 224
  • 1
    I'd probably go with a `std::map`. That way you can give each one a name so that you can easily identify it while still grouping them. – chris Nov 06 '12 at 02:04
  • I thought something like a hashmap would be useful, but it seems a little...subjective. It seems to add another level of complexity (remembering key names), but also leaves a big pile of stuff in a very public scope. Is this OK? – Ben Nov 06 '12 at 02:07
  • 1
    Why not make these `HWND` variables members of the classes that control the corresponding objects? – David Schwartz Nov 06 '12 at 02:08
  • @David - Huh, I hadn't thought to make the move to MVC yet but it looks like this will be the driver. Worth a try. That's probably the solution I'm looking for. – Ben Nov 06 '12 at 02:22
  • I hacked away at what I though was an MVC for way too long. Note for the next guy - it's a real bear to use a `WndProc` as a class member function, especially for a superclass. I gave up after hours and hours, it's definitely above my pay grade (gotta learn more about hooks). So, I've split my top level window into a few "panels", and each panel has a control-type class, which groups their HWNDs neatly enough, and still lets them be accessed for resizing and message handling. – Ben Nov 07 '12 at 06:48

2 Answers2

1

You have a few solutions, depending what your program is.

  1. You can put all those handles in one or many containers like std::vector.
  2. You can map them like chris suggests.
  3. If your program gets big, you might want to organize them into logical units. For example, if 15 of those windows are for one half of your logic and the other 15 for another half (say controls inside tabs) then you might want to group those controls in some way (file, class, whatever is the most logical fit).
ApplePie
  • 8,814
  • 5
  • 39
  • 60
0

You only need one HWND in your main program, and that's for a main window.

The API doesn't require a single main window, but that's most common. And even when from a user point of view the application offers several apparently independent windows, it's a good idea to have a main window in the program (it can be invisible, but provide grouping).

The other windows are then either children of the main window (within it), or windows "owned" by the main window. In general. And in particular for a first ever Windows program. :-) So you don't need separate variables for these windows. Whenever a window should react to something, that's a message to the window, which means a call of one your functions with the relevant window handle as argument.

Every child window can have a unique integer ID, and that's one way to keep track of them.

But as you get ahead you will want to associate state with each window, and the easiest way to do that is to use the Windows "subclassing" API to associate a pointer with each window. Then you can route window procedure calls to a method on an associated C++ object. Where different messages can be routed further to different message handling methods, each with access to window's state (it's just this C++ object).

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • Thanks for the tips. I'm a little confused when you say "only one HWND" because all of the common controls and their various API all create/require `HWND` objects. I'm trying to avoid having 50 `HWND` variables piled up at the front of the entry point, if possible... – Ben Nov 07 '12 at 06:45