Home

Introduction to Windows Controls

    

Controls Fundamentals

 

Introduction

 

A Windows control, also called a control, is an object that displays on, or is part of, an application and allows the user to interact with the computer. There are various types of controls as we will see:

  • A text-based control is an object whose main function is to display or request text
  • A list-based control displays a list of items
  • A progress-based control is used to show the progress of an action
  • a static control can be used to show colors, a picture or something that does not regularly fit in the above categories

To make your application as efficient as possible, you will add controls to a dialog box when you judge it necessary. Some and most controls are already available so you can simply customize their behavior and appearance. Sometimes you will need a control for a specific task or for a better look. If such a control is not available, you may have to create your own.

There are two main ways a control is made part of your application. At design time, which is the time you are visually creating an application, you will select controls and place them on a dialog box. Another technique, referred to as run time, consists of creating a control programmatically. In this case you must write all the code that specifies the control's appearance and behavior.

Practical LearningPractical Learning: Introducing Windows Controls

  1. Start Microsoft Visual Studio
  2. To create a new application, on the main menu, click File -> New Project...
  3. In the middle list, click MFC Application
  4. Set the Name to Geometry1
  5. Click OK
  6. In the first page of the MFC Application Wizard, click Next
  7. In the second page of the wizard, click Dialog Box
  8. Click Next
  9. In the third page of the wizard, click About Box to remove the check mark on it
  10. Change the Dialog Title to Geometry - Quadrilateral
  11. Click Next twice
  12. Click Finish
  13. On the dialog box, click TODO: and press Delete
  14. Test the application to make sure it is working fine
  15. Close the dialog box and return to your programming environment

The Parent-Child Window Relationship

There are two types of windows or controls you will deal with in your applications. The type referred to here is defined by the relationship a window has with regards to other windows that are part of an application:

  • Parent: a window is referred to as a parent when there are, or there can be, other windows that depend on it. For example, if you look at the toolbar of Microsoft Visual Studio, it is equipped with some buttons. The toolbar is a parent to the buttons. When a parent is created, it "gives life" to other windows that can depend on it. The most regular parents you will use are dialog boxes
  • Child: A window is referred to as child when its existence and especially its visibility depend on another window called its parent.

When a parent is created, made active, or made visible, it gives existence and visibility to its children. When a parent gets hidden, it also hides its children. If a parent moves, it moves with its children. The children keep their positions and dimensions inside the parent. When a parent is destroyed, it also destroys its children (sometimes it does not happen so smoothly; a parent may make a child unavailable but the memory space the child was occupying after the parent has been destroyed may still be in use, sometimes filled with garbage, but such memory may not be available to other applications until you explicitly recover it).

Child controls depend on a parent because the parent "carries", "holds", or hosts them. All of the Windows controls you will use in your applications are child controls. A child window can also be a parent of another control. For example, the Standard toolbar of Microsoft Visual Studio is the parent of the buttons on it. If you close or hide the toolbar, its children disappear. At the same time, the toolbar is a child of the application's frame. If you close the application, the toolbar disappears, along with its own children. In this example, the toolbar is a child of the application but is a parent to its buttons.

Author Note

It is important to understand that this discussion refers to parents and children as windows, not as classes.

   

The Client Area of a Parent

To use an object in your application, you must provide it with "physical" presence. If you add the control visually, it assumes the position where you place it. If you are programmatically creating the control, you must know how much space its parent window is making available to its children before even deciding about its location and dimensions.

To provide its parental support to the child controls, the parent window allocates an amount of space in a rectangular shape called the client area:

Client Area

The objects you add are confined to the client area offered by the parent window. After visually adding an object to a parent, it assumes a location and takes some dimensions in this area. The origin of the rectangular client area is on the upper-left corner of the parent window. The horizontal measurements move from the origin to the right. The vertical measurements move from the origin to the bottom:

Origin


An object can be added only in the client area.

Control Design

 

The Toolbox

The controls used to provide functionality to your application are provided by the Toolbox window. By default, the Toolbox is positioned to the left of Microsoft Visual Studio as a long vertical window. By default, the Toolbox shows each control as a row with an icon on the left and the name of the control on the right side::

Toolbox Toolbox Toolbox

If you don't need the explicit name, you can make the Toolbox display only the icons. To do that, right-click any section of the Toolbox and click List View to remove the check box on it:

Toolbox

As mentioned already, by default, the Toolbox is position to the left. If you want, you can move it. To do that, click and drag its title bar away from it current position.

The Toolbox presents a certain number of records. More objects, called ActiveX controls, can be accessed and added to the Toolbox but such additional objects are made available only to the current application.

The first icon in the Toolbox is named Pointer. This is not a control, it allows you do deselect.

The Dialog Editor

To assist you with dialog and controls design, you can use the Dialog Editor. It is a dialog box equipped with various buttons:

Dialog Editor

To get the Dialog Editor:

  • On the main menu, click View -> Toolbars -> Dialog Editor
  • Right-click the main menu or any toolbar and click Dialog Editor

Practical LearningPractical Learning: Using the Dialog Editor

  • On the main menu, click View -> Toolbars -> Dialog Editor

Adding Controls to a Dialog Box

To add one of the controls in your application, you can click it and click a host. You can keep adding controls on the dialog box when necessary. If you want to add a control over and over again, press and hold Ctrl. Then click the control in the Toolbox and release Ctrl. Then click the desired area on the dialog box. Every time you click, the control would be added to the dialog box. Once you have added enough controls, to dismiss it:

  • Click the control again on the Toolbox to deselect it
  • Press Esc

You cannot select more than one control to add on a host.

Another technique you can use to visually add a control is to "design" it. To do this, after clicking the control from the Toolbox, you can click and hold the mouse on the parent window, then drag left, up, right, or down. While you are dragging, you can refer to the right section of the status bar for the current location and dimensions of the control:

Control Design

Practical LearningPractical Learning: Adding a Windows Control to a Dialog Box

  1. On the main menu, click View -> Toolbox.
    In the Toolbox, click Custom Control Custom Control and click the dialog box
  2. Save the dialog box

Control's Design and Sizing Using Grids

To help you position the controls you are adding at design time, you can display some guiding grid dots. To do this:

  • On the main menu, click Format -> Guide Settings... In the Guide Settings dialog box, click Grid:

Grid Settings

  • On the Dialog Editor, click the Toggle Grid button Toggle Grid

After you have allowed the grids, the controls can be positioned and resized anywhere in the area inside the borders of the parent window, using the grids as guides:

Grid

When you click the body of the parent, the top-left corner of the control would be positioned on a dot and the dimensions (width and height) of the control would align with the next dots on its right and bottom. To avoid this default behavior, before clicking the body of the parent, press and hold Alt; then click and drag to draw a rectangle shape of the control. The location would be where you clicked, even if you clicked between two dots. The dimensions would stop where you released the mouse, even it if was between two dots.

After placing a control on a parent window that displays grids, the borders of the child control can only be aligned with the black dots. The grids are separated using a measure called the Dialog Box Unit or DLU. By default, two vertically aligned dots are separated by a height of 6 DLUs. Two horizontally aligned dots are separated by a width of 6 DLUs. If these measures don't fit you, there are two options you can use:

  • After placing the control, to control its location with more precision, press the up, left, right, or down arrow keys (on the keyboard). In this case, the control would move by one pixel in the direction of your choice. To control its size, press and hold Shift. Then press the up or down arrow keys to move only the bottom border of the control; or press the left or right keys to move the right border of the control
  • To modify the distance between dotted grids, display the Guide Settings dialog box available from the Format menu then modify the Width and/or Height values in the Grid Spacing section

Practical LearningPractical Learning: Designing With Grids

  • To show the grid lines, on the Dialog Editor toolbar, click the Toggle Grid button Toggle Grid

Control's Location and Size Without Grids

You can position the controls without using grids. If you do not want to use the grids, you can hide them. To do this, display the Guide Settings dialog box and click either None or Rulers and Guides.

To restrict the area available for controls in the click area of the parent, a dialog box can be equipped with a dotted box. To show it, display the Guide Settings dialog box and click Rulers and Guides:

Rulers and Guides

In the Rulers and Guides view, the studio displays a horizontal ruler above the dialog box and a vertical ruler to the left. It also displays a blue rectangular box on the dialog box. This (blue dotted) rectangle allows you to effectively control the area available to your controls. To set the location and dimensions of the available area, click one of the (blue dotted) rectangle borders or corners and drag in the desired direction. You can click and drag a border or a corner of the dotted rectangle to change the area available to child controls:

Rulers and Guides

After setting the (blue dotted) rectangular location and area, you can add but cannot move a control outside of that (blue dotted) rectangle. The idea is to allow you to design a control or a group of controls in a confined area. The (blue dotted) rectangle provides an effective means of aligning controls. After using it, if you want to add and manipulate controls outside of it, you should display the grids.

Selecting Controls on a Parent Window

To visually manipulate a control, you will first need to select it. To select a control, simply click it. A control that is selected is surrounded with 8 (blue) small squares:

Design Handles

To select more than one control in the same area, click on the dialog box and draw a "fake" rectangle that encloses all of the needed controls. The first control from the selected group has 8 (blue) handles while the other control(s) from the same selected group has (have) 8 white handles (each).

To select controls at random, click one of them. Press and hold either Shift or Ctrl. Then click each one of the needed controls.

Resizing the Controls

After adding a control to a dialog box, it assumes either its default size or the size you drew it with. To change the size of a control, first select it. Then position the mouse on one of its handles. The mouse would assume a sizing cursor that indicates the possible type of resizing you can apply. The mouse cursors are:

Cursor Description
Cursor Moves the seized border in the North-West <-> South-East direction
Cursor Shrinks or heightens the control
Cursor Moves the seized border in the North-East <-> South-West direction
Cursor Narrows or enlarges the control

To resize a control, that is, to give it a particular width or height, position the mouse on one of the handles and drag in the desired direction.

If the dialog box is showing the grid indicators, a control can be moved or resized only on the dotted lines. To resize more than one control at the same time. Firs select them. Then use some options in the Format menu or some buttons from the Dialog Editor toolbar:

Main Menu:
Format -> Make Same Size ->
Dialog Ediror Description
 Width Make Same Width Applies the same width to all selected controls.
The width used will be be that of the last control selected
Height Make Same Width Applies the same height to all selected controls.
The height used will be be that of the last control selected
Size Make Same Width Applies the same width and height to all selected controls.
The height used will be be that of the last control selected

Positioning the Controls

The controls you position on a dialog box assume their given place. Most of the time, these positions are not practical. You can move them around to any positions of your choice. To move a control, click and drag it, while the mouse cursor is a cross Cross, in the desired direction until it reaches the intended position.

To move a group of controls, first select them. Then drag the selection to the desired location. To help with positioning the controls, you can use the main menu or the Dialog Editor toolbar:

Main Menu:
Format -> Align
Dialog Ediror Description
Lefts Make Same Width All selected controls will use the left alignment of the control with the dark blue handles
Rights Make Same Width All selected controls will use the right alignment of the control with the dark blue handles
Tops Make Same Width All selected controls will use the top alignment of the control with the dark blue handles
Bottoms Make Same Width All selected controls will use the bottom alignment of the control with the dark blue handles

Centering the Controls

You can center the controls in the client area of the dialog box based on one control used as the reference. To do this, first select the controls. Then use the Format menu or the Dialog Editor:

Main Menu:
Format -> Center in Dialog
Dialog Ediror Description
Vertical Make Same Width The studio will calculate the total height of all selected controls. Then it will center them with regards to the height of the client area of the dialog box
Horizontal Make Same Width The studio will calculate the total width of all selected controls. Then it will center them with regards to the width of the client area of the dialog box

If you have selected more than three controls, you can apply the same distance among the ranges. Once again, you can use either the Format menu or the Dialog Editor:

Main Menu:
Format -> Space Evenly
Dialog Ediror Description
Across Make Same Width All (vertical) columns of selected controls will be separated by the same width
Down Make Same Width All (horizontal) rows of selected controls will be separated by the same height

You can also center some controls with regards to another control used as reference. To do this, select at least two controls with different widths. Then, on the main menu, click Format -> Align -> Centers or click Format -> Align -> Middles.

Practical LearningPractical Learning: Designing a Dialog Box

  1. Again, on the Toolbox, click Custom Control Custom Control and click the dialog box
  2. Continuing with the Custom Control and the buttons on the Dialog Editor, complete the design of the dialog box as follows:
     
    Application Design
  3. Save all

Tab Ordering

The controls you add to a dialog box are positioned in a sequence that follows the order they were added. When you add a control on the host that already has other controls, regardless of the section or area you place the new control, it is sequentially positioned at the end of the existing controls. If you do not fix it, the user would have a hard time navigating the controls.

The sequence of controls navigation is called the tab order. While designing a dialog box, to change the sequential order of controls, on the main menu, click Format and click Tab Order or press Ctrl + D.

Practical LearningPractical Learning: Tab Ordering the Controls

  1. On the main menu, click Format -> Tab Order
  2. On the dialog box, click the top-left control
  3. Continue clicking the controls from left to right and from top-down
     
    Application Design
  4. Save all
 
 
 

Fundamentals of Creating Windows Controls

 

Introduction to Handles

Every object in Microsoft Windows is assigned a positive number named a handle. This number allows the operating system to communicate with the object. In the same way, the number allows the object to identify itself when other objects of its applications or when the operating system needs to know.

In Microsoft Windows, the handle of an object is identified with a class named HWND. Many times in your code, you will need to get, and refer to, the handle of an object.

Introduction to Win32 Control Creation

There are two particularly important pieces of information about every control of your application. The information stored in the control and the action or type of action the user can perform on that control. At one time in the life of an application, a control holds a value that can be of particular interest either to you or to the user. On the other hand, when interacting with the computer, based on your application, the user will usually face different types of controls that do various things and produce different results. These are two features of controls (their values and the actions the user can perform on them) that you should know as much as possible, about the controls you choose to involve in your application.

To support the ability to create a control, the Win32 library provides two functions named CreateWindow and CreateWindowEx. The syntaxes of these functions are:

HWND CreateWindow(      
	LPCTSTR lpClassName,
    	LPCTSTR lpWindowName,
    	DWORD dwStyle,
    	int x,
    	int y,
    	int nWidth,
    	int nHeight,
    	HWND hWndParent,
    	HMENU hMenu,
    	HINSTANCE hInstance,
    	LPVOID lpParam
);
HWND CreateWindowEx(      
    	DWORD dwExStyle,
    	LPCTSTR lpClassName,
    	LPCTSTR lpWindowName,
    	DWORD dwStyle,
    	int x,
    	int y,
    	int nWidth,
    	int nHeight,
    	HWND hWndParent,
    	HMENU hMenu,
    	HINSTANCE hInstance,
    	LPVOID lpParam
);

In most cases, you can use either of these functions. When doing this, you must specify the control's name. To help with this, the Win32 library provides already defined names of classes you can use to create a control.

When creating a window, you need to declare its handle and initialize it with the CreateWindow() or the CreateWindowEx() function. If the window is created successfully, the function returns a window handle. If the control created was a parent, its handle can be used as the hWndParent argument.

The reason you declare a handle to the parent window is to allow you to refer to it later on. In the same way, if you need to refer to any control that is part of your application, you should define its own handle.

Introduction to MFC Control Creation

The Microsoft Foundation Class library, MFC, is a Microsoft custom implementation of the Win32 library. While programming in Win32 is mostly done manually by writing code, Microsoft Visual Studio makes it possible to visually create an application by adding objects to a host such as a dialog box. Still, most of the time you will need to know the class used to manage an object.

The most fundamental class used for visible objects in the MFC is called CWnd. The CWnd class is derived from the CCmdTarget class:

CWnd

As we will see throughout our lessons, the CWnd class provides all, or almost all, of the functionality you need to create or manage a Windows control. When necessary, we will mentioned the CreateWindow() and/or the CreateWindowEx() function to explain a concept, but most of the time, you will use either CWnd or one of its derived classes to take necessary action.

To assist you with creating a control, the CWnd class is equipped with a method named Create that corresponds to the Win32's CreateWindow() function. The syntax of the CWnd::Create() function is:

virtual BOOL Create(LPCTSTR lpszClassName,
   		    LPCTSTR lpszWindowName,
   		    DWORD dwStyle,
   		    const RECT& rect,
		    CWnd* pParentWnd,
   		    UINT nID,
   		    CCreateContext* pContext = NULL);

To provide the ability to apply extended styles to a control, the CWnd class is equipped with a CreateEx() method that is overloaded with two versions. Their syntaxes are:

virtual BOOL CreateEx(DWORD dwExStyle,
   		      LPCTSTR lpszClassName,
   		      LPCTSTR lpszWindowName,
   		      DWORD dwStyle,
   		      int x,
   		      int y,
   		      int nWidth,
   		      int nHeight,
   		      HWND hWndParent,
   		      HMENU nIDorHMenu,
   		      LPVOID lpParam = NULL );

virtual BOOL CreateEx(DWORD dwExStyle,
   		      LPCTSTR lpszClassName,
   		      LPCTSTR lpszWindowName,
   		      DWORD dwStyle,
   		      const RECT& rect,
   		      CWnd* pParentWnd,
   		      UINT nID,
   		      LPVOID lpParam = NULL);

The Control's Class Name

To create a control, you must specify its name. To do this, you have various options. The Win32 library provides already defined names of classes you can use to create a control. These classes are:

Class Name Description
STATIC A static control can be used to display text, a drawing, or a picture
EDIT As it name suggests, an edit control is used to display text to the user, to request text from the user, or both
RichEdit Like an edit box, a rich edit control displays text, requests it, or does both. Besides all the capabilities of the edit control, this control can display formatted text with characters or words that use different colors or weight. The paragraphs can also be individually aligned. The RichEdit class name is used to create a rich edit control using the features of Release 1.0 of its class
RICHEDIT_CLASS This control is used for the same reasons as the RichEdit class name except that it provides a few more text and paragraph formatting features based on Release 2.0
LISTBOX A list box is a control that displays items, such as text, arranged so each item, displays on its own line
COMBOBOX A combo box is a combination of an edit control and a list box. It holds a list of items so the current selection displays in the edit box part of the control
SCROLLBAR A scroll bar is a rectangular object equipped with a bar terminated by an arrow at each end. It is used to navigate left and right or up and down on a document
BUTTON A button is an object that the user clicks to initiate an action
MDICLIENT This class name is used to create a child window frame for an MDI application

To use one of these classes, you have various options. At design time, in the Toolbox, you can click the Custom Control button and click the dialog box. In the Properties window, click Class and type the class name. If you are programmatically creating the control, pass its name as string to the lpszClassName argument of the Create() or the CreateEx() methods. Here is an example that would start an edit box:

void CSecondDlg::OnThirdControl()
{
    CWnd *memo = new CWnd;

    memo->Create("BUTTON", );
}

The other option you have is to specify the class name as NULL. In this case, the compiler would use a default name:

void Whatever ()
{
    CWnd *second = new CWnd;

    second->Create(NULL, );
}

Practical LearningPractical Learning: Creating a Control

  1. On the dialog box, right-click the top-left control and click Properties.
    In the Properties window, click the Properties button Properties
  2. In the Properties window, click the Class box, type Static and press Enter
  3. Click the control in the top-center of the dialog box
  4. In the Properties window, click Class, type EDIT (this is not case-sensitive) and press Enter

The Control's Window Name

The window name is a default string that displays on the control when the control comes up. In some cases, this string displays as caption on the title bar of a dialog box. This property is different for various controls.

To set the default text of a control, you can either do this when creating the control or change its text at any time. This depends on the control. To set the default text when programmatically creating the control, pass a string value as the lpszWindowName argument of the Create() or CreateEx() method. Here is an example:

void CSecondDlg::OnThirdControl()
{
    CWnd *memo = new CWnd;

    memo->Create("EDIT", "Voice Recorder", );
}

Many (even most) controls do not use a window name. Therefore, you can pass it as NULL.

The Handle to a Window

When you create a parent window, if you want to refer to that parent control, you should use the value returned by the CreateWindow() or the CreateWindowEx() function, which is an HWND value. If you are creating an MFC application, you usually call the Create() method of the window you are creating. As the parent of all window classes of an MFC application, CWnd provides a member variable called m_hWnd. It is defined as follows:

HWND m_hWnd;

This public variable is inherited by all classes that are based on CWnd, which includes all MFC window objects. Consequently, m_hWnd gives you access to the handle to the window you have created. For example, the CDialog class, which is based on CWnd but is the most used host of Windows controls, can provide its m_hWnd variable as the parent of its control. In the same way, to get a handle to any control of your application, access its m_hWnd member variable.

If you had created a window using the Win32 API's CreateWindow() or CreateWindowEx() function, or if for any reason an HWND object exists in your application, you can convert such a window to a CWnd pointer using the CWnd::FromHandle() method. Its syntax is:

static CWnd* PASCAL FromHandle(HWND hWnd);

Here is an example:

HWND ThisWnd;

ThisWnd = CreateWindow(. . .);

CWnd *NewWnd;

NewWnd->FromHandle(ThisWnd); 

Once a control has been created, you and your users can exploit it. On one hand, the user can type a value, select text, scroll, or click something. One of your jobs as a programmer is to predict as many actions as the user may want to perform on your control(s) and take appropriate actions. One way you can refer to a control in your code consists of first providing it with an identifier. Another prerequisite you can take is to declare and associate a control and/or a value variable for the control. Sometimes you will not have declared a control variable for a control but at one time you need to refer to it. One way you can do this is to use the control's identifier and cast it to its corresponding class. This can be taken care of by calling the CWnd::GetDlgItem() method. It comes in two versions as follows:

CWnd* GetDlgItem(int nID) const;
void CWnd::GetDlgItem(int nID, HWND* phWnd) const;

By providing the nID argument as the identifier of the control to this method, you can get a pointer to its class. To do this, you can declare a pointer to the class of the control, then call the GetDlgItem() method. Because GetDlgItem() returns a CWnd pointer, using the features of inheritance, cast this return value to the class of the control.

Control's Identification

Every Windows control in Microsoft Windows should provide a way to identify itself, to the operating system and to other objects on the computer. In Lesson 5, when introducing dialog boxes, we saw how to create a resource file. In such a resource file, you can create an identifier for a control. There are two main ways you can create an identifier for a control:

  • When designing an application, after adding a control to a dialog box, access its Properties window and change the value of the ID field
  • Open the resource file, the file with the .rc extension and create an entry for the control in the dialog box section. Provide a constant value in the line for the control. Open the Resource.h and add the same identifier using its name and its constant value
  • Open the String Table and create an entry for a new identifier by providing a name and a number
  • Use the Resources Symbols dialog box and create a new identifier

If you want to avoid providing an identification for a control, you may have to use the Win32 API's CreateWindow() or CreateWindowEx() function to create the control.

Imagine a control with its identifier has already been added to a dialog box but you want to change that identifier, for any reason you judge necessary. To assist you with this, the CWnd class is equipped with the SetDlgCtrlID() method. Its syntax is:

int SetDlgCtrlID(int nID);

This method assigns or changes the identifier of the control that called it. Imagine the control variable of a control is named m_Edition, you can assign a new identifier to it as follows:

BOOL CDlgControls::OnInitDialog()
{
    CDialog::OnInitDialog();

    m_Edition.SetDlgCtrlID(0x1882);

    return TRUE;
}

If a control has been created and you need its identifier, you can find it out by calling the CWnd::GetDlgCtrlID() method. Its syntax is:

int GetDlgCtrlID() const;

This method simply returns the identifier of the control that called it. The value is returned as an integer. You will mostly use this method to find out if the identifier of a control matches the one the user has just accessed.

Practical LearningPractical Learning: Creating Controls' Identifications

  1. On the dialog box, click the top-left control to select it
  2. In the Properties window, click ID, type IDC_SSIDE_LBL and press Enter
  3. Click the control in the top-middle
  4. In the Properties window, click ID, type IDC_SIDE_EDT and press Enter

Parent-Child Management

 

Introduction

In the previous lessons, we reviewed some of the characteristics of a classic container such as a dialog box. In the next sections, we will review some of the characteristics of child controls. Based on their relationship in the application, a parent and a child must communicate and share some behaviors. To make this happen, you will need to identify or get a reference to the application, to the parent control, or to the control itself. Probably the most fundamental piece of information you must know about an application is its instance.

The Instance of an Application

If you create an MFC application using the CWinApp class, when the application comes up, it creates an instance, which is usually the hInstance in Win32. Sometimes you will need to refer to the instance of your application. To help you with this, CWinApp class is equipped with a property named m_hInstance. Alternatively, for an MFC application, you can call the AfxGetInstanceHandle() global function to get a handle to the instance of your application. This could be accessed as follows:

BOOL CDialog1Dlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    HINSTANCE InstanceOfThisApp = AfxGetInstanceHandle();

    return TRUE;
}

Retrieving Control Information

To help you get information about a control, the Win32 library provides the GetWindowLong() function. Their syntaxes are:

LONG GetWindowLong(HWND hWnd, int nIndex);

After this function executes, it returns a LONG value. If you prefer to get a pointer and if you are working on a 64-bit environ, use the GetWindowLongPtr() function instead. Its syntax is:

LONG_PTR GetWindowLongPtr(HWND hWnd, int nIndex);

The first argument, hWnd, is a handle to the control whose information you are seeking. The nIndex argument specifies the type of information you are looking for. Its possible values are:

nIndex Value Description
GetWindowLong GetWindowLongPtr
GWL_EXSTYLE  This is used to get information about the extended style(s) used on the control
GWL_STYLE This is used to get information about the style(s) used on the control
GWL_WNDPROC GWLP_WNDPROC Remember that a window procedure is a function pointer. If such a procedure was used to handle the message(s) for the hWnd control, use this constant to get the address of that procedure
GWL_HINSTANCE GWLP_HINSTANCE This gives access to the handle to the current application
GWL_HWNDPARENT GWLP_HWNDPARENT This constant can be used to get a handle to the parent window. For example, you can use it the get a handle to a dialog box that is hosting the hWnd control
GWL_ID GWLP_ID This gives you the ID of the hWnd control
GWL_USERDATA GWLP_USERDATA This gives you a 32-bit value used by the current application


If the hWnd argument represents a dialog box, nIndex can use the following values:

nIndex Value Description
GetWindowLong GetWindowLongPtr
DWL_DLGPROC DWLP_DLGPROC This provides the address of, or a pointer, to the procedure of the dialog box
DWL_MSGRESULT DWLP_MSGRESULT This provides the return value of the dialog box's procedure
DWL_USER DWLP_USER This provides additional information about the application

After calling this function and specifying the type of information you need, it returns a (constant) value you can use as you see fit. Here are two methods of getting a handle to the instance of the application. The second example uses the GetWindowLong() function:

BOOL CExerciseDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    HINSTANCE Instance1 = AfxGetInstanceHandle();
    LONG Instance2 = GetWindowLong(m_hWnd, GWL_HINSTANCE);

    m_Instance1.Format("%ld", Instance1);
    m_Instance2.Format("%ld", Instance2);
    UpdateData(FALSE);

    return TRUE; // return TRUE unless you set the focus to a control
}

Changing Control Information

We will see how to define the properties, styles, and other characteristics when creating a control. While the user is interacting with the computer using your application, you may need to change some of these attributes of a window. To change the value of an aspect of the window, you can call the SetWindowLong() function. Its syntax is:

LONG SetWindowLong(HWND hWnd, int nIndex, LONG dwNewLong);

If you want to work with a pointer instead of a value, you can use the SetWindowLongPtr() function. Its syntax is:

LONG_PTR SetWindowLongPtr(HWND hWnd, int nIndex, LONG_PTR dwNewLong);

The hWnd argument is a handle to the window whose informtation you want to change. The value of nIndex species the type of information you want to change. It can have the following values:

nIndex Value Description
GetWindowLong GetWindowLongPtr
GWL_EXSTYLE  Allows changing the extended style(s) of the window or control
GWL_STYLE Allows changing the style(s) of the window or control
GWL_WNDPROC GWLP_WNDPROC Allows changing the procedure of the control
GWL_HINSTANCE GWLP_HINSTANCE Changes the application instance of the control
GWL_ID GWLP_ID Allows changing the ID value of the control
GWL_USERDATA GWLP_USERDATA Gives access to a 32-bit value associated with the window, allowing it to be changed

If the hWnd argument represents a dialog box, the nIndex argument can also have the following values:

nIndex Value Description
GetWindowLong GetWindowLongPtr
DWL_DLGPROC DWLP_DLGPROC Allows changing the procedure of the dialog box
DWL_MSGRESULT DWLP_MSGRESULT Allows changing the return value of the procedure
DWL_USER DWLP_USER Allows changing additional information
 
 
   
 

Home Copyright © 2010-2011 FunctionX, Inc.