16.2.4 Using Extra Bytes in Window and Class Data Structures

You can store extra, application-defined data by using the data structures that describe the attributes of a window or a window class. This extra data is known as window extra bytes and class extra bytes, respectively.

This private data is located at the end of a data structure that Windows maintains for the window. When you call the RegisterClass function, the cbWndExtra member of the WNDCLASS structure specifies the number of extra bytes of information that will be maintained for each window member of that class. The extra bytes are initialized to zero.

The technique of using the private data area of a window is particularly useful in cases where you have two or more windows that belong to the same class, and you want to associate different data with each window. Without the private data facility, you would have to maintain a list of private structures for each window. Then, each time you needed to access the data for a particular window, you would first have to locate the corresponding entry in the list. By using the private data facility, however, you can directly access the private data through the window handle rather than by using a separate list.

An additional advantage of using the window's private data area to store data is that you can encapsulate the data associated with each window better than if you were to store it as static data in the same module as, for example, the window procedure.

To write to the window's private data area, call the SetWindowWord and SetWindowLong functions. These two functions accept a byte offset within the area you set aside for private data. A zero offset refers to the first word or long value in the private area. An offset of 2 (bytes) refers to the second word value in the private area. An offset of 4 (bytes) refers to the third word value or the second long value in the private area. Note that SetWindowWord and SetWindowLong also accept constants such as GWW_STYLE and GWL_WNDPROC, which are defined in WINDOWS.H. These constants are negative offsets within the window's structure. The length of the structure (minus the private area) is thus added to the offset you provide in the call to SetWindowWord or SetWindowLong to determine the offset relative to the beginning of the structure.

To read from the private data area of a window, call the GetWindowWord and GetWindowLong functions. The offsets you specify work the same way as for SetWindowWord and SetWindowLong.

The structure for a window is allocated in USER's local heap. If you want to associate a large amount of data (more than 10 bytes) with the window, you should store a global handle in the window's private area instead of storing the actual data. The handle points to the data. This way, you increase the size of the window's structure only by the two bytes needed for the global handle, rather than by the large size of the private data itself.

Just as you can associate private data with a particular window, you can also associate private data with a window class. The functions that do this are SetClassWord, SetClassLong, GetClassWord, and GetClassLong. There are probably fewer occasions for associating private data with a window class than with a window. Using the private area for the window class is appropriate for data that is logically related to the window class as a whole and that is common among multiple windows of the same class.